Windows 8 将 Stream 传递给 MFSourceReader

Windows 8 passing a Stream to a MFSourceReader

本文关键字:MFSourceReader Stream Windows      更新时间:2023-10-16

我正在尝试制作一个程序,该程序可以从用户的音乐库中获取.mp3文件,并使用Windows Media Foundation的IMFSourceReader将其转换为包含PCM值的数组,以进行一些令人兴奋的DSP操作。但是,我遇到了问题。

我的解决方案有两个项目;一个包含 UI 代码的 C#/XAML 项目和一个包含一些用于使用 Media Foundation 和 XAudio2 的本机代码的C++库,以及一些 C# 代码可以与之交互的public ref类。

我无法使用MFCreateSourceReaderFromURL因为它返回拒绝访问的 HRESULT,即使您在应用清单中具有音乐库功能也是如此。所以看起来我将不得不使用MFCreateSourceReaderFromByteStreamMFCreateSourceReaderFromMediaSource.现在,使用 Windows.Storage.KnownFolders.MusicLibrary 访问音乐文件并获取StreamIInputStream以及其他一些流类型很容易,但我如何将其转换为IMFByteStreamIMFMediaSource或只是以某种方式将 mp3 解码为具有 PCM 值的字节数组?

我还考虑了将音乐文件重新保存在应用程序文件夹中的想法,以便我可以使用MFCreateSourceReaderFromURL或者也许可以绕过直接与媒体基础合作并使用类似 Windows.Media.Transcoding 的东西来转换为 PCM。我不确定这是转码命名空间的用途。

花了几个小时阅读媒体基础文档,我发现了一丝希望MFCreateMFByteStreamOnStream可以从 COM 的IStream转换为字节流,但我需要找到/编写一个包装器将我的 .net 流转换为 IStream。在我开始这项任务之前,我只想确保我朝着正确的方向前进,或者有更好的方法来做到这一点?

提前谢谢。如果我犯了一个愚蠢的错误或错过了使用这些库的一些关键方面,也提前道歉。

好的,大家,我知道你们都在吵着要回答这个问题,但经过 2 天的挠头,我找到了解决方案。您可以将Windows::Storage::Streams::IRandomAccessStream^对象传递给MFCreateMFByteStreamOnStreamEx(http://msdn.microsoft.com/en-us/library/windows/desktop/hh162754(v=vs.85).aspx),方法是将其转换为(IUnknown*),如下所示:

ComPtr<IMFByteStream> spMFByteStream = nullptr; 
MFCreateMFByteStreamOnStreamEx((IUnknown*)streamHandle, &spMFByteStream);
//remember to add your own HRESULT error handling code
ComPtr<IMFSourceReader> _sourceReader = nullptr;
MFCreateSourceReaderFromByteStream(spMFByteStream.Get(),nullptr,&_sourceReader);

streamHandle是您要提供给源读取器的IRandomAcessStream^。这是运行它的代码示例

是时候敬酒了。

如果你能用它制作一个组件(许可与否),我会感兴趣。我不知道有任何组件可以在 WinRT 下将 MP4、WMA 或 M4A 音频文件转码为 PCM。不幸的是,Windows 8不支持将音频文件录制为PCM。

晚了,补充了最初的答案,对于那些想要采用使用 COM IStream 接口包装托管流的路线的人来说,这是一个很好的实现。