다음을 통해 공유


자습서: WMA 파일 인코딩

이 자습서에서는 Transcode API 를 사용하여 WMA(Windows Media Audio) 파일을 인코딩하는 방법을 보여 줍니다.

이 자습서에서는 MP4 파일 인코딩 자습서의 대부분의 코드를 다시 사용하므로 먼저 해당 자습서를 읽어야 합니다. 다른 유일한 코드는 코드 변환 프로필을 만드는 함수 CreateTranscodeProfile입니다.

코드 변환 프로필 만들기

코드 변환 프로필은 인코딩 매개 변수 및 파일 컨테이너를 설명합니다. WMA의 경우 파일 컨테이너는 ASF(고급 스트리밍 형식) 파일입니다. ASF 파일에는 Windows Media 오디오 인코더를 사용하여 인코딩되는 오디오 스트림이 포함되어 있습니다.

트랜스코드 토폴로지를 빌드하려면 트랜스코드 프로필을 만들고 오디오 스트림 및 컨테이너에 대한 매개 변수를 지정합니다. 그런 다음 입력 원본, 출력 URL 및 코드 변환 프로필을 지정하여 토폴로지를 만듭니다.

프로필을 만들려면 다음 단계를 수행합니다.

  1. MFCreateTranscodeProfile 함수를 호출하여 빈 트랜스코드 프로필을 만듭니다.
  2. MFTranscodeGetAudioOutputAvailableTypes를 호출하여 인코더에서 오디오 미디어 형식 목록을 가져옵니다. 이 함수는 IMFMediaType 포인터의 컬렉션을 나타내는 IMFCollection 포인터를 반환합니다.
  3. 코드 변환 요구 사항과 일치하는 오디오 미디어 유형을 선택하고 특성을 특성 저장소에 복사합니다. 이 자습서에서는 목록의 첫 번째 미디어 형식이 사용됩니다.
  4. IMFTranscodeProfile::SetAudioAttributes를 호출하여 오디오 스트림에 대한 특성을 설정합니다.
  5. MFCreateAttributes를 호출하여 컨테이너 수준 특성에 대한 특성 저장소를 만듭니다.
  6. MF_TRANSCODE_CONTAINERTYPE 특성을 ASF 파일 컨테이너를 지정하는 MFTranscodeContainerType_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 코드 변환