Dela via


Självstudie: Koda en WMA-fil

Den här handledningen visar hur du använder API:et Transcode för att koda en fil i Windows Media Audio-format (WMA).

Den här självstudien återanvänder det mesta av koden från självstudien Koda en MP4-fil, så du bör läsa den självstudien först. Den enda kod som skiljer sig är funktionen CreateTranscodeProfile, som skapar transkodprofilen.

Skapa transcode-profilen

En omkodningsprofil beskriver kodningsparametrarna och filcontainern. För WMA är filcontainern en ASF-fil (Advanced Streaming Format). ASF-filen innehåller en ljudström som kodas med hjälp av Windows Media Audio Encoder.

Skapa transkodtopologin genom att skapa transkodprofilen och ange parametrarna för ljudströmmen och containern. Skapa sedan topologin genom att ange indatakällan, utdata-URL:en och transkodprofilen.

Utför följande steg för att skapa profilen.

  1. Anropa funktionen MFCreateTranscodeProfile för att skapa en tom omkodningsprofil.
  2. Anropa MFTranscodeGetAudioOutputAvailableTypes för att hämta en lista över ljudmedietyper från kodaren. Den här funktionen returnerar en IMFCollection- pekare som representerar en samling IMFMediaType- pekare.
  3. Välj den ljudmedietyp som matchar dina omkodningskrav och kopiera attributen till ett attributarkiv. I den här handledningen används den första medietypen i listan.
  4. Anropa IMFTranscodeProfile::SetAudioAttributes för att ange attributen för ljudströmmen.
  5. Anropa MFCreateAttributes för att skapa ett attributarkiv för attribut på containernivå.
  6. Ange attributet MF_TRANSCODE_CONTAINERTYPE till MFTranscodeContainerType_ASF, som anger en ASF-filcontainer.
  7. Anropa IMFTranscodeProfile::SetContainerAttributes för att ange attribut på containernivå för profilen.
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;
}

Transkodnings-API