从 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 访问原始音频/视频帧的主要内容,如果未能解决你的问题,请参考以下文章

从PRISM开始学WPFMVVMViewModel?

在 python 中,为啥从数组读取比从列表读取慢?

从图库中挑选或从相机捕获的高质量图像

从PRISM开始学WPFMVVMCommand?

从PRISM开始学WPFPrism?

mysql 主-主-从-从