網站首頁 編程語言 正文
最近在做項目時,需要進行音頻文件的即時播放,并且要求同時播放多條語音,之前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;
原文鏈接:https://blog.csdn.net/evint888/article/details/122387024
- 上一篇:C#實現文本轉語音功能_C#教程
- 下一篇:C#調用USB攝像頭的方法_C#教程
相關推薦
- 2023-05-16 Golang函數這些神操作你知道哪些_Golang
- 2022-12-09 C++中利用cout和fstream采用非科學計數法輸出_C 語言
- 2022-07-18 SQL?Server中實現錯誤處理_MsSql
- 2022-04-07 Go語言中的Base64編碼原理介紹以及使用_Golang
- 2023-09-18 springboot異常處理的一點總結
- 2022-04-11 基于python實現Pycharm斷點調試_python
- 2022-10-28 go語言?nil使用避坑指南_Golang
- 2022-05-06 golang導入私有倉庫報錯:“server response: not found:xxx: in
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支