设为首页 收藏本站
查看: 2842|回复: 0

[经验分享] 完整的DirectShow捕获音视频的demo(源码)

[复制链接]

尚未签到

发表于 2015-11-24 08:05:33 | 显示全部楼层 |阅读模式
DirectShow获取视频和音频数据
DSC0000.png       

近段时间由于工作上的需要,大概看了下DirectShow,写了个小的demo,方便理解。以后在深入的学习下DirectShow。贴出代码。

对音频所做的处理如下图:

DSC0001.png





  1. common.h文件
  

#ifndef __COMMON_H__
#define __COMMON_H__
#include <DShow.h>
#include &quot;qedit.h&quot;
#include <strsafe.h>
#include <assert.h>
#pragma comment(lib,&quot;Strmiids.lib&quot;)
//define release maco
#define ReleaseInterface(x) \
if ( NULL != x ) \
{ \
x->Release( ); \
x = NULL; \
}
// Application-defined message to notify app of filter graph events
#define WM_GRAPHNOTIFY  WM_APP+100
void Msg(HWND hwnd,TCHAR *szFormat, ...);
bool Bstr_Compare(BSTR bstrFilter,BSTR bstrDevice);
#endif// __COMMON_H__
  
  实现:
  

#include &quot;common.h&quot;
void Msg(HWND hwnd,TCHAR *szFormat, ...)
{
TCHAR szBuffer[1024];  
const size_t NUMCHARS = sizeof(szBuffer) / sizeof(szBuffer[0]);
const int LASTCHAR = NUMCHARS - 1;
va_list pArgs;
va_start(pArgs, szFormat);
(void)StringCchVPrintf(szBuffer, NUMCHARS - 1, szFormat, pArgs);
va_end(pArgs);
szBuffer[LASTCHAR] = TEXT('\0');
MessageBox(hwnd, szBuffer, TEXT(&quot;Message&quot;), MB_OK | MB_ICONERROR);
}
bool Bstr_Compare(BSTR bstrFilter,BSTR bstrDevice)
{
bool flag = true;
int strlenFilter = SysStringLen(bstrFilter);
int strlenDevice = SysStringLen(bstrDevice);
char* chrFilter = (char*)malloc(strlenFilter+1);
char* chrDevice = (char*)malloc(strlenDevice+1);
int j = 0;
if (strlenFilter!=strlenDevice)
flag = false;
else
{
for(; j < strlenFilter;j++)
{
chrFilter[j] = (char)bstrFilter[j];
chrDevice[j] = (char)bstrDevice[j];
}
chrFilter[strlenFilter] = '\0';
chrDevice[strlenDevice] = '\0';
for(j=0; j < strlenFilter;j++)
{
if(chrFilter[j] != chrDevice[j])
flag = false;
}
if(flag == true && j == strlenFilter-1)
flag = true;
}
return flag;
}
  
  


  2.SampleGrabberCallback.h文件,由于截取视频图片,回调函数的实现
  

#ifndef __SAMPLEGRABBERCALLBACK_H__
#define __SAMPLEGRABBERCALLBACK_H__
#include &quot;common.h&quot;
class SampleGrabberCallback : public ISampleGrabberCB
{
public:
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,void** ppvObject);
HRESULT STDMETHODCALLTYPE SampleCB(double Time, IMediaSample *pSample);
HRESULT STDMETHODCALLTYPE BufferCB(double Time, BYTE *pBuffer, long BufferLen);
SampleGrabberCallback();
BOOL SaveBitmap(BYTE * pBuffer, long lBufferSize ); //保存bitmap图片
public:
BOOL m_bGetPicture;  // is get a picture
long m_lWidth;       //存储图片的宽度
long m_lHeight; //存储图片的长度
int  m_iBitCount;    //the number of bits per pixel (bpp)
TCHAR m_chTempPath[MAX_PATH];
TCHAR m_chSwapStr[MAX_PATH];
TCHAR m_chDirName[MAX_PATH];
};
#endif //__SAMPLEGRABBERCALLBACK_H__

实现:  
  

#include &quot;SampleGrabberCallback.h&quot;

