Delen via


Zelfstudie: Een WMA-bestand coderen

In deze zelfstudie ziet u hoe u de Transcode-API- gebruikt om een WINDOWS Media Audio-bestand (WMA) te coderen.

In deze zelfstudie wordt het grootste deel van de code hergebruikt uit de tutorial Encoding an MP4-bestand, dus u moet die zelfstudie eerst lezen. De enige code die verschilt, is de functie CreateTranscodeProfile, waarmee het transcodeprofiel wordt gemaakt.

Het transcodeprofiel maken

Een transcodeprofiel beschrijft de coderingsparameters en de bestandscontainer. Voor WMA is de bestandscontainer een ASF-bestand (Advanced Streaming Format). Het ASF-bestand bevat een audiostream, die is gecodeerd met behulp van de Windows Media Audio Encoder.

Als u de transcodetopologie wilt bouwen, maakt u het transcodeprofiel en geeft u de parameters op voor de audiostroom en de container. Maak vervolgens de topologie door de invoerbron, de uitvoer-URL en het transcodeprofiel op te geven.

Voer de volgende stappen uit om het profiel te maken.

  1. Roep de MFCreateTranscodeProfile functie aan om een leeg transcodeprofiel te maken.
  2. Roep MFTranscodeGetAudioOutputAvailableTypes aan om een lijst met audiomediatypen van de encoder op te halen. Deze functie retourneert een IMFCollection pointer die een verzameling IMFMediaType pointers vertegenwoordigt.
  3. Kies het audiomediatype dat overeenkomt met uw transcoderingsvereisten en kopieer de kenmerken naar een kenmerkarchief. Voor deze zelfstudie wordt het eerste mediatype in de lijst gebruikt.
  4. Roep IMFTranscodeProfile::SetAudioAttributes aan om de kenmerken voor de audiostream in te stellen.
  5. Roep MFCreateAttributes- aan om een kenmerkarchief te maken voor de kenmerken op containerniveau.
  6. Stel het kenmerk MF_TRANSCODE_CONTAINERTYPE in op MFTranscodeContainerType_ASF, waarmee een ASF-bestandscontainer wordt opgegeven.
  7. Roep IMFTranscodeProfile::SetContainerAttributes aan om de kenmerken op containerniveau in te stellen op het profiel.
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-