求DirectShow的AVI录制示例程序

woodyplus 2011-03-28 05:39:22
我需要搭建一个Windows程序模块,功能是需要录制窗口内容,要求可以开始和结束,保存成为AVI格式,求完整的示例程序指教。

网上几乎没有完整的资源可以拿来看,希望各路神仙能够拿自己的示例程序工程打包给我,为了避免无人回答,暂不设置悬赏。本人分多,如果程序没问题可以追加悬赏,希望大家帮忙。

要求工程尽量小而且保证完整。
最好能移植到别的Win32工程中。

发邮箱:mcg890414@163.com

如果给点知道也可以给分~~~~不过请尽量说清楚,网上完全查不到资料啊

我对于 Filter和 Graph不是很理解,求帮助。
...全文
142 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
woodyplus 2011-04-22
  • 打赏
  • 举报
回复
谢谢大姐~
izardMan 2011-04-21
  • 打赏
  • 举报
回复
发到你邮箱了
woodyplus 2011-04-15
  • 打赏
  • 举报
回复
对 6 楼 wuzongman 的回复:

请问这位大神姐姐有没有整个工程可以发给我
邮箱:mcg890414@163.com

收到后就结贴谢谢。
izardMan 2011-04-14
  • 打赏
  • 举报
回复
实现文件:
C/C++ code

/*CaptureClass.cpp*/

#include "StdAfx.h"
#include "CaptureClass.h"

/************************************************************************/
/* 类构造函数实现 */
/************************************************************************/
CCaptureClass::CCaptureClass(void)
{
CoInitialize(NULL); //COM库初始化
m_hWnd = NULL; //视频显示窗口的句柄
m_pVW = NULL ; //视频窗口接口指针清空
m_pMC = NULL ; //媒体控制接口指针清空
m_pGB = NULL ; //滤波器链表管理器接口指针清空
m_pBF = NULL ; //捕获滤波器接口指针清空
m_pCapture = NULL ; //增强型捕获滤波器链表管理器接口指针清空
}

/************************************************************************/
/* 析构函数 */
/************************************************************************/
CCaptureClass::~CCaptureClass(void)
{
if(m_pMC) m_pMC ->Stop(); //首先停止媒体
if(m_pVW){
m_pVW->put_Visible(OAFALSE); //视频窗口不可见
m_pVW->put_Owner(NULL); //视频窗口的父窗口清空
}
SAFE_RELEASE(m_pCapture); //释放增强型捕获滤波器链表管理器接口
SAFE_RELEASE(m_pMC); //释放媒体控制接口
SAFE_RELEASE(m_pGB); //释放滤波器链表管理器接口
SAFE_RELEASE(m_pBF); //释放捕获滤波器接口
CoUninitialize( ); //卸载COM库
}

/************************************************************************/
/* 把指定采集设备与滤波器捆绑 */
/************************************************************************/
bool CCaptureClass::BindFilter(int deviceId,IBaseFilter **pFilter)
{
if( deviceId < 0) return false ;
//枚举所有的视频捕获设备
ICreateDevEnum *pCreateDevEnum ;
//生成设备枚举器pCreateDevEnum
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void**)&pCreateDevEnum);
if( hr != NOERROR ) return false ;
IEnumMoniker *pEm;
//创建视频输入设备类枚举器
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm,0);
if( hr != NOERROR ) return false ;
pEm->Reset(); //复位该设备
ULONG cFetched;
IMoniker *pM;
int index = 0 ;
//获取设备
while( hr = pEm->Next(1,&pM,&cFetched),hr == S_OK , index <= deviceId )
{
IPropertyBag *pBag;
//获取该设备的属性集
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); //获取FriendlyName形式的信息
if( hr == NOERROR )
{
//采集设备与捕获滤波器捆绑
if( index == deviceId ) pM->BindToObject(0,0,IID_IBaseFilter,(void**)pFilter);
SysFreeString(var.bstrVal); //释放二进制数据资源,必须释放
}
pBag ->Release();
}
pM->Release();
index++;
}
return true ;
}

