2024年1月19日发(作者:)

多媒体视频播放器

Document serial number【UU89WT-UU98YT-UU8CB-UUUT-UUT108】

目录

多媒体视频播放器

1基本功能描述

多媒体视频播放工具是目前计算机必备的一个软件,比较流行的有 Real

Player、Windows Media Player 以及国产暴风影音等,能够播放 RM、RMVB、MP3、MPEG、DAT 等多种格式的视频文件 mp3、wma、mdi、wav、avi、dat 等格式的音频文件。

用VC++软件设计并编写出一个多媒体视频播放器。在设计期间,可以选择使用的多媒体控件,制作与用户交互性较好的应用程序界面。对于控件有多种,可以自己选择。本次课程设计要使用 VC++ 内部的 ActiveX 控件——Windows Media

Player 控件,建立自己的多媒体播放器。

此多媒体播放器具有打开文件、播放、暂停、停止、关闭、全屏、音量滑块调节、进度滑块调节、快进、快退、显示隐藏播放列表等基本功能, 可以播放*.mp3、 *.wma、 *.mdi、 *.wav、 *.avi、 *.dat、 *.mpg、*.rmvb等格式的多媒体文件。同时还具有自制的播放列表,可以按照列表上的顺序进行一曲、下一曲的播放。

2设计思路

Windows Media Player是一款Windows系统自带的播放器,支持通过插件增强功能。其控件作为本次课设的媒体控件可以满足要求。并且该控件是微软自带的

免费控件,通常每个电脑都应有这个控件,方便设计出来的软件在各个电脑运行。

根据 Windows Media Player 和各个按钮控件功能的特点,首先要在初始化中对CWMPControl,CWMPSettings,CWMPPlaylist,CWMPMedia 等类的对象进行绑定和定义。播放器的一些基本的功能如播放、暂停、全屏、静音、快进、快退等主要是调用 CWMPControl 和 CWMPPlayer 类中的成员函数来进行实现。对于打开按钮,需要调用通用文件对话框类,调用 szFileFilter()文件过滤函数和

GetFileName()获取文件名函数。

除了以上提到的功能的实现,还有进度滑条Slider_progress和音量滑动条Slider2是通过对 CSliderCtrl 类实现的。

打开程序

初始化

点击“打开”选择文件显示在中

音量滑块50,新建,计时器开启

点击“保存删除列表

双击列表框中内容或选中单击“播放”开始播放

点击

点击“停响应CwnpCo点击“下一int idex=当前光标点击“快响应CwnpCon音量调节

获取位置参数返回OnTimer()

获取当前播放位置“暂停/响应CwnpCon

图1 视频播放器流程图

3软件设计

设计平台可以是Win32的操作平台上,使用已安装的++进行设计和调试。在设计前要确保平台中有WMP控件。结合之前的设计思路,使用 Windows Media

Player 等控件来制作多媒体视频播放器。若是Win64这与++不兼容,可以选择更高的版本。

设计步骤

打开 VC++,点击“新建”,在“新建”窗口选择“工程”选项卡。由于程序是基于

对话框的 MFC 应用程序使用 Windows Media Player等控件来制作多媒体视频播放器。设置好地址位置和工程名后点“确定”。这里的工程名字可以是自己的名字拼音缩写,也可以没有任何含义。

图2 “新建”对话框示意图

在点击“确定”后进入到了“MFC 应用程序向导—步骤1”的设置界面,选择“基本对话框”,然后点击“下一步”。

图3 “MFC 应用程序向导”示意图

在剩下的3个步骤中,全部选择默认的设置,不要做随意更改,直至“完成”便实现了对话框的创建。然后是插入控件,先把系统初始化的按钮用“Delete”删除,在单击鼠标右键选择“插入 ActiveX 控件”,在跳出的对话框中选择“Windows Media Player”(一般当电脑安装了Windows Media Player,其控件也应该存在) ,点击“确定”。

图4加“Windows Media Player”控件示意图

添虽然已经插入控件了,但这时的控件还不能使用,因为控件的各种类并没有一起加入工程类中。右击鼠标,选择“建立类向导……”,这时系统跳出对话框提示是否加入来自控件的类,直接点击“确定”就可以了。

图5 “Windows Media Player”控件类添加示意图