SampleGrabberCallback::SampleGrabberCallback()
{
m_bGetPicture = FALSE;
//Get template path
GetTempPath(MAX_PATH,m_chTempPath);
StringCchCat(m_chTempPath,MAX_PATH,TEXT(&quot;NTKOCapturePic&quot;));
CreateDirectory(m_chTempPath,NULL);
}
ULONG STDMETHODCALLTYPE SampleGrabberCallback::AddRef()
{
return 1;
}
ULONG STDMETHODCALLTYPE SampleGrabberCallback::Release()
{
return 2;
}
HRESULT STDMETHODCALLTYPE SampleGrabberCallback::QueryInterface(REFIID riid,void** ppvObject)
{
if (NULL == ppvObject) return E_POINTER;
if (riid == __uuidof(IUnknown))
{
*ppvObject = static_cast<IUnknown*>(this);
return S_OK;
}
if (riid == IID_ISampleGrabberCB)
{
*ppvObject = static_cast<ISampleGrabberCB*>(this);
return S_OK;
}
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE SampleGrabberCallback::SampleCB(double Time, IMediaSample *pSample)
{
return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE SampleGrabberCallback::BufferCB(double Time, BYTE *pBuffer, long BufferLen)
{
if(FALSE == m_bGetPicture)  //判断是否需要截图
return S_FALSE;
if(!pBuffer)
return E_POINTER;
SaveBitmap(pBuffer,BufferLen);
m_bGetPicture = FALSE;
return S_OK;
}
BOOL SampleGrabberCallback::SaveBitmap(BYTE * pBuffer, long lBufferSize )
{
SYSTEMTIME sysTime;
GetLocalTime(&sysTime);
StringCchCopy(m_chSwapStr,MAX_PATH,m_chTempPath);
StringCchPrintf(m_chDirName,MAX_PATH,TEXT(&quot;\\%04i%02i%02i%02i%02i%02i%03ione.bmp&quot;),
sysTime.wYear,sysTime.wMonth,sysTime.wDay,sysTime.wHour,
sysTime.wMinute,sysTime.wSecond,sysTime.wMilliseconds);
StringCchCat(m_chSwapStr,MAX_PATH,m_chDirName);
//MessageBox(NULL,chTempPath,TEXT(&quot;Message&quot;),MB_OK);
//create picture file
HANDLE hf = CreateFile(m_chSwapStr,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,
CREATE_ALWAYS,0,NULL);
if(hf == INVALID_HANDLE_VALUE)
{
return E_FAIL;
}
BITMAPFILEHEADER bfh;  //Set bitmap header
ZeroMemory(&bfh,sizeof(bfh));
bfh.bfType = 'MB';
bfh.bfSize = sizeof(bfh) + lBufferSize + sizeof(BITMAPFILEHEADER);
bfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPFILEHEADER);
// Write the file header.
DWORD dwWritten = 0;
WriteFile( hf, &bfh, sizeof( bfh ), &dwWritten, NULL );   
// Write the file Format
BITMAPINFOHEADER bih;
ZeroMemory(&bih,sizeof(bih));
bih.biSize = sizeof( bih );
bih.biWidth = m_lWidth;
bih.biHeight = m_lHeight;
bih.biPlanes = 1;
bih.biBitCount = m_iBitCount;  //Specifies the number of bits per pixel (bpp)
WriteFile( hf, &bih, sizeof( bih ), &dwWritten, NULL );
//Write the file Data
WriteFile( hf, pBuffer, lBufferSize, &dwWritten, NULL );
CloseHandle( hf );
return 0;
}

3.CaptureVideo.h 捕获视频,预览和截图文件  
  

#ifndef __CAPTUREVIDEO_H__
#define __CAPTUREVIDEO_H__
#include &quot;SampleGrabberCallback.h&quot;
class CaptureVideo
{
public:
CaptureVideo();
~CaptureVideo();
HRESULT InitializeEnv(); //initialize environment
HRESULT EnumAllDevices(HWND hCombox);  //Enumeration all devices
void CloseInterface(); //close all interface
HRESULT OpenDevice(int deviceID, LONG nLeft, LONG nTop, LONG nWide, LONG nHeight);
HRESULT BindFilter(int deviceID, IBaseFilter **pBaseFilter);
HRESULT SetupVideoWindow(LONG nLeft, LONG nTop, LONG nWidth, LONG nHeight);
void ResizeVideoWindow(LONG nLeft, LONG nTop, LONG nWidth, LONG nHeight);
void GrabOneFrame(BOOL bGrab); // use ISampleGrabberCallbackCB get a picture
HRESULT HandleGraphCapturePicture(void); //capture picture  use GetCurrentBuffer
private:
IGraphBuilder *m_pGraphBuilder;
ICaptureGraphBuilder2 *m_pCaptureGB;
IMediaControl *m_pMediaControl;
IBaseFilter *m_pDevFilter;
ISampleGrabber *m_pSampGrabber;  
IMediaEventEx *m_pMediaEvent;
public:
int m_nCaptureDeviceNumber;      //Device Count
//vector<string> m_vecCapDeviceName; //the Device name
TCHAR m_pCapDeviceName[10][MAX_PATH]; //the Device name
HWND m_App;
BOOL m_bGetOneShot;
BOOL m_bConnect;
IVideoWindow *m_pVideoWindow;
};

#endif  //__CAPTUREVIDEO_H__

实现:  
  

#include &quot;CaptureVideo.h&quot;
SampleGrabberCallback g_sampleGrabberCB;  //CallBack
CaptureVideo::CaptureVideo()
{
//COM Library Initialize
if (FAILED(CoInitialize(NULL)))
{
Msg(m_App,TEXT(&quot;CoInitialize Failed!\r\n&quot;));
return;
}
//initialize member variable
m_nCaptureDeviceNumber = 0;
m_pDevFilter = NULL;
m_pCaptureGB = NULL;
m_pGraphBuilder = NULL;
m_pMediaControl = NULL;
m_pMediaEvent = NULL;
m_pSampGrabber = NULL;
m_pVideoWindow = NULL;
m_App = NULL;
m_bGetOneShot = FALSE;
m_bConnect = FALSE;
InitializeEnv();
}
CaptureVideo::~CaptureVideo()
{
CloseInterface();
CoUninitialize();
}
HRESULT CaptureVideo::EnumAllDevices(HWND hCombox)
{
if (!hCombox)
return S_FALSE;
ICreateDevEnum *pDevEnum;
IEnumMoniker   *pEnumMon;
IMoniker   *pMoniker;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,(LPVOID*)&pDevEnum);
if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumMon, 0);
if (hr == S_FALSE)
{
hr = VFW_E_NOT_FOUND;
return hr;
}
pEnumMon->Reset();
ULONG cFetched;
while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK)
{
IPropertyBag *pProBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag);
if (SUCCEEDED(hr))
{
VARIANT varTemp;
varTemp.vt = VT_BSTR;
hr = pProBag->Read(L&quot;FriendlyName&quot;,&varTemp,NULL);
if (SUCCEEDED(hr))
{
//int nStrSize = WideCharToMultiByte(CP_ACP,0,varTemp.bstrVal,-1,0,0,NULL,FALSE);
//char *strName = new char[nStrSize];
//WideCharToMultiByte(CP_ACP,0,varTemp.bstrVal,-1,strName,nStrSize,NULL,FALSE);
//m_vecCapDeviceName.push_back(string(strName)); //push the device name to vector
StringCchCopy(m_pCapDeviceName[m_nCaptureDeviceNumber],MAX_PATH,varTemp.bstrVal);
m_nCaptureDeviceNumber++; //Device number add 1
::SendMessage(hCombox, CB_ADDSTRING, 0,(LPARAM)varTemp.bstrVal);
SysFreeString(varTemp.bstrVal);
}
pProBag->Release();
}
pMoniker->Release();
}
pEnumMon->Release();
}
return hr;
}
HRESULT CaptureVideo::InitializeEnv()
{
HRESULT hr;
//Create the filter graph
hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,(LPVOID*)&m_pGraphBuilder);
if(FAILED(hr))
return hr;
//Create the capture graph builder
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2,(LPVOID*)&m_pCaptureGB);
if(FAILED(hr))
return hr;
//Obtain interfaces for media control and Video Window
hr = m_pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID*)&m_pMediaControl);
if(FAILED(hr))
return hr;
hr = m_pGraphBuilder->QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVideoWindow);
if(FAILED(hr))
return hr;
hr = m_pGraphBuilder->QueryInterface(IID_IMediaEventEx,(LPVOID*)&m_pMediaEvent);
if(FAILED(hr))
return hr;
hr = m_pMediaEvent->SetNotifyWindow((OAHWND)m_App,WM_GRAPHNOTIFY,0);
if(FAILED(hr))
return hr;
m_pCaptureGB->SetFiltergraph(m_pGraphBuilder);
if(FAILED(hr))
return hr;
return hr;
}
void CaptureVideo::CloseInterface()
{
m_bGetOneShot = FALSE;
if (m_pMediaControl)
m_pMediaControl->Stop();
if(m_pVideoWindow)
{
m_pVideoWindow->get_Visible(FALSE);
m_pVideoWindow->put_Owner(NULL);
}
if(m_pMediaEvent)
m_pMediaEvent->SetNotifyWindow(NULL,WM_GRAPHNOTIFY,0);
//release interface
ReleaseInterface(m_pDevFilter);
ReleaseInterface(m_pCaptureGB);
ReleaseInterface(m_pGraphBuilder);
ReleaseInterface(m_pMediaControl);
ReleaseInterface(m_pMediaEvent);
ReleaseInterface(m_pSampGrabber);
ReleaseInterface(m_pVideoWindow);
}
HRESULT CaptureVideo::BindFilter(int deviceID, IBaseFilter **pBaseFilter)
{
ICreateDevEnum *pDevEnum;
IEnumMoniker   *pEnumMon;
IMoniker   *pMoniker;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,(LPVOID*)&pDevEnum);
if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumMon, 0);
if (hr == S_FALSE)
{
hr = VFW_E_NOT_FOUND;
return hr;
}
pEnumMon->Reset();
ULONG cFetched;
int index = 0;
while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK, index<= deviceID)
{
IPropertyBag *pProBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag);
if (SUCCEEDED(hr))
{
if (index == deviceID)
{
pMoniker->BindToObject(0,0,IID_IBaseFilter,(LPVOID*)pBaseFilter);
}
}
pMoniker->Release();
index++;
}
pEnumMon->Release();
}
return hr;
}
HRESULT CaptureVideo::SetupVideoWindow(LONG nLeft, LONG nTop, LONG nWidth, LONG nHeight)
{
HRESULT hr;
hr = m_pVideoWindow->put_Owner((OAHWND)m_App);
if (FAILED(hr))
return hr;
hr = m_pVideoWindow->put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN);
if(FAILED(hr))
return hr;
ResizeVideoWindow(nLeft,nTop,nWidth,nHeight);
hr = m_pVideoWindow->put_Visible(OATRUE);
if(FAILED(hr))
return hr;
return hr;
}
void CaptureVideo::ResizeVideoWindow(LONG nLeft, LONG nTop, LONG nWidth, LONG nHeight)
{
if(m_pVideoWindow)
{
m_pVideoWindow->SetWindowPosition(nLeft,nTop,nWidth,nHeight);
}
}
HRESULT CaptureVideo::OpenDevice(int deviceID, LONG nLeft, LONG nTop, LONG nWide, LONG nHeight)
{
HRESULT hr;
IBaseFilter *pSampleGrabberFilter;
if (m_bConnect)
{
CloseInterface();
InitializeEnv();
}
hr = CoCreateInstance(CLSID_SampleGrabber,NULL,CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (LPVOID*)&pSampleGrabberFilter);
if(FAILED(hr))
return hr;
//bind device filter
hr = BindFilter(deviceID,&m_pDevFilter);
if (FAILED(hr))
return hr;
hr = m_pGraphBuilder->AddFilter(m_pDevFilter,L&quot;Video Filter&quot;);
if (FAILED(hr))
return hr;
hr = m_pGraphBuilder->AddFilter(pSampleGrabberFilter,L&quot;Sample Grabber&quot;);
if (FAILED(hr))
return hr;
hr = pSampleGrabberFilter->QueryInterface(IID_ISampleGrabber,(LPVOID*)&m_pSampGrabber);
if(FAILED(hr))
return hr;
//set media type
AM_MEDIA_TYPE mediaType;
ZeroMemory(&mediaType,sizeof(AM_MEDIA_TYPE));
//Find the current bit depth
HDC hdc=GetDC(NULL);
int iBitDepth=GetDeviceCaps(hdc, BITSPIXEL);
g_sampleGrabberCB.m_iBitCount = iBitDepth;
ReleaseDC(NULL,hdc);
//Set the media type
mediaType.majortype = MEDIATYPE_Video;
switch(iBitDepth)
{
case  8:
mediaType.subtype=MEDIASUBTYPE_RGB8;
break;
case 16:
mediaType.subtype=MEDIASUBTYPE_RGB555;
break;
case 24:
mediaType.subtype=MEDIASUBTYPE_RGB24;
break;
case 32:
mediaType.subtype=MEDIASUBTYPE_RGB32;
break;
default:
return E_FAIL;
}
mediaType.formattype = FORMAT_VideoInfo;
hr = m_pSampGrabber->SetMediaType(&mediaType);
hr = m_pCaptureGB->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,
m_pDevFilter,pSampleGrabberFilter,NULL);
if(FAILED(hr))
return hr;
hr = m_pSampGrabber->GetConnectedMediaType(&mediaType);
if(FAILED(hr))
return hr;
VIDEOINFOHEADER * vih = (VIDEOINFOHEADER*) mediaType.pbFormat;
g_sampleGrabberCB.m_lWidth = vih->bmiHeader.biWidth;
g_sampleGrabberCB.m_lHeight = vih->bmiHeader.biHeight;
// Configure the Sample Grabber
hr = m_pSampGrabber->SetOneShot(FALSE);
if (FAILED(hr))
return hr;
hr = m_pSampGrabber->SetBufferSamples(TRUE);
if (FAILED(hr))
return hr;
// 1 = Use the BufferCB callback method.
hr = m_pSampGrabber->SetCallback(&g_sampleGrabberCB,1);
//set capture video Window
SetupVideoWindow(nLeft,nTop,nWide,nHeight);
hr = m_pMediaControl->Run();
if(FAILED(hr))
return hr;
if (mediaType.cbFormat != 0)
{
CoTaskMemFree((PVOID)mediaType.pbFormat);
mediaType.cbFormat = 0;
mediaType.pbFormat = NULL;
}
if (mediaType.pUnk != NULL)
{
mediaType.pUnk->Release();
mediaType.pUnk = NULL;
}
m_bConnect = TRUE;
return hr;
}
void CaptureVideo::GrabOneFrame(BOOL bGrab)
{
m_bGetOneShot = bGrab;
g_sampleGrabberCB.m_bGetPicture = bGrab;
}
HRESULT CaptureVideo::HandleGraphCapturePicture(void)
{
//////////////////////////////////////////////////////////////////////////
HRESULT hr;
long evCode = 0;
long lBufferSize = 0;
BYTE *p;
hr = m_pMediaEvent->WaitForCompletion(INFINITE, &evCode); //
if (SUCCEEDED(hr))
{
switch(evCode)
{
case EC_COMPLETE:
m_pSampGrabber->GetCurrentBuffer(&lBufferSize, NULL);
p = new BYTE[lBufferSize];
m_pSampGrabber->GetCurrentBuffer(&lBufferSize, (LONG*)p);// get Current buffer
g_sampleGrabberCB.SaveBitmap(p,lBufferSize); //save bitmap
break;
default:
break;
}
}
//////////////////////////////////////////////////////////////////////////
return hr;
}


