Tutorial: Codieren einer WMA-Datei
In diesem Tutorial erfahren Sie, wie Sie die Transcodierungs-API verwenden, um eine Windows Media Audio-Datei (WMA) zu codieren.
In diesem Tutorial wird der Großteil des Codes aus dem Tutorial Codieren einer MP4-Dateiwiederverwendet. Daher sollten Sie dieses Tutorial zuerst lesen. Der einzige Code, der sich unterscheidet, ist die Funktion CreateTranscodeProfile , die das Transcodierungsprofil erstellt.
Erstellen des Transcodierungsprofils
Ein Transcodierungsprofil beschreibt die Codierungsparameter und den Dateicontainer. Für WMA ist der Dateicontainer eine ASF-Datei (Advanced Streaming Format). Die ASF-Datei enthält einen Audiostream, der mit dem Windows Media Audio Encodercodiert wird.
Erstellen Sie zum Erstellen der Transcodierungstopologie das Transcodierungsprofil, und geben Sie die Parameter für den Audiostream und den Container an. Erstellen Sie dann die Topologie, indem Sie die Eingabequelle, die Ausgabe-URL und das Transcodierungsprofil angeben.
Führen Sie die folgenden Schritte aus, um das Profil zu erstellen.
- Rufen Sie die MFCreateTranscodeProfile-Funktion auf, um ein leeres Transcodeprofil zu erstellen.
- Rufen Sie MFTranscodeGetAudioOutputAvailableTypes auf, um eine Liste der Audiomedientypen vom Encoder abzurufen. Diese Funktion gibt einen POINTERCollection-Zeiger zurück, der eine Auflistung von POINTERMediaType-Zeigern darstellt.
- Wählen Sie den Audiomedientyp aus, der Ihren Transcodierungsanforderungen entspricht, und kopieren Sie die Attribute in einen Attributspeicher. Für dieses Tutorial wird der erste Medientyp in der Liste verwendet.
- Rufen Sie DIE DATEICOLLECTION::GetElement auf, um einen Audiomedientyp aus der Liste auszuwählen.
- Fragen Sie den Medientyp ab, um einen Zeiger auf die INTERFACESAttributes-Schnittstelle des Attributspeichers des Medientyps abzurufen.
- Rufen Sie DIE ATTRIBUTEAttributes::GetCount auf, um die Anzahl der attribute abzurufen, die im Medientyp enthalten sind.
- Rufen Sie MFCreateAttributes auf, um einen neuen Attributspeicher zu erstellen.
- Rufen Sie DIE ATTRIBUTEAttributes::CopyAllItems auf, um die Attribute aus dem Medientyp in den neuen Attributspeicher zu kopieren.
- Rufen Sie ÜBERTRANSCODEProfile::SetAudioAttributes auf, um die Attribute für den Audiostream festzulegen.
- Rufen Sie MFCreateAttributes auf, um einen Attributspeicher für die Attribute auf Containerebene zu erstellen.
- Legen Sie das MF _ TRANSCODE _ CONTAINERTYPE-Attribut auf MFTranscodeContainerType _ ASF fest, das einen ASF-Dateicontainer angibt.
- Rufen Sie DIE ATTRIBUTETRANSCODEProfile::SetContainerAttributes auf, um die Attribute auf Containerebene für das Profil festzulegen.
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;
}