之前在https://blog.csdn.net/fengbingchun/article/details/102806822中介绍过在Windows下获取视频设备列表的方法。其实那种实现方法是有缺陷的,当PC机上连接多个视频设备,并且其中有设备处于启动运行状态时,再调用相关接口获取视频设备可能会崩溃,因为为了获取视频设备列表,它会先以索引0遍历获取视频设备名,然后会执行启动此设备操作。如果此设备已经被其它应用程序启动过,则此时就会崩溃。

其实如果仅仅为了获取视频设备列表,没有必要执行启动设备的操作。以下是测试代码,无需启动任何设备即可获取到所有的视频设备列表。

此测试代码调用的是系统C接口,你也可以调整为调用系统的C++接口实现。

#define CINTERFACE
#define COBJMACROS
#include <strmif.h>
#include <Setupapi.h>
#include <uuids.h>
#include <devguid.h>
#include <memory>
#include <algorithm>namespace {std::unique_ptr<char[]> dup_wchar_to_utf8(wchar_t *w, int& len)
{len = WideCharToMultiByte(CP_UTF8, 0, w, -1, 0, 0, 0, 0);std::unique_ptr<char[]> s(new char[len]);WideCharToMultiByte(CP_UTF8, 0, w, -1, s.get(), len, 0, 0);return s;
}} // namespaceint test_get_windows_camera_list()
{CoInitialize(nullptr);ICreateDevEnum *devenum = nullptr;int r = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, reinterpret_cast<void**>(&devenum));if (r != S_OK) {fprintf(stdout, "fail to CoCreateInstance: %d\n", r);return -1;}IEnumMoniker *classenum = nullptr;r = ICreateDevEnum_CreateClassEnumerator(devenum, CLSID_VideoInputDeviceCategory, (IEnumMoniker **)&classenum, 0);if (r != S_OK) {fprintf(stdout, "fail to ICreateDevEnum_CreateClassEnumerator: %d\n", r);return -1;}IMoniker *m = nullptr;typedef struct devices_info {int index;std::string name;} devices_info;std::vector<devices_info> lists;int device_counter = 0;while (IEnumMoniker_Next(classenum, 1, &m, nullptr) == S_OK) {IPropertyBag *bag = nullptr;VARIANT var;r = IMoniker_BindToStorage(m, 0, 0, IID_IPropertyBag, (void **)&bag);if (r != S_OK) {fprintf(stdout, "fail to IMoniker_BindToStorage: %d\n", r);return -1;}var.vt = VT_BSTR;r = IPropertyBag_Read(bag, L"FriendlyName", &var, nullptr);if (r != S_OK) {fprintf(stdout, "fail to IPropertyBag_Read: %d\n", r);return -1;}int length;auto friendly_name = dup_wchar_to_utf8(var.bstrVal, length);lists.push_back({ device_counter++, friendly_name.get() });if (bag)IPropertyBag_Release(bag);IMoniker_Release(m);}IEnumMoniker_Release(classenum);CoUninitialize();fprintf(stdout, "device lists:\n");std::for_each(lists.cbegin(), lists.cend(), [](const devices_info& info) {fprintf(stdout, "  index: %d, name: %s\n", info.index, info.name.c_str());});return 0;
}

执行结果如下:设备索引与设备名并不是固定不变的,再次拔下设备再插上,此时获得的设备索引和设备名可能与之前不同。

GitHub:https://github.com//fengbingchun/OpenCV_Test