4.CaptureAudio.h 预览音频和保存捕获到的音频到文件  
  

#ifndef __CAPTUREAUDIO_H__
#define __CAPTUREAUDIO_H__
#include &quot;common.h&quot;
class CaptureAudio
{
public:
CaptureAudio();
~CaptureAudio();
HRESULT InitializeEnv(); //initialize environment
HRESULT EnumAllDevices(HWND hCombox);  //Enumeration all devices
void CloseInterface(); //close all interface
HRESULT OpenDevice(BSTR bstrDeviceName);
HRESULT BindDeviceFilter(BSTR deviceName,GUID DEVICE_CLSID,IBaseFilter **pBaseFilter);
HRESULTDeviceConnect(IBaseFilter* pInputDevice,IBaseFilter* pOutputDevice, BSTR bstrInputPin, BSTR bstrOutputDevice);
private:
IGraphBuilder *m_pGraphBuilder;
ICaptureGraphBuilder2 *m_pCaptureGB;
IBaseFilter *m_pDevFilter;
IMediaControl *m_pMediaContrl;
public:
int m_nCaptureDeviceNumber;      //Device Count
//vector<string> m_vecCapDeviceName; //the Device name
TCHAR m_pCapDeviceName[10][MAX_PATH]; //the Device name
TCHAR m_pRendererDeviceName[10][MAX_PATH]; // Render Device name
HWND m_App;
};
#endif  //__CAPTUREAUDIO_H__

