2012-07-03 3 views
1

WinRT에서 실행되는 게임에 음악을 추가하려고합니다. 음악은 인코딩 된 형식 (mp3, ogg 등)이어야하며 스트리밍 가능해야하며 성능상의 이유로 하드웨어에서 디코딩해야합니다.WinRT의 MediaEngine 오디오 재생

샘플을 살펴본 결과 MediaEngine이 이와 같은 작업을 수행 할 수 있음을 알게되었습니다 (희망 사항).

그러나 문제가 발생합니다. IMFByteStreamIRandomAccessStream에서 MFCreateMFByteStreamOnStreamEx()으로 만들려고 할 때마다 ComExceptions가 계속 발생합니다.

나를위한 새로운 패러다임이기 때문에 내가 올바르게 작업을 처리하지 않을 수도 있습니다.

void MyMedia::PlayMusic() 
{ 
    try 
    { 
     StorageFolder^ installedLocation = Windows::ApplicationModel::Package::Current->InstalledLocation; 

     Concurrency::task<StorageFile^> m_pickFileTask = Concurrency::task<StorageFile^>(installedLocation->GetFileAsync("music.mp3"), m_tcs.get_token()); 

     SetURL(StringHelper::toString("music.mp3")); 

     auto player = this; 
     m_pickFileTask.then([&player](StorageFile^ fileHandle) 
     { 
      Concurrency::task<IRandomAccessStream^> fOpenStreamTask = Concurrency::task<IRandomAccessStream^> (fileHandle->OpenAsync(Windows::Storage::FileAccessMode::Read)); 
      fOpenStreamTask.then([&player](IRandomAccessStream^ streamHandle) 
       { 
        try 
        { 
         player->SetBytestream(streamHandle); 

         if (player->m_spMediaEngine) 
         { 
          MEDIA::ThrowIfFailed(
           player->m_spMediaEngine->Play() 
           ); 

         } 
        } catch(Platform::Exception^) 
        { 
         MEDIA::ThrowIfFailed(E_UNEXPECTED); 
        } 

       } 
      ); 
     } 
     ); 

    } catch(Platform::Exception^ ex) 
    { 
     Printf("error: %s", ex->Message); 
    } 


} 

void MyMedia::SetBytestream(IRandomAccessStream^ streamHandle) 
{ 
    HRESULT hr = S_OK; 
    ComPtr<IMFByteStream> spMFByteStream = nullptr; 

    //The following line always throws a ComException 
    MEDIA::ThrowIfFailed(
     MFCreateMFByteStreamOnStreamEx((IUnknown*)streamHandle, &spMFByteStream) 
     ); 

    MEDIA::ThrowIfFailed(
     m_spEngineEx->SetSourceFromByteStream(spMFByteStream.Get(), m_bstrURL) 
     ); 

    return; 
} 

보너스 :

여기에 (내가 전에 언급 한 샘플과 꽤 유사) 일부 코드의 내 오디오의 요구에 더 나은 솔루션을 알고 있다면 댓글을 남겨주세요.

+1

하드웨어 디코딩 관련 : 하드웨어에 따라 다릅니다 (http://blogs.msdn.com/b/b8/archive/2012/06/08/building-a-rich-and-extensible-media-platform 참조). 더 완전한 개요에 대한 aspx) – Sascha

+0

링크 주셔서 감사합니다. 모든 주요 휴대 기기가이 작업을 수행 할 수있을 것이라고 믿습니다. 그렇지 않으면 실행 가능한 게임 플랫폼이 아닙니다. – Habba

답변

2

나는 이것을 해결할 수 있었다. 내가 발견 한 두 가지 문제가있었습니다.

  • 미디어 재단은

MFStartup(MF_VERSION); 미디어 재단 사용할 수 있습니다 전에 호출 할 필요가 초기화되지 않았습니다. 미디어 엔진을 만들기 직전에이 코드를 추가했습니다.

  • 포인터를 참조하십시오.

라인 m_pickFileTask.then([&player](StorageFile^ fileHandle)m_pickFileTask.then([player](StorageFile^ fileHandle)이어야합니다. This은 이미 현재 클래스에 대한 포인터이고 &은 변수의 주소를 제공하므로 실제로 포인터의 포인터를 전달하고있었습니다.