SimpleCapture:基于 Media Foundation 的摄像头视频预览示例(C++ 实战指南)
示例工程【免费下载链接】Windows-classic-samplesThis repo contains samples that demonstrate the API used in Windows classic desktop applications.项目地址https://gitcode.com/gh_mirrors/wi/Windows-classic-samples点击查看免费下载导读SimpleCapture 是 Windows 经典桌面示例仓库中的一个 C 示例程序完整演示了如何使用Media FoundationMF从摄像头等视频采集设备获取实时预览画面。本文将围绕该示例的官方 README结合仓库中的 winmain.cpp 与 Preview.cpp 源码深入讲解设备枚举、MFPlay 播放管线搭建、窗口消息集成、设备热插拔设备丢失处理以及完整的构建运行流程。读完本文你将掌握一套可直接复用的选择摄像头并实时预览的 Win32 原生实现方案。示例概览示例解决什么问题SimpleCapture 的核心目标见 README.md是Demonstrates how to preview video from a capture device using Media Foundation.即使用 Media Foundation 预览来自采集设备的视频。它属于仓库Samples/Win7Samples/multimedia/mediafoundation/目录下的媒体基础示例之一与同目录的 MFCaptureToFile录制到文件形成互补前者解决看后者解决录。示例采用纯 C 实现基于MFPlayMFPlayer2API而非传统的拓扑Topology拼接方式。MFPlay 是 Media Foundation 提供的一个轻量级播放层应用只需与IMFPMediaPlayer接口交互由系统在内部完成 Source → EVR增强视频渲染器的管线编排极大简化了预览功能的代码量。工程结构与关键文件依据 README 的文件清单与 SimpleCapture.vcproj 中的项目配置示例由以下文件组成文件职责winmain.cppWin32 应用入口窗口过程、设备枚举、选择对话框、设备丢失通知Preview.cppCPreview预览封装类管理 MFPlay 播放器与媒体源Preview.hCPreview类的声明SimpleCapture.rc菜单File → Choose Device与设备选择对话框资源resource.h资源 ID 定义SimpleCapture.sln / SimpleCapture.vcproj解决方案与工程文件工程配置支持Win32 与 x64 两种平台Debug/Release 四种配置均链接mfplat.lib mf.lib mfplay.lib shlwapi.lib四个库见 SimpleCapture.vcproj其中mfplay.lib对应 MFPlay APIshlwapi.lib用于StrCmp等字符串辅助函数同时以WarnAsErrortrue将警告视为错误以确保代码质量。核心技术流程第一步枚举视频采集设备当用户在菜单栏选择File → Choose Device时OnChooseDevicewinmain.cpp会执行以下步骤用MFCreateAttributes创建属性存储并设置MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID声明只枚举视频采集设备调用MFEnumDeviceSources得到一组IMFActivate *指针数组每个指针代表一个摄像头设备通过DialogBoxParam弹出设备选择对话框资源IDD_CHOOSE_DEVICE定义于 SimpleCapture.rc用户在列表框中选定设备后将其IMFActivate指针交给CPreview::SetDevice启动预览。对话框初始化时OnInitDialog示例调用每个设备的GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, ...)获取设备友好名称如 USB Camera填充到列表框若设备数为 0则禁用OK按钮——这提供了一种无设备时的友好降级策略。第二步用 MFPlay 搭建预览管线CPreview::SetDevicePreview.cpp是预览启动的核心其调用序列为CloseDevice()释放上一次的播放器实例支持切换设备MFPCreateMediaPlayer(NULL, FALSE, 0, this, m_hwnd, m_pPlayer)创建播放器NULLURL 表示不使用文件地址而是稍后通过对象创建媒体项回调对象为this即CPreview自身它实现了IMFPMediaPlayerCallback视频渲染窗口句柄为m_hwndpActivate-ActivateObject(__uuidof(IMFMediaSource), ...)激活采集设备对应的IMFMediaSource媒体源通过pActivate-GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, ...)取得设备的符号链接symbolic link该字符串将用于后续设备丢失检测m_pPlayer-CreateMediaItemFromObject(pSource, FALSE, 0, NULL)以异步方式为媒体源创建媒体项。整个流程是异步驱动的CreateMediaItemFromObject完成后MFPlay 会通过回调通知OnMediaPlayerEvent触发MFP_EVENT_TYPE_MEDIAITEM_CREATED事件进而调用OnMediaItemCreated。第三步异步事件处理与自动窗口适配CPreview::OnMediaPlayerEventPreview.cpp是 MFPlay 事件的统一入口示例仅关心两类事件MFP_EVENT_TYPE_MEDIAITEM_CREATED媒体项创建完成。处理器OnMediaItemCreated先调用pMediaItem-HasVideo(bHasVideo, bIsSelected)判断媒体项是否含被选中的视频流再调用m_pPlayer-SetMediaItem(pMediaItem)将该媒体项设置为当前播放项MFP_EVENT_TYPE_MEDIAITEM_SET媒体项设置完成。处理器OnMediaItemSet调用m_pPlayer-GetNativeVideoSize(szVideo, NULL)取得视频的原始尺寸然后通过AdjustWindowRect与SetWindowPos将主窗口调整为恰好容纳该尺寸最后调用m_pPlayer-Play()开始播放预览。这段逻辑体现了 MFPlay 的一个重要特性预览窗口可以自动匹配采集视频的原始分辨率开发者无需关心具体摄像头是 640×480、720p 还是 1080p。第四步绘制与缩放WM_PAINT / WM_SIZE预览视频的画面渲染由 MFPlay 内部的 EVR 完成应用窗口只负责提供宿主句柄。在 winmain.cpp 中收到WM_PAINT时若g_pPreview-HasVideo()为真则调用CPreview::UpdateVideo()由播放器重绘当前帧否则用COLOR_APPWORKSPACE颜色填充背景收到WM_SIZE且状态为SIZE_RESTORED时同样调用UpdateVideo()让画面随窗口缩放。CPreview::UpdateVideo内部只是简单转发给m_pPlayer-UpdateVideo()窗口消息与 MFPlay 的对接由此完成。第五步设备丢失热插拔处理示例对摄像头被拔出这一真实场景做了完整处理这也是CPreview特意保存符号链接的原因应用启动创建窗口时OnCreate通过RegisterDeviceNotification注册DBT_DEVTYP_DEVICEINTERFACE类型、KSCATEGORY_CAPTURE类 GUID 的设备通知见 winmain.cpp系统在设备状态变化时向窗口发送WM_DEVICECHANGE窗口过程将其转交给OnDeviceLostOnDeviceLost调用CPreview::CheckDeviceLostPreview.cpp该方法将通知中的dbcc_name与保存的符号链接做不区分大小写的比较_wcsicmp若一致则判定当前预览设备已丢失一旦确认设备丢失OnDeviceLost调用CloseDevice()关闭采集源并弹出 Lost the capture device. 提示框。这一模式建议在任意接入摄像头、麦克风等采集设备的应用中复用。第六步资源释放CPreview::CloseDevicePreview.cpp集中完成清理对播放器调用m_pPlayer-Shutdown()并Release对媒体源调用m_pSource-Shutdown()并Release最后CoTaskMemFree释放符号链接缓冲。应用退出时CleanUp以及切换设备时都会调用该方法保证无 COM 资源泄漏。CPreview 类设计要点CPreviewPreview.h是一个典型的 COM 封装类继承IMFPMediaPlayerCallback实现IUnknown三方法QueryInterface使用QITAB/QISearch辅助宏与OnMediaPlayerEvent回调构造函数为private统一通过静态工厂方法CreateInstance(HWND hVideo, CPreview **ppPlayer)创建创建后引用计数为 1由调用方持有并在不再需要时Release对外暴露SetDevice / CloseDevice / UpdateVideo / CheckDeviceLost / HasVideo五个方法分别对应上文所述的核心操作接口划分清晰便于移植到其他 Win32 应用。构建与运行继承自官方 README使用命令行构建打开 Command Prompt进入示例目录即仓库中的Samples/Win7Samples/multimedia/mediafoundation/SimpleCapture执行命令msbuild SimpleCapture.sln该命令会按工程默认配置生成可执行文件Debug 或 Release取决于 msbuild 默认平台/配置。使用 Visual Studio 构建推荐在 Windows Explorer 中进入Samples/Win7Samples/multimedia/mediafoundation/SimpleCapture目录双击SimpleCapture.sln用 Visual Studio 打开解决方案在Build生成菜单中选择Build Solution生成解决方案应用将生成到默认的\Debug或\Release目录。运行示例通过命令提示符或 Windows Explorer 进入包含可执行文件的目录在命令行输入SimpleCapture.exe并回车或直接在 Windows Explorer 中双击SimpleCapture.exe图标。运行后从File → Choose Device菜单选择你的摄像头设备即可在自动调整好尺寸的窗口中看到实时视频预览拔出摄像头时程序会提示设备丢失并停止预览。从源码看实现细节与扩展思路依赖的 Windows 头文件从 winmain.cpp 的#include可以看到该示例涉及的核心 API 头文件mfapi.hMedia Foundation 基础 API含MFEnumDeviceSources、mfplay.hMFPlay 播放器 API、Dbt.h设备通知结构、ks.h/ksmedia.hKSCATEGORY_CAPTURE设备类别 GUID。构建时需确保目标系统具备 Windows 7 及以上的 Media Foundation 运行环境。与录制到文件示例的对比两条不同技术路线仓库中同目录的 MFCaptureToFile 示例 负责采集并写入文件其 capture.cpp 采用了完全不同的架构基于Source Reader Sink WriterMFCreateSourceReaderFromMediaSource/MFCreateSinkWriterFromURL通过IMFSourceReaderCallback::OnReadSample回调逐帧取出样本并WriteSample写入文件还会对时间戳做 rebasellTimeStamp - m_llBaseTime处理。两者对比可以得出清晰的选型结论只需要实时预览SimpleCapture 场景用 MFPlay代码量最小需要采集录像、逐帧处理或自定义管线用 Source Reader / Sink Writer 或自行构建拓扑。两个示例在设备枚举与设备丢失检测部分代码高度相似都使用MFEnumDeviceSources 符号链接比对说明这两段逻辑是 Media Foundation 采集类应用的通用范式可直接借鉴。常见问题与排错提示构建报缺少 mfplay.lib / mf.lib确认 SDK 版本支持 Media FoundationWindows 7 SDK 及以上并检查 SimpleCapture.vcproj 中的AdditionalDependencies是否完整。运行后设备列表为空 / OK 按钮置灰说明系统未检测到任何摄像头设备检查设备管理器中摄像头驱动是否正常、是否被其他应用独占占用。切换设备失败SetDevice开头会先CloseDevice()释放旧实例若仍异常请确认回调对象this的引用计数管理正确CPreview构造时引用计数为 1MFPCreateMediaPlayer不会额外持有它。拔出摄像头后程序无反应确认OnCreate中RegisterDeviceNotification已成功注册且注册类别为KSCATEGORY_CAPTURE设备通知回调依赖消息循环正常派发WM_DEVICECHANGE。小结SimpleCapture 以约 1000 行 C 代码展示了 Media Foundation 采集预览的完整闭环设备枚举MFEnumDeviceSources→ 媒体源激活IMFActivate→ MFPlay 异步播放IMFPMediaPlayer→ 窗口消息集成WM_PAINT/WM_SIZE→ 设备热插拔防护RegisterDeviceNotification 符号链接比对。其中CPreview封装类的职责划分、符号链接的保存策略以及设备丢失处理流程均可直接迁移到其他 Windows 原生桌面应用中。如需进一步掌握从采集到落盘的完整链路可继续阅读同仓库的 MFCaptureToFile 示例作对比学习。赞分享示例工程【免费下载链接】Windows-classic-samplesThis repo contains samples that demonstrate the API used in Windows classic desktop applications.项目地址https://gitcode.com/gh_mirrors/wi/Windows-classic-samples点击查看免费下载相关推荐Swift Package Manager 插件中的 SourceModuleTarget源码模块目标探测 API 全面解析Swift Package Manager 插件中的 SourceModuleTarget源码模块目标探测 API 全面解析 SourceModuleTarg示例工程ESP32 USB Hub 双摄像头示例基于 esp-iot-solution 与 usb_host_uvc 的多路 UVC 摄像头 HTTP 预览实战ESP32 USB Hub 双摄像头示例基于 esp iot solution 与 usb_host_uvc 的多路 UVC 摄像头 HTTP 预览实战 本篇物联网嵌入式驱动开发硬件开发从零部署 Greenlight v3基于 BigBlueButton 的会议门户安装与 .env 配置全指南从零部署 Greenlight v3基于 BigBlueButton 的会议门户安装与 .env 配置全指南 Greenlight 是 BigBlueButt示例工程上一篇为什么四足机器人开发如此困难斯坦福Pupper V3用开源方案为你破局下一篇tiny11builder精简Windows 11完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

