Руководство. Кодирование WMA-файла
В этом руководстве показано, как использовать API перекодировки для кодирования файла Windows Media Audio (WMA).
В этом руководстве повторно используется большая часть кода из учебника Кодирование MP4-файла, поэтому сначала следует прочитать этот учебник. Единственным отличием кода является функция CreateTranscodeProfile
, которая создает профиль перекодирования.
Создание профиля transcode
Профиль перекодирования описывает параметры кодирования и контейнер файлов. Для WMA контейнер файлов является файлом расширенного формата потоковой передачи (ASF). ASF-файл содержит аудиопоток, который закодирован с помощью кодировщика звука Windows Media.
Чтобы создать топологию перекодировки, создайте профиль перекодировки и укажите параметры для аудиопотока и контейнера. Затем создайте топологию, указав источник входных данных, URL-адрес выходных данных и профиль перекодирования.
Чтобы создать профиль, выполните следующие действия.
- Вызовите функцию MFCreateTranscodeProfile , чтобы создать пустой профиль перекодирования.
- Вызовите MFTranscodeGetAudioOutputAvailableTypes , чтобы получить список типов аудиоданных из кодировщика. Эта функция возвращает указатель IMFCollection , представляющий коллекцию указателей IMFMediaType .
- Выберите тип звукового носителя, соответствующий вашим требованиям к перекодирования, и скопируйте атрибуты в хранилище атрибутов. В этом руководстве используется первый тип мультимедиа в списке.
- Вызовите IMFCollection::GetElement , чтобы выбрать тип звукового носителя из списка.
- Запросите тип носителя, чтобы получить указатель на интерфейс IMFAttributes хранилища атрибутов типа мультимедиа.
- Вызовите IMFAttributes::GetCount , чтобы получить количество атрибутов, содержащихся в типе мультимедиа.
- Вызовите MFCreateAttributes , чтобы создать новое хранилище атрибутов.
- Вызовите IMFAttributes::CopyAllItems , чтобы скопировать атрибуты из типа носителя в новое хранилище атрибутов.
- Вызовите IMFTranscodeProfile::SetAudioAttributes , чтобы задать атрибуты для звукового потока.
- Вызовите MFCreateAttributes , чтобы создать хранилище атрибутов для атрибутов уровня контейнера.
- Задайте для атрибута MF_TRANSCODE_CONTAINERTYPEзначение MFTranscodeContainerType_ASF, указывающее контейнер файлов ASF.
- Вызовите IMFTranscodeProfile::SetContainerAttributes , чтобы задать атрибуты уровня контейнера в профиле.
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;
}
Связанные темы