1

我正在尝试将音乐添加到在 WinRT 上运行的游戏中。音乐应该采用编码格式(mp3、ogg 等),并且应该是可流式传输的并且可以由硬件解码(出于性能原因)。

我浏览了这些示例,发现 MediaEngine 可以做这样的事情(我希望如此)。

但是,我在使它工作时遇到了问题。IMFByteStream每次尝试从IRandomAccessStreamvia创建时,我都会收到 ComExceptions MFCreateMFByteStreamOnStreamEx()

可能是我没有正确处理任务,因为它们对我来说是一个新的范例。

这是一些代码(与我之前提到的示例非常相似):

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

我设法解决了这个问题。我发现了两个问题。

  • 媒体基础未初始化

MFStartup(MF_VERSION);需要在使用 Media Foundation 之前调用。我在创建媒体引擎之前添加了这段代码。

  • 引用一个指针。

线m_pickFileTask.then([&player](StorageFile^ fileHandle)应该是m_pickFileTask.then([player](StorageFile^ fileHandle)This已经是指向当前类的指针,并且&提供了变量的地址,所以我实际上是在传递指针的指针。

于 2012-07-03T14:18:26.683 回答