開源庫:NAudio C#音訊庫之錄音與播放(二)

開源庫: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