实现:  
  

#include &quot;CaptureAudio.h&quot;

CaptureAudio::CaptureAudio()
{
//COM Library Initialize
if (FAILED(CoInitialize(NULL)))
{
Msg(m_App,TEXT(&quot;CoInitialize Failed!\r\n&quot;));
return;
}
//initialize member variable
m_nCaptureDeviceNumber = 0;
m_pDevFilter = NULL;
m_pCaptureGB = NULL;
m_pGraphBuilder = NULL;
m_pMediaContrl = NULL;
m_App = NULL;
InitializeEnv();
}
CaptureAudio::~CaptureAudio()
{
CloseInterface();
CoUninitialize();
}
HRESULT CaptureAudio::EnumAllDevices(HWND hCombox)
{
if (!hCombox)
return S_FALSE;
ICreateDevEnum *pDevEnum;
IEnumMoniker   *pEnumMon;
IMoniker   *pMoniker;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,(LPVOID*)&pDevEnum);
if (SUCCEEDED(hr))
{
// get all Audio input Device Friendly Name
hr = pDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory,&pEnumMon, 0);
if (hr == S_FALSE)
{
hr = VFW_E_NOT_FOUND;
return hr;
}
pEnumMon->Reset();
ULONG cFetched;
while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK)
{
IPropertyBag *pProBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag);
if (SUCCEEDED(hr))
{
VARIANT varTemp;
varTemp.vt = VT_BSTR;
hr = pProBag->Read(L&quot;FriendlyName&quot;,&varTemp,NULL);
if (SUCCEEDED(hr))
{
//int nStrSize = WideCharToMultiByte(CP_ACP,0,varTemp.bstrVal,-1,0,0,NULL,FALSE);
//char *strName = new char[nStrSize];
//WideCharToMultiByte(CP_ACP,0,varTemp.bstrVal,-1,strName,nStrSize,NULL,FALSE);
//m_vecCapDeviceName.push_back(string(strName)); //push the device name to vector
StringCchCopy(m_pCapDeviceName[m_nCaptureDeviceNumber],MAX_PATH,varTemp.bstrVal);
m_nCaptureDeviceNumber++; //Device number add 1
::SendMessage(hCombox, CB_ADDSTRING, 0,(LPARAM)varTemp.bstrVal);
SysFreeString(varTemp.bstrVal);
}
pProBag->Release();
}
pMoniker->Release();
}
pEnumMon->Release();
//get All Audio Renderer Device Friendly Name
hr = pDevEnum->CreateClassEnumerator(CLSID_AudioRendererCategory,&pEnumMon, 0);
if (hr == S_FALSE)
{
hr = VFW_E_NOT_FOUND;
return hr;
}
pEnumMon->Reset();
int index = 0;
while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK)
{
IPropertyBag *pProBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag);
if (SUCCEEDED(hr))
{
VARIANT varTemp;
varTemp.vt = VT_BSTR;
hr = pProBag->Read(L&quot;FriendlyName&quot;,&varTemp,NULL);
if (SUCCEEDED(hr))
{
StringCchCopy(m_pRendererDeviceName[index],MAX_PATH,varTemp.bstrVal);
index++; //Device number add 1
SysFreeString(varTemp.bstrVal);
}
pProBag->Release();
}
pMoniker->Release();
}
pEnumMon->Release();
}
return hr;
}
HRESULT CaptureAudio::InitializeEnv()
{
HRESULT hr;
//Create the filter graph
hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,
IID_IGraphBuilder,(LPVOID*)&m_pGraphBuilder);
if(FAILED(hr))
return hr;
//Create the capture graph builder
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC_SERVER,
IID_ICaptureGraphBuilder2,(LPVOID*)&m_pCaptureGB);
if(FAILED(hr))
return hr;
hr = m_pGraphBuilder->QueryInterface(IID_IMediaControl,(LPVOID*)&m_pMediaContrl);
if(FAILED(hr))
return hr;
m_pCaptureGB->SetFiltergraph(m_pGraphBuilder);
if(FAILED(hr))
return hr;
return hr;
}
void CaptureAudio::CloseInterface()
{
if (m_pMediaContrl)
m_pMediaContrl->Stop();
//release interface
ReleaseInterface(m_pDevFilter);
ReleaseInterface(m_pCaptureGB);
ReleaseInterface(m_pGraphBuilder);
ReleaseInterface(m_pMediaContrl);
}
HRESULT CaptureAudio::OpenDevice(BSTR bstrDeviceName)
{
HRESULT hr;
IBaseFilter  *pWaveDest = NULL, *pWriter = NULL, *pOutputDev = NULL;
IFileSinkFilter *pSink= NULL;
BSTR bstrTempDeviceName;
BSTR bstrOutPin,bstrInPin;
IBaseFilter *pPinTeeFilter = NULL;
hr = BindDeviceFilter(bstrDeviceName,CLSID_AudioInputDeviceCategory, &m_pDevFilter);
if (FAILED(hr))
return hr;
// Add the audio capture filter to the filter graph.
hr = m_pGraphBuilder->AddFilter(m_pDevFilter, L&quot;Capture&quot;);
if (FAILED(hr))
return hr;
/************************************************************************/
/* Audio Prieview                                           */
/************************************************************************/
bstrTempDeviceName = SysAllocString(L&quot;Infinite Pin Tee Filter&quot;);
hr = BindDeviceFilter(bstrTempDeviceName,CLSID_LegacyAmFilterCategory,&pPinTeeFilter);
if (FAILED(hr))
return hr;
hr = m_pGraphBuilder->AddFilter(pPinTeeFilter,bstrTempDeviceName);
bstrInPin = SysAllocString(L&quot;Capture&quot;);
bstrOutPin = SysAllocString(L&quot;Input&quot;);
hr = DeviceConnect(m_pDevFilter,pPinTeeFilter,bstrInPin,bstrOutPin);
if(FAILED(hr))
return hr;
//////////////////////////////////////////////////////////////////////////
// output the Rendered Device
SysReAllocString(&bstrTempDeviceName,m_pRendererDeviceName[0]); //Rendered Device Name;
hr = BindDeviceFilter(bstrTempDeviceName,CLSID_AudioRendererCategory,&pOutputDev);
if(FAILED(hr))
return hr;
hr = m_pGraphBuilder->AddFilter(pOutputDev,bstrTempDeviceName);
if(FAILED(hr))
return hr;
SysReAllocString(&bstrInPin,L&quot;Output1&quot;);
SysReAllocString(&bstrOutPin,L&quot;Audio Input pin (rendered)&quot;);
hr = DeviceConnect(pPinTeeFilter,pOutputDev,bstrInPin,bstrOutPin);
if(FAILED(hr))
return hr;
//////////////////////////////////////////////////////////////////////////

//Add AudioRecorder WAV Dest
SysReAllocString(&bstrTempDeviceName,TEXT(&quot;AudioRecorder WAV Dest&quot;));
hr = BindDeviceFilter(bstrTempDeviceName,CLSID_LegacyAmFilterCategory, &pWaveDest);
if (FAILED(hr))
return hr;
hr = m_pGraphBuilder->AddFilter(pWaveDest,bstrTempDeviceName);
if (FAILED(hr))
return hr;
//Connect the AudioRecorder WAV Dest
SysReAllocString(&bstrInPin,L&quot;Output2&quot;);
SysReAllocString(&bstrOutPin,L&quot;In&quot;);
hr = DeviceConnect(pPinTeeFilter,pWaveDest,bstrInPin,bstrOutPin);
if (FAILED(hr))
return hr;
// output Filter Wirter
SysReAllocString(&bstrTempDeviceName,L&quot;File writer&quot;);
hr = BindDeviceFilter(bstrTempDeviceName,CLSID_LegacyAmFilterCategory,&pWriter);
if (FAILED(hr))
return hr;
IFileSinkFilter *pFileSink= NULL;
SysReAllocString(&bstrTempDeviceName,L&quot;test.wav&quot;);
hr = pWriter->QueryInterface(IID_IFileSinkFilter, (void**)&pFileSink);
if(FAILED(hr))
return hr;
hr = pFileSink->SetFileName((LPCOLESTR)bstrTempDeviceName,NULL);
if(FAILED(hr))
return hr;
hr = m_pGraphBuilder->AddFilter(pWriter,bstrTempDeviceName);
if(FAILED(hr))
return hr;
SysReAllocString(&bstrInPin,L&quot;Out&quot;);
SysReAllocString(&bstrOutPin,L&quot;in&quot;);
hr = DeviceConnect(pWaveDest,pWriter,bstrInPin,bstrOutPin);
if(FAILED(hr))
return hr;
SysFreeString(bstrInPin);
SysFreeString(bstrOutPin);
SysFreeString(bstrTempDeviceName);
hr = m_pMediaContrl->Run();
if(FAILED(hr))
return hr;
return hr;
}
HRESULT CaptureAudio::DeviceConnect(IBaseFilter* pInputDevice,IBaseFilter* pOutputDevice, BSTR bstrInputPin, BSTR bstrOutputDevice)
{
HRESULT hr;
IEnumPins *pInputPins = NULL, *pOutputPins = NULL;
IPin *pIn = NULL, *pOut = NULL;
hr = pInputDevice->EnumPins(&pInputPins);
if (SUCCEEDED(hr))
{
hr = pInputDevice->FindPin(bstrInputPin,&pIn);
if(FAILED(hr))
return hr;
}else
return hr;
hr = pOutputDevice->EnumPins(&pOutputPins);
if (SUCCEEDED(hr))
{
hr = pOutputDevice->FindPin(bstrOutputDevice,&pOut);
if(FAILED(hr))
return hr;
}
hr = pIn->Connect(pOut, NULL);
if (FAILED(hr))
return hr;
return hr;
}
HRESULT CaptureAudio::BindDeviceFilter(BSTR deviceName,GUID DEVICE_CLSID,IBaseFilter **pBaseFilter)
{
ICreateDevEnum *pDevEnum;
IEnumMoniker   *pEnumMon;
IMoniker   *pMoniker;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum,(LPVOID*)&pDevEnum);
if (SUCCEEDED(hr))
{
hr = pDevEnum->CreateClassEnumerator(DEVICE_CLSID,&pEnumMon, 0);
if (hr == S_FALSE)
{
hr = VFW_E_NOT_FOUND;
return hr;
}
pEnumMon->Reset();
ULONG cFetched;
while(hr=pEnumMon->Next(1,&pMoniker,&cFetched),hr == S_OK)
{
IPropertyBag *pProBag;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(LPVOID*)&pProBag);
if (SUCCEEDED(hr))
{
VARIANT varTemp;
varTemp.vt = VT_BSTR;
hr = pProBag->Read(L&quot;FriendlyName&quot;,&varTemp,NULL);
if (SUCCEEDED(hr))
{
if (Bstr_Compare(varTemp.bstrVal,deviceName) == true)
{
hr = pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter,(LPVOID*)pBaseFilter);
if (SUCCEEDED(hr))
return hr;
}
SysFreeString(varTemp.bstrVal);
}
pProBag->Release();
}
pMoniker->Release();
}
pEnumMon->Release();
}
return hr;
}


