共用方式為


教學課程:編碼 WMA 檔案

本教學課程示範如何使用 Transcode API 來編碼 Windows 媒體音訊 (WMA) 檔案。

本教學課程會重複使用 MP4 檔案編碼教學課程的大部分程式碼,因此您應該先閱讀該教學課程。 唯一不同的程式碼是 函 CreateTranscodeProfile 式 ,它會建立轉碼設定檔。

建立轉碼設定檔

轉碼設定檔描述編碼參數和檔案容器。 針對 WMA,檔案容器是 ASF) 檔案 (進階串流格式。 ASF 檔案包含使用 Windows 媒體音訊編碼器編碼的音訊資料流程。

若要建置轉碼拓撲,請建立轉碼設定檔,並指定音訊資料流程和容器的參數。 然後藉由指定輸入來源、輸出 URL 和轉碼設定檔來建立拓撲。

若要建立設定檔,請執行下列步驟。

  1. 呼叫 MFCreateTranscodeProfile 函式來建立空的轉碼設定檔。
  2. 呼叫 MFTranscodeGetAudioOutputAvailableTypes 以從編碼器取得音訊媒體類型清單。 此函式會傳回代表 IMFMediaType指標集合的IMFCollection指標。
  3. 選擇符合轉碼需求的音訊媒體類型,並將屬性複製到屬性存放區。 在本教學課程中,會使用清單中的第一個媒體類型。
  4. 呼叫 IMFTranscodeProfile::SetAudioAttributes 來設定音訊資料流程的屬性。
  5. 呼叫 MFCreateAttributes 以建立容器層級屬性的屬性存放區。
  6. MF_TRANSCODE_CONTAINERTYPE 屬性設定為 MFTranscodeContainerType_ASF,這個屬性會指定 ASF 檔案容器。
  7. 呼叫 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;
}

轉碼 API