#pragma once
#include <Dshow.h>
#include <atlconv.h>
#include <uuids.h>
#include <amvideo.h>
#include <vector>
#include <strmif.h>
#include <string>
#include <iostream>
#pragma comment(lib,"strmiids.lib")
#pragma comment(lib,"quartz.lib")
using namespace std;
class CameraInfoCollector
{
public:
CameraInfoCollector();
~CameraInfoCollector();
public:
std::vector<string> getCameraInfoList(REFGUID guidValue);
WCHAR* getCameraInfoList();
int WChar2AChar(const WCHAR* lpstr, char** pOut, UINT type);
bool IsCamerePermission();
};
=========================================================================================
#include"Device.h"
CameraInfoCollector::CameraInfoCollector()
{
}
CameraInfoCollector::~CameraInfoCollector()
{
}
//guidValue:
//CLSID_AudioInputDeviceCategory:获取音频输入设备列表
//CLSID_VideoInputDeviceCategory:获取视频输入设备列表
std::vector<string> CameraInfoCollector::getCameraInfoList(REFGUID guidValue)
{
std::vector<string> nameList;
HRESULT hr;
// 初始化COM
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) {
printf("Init error!\n");
return nameList;
}
ICreateDevEnum* pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pSysDevEnum);
if (FAILED(hr))
{
pSysDevEnum->Release();
return nameList;
}
IEnumMoniker* pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(guidValue, &pEnumCat, 0);
if (FAILED(hr))
{
pSysDevEnum->Release();
return nameList;
}
IMoniker* pMoniker = NULL;
ULONG cFetched;
auto index = 0;
while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag* pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);
if (SUCCEEDED(hr))
{
IBaseFilter* pFilter;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
if (!pFilter)
{
pMoniker->Release();
break;
}
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
char* pOut = nullptr;
WChar2AChar(varName.bstrVal, &pOut, CP_UTF8);
std::string strRet = std::string(pOut);
nameList.push_back(strRet);
}
VariantClear(&varName);
pFilter->Release();
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
return nameList;
}
int CameraInfoCollector::WChar2AChar(const WCHAR* lpstr, char** pOut, UINT type)
{
size_t count = wcslen(lpstr);
if (pOut == NULL || count == 0)
return 0;
int nACharCount = ::WideCharToMultiByte(type, 0, lpstr, -1, NULL, 0, NULL, NULL);
*pOut = new char[nACharCount];
memset(*pOut, 0, sizeof(char) * (nACharCount));
int result = ::WideCharToMultiByte(type, 0, lpstr, -1, *pOut, nACharCount, NULL, NULL);
if (*pOut == NULL || result > nACharCount)
{
return 0;
}
return nACharCount;
}
//相机是否允许使用
bool CameraInfoCollector::IsCamerePermission()
{
bool bRet = false;
CoInitialize(NULL);
IGraphBuilder* pGraph = NULL;
ICaptureGraphBuilder2* pBuilder = NULL;
ICreateDevEnum* pSysDevEnum;
IEnumMoniker* pEnumCat;
IBaseFilter* pBaseFilter;
IMoniker* pMoniker;
HRESULT hr;
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL,
CLSCTX_INPROC_SERVER, IID_ICaptureGraphBuilder2, (void**)&pBuilder);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void**)&pGraph);
if (SUCCEEDED(hr))
{
hr = pBuilder->SetFiltergraph(pGraph);
}
}
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, reinterpret_cast<void**>(&pSysDevEnum));
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnumCat, 0);
if (pEnumCat->Next(1, &pMoniker, NULL) == S_OK)
{
hr = pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pBaseFilter);
bRet = SUCCEEDED(hr);
LPOLESTR szDisplayName;
pMoniker->GetDisplayName(0, NULL, &szDisplayName);
std::wcout << szDisplayName << std::endl;
}
if (pMoniker)
{
pMoniker->Release();
}
CoUninitialize();
return bRet;
}
//麦克风名称
WCHAR* CameraInfoCollector::getCameraInfoList()
{
HRESULT hr;
// 初始化COM
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (FAILED(hr)) {
printf("Init error!\n");
return NULL;
}
ICreateDevEnum* pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pSysDevEnum);
if (FAILED(hr))
{
pSysDevEnum->Release();
return NULL;
}
IEnumMoniker* pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEnumCat, 0);
if (FAILED(hr))
{
pSysDevEnum->Release();
return NULL;
}
IMoniker* pMoniker = NULL;
ULONG cFetched;
auto index = 0;
while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag* pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropBag);
if (SUCCEEDED(hr))
{
IBaseFilter* pFilter;
hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter, (void**)&pFilter);
if (!pFilter)
{
pMoniker->Release();
break;
}
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
return varName.bstrVal;
}
VariantClear(&varName);
pFilter->Release();
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
return nullptr;
}
=========================================================================================
#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<iostream>
#include"Device.h"
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
#include "libavutil/avutil.h"
#include "libavutil/ffversion.h"
#include <libavutil/imgutils.h>
#include "libswresample/swresample.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
#include "libpostproc/postprocess.h"
}
#pragma comment(lib,"libavcodec.lib")
#pragma comment(lib,"libavcodecd.lib")
#pragma comment(lib,"libavdevice.lib")
#pragma comment(lib,"libavdeviced.lib")
#pragma comment(lib,"libavfilter.lib")
#pragma comment(lib,"libavfilterd.lib")
#pragma comment(lib,"libavformat.lib")
#pragma comment(lib,"libavformatd.lib")
#pragma comment(lib,"libavutil.lib")
#pragma comment(lib,"libavutild.lib")
#pragma comment(lib,"libpostproc.lib")
#pragma comment(lib,"libpostprocd.lib")
#pragma comment(lib,"libswresample.lib")
#pragma comment(lib,"libswresampled.lib")
#pragma comment(lib,"libswscale.lib")
#pragma comment(lib,"libswscaled.lib")
//打印日志
void CwriteLog(std::string msg) {
SYSTEMTIME sys;
GetLocalTime(&sys);
char temp[256];
sprintf(temp, "%4d-%02d-%02d %02d:%02d:%02d-",
sys.wYear, sys.wMonth,
sys.wDay, sys.wHour,
sys.wMinute, sys.wSecond);
std::string inStr;
inStr += temp;
inStr += msg;
printf("=====%s=====\n",inStr.c_str());
}
//打开相机
static int countC = 0;
bool openvideodevice(string cameraName)
{
string cameraname = "video=";
cameraname += cameraName;
AVFormatContext* ctx = NULL;
AVInputFormat* ift = NULL;
AVDictionary* dty = NULL;
int ret = 0;
avdevice_register_all();
ift = (AVInputFormat*)av_find_input_format("dshow");
ret = avformat_open_input(&ctx, cameraname.c_str(), ift, &dty);
if (ret != 0)
{
CwriteLog("start use camera");
countC++;
return false;
}
if (countC ==0)
{
CwriteLog("end use camera");
countC--;
}
avformat_close_input(&ctx);
return true;
}
//打开麦克风
static int countA = 0;
bool OpenAudioDevice(WCHAR* audioName)
{
//1.
string cameraname = "audio=";
char* pCStrKey = (char *)cameraname.c_str();
//第一次调用返回转换后的字符串长度,用于确认为wchar_t*开辟多大的内存空间
int pSize = MultiByteToWideChar(CP_UTF8, 0, pCStrKey, strlen(pCStrKey), NULL, 0);
wchar_t* pWCStrKey = new wchar_t[pSize];
//第二次调用将单字节字符串转换成双字节字符串
MultiByteToWideChar(CP_UTF8, 0, pCStrKey, strlen(pCStrKey), pWCStrKey, pSize);
//2.
DWORD dwLen = WideCharToMultiByte(CP_UTF8, 0, audioName, -1, 0, 0, 0, 0);
wchar_t* pWCStr = new wchar_t[dwLen];
memcpy(pWCStr, audioName, dwLen);
//3.
wchar_t* final = new wchar_t[dwLen+ pSize];
wcscpy(final, pWCStrKey);
wcscat(final, pWCStr);
//4.
int nACharCount = ::WideCharToMultiByte(CP_UTF8, 0, final, -1, NULL, 0, NULL, NULL);
char *pOut = new char[nACharCount+1];
memset(pOut, 0, sizeof(char) * (nACharCount+1));
int result = ::WideCharToMultiByte(CP_UTF8, 0, final, -1, pOut, nACharCount, NULL, NULL);
pOut[nACharCount] = '\0';
AVFormatContext *pFormatCtx_Audio = NULL;
avdevice_register_all();
//查找输入方式
AVInputFormat *pAudioInputFmt = av_find_input_format("dshow");
int ret = 0;
ret = avformat_open_input(&pFormatCtx_Audio, pOut, pAudioInputFmt, NULL);
if (ret != 0)
{
CwriteLog("start use Audio");
countA++;
avformat_close_input(&pFormatCtx_Audio);
return false;
}
if (countA ==0)
{
CwriteLog("end use Audio");
countA--;
}
/*if (pFormatCtx_Audio->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_AUDIO)
{
CwriteLog("Couldn't find video stream information.(无法获取音频流信息");
return false;
}*/
//avformat_close_input(&pFormatCtx_Audio);
return true;
}
int main()
{
system(" chcp 65001");
//guidValue:
//CLSID_AudioInputDeviceCategory:获取音频输入设备列表
//CLSID_VideoInputDeviceCategory:获取视频输入设备列表
CameraInfoCollector ca;
WCHAR* getCameraInfo= ca.getCameraInfoList();
OpenAudioDevice(getCameraInfo);
Sleep(500);
system("pause");
}
特别说明:
本demo 使用的ffmpeg是32位的
下载地址:
https://blog.csdn.net/u014755412/article/details/82835387
查看电脑的相机和麦克风名称
最新推荐文章于 2024-06-27 15:36:38 发布