Open 1592363624 opened 4 months ago
这个库可以实现同时录制麦克风和电脑音频吗 我的代码总是有些问题
using System; using System.Threading.Tasks; using NAudio.Wave; using NAudio.Wave.SampleProviders;
namespace CallRecording.Models { public class Recorder { private readonly object _lockObject = new(); private readonly Logger _logger; private bool _isRecording; private string _outputFileName; private WaveFileWriter _waveFile; private WasapiLoopbackCapture _systemSource; private WaveInEvent _micSource; private MixingSampleProvider _mixer; private BufferedWaveProvider _systemBuffer; private BufferedWaveProvider _micBuffer;
public Recorder(Logger logger) { _logger = logger; } // 开始录音 public void StartRecording(string savePath, string softwareName) { lock (_lockObject) { if (_isRecording) return; // 生成输出文件名 _outputFileName = Utils.GenerateFilename(savePath, softwareName); // 初始化系统声音捕获 _systemSource = new WasapiLoopbackCapture(); _systemSource.DataAvailable += OnSystemDataAvailable; _systemSource.RecordingStopped += OnRecordingStopped; // 初始化麦克风捕获 _micSource = new WaveInEvent(); _micSource.DataAvailable += OnMicDataAvailable; _micSource.RecordingStopped += OnRecordingStopped; // 初始化缓冲区 _systemBuffer = new BufferedWaveProvider(_systemSource.WaveFormat); _micBuffer = new BufferedWaveProvider(_micSource.WaveFormat); // 将输入转换为相同的WaveFormat var systemSampleProvider = _systemBuffer.ToSampleProvider(); var micSampleProvider = _micBuffer.ToSampleProvider(); // 混音器 _mixer = new MixingSampleProvider(new[] { systemSampleProvider, micSampleProvider }) { ReadFully = true }; // 创建WaveFileWriter,用于写入录音文件 _waveFile = new WaveFileWriter(_outputFileName, _mixer.WaveFormat); // 开始录音 _systemSource.StartRecording(); _micSource.StartRecording(); _isRecording = true; // 记录日志 _logger.LogMessage("开始录音...", softwareName); // 启动一个后台任务来写入混音数据 Task.Run(() => WriteMixedData()); } } // 处理系统音频数据 private void OnSystemDataAvailable(object sender, WaveInEventArgs e) { _systemBuffer.AddSamples(e.Buffer, 0, e.BytesRecorded); } // 处理麦克风音频数据 private void OnMicDataAvailable(object sender, WaveInEventArgs e) { _micBuffer.AddSamples(e.Buffer, 0, e.BytesRecorded); } // 后台任务写入混音数据 private void WriteMixedData() { var buffer = new float[_mixer.WaveFormat.SampleRate * _mixer.WaveFormat.Channels]; while (_isRecording) { int samplesRead = _mixer.Read(buffer, 0, buffer.Length); if (samplesRead > 0) { lock (_lockObject) { if (_waveFile != null) { _waveFile.WriteSamples(buffer, 0, samplesRead); _waveFile.Flush(); } } } } } // 处理录音停止事件 private void OnRecordingStopped(object sender, StoppedEventArgs e) { lock (_lockObject) { try { _systemSource?.Dispose(); _micSource?.Dispose(); _waveFile?.Dispose(); _systemSource = null; _micSource = null; _waveFile = null; if (e.Exception != null) { _logger.LogMessage($"录音停止时发生异常: {e.Exception.Message}", "录音器"); } else { _logger.LogMessage($"录音已保存到: {_outputFileName}", "录音器"); } } catch (Exception ex) { _logger.LogMessage($"在处理录音停止事件时发生异常: {ex.Message}", "录音器"); } } } // 停止录音 public void StopRecording() { lock (_lockObject) { if (!_isRecording) return; try { _systemSource.StopRecording(); _micSource.StopRecording(); _logger.LogMessage("录音停止,文件已保存。", "录音器"); } catch (Exception ex) { _logger.LogMessage($"停止录音时发生异常: {ex.Message}", "录音器"); } _isRecording = false; } } // 检查是否正在录音 public bool IsRecording() { lock (_lockObject) { return _isRecording; } } } // 用于将IWaveProvider转换为WaveProvider public class WaveInProvider : IWaveProvider { private readonly IWaveIn _source; private readonly WaveFormat _waveFormat; private readonly BufferedWaveProvider _bufferedWaveProvider; public WaveInProvider(IWaveIn source) { _source = source; _waveFormat = source.WaveFormat; _bufferedWaveProvider = new BufferedWaveProvider(_waveFormat) { BufferLength = 10 * 1024 * 1024 // 设置为10MB的缓冲区大小 }; _source.DataAvailable += (s, a) => _bufferedWaveProvider.AddSamples(a.Buffer, 0, a.BytesRecorded); } public WaveFormat WaveFormat => _waveFormat; public int Read(byte[] buffer, int offset, int count) { return _bufferedWaveProvider.Read(buffer, offset, count); } }
}
这个库可以实现同时录制麦克风和电脑音频吗 我的代码总是有些问题
using System; using System.Threading.Tasks; using NAudio.Wave; using NAudio.Wave.SampleProviders;
namespace CallRecording.Models { public class Recorder { private readonly object _lockObject = new(); private readonly Logger _logger; private bool _isRecording; private string _outputFileName; private WaveFileWriter _waveFile; private WasapiLoopbackCapture _systemSource; private WaveInEvent _micSource; private MixingSampleProvider _mixer; private BufferedWaveProvider _systemBuffer; private BufferedWaveProvider _micBuffer;
}