winfrom中要实现播放声音的效果,无非那么几种方式,调dx,SoundPlayer,Media控件,然而实现一些简单的播放声音功能,直接调系统的api显得更加方便快捷、节省资源。
实际中的需求是播放两种声音:
1.音效,播放时间短,不要求对播放控制,播放完就可以,但是要求不阻塞UI线程;
2.背景音乐,播放时间长,要求循环播放,能暂停,能继续,能停止;
mciSendString 声明如下:
using System.Runtime.InteropServices;
[DllImport("winmm.dll")]
public static extern int mciSendString(string m_strCmd, string m_strReceive, int m_v1, int m_v2);
经测试,将mciSendString的使用总结为两种方式:
1. APIClass.mciSendString(@"close backMusic", null, 0, 0);
APIClass.mciSendString("open \"" + startupPath + "/Sound/tian.mp3\" type mpegvideo alias backMusic", null, 0, 0);
APIClass.mciSendString("play backMusic repeat", null, 0, 0);
2. APIClass.mciSendString("play " + strFileName, null, 0, 0);
第一种方法先打开文件,可以命名别名,可以重复播放,以便后续使用别名暂停、继续播放、停止播放,但是不能在新线程中使用(对音乐文件的操作必须在同一线程中进行,否则无效,通常直接在UI线程中调用);
第二种方法直接播放,可以在新线程中播放,但是不能循环,也无法控制播放过程;
UI层播放音效代码:
///
/// 播放声音效果(新开线程)
///
/// 声效文件名
private void PlaySoundEffect(string strFileName)
{
if (SettingsHelper.EnableSoundEffects)
{
Thread thread = new Thread(new ParameterizedThreadStart(delegate(object fileName)
{
fileName = Application.StartupPath + "/Sound/" + fileName;
MusicHelper.PlaySoundSync(fileName.ToString());
}));
thread.IsBackground = true;
thread.Start(strFileName);
}
}
MusicHelper 工具类代码:
public class MusicHelper
{
public static void StartMusicAsync(string startupPath)
{
APIClass.mciSendString(@"close backMusic", null, 0, 0);
APIClass.mciSendString("open \"" + startupPath + "/Sound/tian.mp3\" type mpegvideo alias backMusic", null, 0, 0);
APIClass.mciSendString("play backMusic repeat", null, 0, 0);
}
public static void PauseMusicAsync()
{
APIClass.mciSendString("pause backMusic", null, 0, 0);
}
public static void ResumeMusicAsync()
{
APIClass.mciSendString("resume backMusic", null, 0, 0);
}
public static void StopMusicAsync()
{
APIClass.mciSendString("close backMusic", null, 0, 0);
}
public static void PlaySoundSync(string strFileName)
{
APIClass.mciSendString("play " + strFileName, null, 0, 0);
}
}
本人关于mciSendString的使用方面的了解就是这些,但是在程序中应用足够了。如果各位看官了解更细节的实现原理,欢迎讨论指导。