利用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播 ...
随机推荐
- WPF操作ini 文件的读写示例
/// <summary> /// IniFiles 的摘要说明. /// 示例文件路径:C:\file.ini /// [Server] //[*] 表示缓存区 /// name=loc ...
- Navi.Soft30.框架.WinForm.开发手册
阅读导航 Navi.Soft30.Core类库.开发手册 http://www.cnblogs.com/xiyang1011/p/5709489.html Navi.Soft30.框架.WinForm ...
- 【网络编程】——linux socket demo
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/socket ...
- 分享一个web应用程序池管理工具
因为项目在联调阶段由于各种各样的原因需要重启应用程序池,而调试服务器基本都需要远登操作.同样的情况也会发生在线上,如果公司权限控制得比较严格,每次都要多部门的服务器权限申请的话有点麻烦, 所以抽点时间 ...
- C#集合-列举(Enumeration)
在计算机这个范畴内存在许多种类的集合,从简单的数据结构比如数组.链表,到复杂的数据结构比如红黑树,哈希表.尽管这些数据结构的内部实现和外部特征大相径庭,但是遍历集合的内容确是一个共同的需求..NET ...
- windows下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件
原创文章,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4535459.html android 程序打包成apk,如果在是命令行方式,一般都要经过如下步骤: 1.用a ...
- Hadoop2.x源码-编译剖析
1.概述 最近,有小伙伴涉及到源码编译.然而,在编译期间也是遇到各种坑,在求助于搜索引擎,技术博客,也是难以解决自身所遇到的问题.笔者在被询问多次的情况下,今天打算为大家来写一篇文章来剖析下编译的细节 ...
- 查看macbook是多少位
Prince-2:~ snowinmay$ uname -aDarwin Prince-2.local 12.5.0 Darwin Kernel Version 12.5.0: Sun Sep 29 ...
- 在线PDF编辑网站http://www.pdfescape.com
网站地址:http://www.pdfescape.com 先转载一个简单介绍的文章 如果你以前很少阅读PDF文档,电脑中也没有PDF阅读器:adobe reader,foxit reader之类的软 ...
- saiku 展示优化
saiku版本:3.7.4 下面是修改步骤,如果觉得麻烦,可以直接下载源代码:https://github.com/lihehuo/saiku 1.关闭自动执行 修改文件:saiku-ui/js/sa ...