Directshow 如何获取摄像头音视频设备,并判断摄像头是否占用。
来源:互联网 发布:淘宝保健品店 编辑:程序博客网 时间:2024/05/21 02:19
Directshow 能很方便的获取连接的 视频和音频设备的名称。本篇文章同时介绍如何判断获取的摄像头是否正在占用。
代码如下:
(1) 获取摄像头音视频设备名称
void CDeviceTree::EnumDevices(){hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum);hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);//将CLSID_VideoInputDeviceCategory 改成 CLSID_AudioInputDeviceCategory 即能获取音频设备if (FAILED(hr)){return;}if(hr == S_OK){ULONG cFetched;while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK){IPropertyBag* pPropBag;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);if(SUCCEEDED(hr)){VARIANT varName;varName.vt=VT_BSTR;VariantInit(&varName);hr = pPropBag->Read(L"FriendlyName", &varName, 0);USES_CONVERSION;LPTSTR lpstrMsg = W2T(varName.bstrVal);if(SUCCEEDED(hr)){//videoDev[videoIndex]=lpstrMsg;//videoIndex++;//此处即得到获得的视频设备名称 你可以将它打印出来 或者存入队列}pPropBag->Release();}pMoniker->Release();}}}
(2) 判断摄像头是否占用。
int DeviceIsBusy(char *videoName,char *audioName){//输入设备的音视频名称HRESULT hr;HRESULT hhr;int ret=0;int videoBusy=1;int audioBusy=1;CoInitialize(NULL);ICreateDevEnum* pSysDevEnum = NULL;hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pSysDevEnum);IEnumMoniker* pEnumCat ;hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);if(hr == S_OK){IMoniker* pMoniker = NULL;IMoniker* pm1=NULL;ULONG cFetched;while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK){IPropertyBag* pPropBag;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);if(SUCCEEDED(hr)){VARIANT varName;varName.vt=VT_BSTR;VariantInit(&varName);hr = pPropBag->Read(L"FriendlyName", &varName, 0);USES_CONVERSION;LPTSTR lpstrMsg = W2T(varName.bstrVal);if(SUCCEEDED(hr)){if (!strcmp(videoName,lpstrMsg))//存在设备{LPBC *pbc=NULL;IBaseFilter *P_VCamTrans=NULL;IBaseFilter *pCap=NULL;CreateBindCtx(0,pbc);hr=pMoniker->BindToObject((IBindCtx *)pbc,0,IID_IBaseFilter,(void **)&pCap); ICaptureGraphBuilder2 *m_pCapGB; IGraphBuilder *m_pGB; IMediaControl *m_pMC; IVideoWindow *m_pVW;hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB); if (FAILED(hr)) return hr; m_pGB->AddFilter(pCap,NULL);hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&m_pCapGB); if (FAILED(hr)) return hr; m_pCapGB->SetFiltergraph(m_pGB);IAMCrossbar *pXBar1 = NULL;hr=m_pCapGB->FindInterface(&LOOK_UPSTREAM_ONLY,NULL,pCap,IID_IAMCrossbar,(void **)&pXBar1);if (SUCCEEDED(hr)){long OutputPinCount;long InputPinCount;long PinIndexRelated;long PhysicalType;long inPort = 0;long outPort = 0;pXBar1->get_PinCounts(&OutputPinCount,&InputPinCount);//对于存在输入输出引脚的摄像头。此处采用轮询所有的引脚 for(int i =0;i<InputPinCount;i++){pXBar1->get_CrossbarPinInfo(TRUE,i,&PinIndexRelated,&PhysicalType);if(PhysConn_Video_Composite==PhysicalType){inPort = i;break;}}for(int i =0;i<OutputPinCount;i++){pXBar1->get_CrossbarPinInfo(FALSE,i,&PinIndexRelated,&PhysicalType);if(PhysConn_Video_VideoDecoder==PhysicalType){outPort = i;break;}}for (int i=0;i<InputPinCount;i++){for (int j=0;j<OutputPinCount;j++){if(S_OK==pXBar1->CanRoute(j,i)){pXBar1->Route(j,i);m_pGB->AddFilter(pCap, L"Capture Filter");m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);hr = m_pVW->put_Owner((OAHWND)NULL); hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);hr = m_pVW->put_Visible(OAFALSE); hr=m_pVW->put_AutoShow(OAFALSE);hhr=m_pMC->StopWhenReady();if (SUCCEEDED(hhr)){videoBusy=0;}}}}if (videoBusy == 1){ret=-1; //视频设备占用}}else{m_pGB->AddFilter(pCap, L"Capture Filter");m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);hr = m_pVW->put_Owner((OAHWND)NULL); hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);hr = m_pVW->put_Visible(OAFALSE); hr=m_pVW->put_AutoShow(OAFALSE);hhr=m_pMC->StopWhenReady();if (FAILED(hhr)){ret=-1; //视频设备占用}}}}pPropBag->Release();}pMoniker->Release();}}//判断音频的方法和上面的一样 重复。hr = pSysDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumCat, 0);if(hr == S_OK){IMoniker* pMoniker = NULL;IMoniker* pm1=NULL;ULONG cFetched;while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK){IPropertyBag* pPropBag;hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);if(SUCCEEDED(hr)){VARIANT varName;varName.vt=VT_BSTR;VariantInit(&varName);hr = pPropBag->Read(L"FriendlyName", &varName, 0);USES_CONVERSION;LPTSTR lpstrMsg = W2T(varName.bstrVal);if(SUCCEEDED(hr)){if (!strcmp(videoName,lpstrMsg))//存在设备{LPBC *pbc=NULL;IBaseFilter *P_VCamTrans=NULL;IBaseFilter *pCap=NULL;CreateBindCtx(0,pbc);hr=pMoniker->BindToObject((IBindCtx *)pbc,0,IID_IBaseFilter,(void **)&pCap); ICaptureGraphBuilder2 *m_pCapGB; IGraphBuilder *m_pGB; IMediaControl *m_pMC; IVideoWindow *m_pVW;hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&m_pGB); if (FAILED(hr)) return hr; m_pGB->AddFilter(pCap,NULL);hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void **)&m_pCapGB); if (FAILED(hr)) return hr; m_pCapGB->SetFiltergraph(m_pGB);IAMCrossbar *pXBar1 = NULL;hr=m_pCapGB->FindInterface(&LOOK_UPSTREAM_ONLY,NULL,pCap,IID_IAMCrossbar,(void **)&pXBar1);if (SUCCEEDED(hr)){long OutputPinCount;long InputPinCount;long PinIndexRelated;long PhysicalType;long inPort = 0;long outPort = 0;pXBar1->get_PinCounts(&OutputPinCount,&InputPinCount);for(int i =0;i<InputPinCount;i++){pXBar1->get_CrossbarPinInfo(TRUE,i,&PinIndexRelated,&PhysicalType);if(PhysConn_Video_Composite==PhysicalType){inPort = i;break;}}for(int i =0;i<OutputPinCount;i++){pXBar1->get_CrossbarPinInfo(FALSE,i,&PinIndexRelated,&PhysicalType);if(PhysConn_Video_VideoDecoder==PhysicalType){outPort = i;break;}}for (int i=0;i<InputPinCount;i++){for (int j=0;j<OutputPinCount;j++){if(S_OK==pXBar1->CanRoute(j,i)){pXBar1->Route(j,i);m_pGB->AddFilter(pCap, L"Capture Filter");m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);hr = m_pVW->put_Owner((OAHWND)NULL); hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);hr = m_pVW->put_Visible(OAFALSE); hr=m_pVW->put_AutoShow(OAFALSE);hhr=m_pMC->StopWhenReady();if (SUCCEEDED(hhr)){audioBusy=0;}}}}if (audioBusy == 1){ret=-1; //音频设备占用}}else{m_pGB->AddFilter(pCap, L"Capture Filter");m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);hr = m_pGB->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);hr = m_pCapGB->RenderStream(NULL, NULL, pCap, NULL, P_VCamTrans);hr = m_pVW->put_Owner((OAHWND)NULL); hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN);hr = m_pVW->put_Visible(OAFALSE); hr=m_pVW->put_AutoShow(OAFALSE);hhr=m_pMC->StopWhenReady();if (FAILED(hhr)){ret=-1; //音频设备占用}}}}pPropBag->Release();}pMoniker->Release();}}pSysDevEnum->Release();CoUninitialize();return ret;}
(3)头文件
#include "windows.h"#include "stdio.h"#include "string.h"#include <string>#include "Dshow.h"#include "atlconv.h"#pragma comment(lib,"Strmiids.lib") #pragma comment(lib,"Quartz.lib")
1 0
- Directshow 如何获取摄像头音视频设备,并判断摄像头是否占用。
- OpenCV 获取摄像头并显示摄像头视频
- OpenCV 获取摄像头并显示摄像头视频
- OpenCV 获取摄像头并显示摄像头视频
- OpenCV 获取摄像头并显示摄像头视频
- OpenCV 获取摄像头并显示摄像头视频
- OpenCV 获取摄像头并显示摄像头视频
- 使用DirectShow.NET获取摄像头视频流
- 判断设备的摄像头是否准备好
- DirectShow的配置及从摄像头读取视频并预览
- FFmpeg获取DirectShow设备数据(摄像头,录屏)
- FFmpeg获取DirectShow设备数据(摄像头,录屏)
- FFmpeg获取DirectShow设备数据(摄像头,录屏)
- FFmpeg获取DirectShow设备数据(摄像头,录屏)
- FFmpeg获取DirectShow设备数据(摄像头,录屏)
- FFmpeg获取DirectShow设备数据(摄像头,录屏)
- FFmpeg获取DirectShow设备数据(摄像头,录屏)
- OK6410如何判断摄像头是否符合UVC+测试摄像头
- 让你彻底会算时针和分针之间的角度是多少的问题
- 如何将jar包添加到maven的本地仓库
- 简单的SD卡文件浏览器
- 3.html5文件类型声明
- VC下获取各个驱动器路径
- Directshow 如何获取摄像头音视频设备,并判断摄像头是否占用。
- 从零开始做游戏 - 引子
- Django: Filter ModelChoiceField by user(or other args in view)
- 移动端前端开发调试
- VC编程如何禁用串口并口红外光驱软驱打印机USB设备
- CentOS安装emacs(包含错误处理)
- Running at Night
- 【58同城招聘】资深算法工程师
- 常用设备接口类GUID