最近来了个项目,有一块功能是usb摄像头录制视频并且录音的实现,网上的东西七七八八什么技术都有,先用opencv打了半天环境不能录音频,后来用ffmpeg,原谅我太菜,视频编码和格式让人头疼,不懂怎么移植到自己的程序中,后来用的directshow,希望大家少走些弯路。
#include "PreviewController.h"
std::string TCHAR2STRING(const TCHAR *STR)
{
int iLen = WideCharToMultiByte(CP_ACP, 0,STR, -1, NULL, 0, NULL, NULL);
char* chRtn =new char[iLen*sizeof(char)];
WideCharToMultiByte(CP_ACP, 0, STR, -1, chRtn, iLen, NULL, NULL);
std::string str(chRtn);
return str;
}
PreviewController::~PreviewController()
{
IVideoWindowPtr pVW = m_pSourceGraph;
if (pVW != NULL)
{
pVW->put_Visible(OAFALSE);
pVW->put_Owner(NULL);
}
StopCapture();
m_pCaptureGraph = NULL;
IMediaControlPtr pMC = m_pSourceGraph;
if (pMC != NULL)
{
pMC->Stop();
pMC = NULL;
}
m_pSourceGraph = NULL;
}
HRESULT
PreviewController::SelectDevice(const TCHAR* pVideo, const TCHAR* pAudio, HWND hwnd, RECT* prc)
{
// create a new device
m_pSourceGraph = NULL;
m_pBridge = NULL;
m_pCapOutput = NULL;
HRESULT hr = m_pBridge.CreateInstance(__uuidof(GMFBridgeController));
if (FAILED(hr))
{
return hr;
}
// init to video-only, in discard mode (ie when source graph
// is running but not connected, buffers are discarded at the bridge)
hr = m_pBridge->AddStream(true, eMuxInputs, true);
m_bAudio = false;
_bstr_t strAudio = pAudio;
IBaseFilterPtr pfAudio;
if (SUCCEEDED(hr) && (strAudio.length() > 0))
{
m_bAudio = true;
hr = m_pBridge->AddStream(false, eMuxInputs, true);
if (SUCCEEDED(hr))
{
hr = LocateFilter(pAudio, CLSID_AudioInputDeviceCategory, &pfAudio);
}
}
if (FAILED(hr))
{
return hr;
}
// locate the requested filter
IBaseFilterPtr pfDevice;
hr = LocateFilter(pVideo, CLSID_VideoInputDeviceCategory, &pfDevice);
if (FAILED(hr))
{
return hr;
}
// create source graph and add sink filter
hr = m_pSourceGraph.CreateInstance(CLSID_FilterGraph);
if (FAILED(hr))
{
return hr;
}
_bstr_t strName = pVideo;
m_pSourceGraph->AddFilter(pfDevice, strName);