最近的项目中,要做这样一个功能,在服务器上可以通过播放器针对不同的音箱设备来播放不同的音乐,就像大学里英语角一样,校广播台对不同的活动中心播放的不同的英文广播。当然我们的项目功能类似,但是却也没校园广播那么复杂,校园广播使用了很好的音频设备,我们得控制成本,所以我们的解决方案是:在服务器上安装一块多通道的专业声卡(录音棚用来录音)或者是安装多块普通的声卡。这样我们在播放音乐的时候可以选择输出的声卡,播放界面如下:
如何去做这样一个播放器呢,.net framework中是不是有这个接口,网上找了一下资料,发现有两种方法.
第一种方法是调用win32下的winmm.dll的API函数去播放文件,代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace HardWaresOperation
{
public class SpeakerBeeper
{
//文件资源
private string SoundSource = @"C:\Documents and Settings\Administrator\桌面\gc22002a.wav";
private string SoundSource;
public SpeakerBeeper(string _SoundSource)
{
SoundSource = _SoundSource;
}
/// <summary>
/// 检查声卡,播放声音
/// </summary>
/// <param name="_SoundSource">声音文件</param>
/// <returns>播放成功,返回true</returns>
public bool SpeakerBeep()
{
if (SBHelper.waveOutGetNumDevs() != 0)
{
SBHelper.PlaySound(SoundSource, IntPtr.Zero, SBHelper.PlaySoundFlags.SND_FILENAME | SBHelper.PlaySoundFlags.SND_ASYNC);
return true;
}
else
{
return false;
}
}
}
// 这是辅助的文件SBHelper.cs
public class SBHelper
{
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000,//同步
SND_ASYNC = 0x0001,//异步
SND_NODEFAULT = 0x0002,//未找到文件默认为静音
SND_MEMORY = 0x0004,//声音文件来自内存
SND_LOOP = 0x0008, //循环播放
SND_NOSTOP = 0x0010,//不停止目前的播放
SND_NOWAIT = 0x00002000,//当播放器忙碌时不等待
SND_ALIAS = 0x00010000, //为已注册的别名时
SND_ALIAS_ID = 0x00110000, //别名为ID
SND_FILENAME = 0x00020000, //文件名
SND_RESOURCE = 0x00040004 //资源名
}
[DllImport("winmm.dll", EntryPoint = "waveOutGetNumDevs")]
//waveOutGetNumdevs()方法
//当机器有声卡时返回1
//没有声卡返回0
public static extern int waveOutGetNumDevs();
[DllImport("winmm.dll")]
//SoundSource声音文件
//参数hmod是应用程序的实例句柄
//psFlag播放模式
public static extern bool PlaySound(string SoundSource, IntPtr hmod, PlaySoundFlags psFlag);
}
}
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace HardWaresOperation
{
public class SpeakerBeeper
{
//文件资源
private string SoundSource = @"C:\Documents and Settings\Administrator\桌面\gc22002a.wav";
private string SoundSource;
public SpeakerBeeper(string _SoundSource)
{
SoundSource = _SoundSource;
}
/// <summary>
/// 检查声卡,播放声音
/// </summary>
/// <param name="_SoundSource">声音文件</param>
/// <returns>播放成功,返回true</returns>
public bool SpeakerBeep()
{
if (SBHelper.waveOutGetNumDevs() != 0)
{
SBHelper.PlaySound(SoundSource, IntPtr.Zero, SBHelper.PlaySoundFlags.SND_FILENAME | SBHelper.PlaySoundFlags.SND_ASYNC);
return true;
}
else
{
return false;
}
}
}
// 这是辅助的文件SBHelper.cs
public class SBHelper
{
public enum PlaySoundFlags : int
{
SND_SYNC = 0x0000,//同步
SND_ASYNC = 0x0001,//异步
SND_NODEFAULT = 0x0002,//未找到文件默认为静音
SND_MEMORY = 0x0004,//声音文件来自内存
SND_LOOP = 0x0008, //循环播放
SND_NOSTOP = 0x0010,//不停止目前的播放
SND_NOWAIT = 0x00002000,//当播放器忙碌时不等待
SND_ALIAS = 0x00010000, //为已注册的别名时
SND_ALIAS_ID = 0x00110000, //别名为ID
SND_FILENAME = 0x00020000, //文件名
SND_RESOURCE = 0x00040004 //资源名
}
[DllImport("winmm.dll", EntryPoint = "waveOutGetNumDevs")]
//waveOutGetNumdevs()方法
//当机器有声卡时返回1
//没有声卡返回0
public static extern int waveOutGetNumDevs();
[DllImport("winmm.dll")]
//SoundSource声音文件
//参数hmod是应用程序的实例句柄
//psFlag播放模式
public static extern bool PlaySound(string SoundSource, IntPtr hmod, PlaySoundFlags psFlag);
}
}
但是发现waveOutGetNumDevs()函数只是用来返回机器是否有声卡,并没有得到机器的声卡设备的列表,知识对当前默认的设备进行播放,达不到要求。