《大模型基础》教材 8 份 PDF 下载指南:单份、全套与英文版一次讲清

《大模型基础》教材 8 份 PDF 下载指南:单份、全套与英文版一次讲清

《大模型基础》教材 8 份 PDF 下载指南:单份、全套与英文版一次讲清 【免费下载链接】Foundations-of-LLMs A book for Learning the Foundations of LLMs 项目地址: https://gitcode.com/GitHub_Trending/fo/Foundations-of-LLMs 这是浙大团队开源的大语言模…

2026/10/16 5:45:42 阅读更多 →
从SLAM到语义地图:家庭机器人如何真正理解房间功能

从SLAM到语义地图:家庭机器人如何真正理解房间功能

在真正的居住环境里,房间从来不是“几堵墙围起来的方块”,而是“一堆生活习惯的集合”。家庭机器人如果只知道自己在家里的坐标,却不知道自己在卧室还是厨房,那它充其量是个会动的遥控车。这些年我经手过不少扫地机器人、陪伴机器…

2026/10/16 5:45:42 阅读更多 →
Plesk Obsidian 全栈监控实战:CustomApp Plesk 模板(Zabbix 6.0)端口、进程与 Web 可达性检查详解

Plesk Obsidian 全栈监控实战:CustomApp Plesk 模板(Zabbix 6.0)端口、进程与 Web 可达性检查详解

