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);
();


发布评论