Tutorial: Codificando um arquivo WMA
Este tutorial mostra como usar a API transcode para codificar um arquivo WMA (Windows Media Audio).
Este tutorial reutiliza a maior parte do código do tutorial Codificando um arquivo MP4, portanto, você deve ler esse tutorial primeiro. O único código que difere é a função CreateTranscodeProfile
, que cria o perfil de transcodificação.
Criar o Perfil de Transcodificação
Um perfil de transcodificação descreve os parâmetros de codificação e o contêiner de arquivos. Para o WMA, o contêiner de arquivos é um arquivo ASF (Formato Avançado de Streaming). O arquivo ASF contém um fluxo de áudio, que é codificado usando o Codificador de Áudio do Windows Media.
Para criar a topologia de transcodificação, crie o perfil de transcodificação e especifique os parâmetros para o fluxo de áudio e o contêiner. Em seguida, crie a topologia especificando a fonte de entrada, a URL de saída e o perfil de transcodificação.
Para criar o perfil, execute as etapas a seguir.
- Chame a função MFCreateTranscodeProfile para criar um perfil de transcodificação vazio.
- Chame MFTranscodeGetAudioOutputAvailableTypes para obter uma lista de tipos de mídia de áudio do codificador. Essa função retorna um ponteiro IMFCollection que representa uma coleção de ponteiros IMFMediaType .
- Escolha o tipo de mídia de áudio que corresponde aos requisitos de transcodificação e copie os atributos para um repositório de atributos. Para este tutorial, o primeiro tipo de mídia na lista é usado.
- Chame IMFCollection::GetElement para selecionar um tipo de mídia de áudio na lista.
- Consulte o tipo de mídia para obter um ponteiro para a interface IMFAttributes do repositório de atributos do tipo de mídia.
- Chame IMFAttributes::GetCount para obter o número de atributos contidos no tipo de mídia.
- Chame MFCreateAttributes para criar um novo repositório de atributos.
- Chame IMFAttributes::CopyAllItems para copiar os atributos do tipo de mídia para o novo repositório de atributos.
- Chame IMFTranscodeProfile::SetAudioAttributes para definir os atributos para o fluxo de áudio.
- Chame MFCreateAttributes para criar um repositório de atributos para os atributos no nível do contêiner.
- Defina o atributo MF_TRANSCODE_CONTAINERTYPE como MFTranscodeContainerType_ASF, que especifica um contêiner de arquivos ASF.
- Chame IMFTranscodeProfile::SetContainerAttributes para definir os atributos no nível do contêiner no 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;
}
Tópicos relacionados