WinRT上的MediaEngine音频播放 [英] MediaEngine audio playback on WinRT

查看:127
本文介绍了WinRT上的MediaEngine音频播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to add music to my game that runs on WinRT. The music should be in an encoded format (mp3, ogg, etc.) and should be streamable and be decoded by the hardware (for performance reasons).

我仔细查看了样本,发现MediaEngine可以做类似的事情(我希望如此).

I've looked through the samples, and found out that MediaEngine can do something like this (I hope).

但是,我在使它工作时遇到了问题.每次尝试通过MFCreateMFByteStreamOnStreamEx()IRandomAccessStream创建IMFByteStream时,我都会不断收到ComExceptions.

However, I'm having problems making it work. I keep getting ComExceptions everytime I try to create IMFByteStream from IRandomAccessStream via MFCreateMFByteStreamOnStreamEx().

可能是我没有正确处理任务,因为它们是我的新范例.

It might be that I'm not handling tasks correctly, since they are a new paradigm for me.

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

Here's some code (pretty similar to the sample I mentioned before):

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

奖金:如果您知道可以更好地解决我的音频需求,请发表评论.

Bonus: If you know a better solution to my audio needs, please leave a comment.

推荐答案

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

I managed to fix this. There was two problems I found.

  • Media Foundation尚未初始化

MFStartup(MF_VERSION);才能使用Media Foundation.我在创建媒体引擎之前添加了此代码.

MFStartup(MF_VERSION); needs to be called before Media Foundation can be used. I added this code just before creating the media engine.

  • 引用指针.

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

Line m_pickFileTask.then([&player](StorageFile^ fileHandle) should be m_pickFileTask.then([player](StorageFile^ fileHandle). This is already a pointer to the current class, and & provides the address of variable, so I was actually passing the pointer's pointer.

这篇关于WinRT上的MediaEngine音频播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