摘要 本文介绍了使用Visual C++ 6.0设计一个播放AVI格式视频资料的播放器。
关键词 数字视频 AVI MCI MFC
AVI(Audio_Video Interleaved)是微软提出的在Window下使用的视频标准。以一系列的位图来存储视频信息,并在文件中加入数字形式存储的数字化视频信息 ,实际上是由一组信息流组成的文件。AVI文件具有文件短,信息量大的优点。并避免许多传统的动画播放所遇到的问题。
多媒体控制接口MCI是Microsoft Windows定义的多媒体接口标准。提供高层的,独立于设备的,控制各种多媒体设备的命令。现有主要的多媒体设备,如CD-ROM,影碟机、激光唱机、波形音频、数字视频等都可以MCI命令进行控制。使用多媒体控制接口MCI进行多媒体编程具有如下优点:
首先,接口封装了各种媒体设备的具体控制细节,编程人员通过多媒体控制接口操作控制多媒体设备,缩短开发多媒体应用程序的时间,提高了开发效率,降低了开发成本。
其次,MCI是一种访问多媒体设备的高层方法,独立于设备,使原有函数不会因硬件设备、控制参数等的改变而改变,提高了程序的可移植性和可靠性。
再者,功能强大,编程人员只需在MCI层面上进行编程,使多媒体应用程序开发变得更加简单。
每一个应用程序都是从功能开始的。我们这个自制的播放器能够以简单的形式来完成复杂的功能应用。我们主要实现视频文件打开、播放、暂停、快进、快退、上一帧、下一帧以及停止、关闭和最小化功能。我们分三步进行编程。
1、定义可重用的MCI类(我们命名为MyDigtal类)
class MyDigtal //处理视频类
{
public:
//视频操作函数
//函数功能-打开视频文件,pWnd--将要包含视频播放窗口的主窗口,left、top-视频播放窗口//在主窗口中的左上角坐标
BOOL Open (CString, CWnd *pWnd, int left = 0, //函数功能-打开视频文件
int top = 0,int width = 20,int height = 20);
void Close (void);//关闭视频文件
BOOL Play (BOOL bLoop = FALSE, BOOL bFullScreen = FALSE);//函数功能-播放视频文件
void Stop (void); //停止播放
void Pause (void); //暂停播放
void Forward (int);//快进
void Backward (int);//后退
int GetFrames (void);//获得视频总帧数,防止视频位置超过视频文件的总帧数
BOOL SeekTo (int);//跳到某一位置,处于暂停状态
//视频状态还回函数
int GetWidth (void);//得到视频宽度
int GetHeight (void);//获得视频高度
int GetFrame (void);//获得当前帧
BOOL IsPlaying ();//是否正在播放
void SetSpeed (int);//设置播放速度
BOOL GetPause (void);//是否暂停
private://数据成员
BOOL m_Open;//是否有媒体文件打开
BOOL m_Pause;//是否暂停
BOOL m_Playing;//是否正在播放
WORD m_DeviceID;//播放设备ID
};
2 函数的实现
MyDigtal::MyDigtal()
{
m_Open = m_Pause = m_Playing = FALSE;
m_DeviceID = 0;
// 初始化成员变量
}
MyDigtal::~MyDigtal()
{
Close ();
}
由于篇幅所限,下面只是列出了一些主要程序。
mciSendCommand (m_DeviceID, MCI_STOP, NULL, NULL);
mciSendCommand (m_DeviceID, MCI_CLOSE, NULL, NULL); // 停止播放并关闭设备
MCI_DGV_OPEN_PARMS MCIOpen; // 打开设备
MCIOpen.lpstrDeviceType = "avivideo";//设置播放设备为视频播放设备
MCIOpen.lpstrElementName = (LPSTR) Filename.GetBuffer (0);//文件名
MCIOpen.hWndParent = pWnd->m_hWnd;//可播放视频文件窗口指针
MCIOpen.dwStyle = WS_CHILD | WS_VISIBLE;
MCI_DGV_SET_PARMS MCISet; // 将文件长度设置为帧
MCISet.dwTimeFormat = MCI_FORMAT_FRAMES;
mciSendCommand (m_DeviceID, MCI_SEEK, MCI_SEEK_TO_START, NULL); // 找到视频文件//的开始位置
MCI_DGV_PLAY_PARMS MCIPlay;//在当前位置开始播放
MCIPlay.dwFrom = GetFrame ();//得到当前的视频位置
MCI_DGV_PAUSE_PARMS MCIPause;//暂停播放
mciSendCommand (m_DeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &MCIPause))
MCI_DGV_STATUS_PARMS MCIStatus;//获的视频的总帧数
MCIStatus.dwItem = MCI_STATUS_LENGTH;
return (int) MCIStatus.dwReturn;//总帧数
MCI_DGV_STATUS_PARMS MCIStatus;//得到视频当前的播放位置
MCIStatus.dwItem = MCI_STATUS_POSITION;
return (int) MCIStatus.dwReturn;
MCI_DGV_STATUS_PARMS MCIStatus;//查询视频是否处于播放状态
MCIStatus.dwItem = MCI_STATUS_MODE;
MCI_SEEK_PARMS MCISeek;//跳转播放
MCISeek.dwTo = nFrame;
MCI_DGV_STEP_PARMS MCIStep;//前进和后退
MCIStep.dwFrames = nFrames;
3 界面及应用功能程序的设计
我们创建一个基于对话框的应用程序。最后生成的程序界面如图1所示。

图1 播放器主界面
在应用程序中,首先要在工程中添加winmm.lib库文件。winmm.lib库中输出了MCI的各类函数。其次要把MyDigtal类加入对话框主程序中,这样在后面用到九个按钮程序中就可以直接调用类中的功能函数。这里,我们特别要注意在函数中必须添加OnTime()函数。对于一个视频,如果开始了播放,它会按照既定的速度进行显示。但在打开一个视频后还需要对其进行进一步的操作,视频在播放时不会发送消息的,只有通过OnTime()函数每隔一定的时间检查一次视频播放状态,然后才可以针对视频的状态,对滑块显示当前帧的窗口进行更新,并确定此时每个按钮的状态。我们一般可以选用100毫秒更新一次。
4 结束语
我们使用VC++6.0这个微软强大的可视化应用程序开发工具,在VC++环境下,利用MFC库和MCI标准,我们可以轻松开发用于播放AVI格式的视频文件。
参考文献
[1] Davis Chapman著 骆长乐译 学用Visual C++ 6.0 清华大学出版社 1999.9
[2] David J.Kruglinski 等 Programming Visual C++(Fifth Edition) Micrsoft Press 2001.6
[3] 周长发 著 多媒体计算机技术开发与应用 电子工业出版社 1995.7
[4] 本书编写组 著 Visual C++ 6.0 MFC类库参考手册 人民邮电出版社 2002.11