最近在写音频播放器,不过有点懒散,开发进度很慢,一天只做了一点点东西。其实就是让程序能播放音频。这个在我大二学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播放音频的更多相关文章

  1. C#调用mciSendString播放音频文件

    mciSendString函数是一个WinAPI,主要用来向MCI(Media Control Interface)设备发送字符串命令. 一.函数的声明如下: private static exter ...

  2. 【转】Android播放音频MediaPlayer的几种方式介绍

    接下来笔者介绍一下Android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类: 1.使用MediaPl ...

  3. windows 自带winmm.dll播放音频问题

    同事用的一个录音小程序在他机器上可以用,换了两个电脑不能用,获取音频长度时总是0,检查代码也没有发现具体问题.最后发现是电脑声卡驱动的问题.更新声卡驱动好了. 附上播放音频的代码: 首先,导入dll文 ...

  4. .NET winform播放音频文件

    前提:最近要求做一个在winform端做一个音频文件播放的功能,至此,总结最近搜寻的相关资料. 一.微软提供了三种方式来播放音频文件 1.通过System.Media.SoundPlayer来播放 2 ...

  5. 【Android】播放音频的几种方式介绍

    接下来笔者介绍一下Android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类: 1.使用MediaPl ...

  6. iOS 9音频应用播放音频之音量设置与声道设置

    iOS 9音频应用播放音频之音量设置与声道设置 iOS 9音频应用音量设置 音量又称响度.音强,是指人耳对所听到的声音大小强弱的主观感受,其客观评价尺度是声音的振幅大小.在iOS 9音频应用的应用中, ...

  7. VC++中MCI播放音频文件 【转】

    MCI播放mp3音频文件例程 源文件中需要包含头文件 Mmsystem.h,在Project->Settings->Link->Object/libray module中加入库 Wi ...

  8. python中的多线程编程与暂停、播放音频的结合

    先给两个原文链接: https://blog.csdn.net/u013755307/article/details/19913655 https://www.cnblogs.com/scolia/p ...

  9. FFmpeg学习3:播放音频

    参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...

随机推荐

  1. 在DataTable中执行DataTable.Select("条件")返回DataTable;

    转:http://blog.csdn.net/hcf_force/article/details/7779062 1.在DataTable中执行DataTable.Select("条件&qu ...

  2. Modbus通讯协议学习 - 串口调试

    概述 我们在做任何事情之前都需要获取很多 调试步骤: 1:485转换器连接硬件 2:485转换器上的USB接口连接电脑. 3:打开设备管理器 ->查看端口 4:打开串口调试工具,在串口配置的地方 ...

  3. Microsoft.Web.RedisSessionStateProvider 运行异常问题

    System.TimeoutException: Timeout performing GET MyKey, inst: 2, mgr: Inactive,  queue: 6, qu: 0, qs: ...

  4. Nginx upstream 长连接

    原文: http://bollaxu.iteye.com/blog/900424 Nginx upstream目前只有短连接,通过HTTP/1.0向后端发起连接,并把请求的"Connecti ...

  5. linux下mysql的root密码忘记解决方法

    1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库. 因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的 状态下,其他的用户也可以任意地登录 ...

  6. POJ 1186 方程的解数

    方程的解数 Time Limit: 15000MS   Memory Limit: 128000K Total Submissions: 6188   Accepted: 2127 Case Time ...

  7. DataContractSerializer序列化与反序列化遇到的奇怪问题

    private static void Serialize1(string filename, object obj)         {             var stream = new F ...

  8. RESTful 良好的API设计风格

    1.使用名词而不是动词 Resource资源 GET读 POST创建 PUT修改 DELETE /cars 返回 cars集合 创建新的资源 批量更新cars 删除所有cars /cars/711 返 ...

  9. 对象与Byte数组相互转化工具方法

    /** * 对象转byte * @param obj * @return */ private byte[] ObjectToByte(Object obj) { byte[] bytes = nul ...

  10. 内存调试的东西D/dalvikvm( 809 ): GC_CONCURRENT freed

    一般Java虚拟机要求支持verbosegc选项,输出详细的垃圾收集调试信息.dalvik虚拟机很安静的接受verbosegc选项,然后什么都不做.dalvik虚拟机使用自己的一套LOG机制来输出调试 ...