5.测试:Main.cpp  
  

#include &quot;CaptureVideo.h&quot;
#include &quot;CaptureAudio.h&quot;
#include &quot;resource.h&quot;
#define ID_COMBOBOX  10000
#define ID_COMBOBOX2 10001
#define ID_TIMER     10002
CaptureVideo g_CaptureVideo;
CaptureAudio g_CaptureAudio;
HWND hwndCombo1;
HWND hwndCombo2;
BSTR bstrDeviceName;
HICON g_hIconLarge;
HICON g_hIconSmall;
int g_nTimerCount = 0;
BOOL CALLBACK WndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
VOID CALLBACK TimerGetPicture(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTimer);
VOID SetWindowPosCenter(HWND hDlg);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{

g_hIconLarge = static_cast<HICON>(LoadImage(hInstance, TEXT(&quot;IDI_ICON1&quot;), IMAGE_ICON,  //set large ico
GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CXICON), 0));
g_hIconSmall = static_cast<HICON>(LoadImage(hInstance, TEXT(&quot;IDI_ICON1&quot;), IMAGE_ICON,   //set small ico
GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CXSMICON), 0));
MSG msg;
HWND hDlg = CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,WndProc);
ShowWindow(hDlg,iCmdShow);
UpdateWindow(hDlg);

