DirectShow最主要的功能就是播放视频,在这里介绍一个简单的基于DirectShow的播放器的例子,是用MFC做的,今后有机会可以基于该播放器开发更复杂的播放器软件。

注:该例子取自于《DirectShow开发指南》

首先看一眼最终结果,如图所示,播放器包含了:打开,播放,暂停,停止等功能。该图显示正在播放周杰伦的《听妈妈的话》。

迅速进入主题,看一看工程是由哪些文件组成的,如下图所示

从上图可以看出,该工程最重要的cpp文件有两个:SimplePlayerDlg.cpp和CDXGraph.cpp。前者是视频播放器对话框对应的类,而后者是对DirectShow功能进行封装的类。尤其是后面那个类,写的很好,可以说做到了“可复用”,可以移植到其他DirectShow项目中。

本文首先分析CDXGraph这个类,SimplePlayerDlg在下篇文章中再进行分析。

首先看看它的头文件:

CDXGraph.h

/* 雷霄骅* 中国传媒大学/数字电视技术* leixiaohua1020@126.com**/
// CDXGraph.h#ifndef __H_CDXGraph__
#define __H_CDXGraph__// Filter graph notification to the specified window
#define WM_GRAPHNOTIFY  (WM_USER+20)class CDXGraph
{
private://各种DirectShow接口IGraphBuilder *     mGraph;  IMediaControl *        mMediaControl;IMediaEventEx *       mEvent;IBasicVideo *        mBasicVideo;IBasicAudio *       mBasicAudio;IVideoWindow  *     mVideoWindow;IMediaSeeking *        mSeeking;DWORD              mObjectTableEntry; public:CDXGraph();virtual ~CDXGraph();public://创建IGraphBuilder,使用CoCreateInstancevirtual bool Create(void);//释放virtual void Release(void);virtual bool Attach(IGraphBuilder * inGraphBuilder);IGraphBuilder * GetGraph(void); // Not outstanding reference countIMediaEventEx * GetEventHandle(void);bool ConnectFilters(IPin * inOutputPin, IPin * inInputPin, const AM_MEDIA_TYPE * inMediaType = 0);void DisconnectFilters(IPin * inOutputPin);bool SetDisplayWindow(HWND inWindow);bool SetNotifyWindow(HWND inWindow);bool ResizeVideoWindow(long inLeft, long inTop, long inWidth, long inHeight);void HandleEvent(WPARAM inWParam, LPARAM inLParam);//各种操作bool Run(void);        // Control filter graphbool Stop(void);bool Pause(void);bool IsRunning(void);  // Filter graph statusbool IsStopped(void);bool IsPaused(void);bool SetFullScreen(BOOL inEnabled);bool GetFullScreen(void);// IMediaSeekingbool GetCurrentPosition(double * outPosition);bool GetStopPosition(double * outPosition);bool SetCurrentPosition(double inPosition);bool SetStartStopPosition(double inStart, double inStop);bool GetDuration(double * outDuration);bool SetPlaybackRate(double inRate);// Attention: range from -10000 to 0, and 0 is FULL_VOLUME.bool SetAudioVolume(long inVolume);long GetAudioVolume(void);// Attention: range from -10000(left) to 10000(right), and 0 is both.bool SetAudioBalance(long inBalance);long GetAudioBalance(void);bool RenderFile(const char * inFile);bool SnapshotBitmap(const char * outFile);private:void AddToObjectTable(void) ;void RemoveFromObjectTable(void);//各种QueryInterface,初始各种接口bool QueryInterfaces(void);
};#endif // __H_CDXGraph__

该头文件定义了CDXGraph类封装的各种DirectShow接口,以及提供的各种方法。在这里因为方法种类特别多,所以只能选择最关键的方法进行分析。下面打开CDXGraph.cpp看看如下几个方法吧:

Create():用于创建IGraphBuilder

//创建IGraphBuilder,使用CoCreateInstance
bool CDXGraph::Create(void)
{if (!mGraph){if (SUCCEEDED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,IID_IGraphBuilder, (void **)&mGraph))){AddToObjectTable();return QueryInterfaces();}mGraph = 0;}return false;
}

需要注意的是,Create()调用了QueryInterfaces()

QueryInterfaces():用于初始化各种接口

//各种QueryInterface,初始各种接口
bool CDXGraph::QueryInterfaces(void)
{if (mGraph){HRESULT hr = NOERROR;hr |= mGraph->QueryInterface(IID_IMediaControl, (void **)&mMediaControl);hr |= mGraph->QueryInterface(IID_IMediaEventEx, (void **)&mEvent);hr |= mGraph->QueryInterface(IID_IBasicVideo, (void **)&mBasicVideo);hr |= mGraph->QueryInterface(IID_IBasicAudio, (void **)&mBasicAudio);hr |= mGraph->QueryInterface(IID_IVideoWindow, (void **)&mVideoWindow);hr |= mGraph->QueryInterface(IID_IMediaSeeking, (void **)&mSeeking);if (mSeeking){mSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);}return SUCCEEDED(hr);}return false;
}

Release():释放各种接口

//释放
void CDXGraph::Release(void)
{if (mSeeking){mSeeking->Release();mSeeking = NULL;}if (mMediaControl){mMediaControl->Release();mMediaControl = NULL;}if (mEvent){mEvent->Release();mEvent = NULL;}if (mBasicVideo){mBasicVideo->Release();mBasicVideo = NULL;}if (mBasicAudio){mBasicAudio->Release();mBasicAudio = NULL;}if (mVideoWindow){mVideoWindow->put_Visible(OAFALSE);mVideoWindow->put_MessageDrain((OAHWND)NULL);mVideoWindow->put_Owner(OAHWND(0));mVideoWindow->Release();mVideoWindow = NULL;}RemoveFromObjectTable();if (mGraph) {mGraph->Release(); mGraph = NULL;}
}

