基于DirectShow视频播放器

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。DirectShow为多媒体的捕捉和回放提供了强有力的支持。运用DirectShow我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。它广泛地支持各种媒体格式,包括Asf、Mpeg、Avi、Dv、Mp3、Wave等等,使得多媒体数据的回放变得轻而易举。另外,DirectShow还集成了DirectX其它部分(比如DirectDraw、DirectSound)的技术,直接支持DVD播放,视频的非线性编辑,以及与数据摄像机的交换换。更值得一提的是,DirectShow提供的是一种开放式的开发环境,我们可以根据自己的需要定制自己的组件。(引)入门DirectShow使用一种叫做FilterGraph的模型来管理整个数据流的处理过程,参与数据流处理的各个功能模块称做Filter,各个Filter在FilterGraph中按一定的顺序连成一条流水线协调工作,完成一些相对独立的功能,如Filter可以完成如下的一些功能:读文件从视频设备中获取视频对视频流进行解码将数据送往声卡或显卡每个Filter都有输入端和输出端,例如一个MPEG-1解码Filter它的输入是MPEG编码的流数据,它的输出端是一解码过的流数据。DirectShow正是通过将不同的Filter连接在一起完成特定的功能的,我们将这些Filter的连接叫做FilterGraph,如下图A给出是播放AVI的FilterGraph:图A播放AVI文件的GraphFilter图上图中每个模块分别代表了不同的Filter,媒体文件Filter从硬盘读取AVI文件,AVI分离Filter将文件分离为音频流和视频流,AVI解码Filter对视频流进行解码并送往Video表现Filter,由后者将各帧在显示器上显示,默认的DirectSound设备用DirectSound将音频流输出。我们的应用并不需要对这当中的所以的数据流进行管理,在DirectShow提供一个称做FilterGraph管理器的高级组件。在我们的应用中只需要调用它的API即可,如Run、Stop等,如果你想对其中的数据流做更进一步的控制,你可以对这些Filter直接通过COM接口进行存取。FilterGraph管理器同时也提供了另一个功能:应用程序可以通过管理器控制FilterGraph如何生成。DirectShow应用从广义上说,所有的DirectShow应用都必须完成三件事情,如下图B所示:图B1.生成FilterGraph管理器的一个实例。2.利用FilterGrapth实例生成FilterGraph,具体应该由哪些Filter组成FilterGraph视我们的应用的需要而定。3.通过对FilterGraph管理器的方法调用和来自FilterGraph的消息的响应FilterGraph和数据流进行控制。DirectShow是基于COM的,FilterGraph管理器和Filter都是COM对象,在开始着手之前你应该对COM有个基本的认识。下面让我们着手开始做一个简单的DirectShow应用,在这个应用中我们实现这样的功能:打开一个媒体文件,并对其进行播放。设置环境在利用DirectShow进行流媒体的处理之前,必须正确安装DirectX的SDK,DirectXSDK可以到微软的网站上下载,目前,DirectX最新版本为9.0。本文将对DirectShow的应用进行入门级的应用。在正确安装好DirectXSDK后,我们必须设置DirectXSDK的头文件和库文件,使其在VisualStudio的搜索路径内。对于VisualStudio.NET2003可如下进行设置:菜单→工具→选项→项目→VC++目录,在包含文件中加入D:\DXSDK\Include,在库文件中加入D:\DXSDK\lib(我的SDK的安装路径是D:\DXSDK):头文件文件名称描述Dshow.h所有的DirectShow应用都必须包含库文件文件名称描述Strmiids.lib此库文件中导出类标识(CLSID)和接口标识(IID),所有的DirectShow应用都必须包含此文件。Quartz.lib此库文件中导出函数AMGetErrorText,如果你的程序中调用了此函数,则必须包含此库文件。开始工程打开VisualStudio.NET2003,文件→新建→项目1.生成基于MFC的应用程序,名称PlayWnd。2.选择应用程序类型基于对话框,点击完成。3.设置工程属性项目→PlayWnd属性→配置属性→链接器→输入→附加依赖项,添加库文件Strmiids.lib和Quartz.lib。由于Dshow.h头文件是在任何DirectShow工程中都要用到的,因此我们stdafx.h加入如下行:#includeDshow.h4.设计对话框,如下:IDC_STATIC控件类型StaticTextCaption媒体文件名:IDC_MEDIAFILE_EDIT控件类型EditControlIDC_BROWSE_BUTTON控件类型ButtonCaption浏览IDC_VW_FRAME控件类型PictureControlTypeRectangleIDC_PLAY_BUTTON控件类型ButtonCaption播放IDC_PAUSE_BUTTON控件类型ButtonCaption暂停IDCANCEL控件类型ButtonCaption关闭5.COM的初始化和卸载,修改PlayWnd.cpp添加初始化代码(加入的代码用黑体表示,下同)BOOLCPlayWndApp::InitInstance(){//如果一个运行在WindowsXP上的应用程序清单指定要//使用ComCtl32.dll版本6或更高版本来启用可视化方式,//则需要InitCommonControls()。否则,将无法创建窗口。InitCommonControls();//初始化COM接口HRESULThr=CoInitialize(NULL);if(FAILED(hr)){TRACE(ERROR-CouldnotinitializeCOMlibrary.\n);returnFALSE;}CWinApp::InitInstance();AfxEnableControlContainer();修改PlayWnd.cpp添加卸载COM代码,注意需要对虚函数ExitInstance进行重载,并在PlayWnd.h文件中声明:public:virtualintExitInstance();intCPlayFileApp::ExitInstance(){//TODO:在此添加专用代码和/或调用基类//关闭COMCoUninitialize();returnCWinApp::ExitInstance();}6.定义媒体控制成员变量修改PlayWndDlg.h如下:protected:HICONm_hIcon;//生成的消息映射函数virtualBOOLOnInitDialog();afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam);afx_msgvoidOnPaint();afx_msgHCURSOROnQueryDragIcon();DECLARE_MESSAGE_MAP()//和媒体控制相关的成员变量private:IGraphBuilder*m_pGraph;//IGraphBuilder接口提供了生成FilterGraph相//关的方法IMediaControl*m_pMediaControl;//IMediaControl接口提供了控制流经Filter//Graph数据流的相关方法IMediaEventEx*m_pEvent;//IMediaEventEx继承自IMediaEvent,提供了从//FilterGraph管理器获取事件消息的方法IMediaSeeking*m_pMediaSeeking;//IMediaSeeking提供了控制流的播放位置和播放//速度的方法CStringm_strMediaFile;//当前播放的媒体文件的名称BOOLm_isPlaying;//当前的播放状态};在CPlayWndDlg的构造函数中添加初始化代码CPlayWndDlg::CPlayWndDlg(CWnd*pParent/*=NULL*/):CDialog(CPlayWndDlg::IDD,pParent){m_hIcon=AfxGetApp()-LoadIcon(IDR_MAINFRAME);m_pGraph=NULL;m_pMediaControl=NULL;m_pEvent=NULL;m_pMediaSeeking=NULL;m_strMediaFile=;m_isPlaying=FALSE;}由于一些和窗体控制有关的初始化代码不能放在构造函数中进行,我们将其放在CPlayWndDlg::OnInitDialog()中,我们必须在此必须对CPlayWndDlg添加WS_CLIPCHILDREN的Style,因为在我们的应用中把视频窗体作为CPlayWndDlg的一个子窗体来使用的,这是非常重要的,许多开发人员在刚开始使用DirectShow时,父窗体的Style没有设置正确,造成视频不能正确显示,代码如下://设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动//执行此操作SetIcon(m_hIcon,TRUE);//设置大图标SetIcon(m_hIcon,FALSE);//设置小图标//TODO:在此添加额外的初始化代码ModifyStyle(0,WS_CLIPCHILDREN);((CEdit*)GetDlgItem(IDC_MEDIAFILE_EDIT))-SetReadOnly(TRUE);returnTRUE;//除非设置了控件的焦点,否则返回TRUE}添加相应的清除代码,重载CPlayWndDlg的DestoryWindow方法,如下:BOOLCPlayWndDlg::DestroyWindow(){//TODO:在此添加专用代码和/或调用基类if(m_pGraph)m_pGraph-Release();if(m_pMediaControl)m_pMediaControl-Release();if(m_pEvent)m_pEvent-Release();if(m_pMediaSeeking)m_pMediaSeeking-Release();m_pGraph=NULL;m_pMediaControl=NULL;m_pEvent=NULL;m_pMediaSeeking=NULL;returnCDialog::DestroyWindow();}7.修改CPlayWndDlg::OnPaint(),由于现在视频显示区域必须由我们自己进行重画:voidCPlayWndDlg::OnPaint(){if(IsIconic()){CPaintDCdc(this);//用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND,reinterpret_castWPARAM(dc.GetSafeHdc()),0);//使图标在工作矩形中居中intcxIcon=GetSystemMetrics(SM_CXICON);intcyIcon=GetSystemMetrics(SM_CYICON);CRectrect;GetClientRect(&rect);intx=(rect.Width()-cxIcon+1)/2;inty=(rect.Height()-cyIcon+1)/2;//绘制图标dc.DrawIcon(x,y,m_hIcon);}else{if(m_isPlaying==FALSE){CClientDCdc(GetDlgI

1 / 15
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功