Esercitazione: Codifica di un file WMA

Questa esercitazione illustra come usare l'API Transcode per codificare un file WINDOWS Media Audio (WMA).

Questa esercitazione riutilizza la maggior parte del codice dall'esercitazione Codifica di un file MP4, quindi è necessario leggere prima tale esercitazione. L'unico codice diverso è la funzione CreateTranscodeProfile, che crea il profilo transcode.

Creare il profilo transcode

Un profilo transcode descrive i parametri di codifica e il contenitore di file. Per WMA, il contenitore di file è un file ASF (Advanced Streaming Format). Il file ASF contiene un flusso audio, codificato usando windows Media Audio Encoder.

Per compilare la topologia di transcode, creare il profilo di transcode e specificare i parametri per il flusso audio e il contenitore. Creare quindi la topologia specificando l'origine di input, l'URL di output e il profilo di transcode.

Per creare il profilo, seguire questa procedura.

  1. Chiamare la funzione MFCreateTranscodeProfile per creare un profilo transcode vuoto.
  2. Chiamare MFTranscodeGetAudioOutputAvailableTypes per ottenere un elenco di tipi di supporti audio dal codificatore. Questa funzione restituisce un puntatore FMCollection che rappresenta una raccolta di puntatori FMMediaType .
  3. Scegliere il tipo di supporto audio che corrisponde ai requisiti di transcoding e copiare gli attributi in un archivio attributi. Per questa esercitazione viene usato il primo tipo di supporto nell'elenco.
  4. Chiamare FMTranscodeProfile::SetAudioAttributes per impostare gli attributi per il flusso audio.
  5. Chiamare MFCreateAttributes per creare un archivio attributi per gli attributi a livello di contenitore.
  6. Impostare l'attributo MF_TRANSCODE_CONTAINERTYPE su MFTranscodeContainerType_ASF, che specifica un contenitore di file ASF.
  7. Chiamare FMTranscodeProfile::SetContainerAttributes per impostare gli attributi a livello di contenitore nel profilo.
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