<Win32_17>集音频和视频播放功能于一身的简易播放器
前段时间,在学习中科院杨老师的教学视频时,他说了一句话:
"我很反对百八十行的教学程序,要来就来一个完整的程序"
对此,我很是赞同。所谓真刀真枪的做了,你才会发现其中的奥秘——然而,能写一个完整的程序,首先你肯定是理解掌握了相关的技术,其次你享受了一个完整开发的基本"旅程"
因此,除非是很重要的技术,我会仅仅用一个几十行代码的程序加以说明,否则我就会用一个完整的程序来实现一些基本功能——通过这个完整的程序来掌握相关技术,我感觉很好……
好了,F话不多说了,切入正题
……
*****************************************************程序效果***********************************************************
还是先来看一看鄙人写的简易播放器实现的效果吧:
可以看到,它既可以播放mp3音频文件,也可以播放avi视频文件
*****************************************************实现细节***********************************************************
(1)利用win32提供的MCI来播放音频或者视频文件
(2)用一个文件浏览对话框来提供文件选择功能
(3)做一个标准菜单——包含快捷键
*****************************************************代码详解***********************************************************
(1)创建一个文件浏览对话框
1>初始化OPENFILENAME结构体变量,它的成员有很多,不过一般只有一下几个很常用(其余的,读者可以参见msdn):
lStructSize—— 结构体变量大小,用sizeof(OPENFILENAME)指定
hwndOwner—— 拥有它的窗口句柄
lpstrFilter—— 文件过滤
lpstrFile—— 保存文件绝对路径
nMaxFile—— 绝对路径的最大长度
lpstrFileTitle——对话框标题
nMaxFileTitle— 对话框标题的最大长度
Flags———— 标示
它的初始化以及相应操作,我是在一个函数中实现的——openFileDialog,具体代码如下:
//打开文件浏览对话框
VOID openFileDialog(HWND hOwner)
{
static TCHAR szFilePath[MAX_PATH], szTitleName[MAX_PATH];
OPENFILENAME ofn;
TCHAR szFileFilter[] = TEXT("Media Files(*.avi;*.mpg;*.mpeg;*.asf;*.wmv;*.mp2;*.mp3)\0")\
TEXT("*.avi;*.mpg;*.mpeg;*.asf;*.wmv;*.mp2;*.mp3\0")\
TEXT("Movie File(*.avi;*.mpg;*.mpeg)\0*.avi;*.mpg;*.mpeg\0")\
TEXT("Windows Media File(*.asf;*.wmv)\0*.asf;*.wmv\0")\
TEXT("Audio File(*.mp2;*.mp3)\0*.mp2;*.mp3\0"); //初始化ofn结构体变量
ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hOwner;
ofn.lpstrFilter = szFileFilter;
ofn.lpstrFile = szFilePath;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = szTitleName;
ofn.nMaxFileTitle = MAX_PATH;
ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; //打开文件浏览对话框
if(GetOpenFileName(&ofn))
{
int i=0, j=0, k=0; /*
因为ASCII的字符串中, '\'只能以'\\'才能识别, 所以还得自行在'\'之后添加一个'\'
*/
while(szFilePath[i])
{
szFileDir[j++] = szFilePath[i];
if(szFileName[i++] == '\\')
szFileDir[j++] = '\\';
if(i >= ofn.nFileOffset)
szFileName[k++] = szFilePath[i];
} szFileDir[j] = '\0';
szFileName[k] = '\0'; //先停止当前播放的视、音频文件
mciSendString("Close movie", NULL, 0, 0);
openFile(hOwner); if(!isMp)
{
//打开视频文件后 , 先短暂播放一截 , 给你一个预览的效果
mciSendString("Play movie", NULL, 0, 0);
mciSendString("Pause movie", NULL, 0, 0);
} //设置窗口标题为当前打开文件的完整路径
SetWindowText(hOwner, szFileDir); isEnable = TRUE;//标记菜单项可执行
}
}
(2)MCI代码细节
1>打开利用MCI关联系统设备打开相应文件,这需要使用到MCI_DGV_OPEN_PARMS,来看看msdn:
typedef struct {
DWORD_PTR dwCallback; //就是窗口句柄,用于MCI_NOTIFY这个标示
UINT wDeviceID; //设备ID,一般为0
LPSTR lpstrDeviceType; //设备类型
LPSTR lpstrElementName; //打开文件的绝对地址
LPSTR lpstrAlias; //设备别名
DWORD dwStyle; //窗口风格(如果你想在主窗口中播放, 需要设定为子窗口风格WS_CHILD)
HWND hWndParent; //父窗口句柄
} MCI_DGV_OPEN_PARMS;2>初始化好这个变量后,就要通知系统打开相应设备,用mciSendCommand这个函数,还是先来看看msdn:
MCIERROR mciSendCommand(
MCIDEVICEID IDDevice, //设备ID, 一般为0
UINT uMsg, //MCI消息
DWORD fdwCommand, //MCI命令
DWORD_PTR dwParam //指向刚刚初始化的结构体变量
);3>下面需要创建一个窗口用于播放视频,使用MCI_DGV_STATUS_PARMS结构体:
typedef struct {
DWORD_PTR dwCallback; //也是窗口句柄 , 同上
DWORD dwReturn; //播放视频的窗口句柄
DWORD dwItem; //下面不是很重要,一般可以不管
DWORD dwTrack;
LPSTR lpstrDrive;
DWORD dwReference;
} MCI_DGV_STATUS_PARMS;4>我写了一个函数——openFile打开文件,用于实现上述功能,具体如下:
//打开音频或视频文件
VOID openFile(HWND hParent)
{
MCI_DGV_OPEN_PARMS mciOpen;//MCI打开参数结构体
MCI_DGV_STATUS_PARMS mciStatus;//MCI状态参数结构体
UINT uDeviceID;//设备ID
RECT rClient;//父窗口客户区大小 mciStatus.dwItem=MCI_DGV_STATUS_HWND; //初始化mciOpen以及打开avi文件
ZeroMemory(&mciOpen,sizeof(mciOpen));
mciOpen.dwCallback =(DWORD)hParent;
mciOpen.lpstrAlias = TEXT("movie");//设备别名 mciOpen.lpstrElementName= szFileDir;//avi文件地址 mciOpen.hWndParent = hParent;//父窗口
mciOpen.dwStyle = WS_CHILD;//窗口风格 mciSendCommand(0 , MCI_OPEN, MCI_OPEN_ALIAS | MCI_OPEN_ELEMENT |
MCI_DGV_OPEN_PARENT | MCI_DGV_OPEN_WS, (DWORD)&mciOpen); //获取播放avi视频的子窗口hVideo
uDeviceID=mciOpen.wDeviceID;
mciSendCommand(uDeviceID, MCI_STATUS , MCI_STATUS_ITEM, (DWORD)&mciStatus);
hVideo=(HWND)mciStatus.dwReturn;//获取播放视频的窗口句柄 //重绘主窗口
GetClientRect(hParent, &rClient);
SendMessage(hParent, WM_SIZE, 0, MAKELONG(rClient.right - rClient.left, rClient.bottom - rClient.top)); //判断当前打开的文件是否是音频文件
if(strstr(szFileDir, TEXT("mp3")) || strstr(szFileDir, TEXT("mp2")))
{
isMp = TRUE;
}
}
(3)做一个标准菜单
这个和上次讲的一样,只不过加了"快捷键",菜单的创建和加载就不多说了,主要讲一下快捷键的用法
我们日常些一般程序的消息循环代码如下:
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}使用键盘快速键之后修改的代码:
hAccel = LoadAccelerators (hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR)); while(GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator (hwnd, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}P先生关于它的说明是:
TranslateAccelerator函数将键盘消息翻译成WM_COMMAND或WM_SYSCOMMAND,当有键盘消息来的时候,该函数在加速键表中寻找句柄为hAccel的匹配值,如果找到匹配值,就会调用句柄为hwnd的窗口回调函数
你不需要其它代码来维护,这个函数帮你完成了"快捷键的映射"
***************************************************************************************************************
ok,代码大致讲述到此为止,还有很多细节不便在此细说,读者可以详细拜读我上传的源代码,内含详细注释
PS:可能你会发现我的程序在你的电脑上不能播放视频,这是因为你电脑上没有avi视频的解码器,MCI不能识别
解决方法就是安装我上传资源的XviD.rar中的解码程序
<Win32_17>集音频和视频播放功能于一身的简易播放器的更多相关文章
- FFmpeg简易播放器的实现-音视频同步
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10284653.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- FFmpeg简易播放器的实现-音频播放
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10068490.html 基于FFmpeg和SDL实现的简易视频播放器,主要分为读取视频文 ...
- Windows Store App 音频和视频
在Windows应用商店应用中提供了MediaElement控件,该控件能为应用提供音频和视频播放功能.就像之前提到的,虽然在多媒体应用开发中,开发人员可以自行开发一套音频.视频编解码规范和开发媒体播 ...
- HTML 多媒体、Object 元素、音频、视频
Web 上的多媒体指的是音效.音乐.视频和动画. 现代网络浏览器已支持很多多媒体格式. 什么是多媒体? 多媒体来自多种不同的格式.它可以是您听到或看到的任何内容,文字.图片.音乐.音效.录音.电影.动 ...
- HTML的音频和视频
目录 [1]媒体格式 音频格式 视频格式 [2]元素 插件元素 HTML5元素 [3]HTML音频 [4]HTML视频 前面的话 多媒体元素(比如视频和音频)存储于媒体文件中,确定媒体类型的最常用的方 ...
- iOS音频与视频的开发(一)-使用AVAudioPlayer播放音乐、使用AVPlayerViewController播放视频
iOS的多媒体支持非常强大,它提供了多套支持多媒体的API,无论是音频.视频的播放,还是录制,iOS都提供了多种API支持.借助于这些API的支持,iOS应用既可以查看.播放手机相册中的照片.视频,也 ...
- HTML5的Audio标签打造WEB音频播放器
目前,WEB页面上没有标准的方式来播放音频文件,大多数的音频文件是使用插件来播放,而众多浏览器都使用了不同的插件.而HTML5的到来,给我们提供了一个标准的方式来播放WEB中的音频文件,用户不再为浏览 ...
- 【转】C# 视频监控系列(13):H264播放器——控制播放和截图
本文原文地址:http://www.cnblogs.com/over140/archive/2009/03/30/1421531.html 阿里云栖社区也有相关的视频开发案例:https://yq.a ...
- 【转】C# 视频监控系列(12):H264播放器——播放录像文件
原文地址:http://www.cnblogs.com/over140/archive/2009/03/23/1419643.html?spm=5176.100239.blogcont51182.16 ...
随机推荐
- SAP 标准单价、移动单价在 AP 中的影响--(详细)
今天我将向大家介绍下SAP中两种单价模式在系统中所产生的影响,先主要讲讲在AP中影响,它主要有两个方面产生影响(物料收货migo,发票校验miro). 演示背景(假设以下都为本位币交易): 库存(单价 ...
- WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇)
原文:WCF技术剖析之十四:泛型数据契约和集合数据契约(下篇) [爱心链接:拯救一个25岁身患急性白血病的女孩[内有苏州电视台经济频道<天天山海经>为此录制的节目视频(苏州话)]]在.NE ...
- 如何捕获Wince下form程序的全局异常
前言 上两篇文章我们总结了在winform程序下如何捕获全局的异常.那么同样的问题,在wince下我们如何来处理呢?用相同的代码来处理可以吗? 答案是否定的,上面的方案1完全不能解决wince下的情况 ...
- 分享一个获取代理ip的python函数
分享一个获取代理ip的python函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #coding:utf-8 from bs4 import Beaut ...
- N使用exus2打造企业maven仓库(三)
假设项目中,我没有使用maven,我应该做出选择,或为项目.或者用它来推动这个项目从maven.有人会问,为什么maven?无需maven我们没有很好的操作. 这里,只说两件事情我最欣赏:第一点是管理 ...
- Codility上的问题 (16) Omicron 2012
比较无聊的题,求斐波那契数的第N^M项. f(0) = 0, f(1) = 1, f(n) = f(n - 1) + f(n - 2),结果对10000103取模. N, M在[0..10^7]之间. ...
- Swift - 发送消息(文本,图片,文件等)给微信好友或分享到朋友圈
通过调用微信提供的API接口,我们可以很方便的在应用中发送消息给微信好友,或者分享到朋友圈.在微信开发平台(https://open.weixin.qq.com)里,提供了详细的说明文档和样例.但由于 ...
- AJAX - 类型“System.Web.UI.UpdatePanel”不具有名为“FileUpload”的公共属性。
类型“system.web.ui.updatepanel” 不具有名为“***”的公共属性,其实原因很简单.就是少了一个<ContentTemplate></ContentTempl ...
- 使用高德地图API
http://lbs.amap.com/smart/map/developer/mode/ 简单的附上一张图,其实能做得比这个更强大.
- Linux下同时运行不同版本的qt程序
因项目需要,可能有不同版本的qt程序要运行到同一台机器上,本次实验是qt4.8.5和qt5.3.1开发的程序同时运行在同一台机器上,此机器可以不按照qt的任何版本,当然,两个版本开发的qt与机器的位数 ...