接着对控件关联变量,右击加入的WMP控件,点击“属性”,把ID改为“IDC_player”,然后打开“建立类向导……”点到“Member Variables”页面向IDC_player添加变量。单击“ADD Variables”,会弹出图6所示的“Add

member name”对话框,命名为“m_player”,设为控制“Control”型,点击“OK” 。

图6

变量命名示意图

关联变量之后才算是真正的添加了该控件,可以发现在关联变量之后,控件工具栏多了“Windows Media Player”控件的选项,并且在“Source Files”中增加了17个类,相应的头文件也增加了17个,其中最主要的类为 Cwmpplayer4,Cwmpcontrols,Cwmpmedia,Cwmpsettings 四个大类。

Cwmpplayer4 类主要是关于对其他类的对象的调用以及基本的控件功能的实现,提供了与 Windows Media Player 控件进行交互的基本方法,其中部分成员函数还能够进一步获取得到其他相关类对象的实例;Cwmpcontrols 类主要是对控件的更多的操作;Cwmpmedia 类主要是对于媒体文件资源的一些操作;

Cwmpsettings 类主要是对于媒体文件中的一些基本设置的操作。

界面设计

首先是打开按钮,用于媒体文件的打开;然后依次是播放、暂停、停止、快进、快退、静音、全屏、退出、上一首、下一首、显示/隐藏按钮,以及视频进度滑块和音量滑块条 Slider 控件。对控件主要进行变量的关联,以及 ID 的修改,对于普通按钮进行ID修改,结果如下下表1、表2、表3和表4所示。

表1

按钮 ID

IDC_BUTTON_open

IDC_BUTTON_fullscreen

IDC_BUTTON_play

IDC_BUTTON_panse

IDC_BUTTON_stop

IDC_BUTTON_fastforward

IDC_BUTTON_fasteverse

IDC_BUTTON_pre

控件 ID 以及对应响应函数表

控件 Caption

消息响应函数

打开

OnBUTTONopen()

全屏

OnBUTTONfullscreen()

播放

OnBUTTONplay()

暂停/播放

OnBUTTONpanse()

停止

OnBUTTONstop()

OnBUTTONFastforward(快进

)

快退

OnBUTTONfasteverse()

上一曲

OnBUTTONpre()

类型

命令按钮

命令按钮

命令按钮

命令按钮

命令按钮

命令按钮

命令按钮

命令按钮

IDC_BUTTON_next

IDC_BUTTON4_mute

IDCANCEL

IDC_BUTTON_show

IDC_BUTTON_save

IDC_BUTTON_clear

下一曲

静音

退出

隐藏/展开

保存列表

删除列表

OnBUTTONnext()

OnBUTTON4mute()

OnBUTTONshow()

OnBUTTONsave()

OnBUTTONclear()

命令按钮

命令按钮

命令按钮

命令按钮

命令按钮

命令按钮

然后是加入一些关联变量的控件,之前加入了WMPlayer,还要加入类别为“滑块”的Slider来当调节声音的滑块,还有加入类别为“列表框”的List Control来充当播放列表。

表2

按钮ID

IDC_OCX1

IDC_SLIDER_progress

IDC_SLIDER_vol

IDC_LIST_MENU

控件 ID 以及关联变量表

变量名称

m_player

m_jindu

m_vol

m_list2

类型

CWMPlayer4

CSliderCtrl

CSliderCtrl

CListBox

控件 Caption

WMPlayer

Slider

Slider

List Control

在按钮对应的消息响应函数中写程序将要用到表2的变量和WMP控件中的5个类的函数。

在这五个类中:Cwmpplayer4 类主要是关于对其他类的对象的调用以及基本的控件功能的实现,是WMP控件函数与外部交流的桥梁,不可缺少。宁外其部分成员函数还能够进一步获取得到其他相关类对象的实例; Cwmpcontrols 类主要是对控件的更多的操作,例如播放、暂停;Cwmpmedia 类主要是对于媒体文件资源的一些操作,例如获取路径和名称;Cwmpplaylist类主要是关于播放列表的操作;Cwmpsettings 类主要是对于媒体文件中的一些基本设置的操作。

表3

类名

CWMPControls

CWMPSettings

CWMPMedia

其他类及对应对象表

对象名

m_Control

m_Setting

m_Media

头文件名

