【MediaFoundation】读取音视频

2023-11-03 19:52

本文主要是介绍【MediaFoundation】读取音视频,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原文链接: 官方文档

Microsoft Media Foundation支持音频和视频捕获。视频捕获设备通过UVC类驱动程序支持,并必须与UVC 1.1兼容。音频捕获设备通过Windows音频会话API(WASAPI)支持。

在Media Foundation中,捕获设备通过媒体源对象来表示,该对象公开了IMFMediaSource接口。在大多数情况下,应用程序不会直接使用这个接口,而是会使用一个更高级的API,如Source Reader,来控制捕获设备。

枚举音视频捕获设备

要枚举系统上的捕获设备,请执行以下步骤:

  1. 调用MFCreateAttributes函数来创建一个属性存储。
  2. MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE属性设置为以下值之一:
描述
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_GUID列举音频设别
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID列举视频设别
  1. 调用MFEnumDeviceSources函数。该函数分配了一个IMFActivate指针的数组。每个指针表示系统上一个设备的激活对象。
  2. 调用IMFActivate::ActivateObject 方法从一个激活的对象中创建一个媒体源的实例。
  3. 可以访问被激活的对象的属性,包括:
    • MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME 包含设备展示的名字。这个展示的名字是给用户看的,并不一定是唯一的。
    • 对于视频设备,MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK 属性包含了设备的符号链接。符号链接在系统上唯一标识设备,但不是可读的字符串。
    • 对于音频设备, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_ENDPOINT_ID 效果同上。

下面是一个完整的Demo用于输出视频设备的名称。

#include <iostream>
#include <Windows.h>
#include <mferror.h>
#include <comdef.h>
#include <mfidl.h>
#include <mfapi.h>
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "mf.lib")
#pragma comment(lib, "mfplat.lib")void DebugShowDeviceNames(IMFActivate** ppDevices, UINT count)
{for (DWORD i = 0; i < count; i++){HRESULT hr = S_OK;WCHAR* szFriendlyName = NULL;// Try to get the display name.UINT32 cchName;hr = ppDevices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME,&szFriendlyName, &cchName);if (SUCCEEDED(hr)){// 调试的时候输出到调试窗口/*OutputDebugString(szFriendlyName);OutputDebugString(L"\n");*/// 直接输出到终端std::wcout << szFriendlyName << std::endl;}CoTaskMemFree(szFriendlyName);}
}HRESULT CreateVideoCaptureDevice(IMFMediaSource** ppSource)
{*ppSource = NULL;UINT32 count = 0;IMFAttributes* pConfig = NULL;IMFActivate** ppDevices = NULL;// Create an attribute store to hold the search criteria.HRESULT hr = MFCreateAttributes(&pConfig, 1);// Request video capture devices.if (SUCCEEDED(hr)){hr = pConfig->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE,MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID);}// Enumerate the devices,if (SUCCEEDED(hr)){hr = MFEnumDeviceSources(pConfig, &ppDevices, &count);DebugShowDeviceNames(ppDevices, count);}// Create a media source for the first device in the list.if (SUCCEEDED(hr)){if (count > 0){hr = ppDevices[0]->ActivateObject(IID_PPV_ARGS(ppSource));}else{hr = MF_E_NOT_FOUND;}}for (DWORD i = 0; i < count; i++){ppDevices[i]->Release();}CoTaskMemFree(ppDevices);return hr;
}int main()
{IMFMediaSource* ppSource = nullptr;auto ret = CreateVideoCaptureDevice(&ppSource);
}

使用捕获设备

在为捕获设备创建媒体源后,使用 Source Reader 从设备获取数据。Source Reader 提供包含捕获音频数据或视频帧的媒体样本。下一步取决于你的应用场景:

  • 视频预览:使用 Microsoft Direct3D 或 Direct2D 来显示视频
  • 文件捕获:使用 Sink Writer 对文件进行编码
  • 音频预览: Use WASAPI.

如果你想将音频捕获与视频捕获结合起来,可以使用聚合媒体源。聚合媒体源包含一组媒体源,并将所有的流合并到一个单一的媒体源对象中。要创建聚合媒体源的实例,调用 MFCreateAggregateSource 函数。

关闭设备

当不再需要捕获设备时,你必须通过调用 MFCreateDeviceSource 或 IMFActivate::ActivateObject 获取的 IMFMediaSource 对象上调用 Shutdown 来关闭设备。如果不调用 Shutdown,可能会导致内存链接,因为系统可能会保持对 IMFMediaSource 资源的引用,直到调用 Shutdown 为止。

if (g_pSource)
{g_pSource->Shutdown();g_pSource->Release();g_pSource = NULL;
}

如果申请了字符容器或者符号链接设别,你应该释放这些对象

   CoTaskMemFree(g_pwszSymbolicLink);g_pwszSymbolicLink = NULL;g_cchSymbolicLink = 0;

这篇关于【MediaFoundation】读取音视频的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/340510

相关文章

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

Python中文件读取操作漏洞深度解析与防护指南

《Python中文件读取操作漏洞深度解析与防护指南》在Web应用开发中,文件操作是最基础也最危险的功能之一,这篇文章将全面剖析Python环境中常见的文件读取漏洞类型,成因及防护方案,感兴趣的小伙伴可... 目录引言一、静态资源处理中的路径穿越漏洞1.1 典型漏洞场景1.2 os.path.join()的陷

如何使用 Python 读取 Excel 数据

《如何使用Python读取Excel数据》:本文主要介绍使用Python读取Excel数据的详细教程,通过pandas和openpyxl,你可以轻松读取Excel文件,并进行各种数据处理操... 目录使用 python 读取 Excel 数据的详细教程1. 安装必要的依赖2. 读取 Excel 文件3. 读

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

基于Python实现读取嵌套压缩包下文件的方法

《基于Python实现读取嵌套压缩包下文件的方法》工作中遇到的问题,需要用Python实现嵌套压缩包下文件读取,本文给大家介绍了详细的解决方法,并有相关的代码示例供大家参考,需要的朋友可以参考下... 目录思路完整代码代码优化思路打开外层zip压缩包并遍历文件:使用with zipfile.ZipFil

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

利用Python实现添加或读取Excel公式

《利用Python实现添加或读取Excel公式》Excel公式是数据处理的核心工具,从简单的加减运算到复杂的逻辑判断,掌握基础语法是高效工作的起点,下面我们就来看看如何使用Python进行Excel公... 目录python Excel 库安装Python 在 Excel 中添加公式/函数Python 读取

Python如何实现读取csv文件时忽略文件的编码格式

《Python如何实现读取csv文件时忽略文件的编码格式》我们再日常读取csv文件的时候经常会发现csv文件的格式有多种,所以这篇文章为大家介绍了Python如何实现读取csv文件时忽略文件的编码格式... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍我们再日常读取csv文件的时候经常

C#中读取XML文件的四种常用方法

《C#中读取XML文件的四种常用方法》Xml是Internet环境中跨平台的,依赖于内容的技术,是当前处理结构化文档信息的有力工具,下面我们就来看看C#中读取XML文件的方法都有哪些吧... 目录XML简介格式C#读取XML文件方法使用XmlDocument使用XmlTextReader/XmlTextWr

Java读取InfluxDB数据库的方法详解

《Java读取InfluxDB数据库的方法详解》本文介绍基于Java语言,读取InfluxDB数据库的方法,包括读取InfluxDB的所有数据库,以及指定数据库中的measurement、field、... 首先,创建一个Java项目,用于撰写代码。接下来,配置所需要的依赖;这里我们就选择可用于与Infl