背景:我正在爲Win8編寫一個metro風格的應用程序。我需要能夠播放音樂文件。由於質量和空間要求,我們使用編碼音頻(mp3/ogg)。我使用XAudio2播放聲音效果(.wav文件),但由於我無法找出播放編碼音頻的方式,因此我決定使用Media Foundation(IMFMediaPlayer界面)播放音樂文件, 。IMFMediaPlayer在SetSourceFromByteStream期間掛起
我下載了metro apps示例,發現Media Engine Native C++視頻播放示例最接近我所需要的。
既然我的應用程序有MediaPlayer播放音樂,我遇到了一個問題。如果運行該應用程序的設備足夠慢,則MediaPlayer會掛起。當我在設備上運行應用程序的發佈版本時,它很好,我可以聽到音樂很好。但是,當我連接調試器或在較慢的設備上運行它時,它會在爲MediaPlayer設置字節流時進行掛起。
下面是一些代碼,你會發現它非常類同樣品:
StorageFolder^ installedLocation = Windows::ApplicationModel::Package::Current->InstalledLocation;
m_pickFileTask = Concurrency::task<StorageFile^>(installedLocation->GetFileAsync(filename)), m_tcs.get_token());
auto player = this;
m_pickFileTask.then([player](StorageFile^ fileHandle)
{
player->SetURL(fileHandle->Path);
Concurrency::task<IRandomAccessStream^> fOpenStreamTask = Concurrency::task<IRandomAccessStream^> (fileHandle->OpenAsync(Windows::Storage::FileAccessMode::Read));
fOpenStreamTask.then([player](IRandomAccessStream^ streamHandle)
{
MEDIA::ThrowIfFailed(
player->m_spMediaEngine->Pause()
);
MEDIA::GetMediaError(player->m_spMediaEngine);
player->SetBytestream(streamHandle);
if (player->m_spMediaEngine)
{
MEDIA::ThrowIfFailed(
player->m_spEngineEx->Play()
);
MEDIA::GetMediaError(player->m_spMediaEngine);
}
}
);
}
);
而這裏的SetBytestream方法:
SetBytestream(IRandomAccessStream^ streamHandle)
{
if(m_spMFByteStream != nullptr)
{
m_spMFByteStream->Close();
m_spMFByteStream = nullptr;
}
MEDIA::ThrowIfFailed(
MFCreateMFByteStreamOnStreamEx((IUnknown*)streamHandle, &m_spMFByteStream)
);
MEDIA::ThrowIfFailed(
m_spEngineEx->SetSourceFromByteStream(m_spMFByteStream.Get(), m_bstrURL)
);
MEDIA::GetMediaError(m_spEngineEx);
return;
}
它掛線是:
m_spEngineEx->SetSourceFromByteStream(m_spMFByteStream.Get(), m_bstrURL)
當我調試應用程序時,我可以按暫停並查看堆棧。好了,不多的,但至少我可以看到它,它是無限的
ntdll.dll!77b7f4dc()
任何想法,爲什麼我的應用程序會以這樣的方式掛?
(可選:如果你知道一個更好的方式在C++地鐵風格的應用程序來播放MP3/OGG,讓我知道)