CWMPPlaylist

m_Playlist

表4 其他数据定义

数据类型

BOOL

int

变量名

flag,flag2,n

vol

数据类型

CString

CString

变量名

m_FileName

m_PathName

除了对各个控件关联变量以及消息响应函数,还要对对话框类进行消息响应函数的关联,如当一首歌播放完后的模式选择。应用到 WM_TIMER 消息响应函数以及SetTimer()和KillTimer()函数,如图建立OnTimer函数。

图7 添加“WM_TIMER”消息函数示意图

还有菜单的设计,其相对简单,只要名称和ID与表1保持一致就可以了。在“Resource File”中右击鼠标添加“MENU”,属性为“IDR_MENU1”。但是菜单并未与对话窗口有实质联系,需要将菜单加入到“IDD_SHIFAN_DIALOG”中来,在

“IDD_SHIFAN_DIALOG”窗口空白右键单击,选中菜单“IDR_MENU1”,这样便完成了对菜单的加载。

图8 控件按钮分布图

编译运行程序后得到了初步的界面效果图,当然还没有加入函数。同时在左上角会显示自己写的工程名“YLJ_Media_Player”,如图8所示。

关键功能的实现

对于各个按钮、列表功能的实现主要是通过对各个函数加入相应的代码,下文将列出相应的关键代码。

“打开”功能的实现

“打开”按钮主要是实现了对打开的文件进行过滤,主要使用了szFileFilter()函数。点击确定时,首先是把文件路径传给播放列表中,列表在从文件路径中提取文件名来显示。然后又把文件路径通过SetUrl()交给控件读取播放。

void CYLJ_Media_PlayerDlg::OnBUTTONopen()

{

char szFileFilter[]="所有支持类型

|*.mp3;*.mp4;*.wma;*.dat;*.wav;*.avi;*.mov;*.rmvb;*.mmm;*.mid;*.rmi;*.mpeg;*.mpg|"

"Mp3 File(*.mp3)|*.mp3|"

"Mp4 File(*.mp4)|*.mp4|"

"Wma File(*.wma)|*.wma|"

"Video File(*.dat)|*.dat|"

"Wave File(*.wav)|*.wav|"

"AVI File(*.avi)|*.avi|"

"Movie File(*.mov)|*.mov|"

"Rmvb File(*.rmvb)|*.rmvb|"

"Media File(*.mmm)|*.mmm|"

"Mid File(*.mid;*,rmi)|*.mid;*.rmi|"

"MPEG File(*.mpeg)|*.mpeg|"

"MPG File(*.mpg)|*.mpg|"

"All File(*.*)|*.*||";ause();

}

else{

}

}

void CYLJ_Media_PlayerDlg::OnBUTTONstop()

{

().stop();

}

全屏功能的实现也是调用SetFullScreen(TRUE)函数来实现。

void CYLJ_Media_PlayerDlg::OnBUTTONfullscreen()

{

(TRUE);

}

“上一首”和“下一首”功能实现

().play();

“上一首”就是让光标往上移一行,也就是对应的光标变量(index)减去1。当要判断光标在第一行的情况,也就是index=0的时候,这时光标应移到最后一首歌曲或视频上。

void CYLJ_Media_PlayerDlg::OnBUTTONpre()

{

CString str;

int index=()-1;etVolume());”实现的。设置音量用的是“SetVolume()”函数。在“OnInitDialog()”函数中已对滑块范围进行初始化——CSliderCtrl*

pSlide1 =(CSliderCtrl*) GetDlgItem(IDC_SLIDER1);pSlide1->SetRange(0,

100); 使音量变化范围为0~100。

void CYLJ_Media_PlayerDlg::OnReleasedcaptureSlider1(NMHDR* pNMHDR,

LRESULT* pResult)

{

().SetVolume());

*pResult = 0;

}

另外静音程序如下,在静音按钮按下后把系统音量保存在vol中,等恢复时使用,再设置为静音,再次按下后取消静音然后恢复开始音量。

void CYLJ_Media_PlayerDlg::OnBUTTON4mute()