while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
CoUninitialize();
// Exit
DestroyIcon(g_hIconLarge);
DestroyIcon(g_hIconSmall);
return msg.wParam;
}
BOOL CALLBACK WndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
int nGetComboxCount = 0;
int iGetCurSel = 0;
DWORD dwBaseUnits;
switch(message)
{
case WM_INITDIALOG:
{
SendMessage(hDlg,WM_SETICON,FALSE,reinterpret_cast<LPARAM>(g_hIconSmall));
SendMessage(hDlg,WM_SETICON,TRUE,reinterpret_cast<LPARAM>(g_hIconLarge));
//////////////////////////////////////////////////////////////////////////
SetWindowPosCenter(hDlg); //set Dialog at window center
//////////////////////////////////////////////////////////////////////////
g_CaptureVideo.m_App = hDlg;
g_CaptureAudio.m_App = hDlg;
dwBaseUnits = GetDialogBaseUnits();
hwndCombo1 = CreateWindow(TEXT(&quot;COMBOBOX&quot;), TEXT(&quot;&quot;),
CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,
(6 * LOWORD(dwBaseUnits)) / 4,
(2 * HIWORD(dwBaseUnits)) / 8,
(100 * LOWORD(dwBaseUnits)) / 4,
(50 * HIWORD(dwBaseUnits)) / 8,
hDlg, (HMENU)ID_COMBOBOX, NULL, NULL);   
hwndCombo2 = CreateWindow(TEXT(&quot;COMBOBOX&quot;), TEXT(&quot;&quot;),
CBS_DROPDOWN | WS_CHILD | WS_VISIBLE,
(110 * LOWORD(dwBaseUnits)) / 4,
(2 * HIWORD(dwBaseUnits)) / 8,
(100 * LOWORD(dwBaseUnits)) / 4,
(50 * HIWORD(dwBaseUnits)) / 8,
hDlg, (HMENU)ID_COMBOBOX2, NULL, NULL);   
//Video
g_CaptureVideo.EnumAllDevices(hwndCombo1); //Enum All Camera
nGetComboxCount = ComboBox_GetCount(hwndCombo1);
if (nGetComboxCount == 0)
ComboBox_Enable(hwndCombo1,FALSE);
else
ComboBox_SetCurSel(hwndCombo1,0);
if(g_CaptureVideo.m_nCaptureDeviceNumber == 0)
{
Msg(hDlg,TEXT(&quot;没有摄像头设备&quot;));
EnableWindow(GetDlgItem(hDlg,IDC_PREVIWE),FALSE);
}
EnableWindow(GetDlgItem(hDlg,IDONESHOT),FALSE);
// Audio
g_CaptureAudio.EnumAllDevices(hwndCombo2);
nGetComboxCount = ComboBox_GetCount(hwndCombo2);
if (nGetComboxCount == 0)
ComboBox_Enable(hwndCombo2,FALSE);
else
ComboBox_SetCurSel(hwndCombo2,0);
if(g_CaptureAudio.m_nCaptureDeviceNumber == 0)
{
Msg(hDlg,TEXT(&quot;没有音频设备&quot;));
EnableWindow(GetDlgItem(hDlg,IDC_PREVIWE),FALSE);
}
}
return TRUE;
case WM_DESTROY:
{
g_CaptureVideo.CloseInterface();
PostQuitMessage(0);
}
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDCANCEL:
{
PostQuitMessage(0);
}
break;
case IDONESHOT:
{
//g_CaptureVideo.GrabOneFrame(TRUE);
SetTimer(hDlg,ID_TIMER,150,TimerGetPicture);
}
break;
case IDC_PREVIWE:
{
//Video
iGetCurSel = ComboBox_GetCurSel(hwndCombo1);
g_CaptureVideo.OpenDevice(iGetCurSel,20,30,430,400);
EnableWindow(GetDlgItem(hDlg,IDONESHOT),TRUE);
//Audio
iGetCurSel = ComboBox_GetCurSel(hwndCombo2);
bstrDeviceName = SysAllocString(g_CaptureAudio.m_pCapDeviceName[iGetCurSel]);
g_CaptureAudio.OpenDevice(bstrDeviceName);
}
break;
default: break;
}
case WM_MOVE:
g_CaptureVideo.m_pVideoWindow->NotifyOwnerMessage((OAHWND)hDlg, message, wParam, lParam);
break;
}
return (FALSE);
}
VOID CALLBACK TimerGetPicture(HWND hDlg, UINT message, UINT iTimerID, DWORD dwTimer)
{
if(g_nTimerCount < 25)
{
g_CaptureVideo.GrabOneFrame(TRUE);
g_nTimerCount++;
}else
{
KillTimer(hDlg,ID_TIMER);
g_nTimerCount = 0;
}
}
VOID SetWindowPosCenter(HWND hDlg)
{
int cxWindow,cyWindow;  //window Screen width and height
RECT hDlgRect;          //Dialog Rect
int cxDialog,cyDialog;  //Dialog Screen width and height
int cxSetPos,cySetPos;
GetWindowRect(hDlg,&hDlgRect);
//
cxDialog = hDlgRect.right - hDlgRect.left;
cyDialog = hDlgRect.bottom - hDlgRect.top;
//
cxWindow = GetSystemMetrics(SM_CXSCREEN);
cyWindow = GetSystemMetrics(SM_CYSCREEN);
//
cxSetPos = (cxWindow-cxDialog)/2;
cySetPos = (cyWindow-cyDialog)/2;
SetWindowPos(hDlg,NULL,cxSetPos,cySetPos,0,0,SWP_NOSIZE);

}
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-142814-1-1.html 上篇帖子: 每日一题(35) 下篇帖子: ntop安装与配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表