最近在做项目时,需要进行音频文件的即时播放,并且要求同时播放多条语音,之前C#程序中语音播放一直使用System.Media类库的SoundPlayer类进行播放,但是这个播放类有个弊端,就是在播放时不能抢占式播放语音,经过查找资料DirectX.DirectSound可同时播放多条语音。
DirectX.DirectSound的特点
1、可同时播放多条语音
2、可分左右声道进行播放
3、可随时释放正在播放的语音
此组件处理流程:
1、创建播放线程
public void StartDirectXSoundThread(Control _con) ?{ ? ? IsStart = true; ? ? if (control == null) control = _con; ? ? Task task = new Task(() => ? ? ? { ? ? ? ? while (true) ? ? ? ? ? ? { ? ? ? ? ? ? ?? try ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? if (!IsStart) break; ? ? ? ? ? ? ? ? if (!IsPlaying()) ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? if (soundlist.Count > 0) ? ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? if (!IsPlayVoice) ? ? ? ? ? ? ? ? ? ? ? ? ?{ ? ? ? ? ? ? ? ? ? ? ? ? ? ?IsPlayVoice = true; ? ? ? ? ? ? ? ? ? ? ? ? ? ?control.Invoke((MethodInvoker)delegate ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SoundPlay(soundlist[0]); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? soundlist.RemoveAt(0); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? } ? ? ? ? ? } ? ? ? ?catch (Exception ex) ? ? ? ? { ? ? ? ? ? LogHelper.Debug(ex); ? ? ? ? } ? ? ? ? ? finally ? ? ? ? { ? ? ? ? ? } ? ? ? ? ? Thread.Sleep(100); ? ? ? ? } ? ? }); task.Start(); }
2、释放播放线程
public void StopDirectXSoundThread() { ? IsStart = false; ?}
3、判断是否播放中,通过PlayPosition!=0和播放缓冲是否null的条件判断是否播放
private bool IsPlaying() ? { ? ? bool Ret = false; ? ? ? ?try ? ? ? ? ?{ ? ? ? ? ? if (IsCreate) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? if (secBuffer != null) ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? if (secBuffer.PlayPosition != 0) ? ? ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? ? ? Ret = true; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ?catch (Exception ex) ? ? ? { ? ? ? ? ? ? LogHelper.Debug(ex); ? ? ? ? } ? ? ? return Ret; }
4、播放音频
public void SoundPlay(string _wavpath) ? ? ? ? { ? ? ? ? ? ? try ? ? ? ? ? ? { ? ? ? ? ? ? ? ? if (_wavpath.IndexOf("\\") < 0) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? _wavpath = SoundPath + _wavpath; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if (_wavpath.IndexOf(".wav") < 0) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? _wavpath += ".wav"; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if (!File.Exists(_wavpath)) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? LogHelper.Info("无" + _wavpath + "文件!"); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? else ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? secDev.SetCooperativeLevel(control, CooperativeLevel.Normal); ? ? ? ? ? ? ? ? ? ? BufferDescription buffdes = new BufferDescription() ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? GlobalFocus = true ? ? ? ? ? ? ? ? ? ? }; ? ? ? ? ? ? ? ? ? ? secBuffer = new SecondaryBuffer(_wavpath, buffdes, secDev); ? ? ? ? ? ? ? ? ? ? secBuffer.Play(0, BufferPlayFlags.Default);//设置缓冲区为默认播放? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? IsCreate = true; ? ? ? ? ? ? ? ? IsPlayVoice = false; ? ? ? ? ? ? } ? ? ? ? ? ? catch (Exception ex) ? ? ? ? ? ? { ? ? ? ? ? ? ? ? LogHelper.Debug(ex); ? ? } }
左右声道通过secBuffer.Pan属性进行控制,值含义见下图:
a、Center中心通道,左右通道同时播放,默认值0
b、Right右通道,值10000
c、Right左通道,值-10000
5、清除播放中音频 ,播放中的音频可以通过Dispose()方法进行释放
public void ClearPlay() ? { ? if (secBuffer != null) ? ?{ ? ? soundlist.Clear(); ? ? secBuffer.Dispose(); ? ? IsCreate = false; ? ? ?} }
6、定义
/// <summary> /// 播放设备 /// </summary> private Device secDev = new Device(); ? /// <summary> /// 播放缓冲区 /// </summary> private SecondaryBuffer secBuffer = null; ? /// <summary> /// 可视化组件 /// </summary> private Control control; ? /// <summary> /// 是否被创建 /// </summary> private bool IsCreate = false;
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持源码搜藏网。