`

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

 
阅读更多

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,使用CoCreateInstance
	virtual bool Create(void);
	//释放
	virtual void Release(void);
	virtual bool Attach(IGraphBuilder * inGraphBuilder);

	IGraphBuilder * GetGraph(void); // Not outstanding reference count
	IMediaEventEx * 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 graph
	bool Stop(void);
	bool Pause(void);
	bool IsRunning(void);  // Filter graph status
	bool IsStopped(void);
	bool IsPaused(void);

	bool SetFullScreen(BOOL inEnabled);
	bool GetFullScreen(void);

	// IMediaSeeking
	bool 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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    C# Directshow简单播放器实例

    在“C# Directshow简单播放器实例”中,我们看到一个针对初学者的学习项目,它旨在教授如何利用C#语言和DirectShow库在WinCE环境下创建一个基本的多媒体播放器。该播放器能够支持多种视频格式,如3gp、avi和wmv。 ...

    MP3播放器并且封装了一个CMP3类

    在这个项目中,开发者基于Microsoft Foundation Class (MFC)库构建了一个简单的MP3播放器。MFC是微软提供的一套C++类库,它封装了Windows API,使得Windows应用程序的开发更加便捷。 首先,我们关注的是"CMP3类"的...

    基于mfc播放器

    【基于MFC播放器】是一个面向初学者的项目,它利用Microsoft Foundation Classes (MFC) 框架创建了一个简单的用户界面,用于实现媒体播放功能。MFC是微软为Windows平台开发的应用程序提供的一种C++类库,它封装了...

    基于MFC的简易音乐播放器

    本实验旨在设计一个基于MFC的简易Windows音乐播放器。该播放器的目标是在Windows XP平台上使用Visual C++进行开发,并确保其能在Windows 2000/XP等操作系统上运行。通过这个项目,不仅可以学习MFC的基本使用方法,还...

    mfc的简单音频播放器源代码

    总之,创建一个基于MFC的简单音频播放器涉及MFC类库的使用、音频处理库的集成、用户界面设计以及错误处理等多个方面。通过这个项目,你可以深化对MFC的理解,同时增强C++编程和多媒体处理技能。

    简单MFC音乐播放器

    这个“简单MFC音乐播放器”项目,是基于MFC框架实现的一个小型音频播放器,它具备基本的音乐操作功能,如打开、添加音乐文件,以及快进、快退、暂停等控制。下面我们将详细讨论这个音乐播放器涉及到的MFC技术和音乐...

    基于windows程序设计的视频播放器

    在本文中,我们将深入探讨如何基于Windows程序设计创建一个简单的视频播放器,主要利用WIN32 SDK(Software Development Kit)的API函数。标题中的“基于Windows程序设计的视频播放器”意味着我们将不依赖像MFC...

    基于MFC的简易Windows播放器

    【基于MFC的简易Windows播放器】 MFC(Microsoft Foundation Classes)是微软提供的一套C++库,用于简化Windows应用程序的开发。它基于面向对象的设计,封装了Windows API,为开发者提供了更高级别的抽象,使得...

    精致简易的音乐播放器加源代码

    在这个项目中,作者以一种简单而精致的方式构建了一个音乐播放器,它不仅展示了编程技术的应用,也蕴含着对音乐与情感的独特表达。这个播放器是用Microsoft Visual Studio 2008中的MFC(Microsoft Foundation ...

    多功能音乐播放器(基于MFC, 可控颜色 )

    "多功能音乐播放器(基于MFC,可控颜色)" 是一个软件开发项目,主要目标是创建一个具备多种功能的音乐播放应用程序。该播放器利用Microsoft Foundation Classes (MFC)库来构建,这是一套由微软提供的C++类库,用于...

    MFC简单音乐播放器

    这个“MFC简单音乐播放器”项目是一个基于MFC的源代码实现,它允许用户在Windows操作系统上播放音乐。通过这个项目,我们可以深入学习MFC框架在开发桌面应用时如何处理多媒体功能。 1. **MFC基础** MFC是微软为...

    VC++ 基于MFC的音乐播放器程序

    总的来说,"VC++ 基于MFC的音乐播放器程序"是一个综合性的项目,涵盖了Windows编程的基础、多媒体处理、用户交互等多个领域,对于初学者来说,是一个很好的实践和学习平台。通过分析和理解这个项目,可以深入理解MFC...

    VS2013基于MFC制作的音乐播放器

    首先,"VS2013基于MFC制作的音乐播放器"这个标题表明我们要讨论的是一个使用Visual Studio 2013开发的项目,该项目利用MFC库实现了音乐播放的功能。MFC的运用让开发者可以快速构建出具有专业外观和行为的Windows应用...

    mfc完整的简单音乐播放器

    1. **MFC框架基础**:MFC基于面向对象编程,它封装了Windows API,简化了Windows程序的开发。项目中的类,如CWinApp、CFrameWnd、CView等,都是MFC框架的核心组成部分。 2. **资源管理**:MFC支持资源脚本(.rc文件...

    aviplayer一个播放器

    aviplayer是一个基于MFC(Microsoft Foundation Classes)库开发的小型视频播放器,专为播放主流视频格式而设计。MFC是微软提供的C++类库,用于构建Windows应用程序,它简化了GUI(图形用户界面)编程,使得开发者...

    基于MFC的OpenCV视频播放器

    在本文中,我们将深入探讨如何使用OpenCV库与Microsoft Foundation Class (MFC)框架结合,构建一个简单的视频播放器。这个播放器具备播放、暂停、快进/快退、打开视频文件以及退出等基本功能。请注意,由于设计限制...

    VC++编写的视频播放器,基于MFC

    **VC++编写的视频播放器基于MFC** 在软件开发领域,Visual C++(简称VC++)是一款...通过分析和理解这些文件,开发者可以学习到如何使用VC++和MFC构建一个简单的视频播放器,以及如何集成多媒体库来实现视频播放功能。

    简单音乐播放器

    总的来说,"简单音乐播放器"项目结合了MFC的窗口和控件管理、Active Movie Control的多媒体处理能力、托盘图标技术以及自定义UI设计,为用户提供了一个简洁而实用的音乐播放解决方案。在实际开发过程中,开发者需要...

    VC用MCISendCommand做的播放器

    在VC++中,我们可以使用C++的类封装这些功能,创建一个简单的播放器类。类中可以包含成员函数,如`OpenFile()`, `Play()`, `Stop()`, `Pause()`和`Resume()`,分别对应上述的MCI命令。这样,用户只需调用相应的成员...

    用MFC制作的音乐播放器

    本项目基于MFC构建了一个简单的音乐播放器,专注于播放MP3格式的音频文件。下面将详细介绍如何使用MFC来实现这样一个功能。 1. **MFC基础** MFC是微软对Windows API的封装,它提供了一组面向对象的类,用于创建...

Global site tag (gtag.js) - Google Analytics