WinRT上的MediaEngine音频播放 [英] MediaEngine audio playback on WinRT
问题描述
我正在尝试向运行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屋!