/************************************************************************/
/* 设置视频显示窗口的特性 */
/************************************************************************/
HRESULT CCaptureClass::SetupVideoWindow()
{
HRESULT hr ;
//m_hWnd为类CCaptureClass的成员变量,在使用该函数前须初始化
hr = m_pVW->put_Visible(OAFALSE); //视频窗口不可见
hr = m_pVW->put_Owner((OAHWND)m_hWnd); //窗口所有者:传入的窗口句柄
if(FAILED(hr)) return hr ;
hr = m_pVW->put_WindowStyle( WS_CHILD | WS_CLIPCHILDREN); //窗口风格设置
if( FAILED(hr)) return hr ;
ResizeVideoWindow(); //更改窗口大小
hr = m_pVW->put_Visible(OATRUE); //视频窗口可见
return hr ;
}

/************************************************************************/
/* 更改视频窗口大小 */
/************************************************************************/
void CCaptureClass::ResizeVideoWindow()
{
if( m_pVW ){
//让图像充满整个指定窗口
CRect rc ;
::GetClientRect(m_hWnd,&rc); //获取显示窗口的客户区
m_pVW->SetWindowPosition(0,0,rc.right,rc.bottom); //设置视频显示窗口的位置
}
}

/************************************************************************/
/* 开始预览视频设备 */
/************************************************************************/
HRESULT CCaptureClass::PreviewImages(int iDeviceID , HWND hWnd)
{
HRESULT hr ;
//初始化视频捕获滤波器链表管理器
hr = InitCaptureGraphBuilder();
if(FAILED(hr)){
AfxMessageBox(_T("Failed to get video interfaces!"));
return hr ;
}

//把指定采集设备与滤波器绑定
if( !BindFilter(iDeviceID,&m_pBF)) return S_FALSE;
//把滤波器添加到滤波器链表中
hr = m_pGB->AddFilter(m_pBF,L"Capture Filter");
//渲染媒体,把链表中的滤波器链接起来
hr = m_pCapture->RenderStream(&PIN_CATEGORY_PREVIEW,&MEDIATYPE_Video,m_pBF,NULL,NULL);
if(FAILED(hr)){
AfxMessageBox(_T("Can't build the graph"));
return hr ;
}

//设置视频显示窗口
m_hWnd = hWnd; //初始化窗口句柄
SetupVideoWindow(); //设置显示窗口

hr = m_pMC->Run();
if(FAILED(hr)){
AfxMessageBox(_T("Couldn't run the graph!"));
return hr ;
}
return S_OK ;
}

/************************************************************************/
/* 设置捕获视频的文件,开始捕捉视频数据写文件 */
/************************************************************************/
HRESULT CCaptureClass::CaptureImages(CString inFileName)
{
HRESULT hr = 0 ;
m_pMC ->Stop(); //先停止视频
//设置文件名,注意第二个参数的类型
hr = m_pCapture->SetOutputFileName(&MEDIASUBTYPE_Avi,inFileName.AllocSysString(),&pMux,NULL) ;
//渲染媒体,链接所有滤波器
hr = m_pCapture->RenderStream(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,m_pBF,NULL,pMux);
pMux->Release();
m_pMC->Run(); //回复视频
return hr ;
}

int CCaptureClass::EnumDevices(HWND hList)
{
if (!hList)
return -1;
int id = 0;

//枚举视频扑捉设备
ICreateDevEnum *pCreateDevEnum; /*此接口生成一个特殊类别的设备枚举器,The System Device Enumerator exposes this interface*/
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)return -1;

IEnumMoniker *pEm=0; //此接口用来枚举一个"名字"组件或者枚举名字表中的名字
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEm, 0);//CreateClassEnumerator方法为指定的设备类生成一个类枚举器