{

n=!n;

if (n)

{

vol=().GetVolume();etMute(TRUE);etMute(FALSE);etVolume(vol);etDuration();

(0,m_time);etCurrentPosition((double)nPos);

}

视频进度的控制主要是SB_THUMBTRACK、SB_PAGEDOWN、SB_PAGEUP,三个消息响应即移动滑块、单击滑块右边滑条、单击滑块左边滑条的消息响应来实现视频进度的控制。

break;

case SB_PAGEDOWN:

NewPos=();

().SetCurrentPosition((double)NewPos);

break;

case SB_PAGEUP:

}

NewPos=();

().SetCurrentPosition((double)NewPos);

break;

4结论与心得体会

平时我挺喜欢听歌看电影的,当看到老师给的选题中有多媒体视频播放器这个题目,我开始是还是挺激动的,能够自己做一个简单的程序,满足自己的爱好也是挺有成就感的。

在一开始选这个课题时,我和其他同学都觉得很难。不像简单计算器和画图软件等课题曾在上课提到过,对于多媒体播放器我看到看到了题目不知道该怎样做。然后我花了大量时间去了解第一步怎么做,分别查找了各个控件基本用法功能,最后选用了 Windows Media Player 控件,因为我vc中只能找到这个与视频有关的控件,于是在网上查了一些关于 Windows Media Player 控件的资料,结果按照网上说的方法来根本无法实现,因为网上都说要先插入17个Windows

Media Player 控件相关的类,但是我vc却不照网上那样实现,所以在头两天是在摸索中,耗费了很多时间,最后我先不管第一步,直接插入控件,然后发现关联变量时会有提示要插入17个类,点确定就行,问题就这么解决了。

然后我和同组的同学在网上找相应的资料,找到怎样在VC++里加入控件,各个控件的说明书。进过比较和分析,我们一致采用Windows Media Player多媒体软件旗下的控件WMP控件。因为WMP控件本身就是微软自带的控件,不存在兼容问题。还有每个电脑多都有Windows Media Player播放器,其控件也都注册了。

知道怎样使用WMP控件,就可以很轻松地完成软件流程图的设计。我结合了自己在网上搜索的资料,做好了整个多媒体播放器的整体设计,确定了软件的框架、主要构件以及构件之间的关联,而后由总体设计逐渐深入完成软件的详细设

计和开发过程。编写代码更加有条理,才会更加符合软件工程的标准。整个程序设计我做了两天,每天熬夜到1点多,也学会了不少东西。

最后终于变好了,编写的软件可以满足课程设计给出的要求。系统能选择打开、播放、暂停、停止音频文件和视频文件,并能控制声音的大小, 可以播放*.mp3、 *.wma、 *.mdi、 *.wav、 *avi、 *dat 等格式的多媒体文件。看到点击每一个按钮都能有相应的反应,顿时有了一种莫名的成就感,也感觉到自己的汗水得到了回报。

纸上得来终觉浅,绝知此事要躬行。要想完成一项作品,并不是想的那样简单,做起来总是会遇到问题的,这时就需要要解决问题的能力和坚持不懈的决心。通过本次试验,我收获了很多,对面向对象程序设计这门课所学的知识有了更好的理解。书山有路勤为径,学海无涯苦作舟。

5参考文献

[1]揣锦华.面向对象程序设计与 VC++实践[M].西安电子科技大学出版社.2005

[2]郑阿奇.Visual C++教程[M].北京:机械工业出版社.2004

[3]周长发.Visual C++.NET 多媒体编程[M].电子工业出版社.2002

[4]Steve Mack.流媒体宝典.电子工业出版社.2003

[5]王育坚.Visual C++面向对象编程教程.第 2 版.北京:清华大学出版社,2008

6思考题

1)控件自带的类和本程序中的类是如何共同作用的

答:控件自带的的类肯定会在对话框的主程序中被调用,那么就要在主程序中#include入对应类的头文件。对需要用到的类生成对应的对象以实现类中函数的使用。

调用了控件类中的函数后,还需要调用对话框自身的函数,比如消息及消息响应函数等函数,以及各控件对应的消息响应函数。如此便可以实现控件自带类和本程序中的类的共同作用。

2)说明程序中调用的控件函数的作用

答:控件的不同类有不同的函数与之对应,不同函数有不同的功能。其函数功能见表。

表5

功能

打开

播放

暂停

快进

快退

声音滑块

全屏

7 附录

控件函数和对应的功能

功能

进度刷新

停止

上一首

下一首

保存列表

清空列表

