Share via


Tutorial: Codificación de un archivo WMA

En este tutorial se muestra cómo usar la API transcodificar para codificar un archivo de Audio de Windows Media (WMA).

En este tutorial se reutiliza la mayoría del código del tutorial Codificación de un archivo MP4, por lo que primero debe leer ese tutorial. El único código que difiere es la función CreateTranscodeProfile, que crea el perfil de transcodificación.

Creación del perfil de transcodificación

Un perfil de transcodificación describe los parámetros de codificación y el contenedor de archivos. Para WMA, el contenedor de archivos es un archivo de formato de streaming avanzado (ASF). El archivo ASF contiene una secuencia de audio, que se codifica mediante el codificador de audio de Windows Media.

Para compilar la topología de transcodificación, cree el perfil de transcodificación y especifique los parámetros para la secuencia de audio y el contenedor. A continuación, cree la topología especificando el origen de entrada, la dirección URL de salida y el perfil de transcodificación.

Para crear el perfil, realice los pasos siguientes.

  1. Llame a la función MFCreateTranscodeProfile para crear un perfil de transcodificación vacío.
  2. Llame a MFTranscodeGetAudioOutputAvailableTypes para obtener una lista de tipos de medios de audio del codificador. Esta función devuelve un puntero IMFCollection que representa una colección de punteros IMFMediaType .
  3. Elija el tipo de medio de audio que coincida con los requisitos de transcodificación y copie los atributos en un almacén de atributos. Para este tutorial, se usa el primer tipo de medio de la lista.
  4. Llame a IMFTranscodeProfile::SetAudioAttributes para establecer los atributos de la secuencia de audio.
  5. Llame a MFCreateAttributes para crear un almacén de atributos para los atributos de nivel de contenedor.
  6. Establezca el atributo MF_TRANSCODE_CONTAINERTYPEen MFTranscodeContainerType_ASF, que especifica un contenedor de archivos ASF.
  7. Llame a IMFTranscodeProfile::SetContainerAttributes para establecer los atributos de nivel de contenedor en el perfil.
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;
}

API de transcodificación