从 Windows.Media.Core.MediaSource 访问原始音频/视频帧
Posted
技术标签:
【中文标题】从 Windows.Media.Core.MediaSource 访问原始音频/视频帧【英文标题】:Access raw audio/video frames from Windows.Media.Core.MediaSource 【发布时间】:2020-09-07 20:36:56 【问题描述】:我想在没有MediaPlayer
的控制台应用程序中使用Windows.Media.Core.MediaSource
。相反,我只想将源设置为 mp4
流,然后获取原始音频和视频样本。
下面是我的代码,它可以加载MediaSource
,但我看不到如何请求音频和视频样本?有一个 MediaStreamSource
属性,但它始终是 null
。
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Windows.Media.Capture.Frames;
using Windows.Media.Core;
using Windows.Media.MediaProperties;
using Windows.Media.Playback;
namespace ConsoleApp7
[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
void GetBuffer(out byte* buffer, out uint capacity);
class Program
static async Task Main(string[] args)
var fs = File.Open("big_buck_bunny.mp4", FileMode.Open);
var mp4Src = Windows.Media.Core.MediaSource.CreateFromStream(fs.AsRandomAccessStream(), "video/mp4");
await mp4Src.OpenAsync();
Console.WriteLine($"state mp4Src.State, duration mp4Src.Duration, isopen mp4Src.IsOpen, has source mp4Src.MseStreamSource.");
// Get access to raw audio/video samples???
Console.ReadLine();
【问题讨论】:
【参考方案1】:此 API 是 UWP 媒体播放器 API 的一部分。您不应该使用 MediaSource
阅读视频/音频示例,因为它被指定为具有统一媒体播放器播放项目管理的不同类型的 Media Foundation 媒体源的包装器。
MediaSource
唯一有用的是包装源并安排它们用于媒体播放器播放。媒体播放器能够在后台访问底层媒体基础资源。
MediaStreamSource
属性尤其是null
,因为此媒体源实例不基于MediaStreamSource
实现。如果您创建了提供 MediaStreamSource
的媒体源,您将分别拥有该属性,前提是您可以访问最初提供的实现层。你有一个不同类型的源,所以你的非空属性很可能是IRandomAccessStream
。
要检索单个样本,您需要诸如 Media Foundation Media Sources、Media Foundation Source Reader、Windows.Media.Capture.Frames
for camera 之类的东西。
【讨论】:
好的,谢谢。因此,如您所知,我将无法使用 UWP Windows.Media.* API 从 mp4 文件中获取原始帧?这是否也意味着可能没有 WinRT 包装器 (github.com/MicrosoftDocs/winrt-api) 来执行此操作?我真的很想避免需要我的自定义 C++ dll。 Source Reader API 适用于 UWP 应用程序,您为什么不使用它?您可以将它与 C++、WRL、C++/CX 代码或 C++/WinRT 一起使用。这个Windows.Media.
的故事覆盖在普通媒体基础之上,对开发人员不太友好。获取单个帧并不是一件好事。
“Source Reader API”是指 Win32 Media Foundation API 吗?如果是的话,它可以工作,但要将它与 .net 核心应用程序一起使用,它需要分发 C++ dll。在开发 nuget 库时,这意味着使用 x86、x64(以及现在的 ARM64)进行构建/测试。并且通常还以某种方式协调/版本控制 C++ 运行时。最好依赖已安装的 .net 核心库。
您写道您正在开发自定义 C++ DLL,所以我假设您无论如何都必须为每个平台构建一个。是的,它是 Win32 Media Foundation API,但它是 Windows 核心,据我所知,您不需要为它重新分发任何东西。
好的,再次感谢,所以对于采样文件的 UWP/WinRT 角度,答案是“否”。遗憾的是,UWP Windows.Media.Capture.MediaCapture 非常适合采样网络摄像头。我想消除对现有 C++ dll(确实使用 IMFMediaSource)的需求,而不是开发一个。我将改为探索 PInvoke 方法。以上是关于从 Windows.Media.Core.MediaSource 访问原始音频/视频帧的主要内容,如果未能解决你的问题,请参考以下文章