Tutoriel : Encodage d’un fichier WMA

Ce tutoriel montre comment utiliser l’API Transcode pour encoder un fichier Windows Media Audio (WMA).

Ce tutoriel réutilise la majeure partie du code du didacticiel Encodage d’un fichier MP4. Vous devez donc d’abord lire ce tutoriel. Le seul code qui diffère est la fonction CreateTranscodeProfile, qui crée le profil de transcode.

Créer le profil transcode

Un profil de transcode décrit les paramètres d’encodage et le conteneur de fichiers. Pour WMA, le conteneur de fichiers est un fichier ASF (Advanced Streaming Format). Le fichier ASF contient un flux audio, qui est encodé à l’aide de l’encodeur audio Windows Media.

Pour générer la topologie de transcode, créez le profil de transcode et spécifiez les paramètres du flux audio et du conteneur. Créez ensuite la topologie en spécifiant la source d’entrée, l’URL de sortie et le profil de transcode.

Pour créer le profil, effectuez les étapes suivantes.

  1. Appelez la fonction MFCreateTranscodeProfile pour créer un profil de transcode vide.
  2. Appelez MFTranscodeGetAudioOutputAvailableTypes pour obtenir la liste des types de médias audio à partir de l’encodeur. Cette fonction retourne un pointeur IMFCollection qui représente une collection de pointeurs IMFMediaType .
  3. Choisissez le type de média audio qui correspond à vos exigences de transcodage et copiez les attributs dans un magasin d’attributs. Pour ce didacticiel, le premier type de média de la liste est utilisé.
  4. Appelez IMFTranscodeProfile::SetAudioAttributes pour définir les attributs du flux audio.
  5. Appelez MFCreateAttributes pour créer un magasin d’attributs pour les attributs au niveau du conteneur.
  6. Définissez l’attribut MF_TRANSCODE_CONTAINERTYPEsur MFTranscodeContainerType_ASF, ce qui spécifie un conteneur de fichiers ASF.
  7. Appelez IMFTranscodeProfile::SetContainerAttributes pour définir les attributs au niveau du conteneur sur le profil.
template <class Q>
HRESULT GetCollectionObject(IMFCollection *pCollection, DWORD index, Q **ppObj)
{
    IUnknown *pUnk;
    HRESULT hr = pCollection->GetElement(index, &pUnk);
    if (SUCCEEDED(hr))
    {
        hr = pUnk->QueryInterface(IID_PPV_ARGS(ppObj));
        pUnk->Release();
    }
    return hr;
}

HRESULT CreateTranscodeProfile(IMFTranscodeProfile **ppProfile)
{
    IMFTranscodeProfile *pProfile = NULL;     // Transcode profile.
    IMFCollection   *pAvailableTypes = NULL;  // List of audio media types.
    IMFMediaType    *pAudioType = NULL;       // Audio media type.
    IMFAttributes   *pAudioAttrs = NULL;      // Copy of the audio media type.
    IMFAttributes   *pContainer = NULL;       // Container attributes.

    DWORD dwMTCount = 0;
    
    // Create an empty transcode profile.
    HRESULT hr = MFCreateTranscodeProfile(&pProfile);
    if (FAILED(hr))
    {
        goto done;
    }

    // Get output media types for the Windows Media audio encoder.

    // Enumerate all codecs except for codecs with field-of-use restrictions.
    // Sort the results.

    DWORD dwFlags = 
        (MFT_ENUM_FLAG_ALL & (~MFT_ENUM_FLAG_FIELDOFUSE)) | 
        MFT_ENUM_FLAG_SORTANDFILTER;

    hr = MFTranscodeGetAudioOutputAvailableTypes(MFAudioFormat_WMAudioV9, 
        dwFlags, NULL, &pAvailableTypes);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pAvailableTypes->GetElementCount(&dwMTCount);
    if (FAILED(hr))
    {
        goto done;
    }
    if (dwMTCount == 0)
    {
        hr = E_FAIL;
        goto done;
    }

    // Get the first audio type in the collection and make a copy.
    hr = GetCollectionObject(pAvailableTypes, 0, &pAudioType);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = MFCreateAttributes(&pAudioAttrs, 0);       
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pAudioType->CopyAllItems(pAudioAttrs);
    if (FAILED(hr))
    {
        goto done;
    }

    // Set the audio attributes on the profile.
    hr = pProfile->SetAudioAttributes(pAudioAttrs);
    if (FAILED(hr))
    {
        goto done;
    }

    // Set the container attributes.
    hr = MFCreateAttributes(&pContainer, 1);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pContainer->SetGUID(MF_TRANSCODE_CONTAINERTYPE, MFTranscodeContainerType_ASF);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pProfile->SetContainerAttributes(pContainer);
    if (FAILED(hr))
    {
        goto done;
    }

    *ppProfile = pProfile;
    (*ppProfile)->AddRef();

done:
    SafeRelease(&pProfile);
    SafeRelease(&pAvailableTypes);
    SafeRelease(&pAudioType);
    SafeRelease(&pAudioAttrs);
    SafeRelease(&pContainer);
    return hr;
}

Transcode API