利用mciSendString播放音频
最近在写音频播放器,不过有点懒散,开发进度很慢,一天只做了一点点东西。其实就是让程序能播放音频。这个在我大二学winform程序开发时书上有说,那是书上教的是用media player的COM组件,而且当时什么也不会,写出来的东西只能播放单个音频。要播放完整个播放表的所有歌曲,必须得在播放完一个音频时点击播放下一个音频,也就是不懂得自动切换音频。当时也有想过,如果能获取到一个音频的长度就好了,但是那时候不懂得百度,即使百度了也不懂得那些Thread啊什么的。
现在对Thread有了一些认识,也用过系统的API,感觉写个播放器完完全全没问题,而且对一个单纯用于听歌的播放器有点自己的想法。于是上网搜搜相关资料。
不出我的所料,播放音频能够通过系统API来实现。其实播放音频有两种方式,第一种就是我大二时看书说的用media player的COM组件;第二种就是网上找到的系统API。
这篇文章呢就不是说我怎么怎么写播放器,而是说说我在使用这个系统API时的一些感想罢了。
用到的API函数有两个一个是GetShortPathName,另一个是mciSendString,同时还有一些在调用这些函数时用到的字符串遍历,下面则是函数声明和字符串变量的声明
- [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
- public static extern int GetShortPathName(
- string lpszLongPath,
- string shortFile,
- int cchBuffer
- );
- [DllImport("winmm.dll", EntryPoint = "mciSendString", CharSet = CharSet.Auto)]
- public static extern int mciSendString(
- string lpstrCommand,
- string lpstrReturnString,
- int uReturnLength,
- int hwndCallback
- );
- //定义API函数使用的字符串变量
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
- public string Name = "";
- [MarshalAs(UnmanagedType.ByValTStr, SizeConst = )]
- public string durLength = "";
- [MarshalAs(UnmanagedType.LPTStr, SizeConst = )]
- public string TemStr = "";
GetShortPathName方法主要是在载入音频文件时用得到,其他地方没发现用得着它。主要是用mciSendString,这些函数在MSDN上都能找到详细的介绍,经发现其实用micSendString播放音乐就相当于发一系列的命令,由函数的第一个参数名就看出来了,可是MSDN上的那些指令的介绍我还没看得明白,我所用到的指令都是在网上查回来的,说起来挺笨拙的,开了一个音频播着,然后就弄个文本框输入各种各样的指令,看看这条指令对不对,这个很像我现在从事的工作里的有个操作——串口调试。
好了,既然说是通过指令的,那下面则把用到的指令分门别类地罗列一下
- 载入文件
open "+ 文件名 + " alias media
这里的文件名并不是平时资源管理器中的文件名或者全文件名,而是通过调用GetShortPathName方法得出来的文件名。alias 后面跟着那个media 其实是对当前打开的音频作一个命名而已。这个命名是不唯一不能重复,但接着播放音乐,暂停、停止等操作都要用到它的。
- 设置格式
set media time format milliseconds
这里就用到上面的那个命名了,这里设成milliseconds(毫秒)是干嘛的呢,我也没弄清楚,我试过设成seconds都是同样没变化的。
播放动作控制
play media //重头开始播放
pause media //暂停播放
resume media //继续播放
close media //停止播放
close all //关闭所有
play media FROM N To M //从N毫秒处开始播放到M处毫秒结束,不过这条命令可以不要后面的To M
- 关于时间
status media position //当前音频的播放进度
status media length //当前音频的长度
传这两个命令的时候,接收值就要用到micSendString方法的第二个参数了。
- 关于音量
setaudio media volume to Number //设置音量大小
这里的Number是0~1000的范围
setaudio media off //关闭声音
setaudio media on //开启声音
这个呢我只在我自己的系统Win7下试过,XP就没试过不知怎么,Win7的系统音频是一个合成器的模式,
每个进程都有它独立的音量设置,与系统的音量不同,我们平时设置的音量其实是扩音器的音量。因此这里只能设当前进程的音量。并不会影响系统的音量。而且调节了音量在系统音频合成器是看不到音量的滑块有变化的,包括静音。这一点我看了别的播放器,像我上面截图的KuGoo啊,QQ影音也是这样子的。其实还有另外的一个API函数可以设置音量的,那个函数就能改变上图的音量滑块了,但是仍然改变不了扬声器的音量大小。我还想到一点,就是QQ影音和有一些视频网站,它能把声音调到100%以上,我最初有想过做成那样子,不过现在没找到方法,那个估计要对音频的声音波形放大的。还有一个就是这个音频操作只对当前播放的音频起作用,切换到下一个音频的时候之前设的音量啊,开闭音量都没作用的。
现在命令介绍完了,到说使用那个micSendString的状况了。
我曾经尝试开多线程去播放音乐,就是一条线程就载入一个音频,播放这样子。结果呢,一首歌没播完,然后播另一首歌时,两首歌同时响起,用了close all,stop这些命令都没效果,后来发现了这个与调用micSendString方法时传进去的第二个参数有关系,也就是说播放一个音频的过程中发送的所有命令通通都用同一个lpstrReturnString对象做参数好了。
上面一段说到播放一个音频就用同一个lpstrReturnString对象,要做到这个才能正常操作,而且也很节省资源,不用每次都构造一个新的对象。但也不能省过头,我试过播放多个音频都用了同一个lpstrReturnString对象,结果到有时候就发送命令失效了,要想得到音频的长度获取不到,要想播放音频,没播放。
以上的两个问题我都找到了解决的办法。但是下面这个我就想不明白是什么回事了。用winform程序去调用micSendString能成功调用,能播放到,但是同样的代码放到一个控制台里面就不一定能调用成功了,会播放不了的。为什么说不一定呢,当我建项目时选控制台类型,生成的exe它是播不了的,当我建项目是winform类型,生成把它改成控制台类型,生成的控制台又能成功播放了。网上有种说法是说“那个micSendString是跟窗体关联的,控制台调用的话就播放不了的。”但我觉得还是解释不了我这个奇怪的现象。呵呵!这个还要等各位园友来指教啊!
虽然对micSendString接触了几天,但我知道还是理解不透彻的,以上有什么说错的还得请各位园友批评指正。谢谢!
利用mciSendString播放音频的更多相关文章
- C#调用mciSendString播放音频文件
mciSendString函数是一个WinAPI,主要用来向MCI(Media Control Interface)设备发送字符串命令. 一.函数的声明如下: private static exter ...
- 【转】Android播放音频MediaPlayer的几种方式介绍
接下来笔者介绍一下Android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类: 1.使用MediaPl ...
- windows 自带winmm.dll播放音频问题
同事用的一个录音小程序在他机器上可以用,换了两个电脑不能用,获取音频长度时总是0,检查代码也没有发现具体问题.最后发现是电脑声卡驱动的问题.更新声卡驱动好了. 附上播放音频的代码: 首先,导入dll文 ...
- .NET winform播放音频文件
前提:最近要求做一个在winform端做一个音频文件播放的功能,至此,总结最近搜寻的相关资料. 一.微软提供了三种方式来播放音频文件 1.通过System.Media.SoundPlayer来播放 2 ...
- 【Android】播放音频的几种方式介绍
接下来笔者介绍一下Android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类: 1.使用MediaPl ...
- iOS 9音频应用播放音频之音量设置与声道设置
iOS 9音频应用播放音频之音量设置与声道设置 iOS 9音频应用音量设置 音量又称响度.音强,是指人耳对所听到的声音大小强弱的主观感受,其客观评价尺度是声音的振幅大小.在iOS 9音频应用的应用中, ...
- VC++中MCI播放音频文件 【转】
MCI播放mp3音频文件例程 源文件中需要包含头文件 Mmsystem.h,在Project->Settings->Link->Object/libray module中加入库 Wi ...
- python中的多线程编程与暂停、播放音频的结合
先给两个原文链接: https://blog.csdn.net/u013755307/article/details/19913655 https://www.cnblogs.com/scolia/p ...
- FFmpeg学习3:播放音频
参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...
随机推荐
- nodejs express 框架解密2-如何创建一个app
本文是基于express 3.4.6 的 1.在我们的app.js 文件里面有这么几行 http.createServer(app).listen(app.get('port'), function( ...
- ubuntu系统中的VMware 安装win7 Ghost镜像的几个坑
1.ghost镜像安装时要先分区 2.分区后要激活 3.VM(虚拟机安装win7 提示 :units specified don't exist, SHSUCDX can't install)解决方法 ...
- MySQL解决插入emoji表情失败的问题
普通的字符串或者表情都是占位3个字节,所以utf8足够用了,但是移动端的表情符号占位是4个字节,普通的utf8就不够用了,为了应对无线互联网的机遇和挑战.避免 emoji 表情符号带来的问题.涉及无线 ...
- algo_预备
章 C + +程序设计 大家好!现在我们将要开始一个穿越" 数据结构.算法和程序" 这个抽象世界的特殊旅程,以解决现实生活中的许多难题.在程序开发过程中通常需要做到如下两点:一是高 ...
- Source Insight 使用
1.括号配对高亮:“在前括号左侧,后括号左侧” 双击鼠标左键,可以选定匹配括号和其中内容(<>,(),L{R},[]之间) 2.让{ 和 } 不缩进:Options -> Docum ...
- StringEx
static class StringEx { public static string MD5(this String str) { byte[] bytes = new MD5CryptoServ ...
- Android实战技巧:深入解析AsyncTask
AsyncTask的介绍及基本使用方法 关于AsyncTask的介绍和基本使用方法可以参考官方文档和Android实战技巧:多线程AsyncTask这里就不重复. AsyncTask引发的一个问题 上 ...
- 程序员之路:以Android证道
大道三千,何以证道? 最近有私信.邮件给我咨询一些职业生涯规划的同学,我在这里以过来人的身份给大家一些建议. 任何行业,任何职位,无论高低,无论大小,都可以分为广博.精深两个方向. 精深自然指的是在某 ...
- ubuntu下解决wireshark权限问题
wireshark要监控eth0,但是必须要root权限才行.但是,直接用root运行程序是相当危险,也是非常不方便的. 解决方法如下: 1.添加wireshark用户组 sudo groupadd ...
- python 字符串查找
python 字符串查找有4个方法,1 find,2 index方法,3 rfind方法,4 rindex方法. 1 find()方法: )##从下标1开始,查找在字符串里第一个出现的子串:返回结果3 ...