进度控制

控件函数

OnTimer()

OnBUTTONstop()

OnBUTTONpre()

OnBUTTONnext()

OnBUTTONsave()

OnBUTTONclear()

OnHScroll()

控件函数

OnBUTTONopen()

OnBUTTONplay()

OnBUTTONpause()

OnBUTTONFastforward

OnBUTTONFastreverse()

OnReleasedcaptureSlider1()

OnBUTTONfullscreen()

调试报告

调试一

运行时错误指明如下如图所示:

图9 调试一错误提示

错误提示为:use of undefined type 'CWMPControls'。在这行代码中,我用控件变量m_player调用GetControls()函数来获得CWMPControls类的对象以调用该的成员函数pause()函数,根据错误提示可知,我这行代码是写在视图类中,调用pause()属于类外调用,但是该类不认识CWMPControls类,所以要在视图类的最前面要加个头文件#include ""。

调试二

在调试播放列表时,看到播放列表中显示了路径感觉没有必要,所以修改了代码使只把歌曲名给了代码。但这样再来播放列表上的歌曲时不能播放。

图10 调试二的说明图

原因:是因为播放列表上只有歌曲名,没了路径的话是不能找到文件的,所以不能播放。所以解决方法是修改代码使其把歌曲路径递给播放列表。但后来听老师的解说,可以通过取字符串函数来从路径里取文件名。即播放列表中储存的是路径,但显示的是路径中文件名。

测试结果

编写好的软件能选择打开、播放、暂停、停止音频文件和视频文件,并能控制声音的大小,以及播放的进度,可以播放*.mp3、 *.wma、 *.mdi、 *.wav、

*avi、 *dat 等格式的多媒体文件。同时还具有自制的播放列表,可以按照列表上的顺序进行一曲、下一曲的播放,同时还有保存列表和删除歌曲的作用。

图11 播放器播放音乐展示

图 播放器隐藏列表展示

关键源代码

void CYLJ_Media_PlayerDlg::OnBUTTONopen()

{

char szFileFilter[]=

"所有支持类型

12

|*.mp3;*.mp4;*.wma;*.dat;*.wav;*.avi;*.mov;*.rmvb;*.mmm;*.mid;*.rmi;*.mpeg;*.mpg|"

}

void CYLJ_Media_PlayerDlg::OnBUTTONplay()

"Mp3 File(*.mp3)|*.mp3|"

"Mp4 File(*.mp4)|*.mp4|"

"Wma File(*.wma)|*.wma|"

"Video File(*.dat)|*.dat|"

"Wave File(*.wav)|*.wav|"

"AVI File(*.avi)|*.avi|"

"Movie File(*.mov)|*.mov|"

"Rmvb File(*.rmvb)|*.rmvb|"

"Media File(*.mmm)|*.mmm|"

"Mid File(*.mid;*,rmi)|*.mid;*.rmi|"

"MPEG File(*.mpeg)|*.mpeg|"

"MPG File(*.mpg)|*.mpg|"

"All File(*.*)|*.*||";ause();

}

else{

}

().play();

{

}

void CYLJ_Media_PlayerDlg::OnBUTTON4mute()

{

vol=().GetVolume();etMute(TRUE);etMute(FALSE);etVolume(vol);etVolu

CString str;

int index=();

(index,str);

(str);

n=!n;

if (n)

{

me());

}

*pResult = 0;

void CYLJ_Media_PlayerDlg::OnHScroll(UINT nSBCode, UINT nPos,

CScrollBar* pScrollBar)

{

int m_time;

m_time=(int)().GetDuration();

}

(0,m_time);etCurrentPosition((double)nPos);

}

CDialog::OnHScroll(nSBCode, nPos, pScrollBar);

break;

case SB_PAGEDOWN:

NewPos=();

().SetCurrentPosition((double)NewPos);

break;

case SB_PAGEUP:

}

NewPos=();

().SetCurrentPosition((double)NewPos);

break;

void CYLJ_Media_PlayerDlg::OnTimer(UINT nIDEvent)

{

}

void CYLJ_Media_PlayerDlg::OnHelp()

((int)().GetCurrentPosition());

(100-(int)().GetVolume());

CDialog::OnTimer(nIDEvent);

{

}

CDialog dlg(CAboutDlg::IDD);

();