Run():播放

bool CDXGraph::Run(void)
{if (mGraph && mMediaControl){if (!IsRunning()){if (SUCCEEDED(mMediaControl->Run())){return true;}}else{return true;}}return false;
}

Stop():停止

bool CDXGraph::Stop(void)
{if (mGraph && mMediaControl){if (!IsStopped()){    if (SUCCEEDED(mMediaControl->Stop())){return true;}}else{return true;}}return false;
}

Pause():暂停

bool CDXGraph::Pause(void)
{if (mGraph && mMediaControl){if (!IsPaused()){ if (SUCCEEDED(mMediaControl->Pause())){return true;}}else{return true;}}return false;
}

SetFullScreen():设置全屏

bool CDXGraph::SetFullScreen(BOOL inEnabled)
{if (mVideoWindow){HRESULT hr = mVideoWindow->put_FullScreenMode(inEnabled ? OATRUE : OAFALSE);return SUCCEEDED(hr);}return false;
}

GetDuration():获得视频时长

bool CDXGraph::GetDuration(double * outDuration)
{if (mSeeking){__int64 length = 0;if (SUCCEEDED(mSeeking->GetDuration(&length))){*outDuration = ((double)length) / 10000000.;return true;}}return false;
}

SetAudioVolume():设置音量

bool CDXGraph::SetAudioVolume(long inVolume)
{if (mBasicAudio){HRESULT hr = mBasicAudio->put_Volume(inVolume);return SUCCEEDED(hr);}return false;
}

RenderFile():关键!

bool CDXGraph::RenderFile(const char * inFile)
{if (mGraph){WCHAR    szFilePath[MAX_PATH];MultiByteToWideChar(CP_ACP, 0, inFile, -1, szFilePath, MAX_PATH);if (SUCCEEDED(mGraph->RenderFile(szFilePath, NULL))){return true;}}return false;
}

播放器源代码下载: http://download.csdn.net/detail/leixiaohua1020/6453467

一个简单的基于 DirectShow 的播放器 1(封装类)相关推荐

  1. 一个简单的基于 DirectShow 的播放器 2(对话框类)

    上篇文章分析了一个封装DirectShow各种接口的封装类(CDXGraph):一个简单的基于 DirectShow 的播放器  1(封装类) 本文继续上篇文章,分析一下调用这个封装类(CDXGrap ...

  2. 最简单的基于 DirectShow 的视频播放器

    源程序下载链接:https://download.csdn.net/download/bmjhappy/11250669 50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍 ...

  3. 转:最简单的基于 DirectShow 的视频播放器

    50行代码实现的一个最简单的基于 DirectShow 的视频播放器 本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectSho ...

  4. 50行代码实现的一个最简单的基于 DirectShow 的视频播放器

    本文介绍一个最简单的基于 DirectShow 的视频播放器.该播放器对于初学者来说是十分有用的,它包含了使用 DirectShow 播放视频所有必备的函数. 直接贴上代码,具体代码的含义都写在注释中 ...

  5. HTML:给自己设计一个简单的专属网页音乐播放器

    Hello,大家好,我是wangzirui32,今天我们来学习如何给自己设计一个简单的网页音乐播放器. 开始学习吧! 学习目录 1. 项目架构 2. player.html 编写 3. style.c ...

  6. 基于 DirectShow 的播放器

    https://blog.csdn.net/leixiaohua1020/article/details/13019147 COM编程之 QueryInterface https://www.cnbl ...

  7. 最简单的基于DirectShow的示例:视频播放器自定义版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  8. 最简单的基于DirectShow的示例:视频播放器图形界面版

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

  9. 最简单的基于DirectShow的示例:视频播放器

    ===================================================== 最简单的基于DirectShow的示例文章列表: 最简单的基于DirectShow的示例:视 ...

最新文章

  1. 提高开发效率之VS Code基础配置篇
  2. matlab练习程序(图像区域分裂)
  3. python 字符编码
  4. IOS学习之路五(代码实现UITableView)
  5. Bilateral Filtering(双边滤波) for SSAO
  6. 微课堂 | 腾讯产品经理刘涵宇:给产品经理和设计师的用户体验知识
  7. Windows YII2安装
  8. 前端之CSS第二部分属性相关
  9. JAVA异常和基础类库
  10. [转]英特尔为什么能在CPU方面领跑?
  11. Prescan:关于Prescan与Matlab联合仿真问题小总(不定时补充)
  12. 通达信 移动平均算法_中山证券通达信下载-中山证券通达信软件 v1.06 官方版
  13. c语言中compar的用法,C/C++中关于std::string的compare陷阱示例详解
  14. 局域网内ip冲突引起的怪异现象
  15. BIGO前端一面面经
  16. 路由器找不到拨号服务器,路由器宽带拨号上网连接不上怎么解决?
  17. Log4j2写日志的艺术
  18. 国网大数据中心是如何进行数据治理的?
  19. es的基本操作(创建索引,添加数据,删除数据,判断索引是否存在)
  20. U盘、移动硬盘错误0x80071ac3!

热门文章

  1. 十步完成windows服务的安装
  2. 李开复写给大学生的第四封信的一些笔录
  3. NUC1154 Vertical Histogram【打印图案】
  4. exponential family distribution(指数族分布)
  5. 尔雅/广雅 —— 古代的字典
  6. The Python Challenge 题解
  7. 一题多解(四)—— 数组中唯一出现 2 次的数
  8. 中英文对照 —— 战争与军事
  9. centos7 php多版本切换_CentOS7服务搭建----搭建私有云盘01
  10. testmeshpro合批_TextMesh Pro新手使用手册