【免费下载链接】community-templates Zabbix Community Templates repository 项目地址: https://gitcode.com/gh_mirrors/co/community-templates 点击查看 免费下载 community-templates(Zabbix Community Templates 社区模板仓库)中的 C…

2026/10/16 5:44:42 阅读更多 →

最新新闻

Lunar 6.7.11 修复说明:Sync Mode 在 MacBook Air 与 iMac 上改用 nits 同步

Lunar 6.7.11 修复说明:Sync Mode 在 MacBook Air 与 iMac 上改用 nits 同步

桌面应用 【免费下载链接】Lunar Intelligent adaptive brightness for your external monitors 项目地址: https://gitcode.com/gh_mirrors/lu/Lunar 点击查看 免费下载 Lunar 6.7.11 是一个针对 Sync Mode(同步模式) 的定向修复版本。此次…

2026/10/16 6:27:53 阅读更多 →
MooTool Next-Compose 增量演进:MCP stdio 工具链、F03 格式化引擎与更新下载流的工程化落地

MooTool Next-Compose 增量演进:MCP stdio 工具链、F03 格式化引擎与更新下载流的工程化落地

桌面应用开发工具 【免费下载链接】MooTool Handy tool set for developers 项目地址: https://gitcode.com/gh_mirrors/mo/MooTool 点击查看 免费下载 导读 本篇以仓库中的增量开发记录 next-compose/docs/diff/561-mcp-reformat-update-env-net-vault-css-slice…

