1

WinRT で実行するゲームに音楽を追加しようとしています。音楽はエンコードされた形式 (mp3、ogg など) である必要があり、ストリーミング可能で、ハードウェアによってデコードされる必要があります (パフォーマンス上の理由から)。

サンプルを調べたところ、MediaEngine でこのようなことができることがわかりました (希望します)。

しかし、私はそれを機能させるのに問題があります。viaIMFByteStreamから作成しようとするたびに ComExceptions が発生し続けます。IRandomAccessStreamMFCreateMFByteStreamOnStreamEx()

タスクは私にとって新しいパラダイムであるため、タスクを正しく処理していない可能性があります。

以下にいくつかのコードを示します (前述のサンプルとかなり似ています)。

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;
}

ボーナス: 私のオーディオ ニーズに対するより良い解決策を知っている場合は、コメントを残してください。

4

1 に答える 1

2

私はなんとかこれを修正することができました。私が見つけた2つの問題がありました。

  • MediaFoundationが初期化されていません

MFStartup(MF_VERSION);Media Foundationを使用する前に、呼び出す必要があります。メディアエンジンを作成する直前にこのコードを追加しました。

  • ポインタを参照しています。

m_pickFileTask.then([&player](StorageFile^ fileHandle)はである必要がありますm_pickFileTask.then([player](StorageFile^ fileHandle)Thisはすでに現在のクラスへのポインタであり&、変数のアドレスを提供しているので、実際にはポインタのポインタを渡していました。

于 2012-07-03T14:18:26.683 に答える