if (hr != NOERROR)return -1;

pEm->Reset(); //由于IEnumMoniker接口有一个标准的参考计数,pEm->Release(),一定要释放此接口
ULONG cFetched;

IMoniker *pM; //此接口包含允许你使用“名字”对象的方法,而名字对象包含能唯一确定COM对象的方法
while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK) //返回枚举器队列中指定数目的条款,下“1”个
{
IPropertyBag *pBag; //接口IPropertyBag提供一个有属性包的对象,对象可以在包里存储它的特征
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag); //返回包含被“moniker”确定的对象的存储位置的接口指针
if(SUCCEEDED(hr))
{
VARIANT var; //VARIANT结构体包括很多类型
var.vt = VT_BSTR; //vt, describes which of the union members is valid,bstrVal是有效的
hr = pBag->Read(L"FriendlyName", &var, NULL); //Asks the property bag to read the named

//property into a caller-initialized VARIANT,var接收
if (hr == NOERROR)
{
//CP_ACP:The current system Windows "ANSI" code page
//var.bstrVal被转化的
//-1表示长度被自动计算;str表示转化侯接收目标的地方;两个NULL使函数更快
id++;

//此函数处理指定的消息,hList窗口的句柄,此窗口处理此消息;CB_ADDSTRING要处理的消息
::SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)var.bstrVal);

SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
}
return id;
}

HRESULT CCaptureClass::InitCaptureGraphBuilder()
{
HRESULT hr ;
//创建IGraphBuilder接口
hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,IID_IGraphBuilder,(void**)&m_pGB);
if(FAILED(hr)) return hr ;
//创建ICaptureGraphBuilder2接口
hr = CoCreateInstance(CLSID_CaptureGraphBuilder2,NULL,CLSCTX_INPROC,IID_ICaptureGraphBuilder2,(void**)&m_pCapture) ;
if(FAILED(hr)) return hr ;
//初始化滤波器链表管理器IGraphBuilder
m_pCapture->SetFiltergraph(m_pGB);
//查询媒体控制接口
hr = m_pGB->QueryInterface(IID_IMediaControl,(void**)&m_pMC);
if(FAILED(hr)) return hr ;
//查询视频窗口接口
hr = m_pGB -> QueryInterface(IID_IVideoWindow,(LPVOID*)&m_pVW);
if(FAILED(hr)) return hr ;
return hr ;
}

//////////////////////////////////////////////////////////////////////////
//配置摄像头数据源格式:分辨率、RGB/I420等
void CCaptureClass::ConfigCameraPin(HWND hwndParent)
{
HRESULT hr ; //返回值
IAMStreamConfig *pSC ; //流配置接口
ISpecifyPropertyPages *pSpec ; //属性页接口
//只有停止后,才能进行引脚属性的设置
m_pMC ->Stop();
//首先查询捕获CAPTURE、视频VIDEO接口
hr = m_pCapture->FindInterface(&PIN_CATEGORY_CAPTURE,&MEDIATYPE_Video,m_pBF,IID_IAMStreamConfig,(void**)&pSC);
CAUUID cauuid ; //所有属性页结构体
hr = pSC->QueryInterface(IID_ISpecifyPropertyPages,(void**)&pSpec);
if( hr == S_OK ){
hr = pSpec->GetPages(&cauuid); //获取所有属性页
//显示属性页
hr = OleCreatePropertyFrame(hwndParent,30,30,NULL,1,(IUnknown**)&pSC,cauuid.cElems,(GUID*)cauuid.pElems,0,0,NULL);
//释放内存、资源
CoTaskMemFree(cauuid.pElems);
pSpec->Release();
pSC->Release();
}

//回复运行
m_pMC->Run();
}