2026/10/16 6:27:53 阅读更多 →
AtCoder Beginner Contest 478

AtCoder Beginner Contest 478

AtCoder Beginner Contest 478 A - Grapes 题意:有N个人,编号为1到N,现在要把M颗葡萄分给他们。每次按照1, 2, …, N的顺序,每人分一颗,分到第N个人以后再从第1个人开始,直到所有葡萄分完。最后输出每个人分…

2026/10/16 6:27:53 阅读更多 →
google-api-nodejs-client 的 ondemandscanning 模块演进全解读:从 CHANGELOG 版本脉络到容器镜像漏洞扫描实战

google-api-nodejs-client 的 ondemandscanning 模块演进全解读:从 CHANGELOG 版本脉络到容器镜像漏洞扫描实战

后端 【免费下载链接】google-api-nodejs-client Googles officially supported Node.js client library for accessing Google APIs. Support for authorization and authentication with OAuth 2.0, API Keys and JWT (Service Tokens) is included. 项目地址: h…

2026/10/16 6:27:53 阅读更多 →
用Python和SQLite自建个人财务数据中台:从记账到自由分析

用Python和SQLite自建个人财务数据中台:从记账到自由分析

1. 从"financial-services"到个人财务数据中台:我为什么自建了一套记账分析系统先说个背景。我一直在关注"financial-services"这个方向,但说实话,金融服务的概念太大了——从银行App到支付工具,从个人记账软…

2026/10/16 6:27:53 阅读更多 →
Zabbix 监控 TACACS 服务实战:App TACACS Service 模板(net.tcp.service 简单检查)全解析

Zabbix 监控 TACACS 服务实战:App TACACS Service 模板(net.tcp.service 简单检查)全解析

【免费下载链接】community-templates Zabbix Community Templates repository 项目地址: https://gitcode.com/gh_mirrors/co/community-templates 点击查看 免费下载 本文围绕 Zabbix Community Templates 仓库中的 App TACACS Service 模板展开,讲解…

2026/10/16 6:26:53 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →