4.使用DShow采集摄像头图像和麦克风声音到本地(摄像头录制)
2017-02-10 16:50
489 查看
上一篇介绍如何拍照,这一篇介绍一下如何录制摄像头视频和麦克风的声音,并合成一个视音频文件(avi)。
在上一篇的基础上,需要再创建一个本机音频采集设备的Filter,注意,如果你的机器没有音频采集设备,也就是麦克风,那就无法完成下面的工作,或者说只能生成一个视频文件。
首先,创建视频采集Filter,然后创建音频采集设备的Filter,创建过程跟上一篇中创建视频采集设备Filter类似,代码如下:
//这一步要调用,否则时间戳可能不对
IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface( IID_IConfigInterleaving, (void **)&pInterleave);
if(SUCCEEDED(hr))
{
pInterleave->put_Mode(INTERLEAVE_CAPTURE);
}
其实pMux就代表生成的视音频文件的Filter,下面将其加入图表
m_pGraphBuilder->AddFilter(pMux, L"Video Filter");
然后连接视音频采集设备的Filter到pMux上,即可完成采集到本地的工作,代码如下:
//视频音频都要连到pMux上
m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoFilter, NULL, pMux);
m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, m_pAudioFilter, NULL, pMux);
if (pConfigMux)//记得释放
{
pConfigMux->Release();
}
if (pInterleave)
{
pInterleave->Release();
}
pMux->Release();
以上就是最简单的视音频采集方案,可以看到,视音频采集设备的Filter直接连到视音频文件的Filter上了,中间没有其他Filter,这样采集出来的视音频文件比较大,没有经过编码的处理,这是后面要解决的问题,具体工作后面再讲。
本篇的界面完成后如下:
点击采集到本地,即可生成本地AVI视音频文件,注意工程中的路径请按照实际情况修改。
详细工程代码见这里:工程代码下载
转载请一定注明出处,谢谢!
在上一篇的基础上,需要再创建一个本机音频采集设备的Filter,注意,如果你的机器没有音频采集设备,也就是麦克风,那就无法完成下面的工作,或者说只能生成一个视频文件。
首先,创建视频采集Filter,然后创建音频采集设备的Filter,创建过程跟上一篇中创建视频采集设备Filter类似,代码如下:
void CGetDeviceInfoDlg::CreateAudioFilter(CString strSelectedDevice, IBaseFilter **pBaseFilter) { ICreateDevEnum *pCreateDevEnum = NULL; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void**)&pCreateDevEnum); IEnumMoniker *pEm = NULL; hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory, &pEm, 0); if (hr != NOERROR) return; ULONG cFetched; IMoniker *pM = NULL; while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) { IPropertyBag *pBag=0; hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag); if(SUCCEEDED(hr)) { VARIANT var; var.vt = VT_BSTR; hr = pBag->Read(L"FriendlyName", &var, NULL); //还有其他属性,像描述信息等等... if(hr == NOERROR) { //获取设备名称 char camera_name[1024]; WideCharToMultiByte(CP_ACP,0,var.bstrVal,-1, camera_name, sizeof(camera_name) ,"",NULL); CString str(camera_name); SysFreeString(var.bstrVal); if (strSelectedDevice == str) { hr = pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pBaseFilter); if (FAILED(hr)) { OutputDebugString(_T("BindToObject Failed")); } } } pBag->Release(); } pM->Release(); } pEm->Release(); pCreateDevEnum->Release(); }获取到后,将其加入到图表中去,
HRESULT hr = m_pGraphBuilder->AddFilter(m_pAudioFilter, L"Audio Capture Filter"); if (S_OK != hr) { MessageBox(_T("把m_pAudioFilter添加到IGraphBuilder失败"), _T("提示")); return; }后面这一步比较重要,设置需要生产的文件信息,即:
IBaseFilter *pMux = NULL; IFileSinkFilter *pSink = NULL; hr = m_pCapture->SetOutputFileName( &MEDIASUBTYPE_Avi, // Specifies AVI for the target file. MEDIASUBTYPE_Avi L"D:\\JYSoft\\temp\\myvideo.avi", // File name. &pMux, // Receives a pointer to the mux. &pSink); // (Optional) Receives a pointer to the file sink. //如果要录制多段,可以用下面的语句重命名文件,就能生成新的文件 //pSink->SetFileName(L"D:\\JYSoft\\temp\\Example", pmt);由于是视音频都要采集,涉及到视音频的同步问题,这里要把音频流作为主流,也就说以音频的时钟为基准,让视频来同步音频。代码如下:
IConfigAviMux *pConfigMux = NULL; hr = pMux->QueryInterface(IID_IConfigAviMux, (void**)&pConfigMux); if (SUCCEEDED(hr)) { pConfigMux->SetMasterStream(1); }
//这一步要调用,否则时间戳可能不对
IConfigInterleaving *pInterleave = NULL;
hr = pMux->QueryInterface( IID_IConfigInterleaving, (void **)&pInterleave);
if(SUCCEEDED(hr))
{
pInterleave->put_Mode(INTERLEAVE_CAPTURE);
}
其实pMux就代表生成的视音频文件的Filter,下面将其加入图表
m_pGraphBuilder->AddFilter(pMux, L"Video Filter");
然后连接视音频采集设备的Filter到pMux上,即可完成采集到本地的工作,代码如下:
//视频音频都要连到pMux上
m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, m_pVideoFilter, NULL, pMux);
m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, m_pAudioFilter, NULL, pMux);
if (pConfigMux)//记得释放
{
pConfigMux->Release();
}
if (pInterleave)
{
pInterleave->Release();
}
pMux->Release();
以上就是最简单的视音频采集方案,可以看到,视音频采集设备的Filter直接连到视音频文件的Filter上了,中间没有其他Filter,这样采集出来的视音频文件比较大,没有经过编码的处理,这是后面要解决的问题,具体工作后面再讲。
本篇的界面完成后如下:
点击采集到本地,即可生成本地AVI视音频文件,注意工程中的路径请按照实际情况修改。
详细工程代码见这里:工程代码下载
转载请一定注明出处,谢谢!
相关文章推荐
- zip4j -- Java处理zip压缩文件的完整解决方案
- 13.6.1
- mongo学习
- Android Wear 之 WearableListView
- UVA 11082 Matrix Decompressing(最大流)
- HALCON学习一(Halcon函数)
- ELASTIC 5.2部署并收集nginx日志
- JS和${}的一些问题
- linux下将c++编译成so,调用该so文件
- MySql多行数据合并成一行,将字段中的值拼接在一起
- react native安装过程遇到的问题
- 国外程序员整理的Java资源大全
- ES6常用新特性总结
- 为什么老板利用激励提升在客户现场工作员工的生产力,反而可能降低对客户的价值?
- JAVA--基本数据类型
- VS平台简单的使用C++调用Python3.5的方法
- Java基础13-总结StringBuffer,StringBuilder,数组高级,Arrays,Integer,Character
- 关于恢复万象OL的C盘系统后,重装万象OL后MSDE服务不能启动的解决
- 生成动态报表的Java项目打成.jar包文件运行时出错
- Java基础13-总结StringBuffer,StringBuilder,数组高级,Arrays,Integer,Character