Windows下获取视频设备的一种改进实现相关推荐

  1. c语言windows获取时间,【转载】c/c++在windows下获取时间和计算时间差的几种方法总结...

    一.标准C和C++都可用 1.获取时间用time_t time( time_t * timer ),计算时间差使用double difftime( time_t timer1, time_t time ...

  2. Windows下获取usb视频设备vendor id和product id的4种方法

    之前在https://blog.csdn.net/fengbingchun/article/details/103507754 博文中介绍过如何在Linux获取usb视频设备的vendor id和pr ...

  3. QT在Windows下检测USB设备热拔插的思路

    一.问题描述: 使用QT开发视频会议时需要实现实时检测USB摄像头/麦克风拔插的功能,这里主要涉及到对一些Windows API的了解以及windows系统的设备管理识别不同种设备时的原理,在实现过程 ...

  4. 海康威视SDK通过NVR获取视频设备的状态

    海康威视SDK通过NVR获取视频设备的状态 前言 项目现场是通过NVR对多路摄像头设备进行集中管理,包括实时画面的预览和视频信号的存储.回放. 现在要实现这样一个功能:定期查询摄像头的状态,以确保摄像 ...

  5. C++在windows下获取本地主机ipv4地址和ipv6地址的代码

    把内容过程中经常用的内容段记录起来,下面内容段是关于C++在windows下获取本地主机ipv4地址和ipv6地址的内容,应该是对码农有所用处. #include <Winsock2.h> ...

  6. linux和windows下忘记mysql密码的几种找回方法

    linux和windows下忘记mysql密码的几种找回方法 关于linux忘记mysql密码处理方法,下面提供了5种linux忘记mysql密码找回方法哦. 方法一(先进入root权限): # /e ...

  7. c/c++在windows下获取时间和计算时间差的几种方法总结

    一.标准C和C++都可用 1.获取时间用time_t time( time_t * timer ),计算时间差使用double difftime( time_t timer1, time_t time ...

  8. windows下flv视频网站进度条随意拖放[转]

    网站中视频都转换成flv格式,奈何flv格式无法拖拽,此问题纠结了好久,最终得以解决.现将解决思路记录下来,大多数源于网上找到的. 视频拖拽满足要求 1.播放器要支持 2.flv视频要有关键帧和met ...

  9. bat中文乱码_详解Windows下获取时间bat脚本总结,值得收藏

    概述 最近都在写ftp windows环境的一些bat脚本,为了方便显示,想要记录一下每次操作的时间,所以在这里总结一下windows环境bat脚本获取时间的常用命令. windows环境获取时间相关 ...

最新文章

  1. Can not get new positive sample
  2. 随机变量的分布函数-定义域问题
  3. Android之startService与bindService的区别
  4. 如何移植mysql数据库_如何把本地MySql数据库移植到远程服务器上
  5. 判断mac地址单播还是组播(shell脚本)
  6. .net 编译后有个pdb文件,是用来干什么的,那位大侠知道?
  7. C#LeetCode刷题之#110-平衡二叉树(Balanced Binary Tree)
  8. 修改蓝牙耳机按键映射_拆解报告:QCY T4 TWS蓝牙耳机
  9. javascript设计模式_JavaScript设计模式:命令模式(通俗易懂)
  10. 编写QT代码实现与FlightGear通信
  11. 老男孩Linux性能优化实战课程教学
  12. 南阳oj 58 bfs入门
  13. echarts绘制进度条
  14. 基于SSM的网上手机商城购物系统设计与实现 文档+项目源码及数据库文件+运行说明
  15. 联盛德 HLK-W806 (十二): Makefile组织结构和编译流程说明
  16. 零基础掌握计算机入门
  17. 在ANSYS workbench中如何对物体局部区域进行网格细密化
  18. CF, SD, MiniSD, HPI,
  19. Centos系统上安装并配置mysql的教程?
  20. 我今年39岁了, 25岁研究生毕业,工作14年,回头看看,应该说走了不少的弯路

热门文章

  1. C++中的.hpp理解
  2. Python Qt GUI设计:QClipboard剪贴数据类(基础篇—19)
  3. 【python】一个目录里面多个python程序文件,统计一下里面有多少行代码。即分别列出:代码、空行、注释的行数。
  4. ssl 接收到一个超出最大准许长度的记录_我所经历的一次Dubbo服务雪崩,这是一个漫长的故事...
  5. uint8_t uint16_t uint32_t uint64_t 解析
  6. 在使用stl中的ifstream出错时如何快速排错?
  7. 在Ubuntu 14.04 64bit上安装epub阅读器Sigil 0.8.2
  8. js控制图片的缩放代码示例
  9. 完整的Blender三维课程:素描到三维艺术的初学者
  10. 二叉树:二叉搜索树的创建和插入