//////////////////////////////////////////////////////////////////////////
//配置图像参数:亮度、色度、饱和度等
void CCaptureClass::ConfigCameraFilter(HWND hwndParent)
{
HRESULT hr = 0 ;
ISpecifyPropertyPages *pProp ;
hr = m_pBF->QueryInterface(IID_ISpecifyPropertyPages,(void**)&pProp);
if(SUCCEEDED(hr))
{
//获取滤波器名称和IUnknown接口指针
FILTER_INFO FilterInfo ;
hr = m_pBF->QueryFilterInfo(&FilterInfo);
IUnknown *pFilterUnk ;
m_pBF->QueryInterface(IID_IUnknown,(void**)&pFilterUnk);
//显示该页
CAUUID caGUID ;
pProp ->GetPages(&caGUID);
OleCreatePropertyFrame(
hwndParent,
0,0,
FilterInfo.achName,
1,
&pFilterUnk,
caGUID.cElems,
caGUID.pElems,
0,
0,NULL
);
//释放内存、资源
CoTaskMemFree(caGUID.pElems);
pFilterUnk->Release();
FilterInfo.pGraph ->Release();
pProp->Release();
}
m_pMC->Run();
}
izardMan 2011-04-14
  • 打赏
  • 举报
回复
/*CaptureClass.h*/

#pragma once
#define __IDxtCompositor_INTERFACE_DEFINED__
#define __IDxtAlphaSetter_INTERFACE_DEFINED__
#define __IDxtJpeg_INTERFACE_DEFINED__
#define __IDxtKey_INTERFACE_DEFINED__
#include <windows.h>
#include <atlbase.h>
#include <DShow.h>
#include <qedit.h>//ISampleGrabber接口要求的

#ifndef SAFE_RELEASE
#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
#endif
class CCaptureClass
{
public:
CCaptureClass(void);
public:
~CCaptureClass(void);
int EnumDevices(HWND hList);
//void SaveGraph(TCHAR *wFileName); //保存滤波器链表
void ConfigCameraPin(HWND hwndParent); //配置摄像头的视频格式
void ConfigCameraFilter(HWND hwndParent); //配置摄像头的图像参数
HRESULT CaptureImages(CString inFileName); //捕获保存视频
HRESULT PreviewImages(int iDeviceID , HWND hWnd); //采集预览视频
private:
HWND m_hWnd; //视频显示窗口的句柄
IGraphBuilder *m_pGB; //滤波器链表管理器
ICaptureGraphBuilder2 *m_pCapture; //增强型捕获滤波器链表管理器
IBaseFilter *m_pBF; //捕获滤波器
IMediaControl *m_pMC; //媒体控制接口
IVideoWindow *m_pVW; //视频显示窗口接口
IBaseFilter *pMux; //写文件滤波器
protected:
bool BindFilter(int deviceId,IBaseFilter **pFilter); //把指定的设备滤波器捆绑到链表中
void ResizeVideoWindow(); //更改视频显示窗口
HRESULT SetupVideoWindow(); //设置视频显示窗口的特性
HRESULT InitCaptureGraphBuilder(); //创建滤波器链表管理器,查询其各种控制接口
};
woodyplus 2011-04-07
  • 打赏
  • 举报
回复
3楼大神,不好意思,我没有这个注册帐户。
麻烦您帮我下载一下,发送到我的邮箱里mcg890414@163.com
收到后就结帖给分。

[Quote=引用 3 楼 masterz 的回复:]
http://www.codeproject.com/KB/audio-video/DXCapture.aspx
Simultaneous Previewing & Video Capture using DirectShow
[/Quote]
masterz 2011-04-01
  • 打赏
  • 举报
回复
http://www.codeproject.com/KB/audio-video/DXCapture.aspx
Simultaneous Previewing & Video Capture using DirectShow
黑泡泡选手 2011-03-31
  • 打赏
  • 举报
回复
网上肯定有,只是你没有发现!
woodyplus 2011-03-31
  • 打赏
  • 举报
回复
自己顶一下,没人看到么?

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