開源庫:NAudio C#音訊庫之錄音與播放(一)
開源庫:NAudio C#音訊庫之錄音與播放(二)
開源庫:NAudio C#音訊庫之錄音與播放(三)
NAudio是一個C#版的音訊處理庫,支援音訊的輸入輸出,音訊檔案的處理。
接上一篇AudioService完成後,繼續實現AudioRecorder類。
這裡將使用WaveFileWriter寫入檔案,有一點需要注意,WaveFileWriter必須要Close或Dispose,否則任何播放軟體都會認為音訊檔案錯誤,因使用的RIFF格式中,檔案頭中有兩個地方需要填寫檔案總長和資料總長,WaveFileWriter在Dispose時完成這一任務。如發生意外,導致檔案無法使用,可參考RIFF定義手工修復。
關鍵引數設定
// 同步鎖private readonly object _locker = new object();// 檔案寫入private WaveFileWriter _writer;// 開始時間private readonly DateTime _starTime;// 最後一次接收資料時間private DateTime _lastAudioData = DateTime。MinValue;
事件
public event RecorderStatusChangedHandle OnRecorderStatusChanged;
啟動錄音
public void Start() { lock (_locker) { if (_running) return; if (!Directory。Exists(_dir)) { Directory。CreateDirectory(_dir); Console。WriteLine(“建立目錄{0}”, _dir); } Console。WriteLine(“開始啟動錄音”); _running = true; // 建立writer, _wav為儲存檔案的完整路徑 _writer = new WaveFileWriter(_wav, AudioService。Format); // 訂閱資料事件 AudioService。Service。DataAvailable += Service_DataAvailable; // 通知狀態改變 OnRecorderStatusChanged?。Invoke(this, _running, StarTime, new TimeSpan(0, 0, 0)); }}
資料記錄
try { if (_writer == null || !Running) return; _writer。Write(e, 0, e。Length); if (!((DateTime。Now - _lastAudioData)。TotalMilliseconds > 100)) return; _lastAudioData = DateTime。Now; OnRecorderStatusChanged?。Invoke(this, Running, StarTime, _writer。TotalTime); } catch (Exception exp) { Console。WriteLine(exp); }
停止錄音
public void Stop() { lock (_locker) { if (!_running) return; _running = false; // 登出訂閱 AudioService。Service。DataAvailable -= Service_DataAvailable; _writer?。Dispose(); _writer = null; Console。WriteLine(“錄音停止”); } OnRecorderStatusChanged?。Invoke(this, Running, _starTime, TimeSpan。Zero);}
NAudio原始碼地址:https://github。com/naudio/NAudio
本文程式碼地址:https://github。com/wuqinchao/JwRecorder