NAudio - 录制多个设备并保存到 MP3

NAudio - Record multiple devices and save to MP3

我已经购买了适用于 NAudio 的 PluralSight 课程,并且正在学习很多视频。

我正在尝试弄清楚如何执行以下操作: 将所有麦克风和所有扬声器录制到一个 MP3 中。

到目前为止我有以下代码:

using NAudio.CoreAudioApi;
using NAudio.Wave;
using NAudio.Wave.SampleProviders;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AudioTest1 {

    public class AudioDevice {
        public MMDevice Device { get; set; }
        public bool IsSelected { get; set; }
        public string FriendlyName { get; set; }
        private IWaveIn __Capture;
        public IWaveIn Capture {
            get {
                return __Capture;
            }
            set {
                if(__Capture != null) {
                    __Capture.DataAvailable -= this.__Capture_DataAvailable;
                }

                __Capture = value;

                if (__Capture != null) {
                    __Capture.DataAvailable += this.__Capture_DataAvailable;
                }
            }
        }

        private void __Capture_DataAvailable(object sender, WaveInEventArgs e) {
            if(Buffer != null) {
                Buffer.AddSamples(e.Buffer, 0, e.BytesRecorded);
            }
        }

        public IWaveProvider Provider { get; set; }
        public BufferedWaveProvider Buffer { get; set; }

        public IWaveProvider Output { get; set; }

    }

    public class MainWindowDataModel {

        public ObservableCollection<AudioDevice> AudioDevices { get; private set; } = new ObservableCollection<AudioDevice>();

        public WaveFormat Format = new WaveFormat(16000, 8, 1);

        public MainWindowDataModel(){


            using (var Enumerator = new MMDeviceEnumerator()) {
                var Devices = Enumerator.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active).ToList();
                foreach(var Device in Devices) {

                    Device.AudioEndpointVolume.Mute = false;
                    var Capture =
                        Device.DataFlow == DataFlow.Capture
                        ? new WasapiCapture(Device)
                        : new WasapiLoopbackCapture(Device)
                        ;

                    var Provider = new WaveInProvider(Capture);
                    var Silence = new SilenceProvider(Capture.WaveFormat);
                    var Buffer = new BufferedWaveProvider(Capture.WaveFormat);

                    var Output = Device.DataFlow == DataFlow.Capture
                        ? new MixingWaveProvider32(new IWaveProvider[] { Provider })
                        : new MixingWaveProvider32(new IWaveProvider[] { Silence, Buffer })
                        ;


                    AudioDevices.Add(new AudioDevice() {
                        Device = Device,
                        IsSelected = true,
                        FriendlyName = Device.FriendlyName,
                        Capture = Capture,
                        Provider = Provider,
                        Buffer = Buffer,
                        Output = Output,
                    });

                    Capture.StartRecording();

                }

                var C = new MixingSampleProvider(from x in AudioDevices select x.Output.ToSampleProvider());
                //C.AddMixerInput(new SignalGenerator());

                WaveFileWriter.CreateWaveFile(@"C:\Test2.wav", C.Take(TimeSpan.FromSeconds(5)).ToWaveProvider());


            }



        }

    }
}

当我尝试创建 wave 文件时,函数似乎立即 return 而不是等待 5 秒过去。我一起录制这段音频的最佳方式是什么?

在录制时即时混合音频实际上非常棘手,因为缓冲区从每个录制设备到达的时间不同,并且持续时间可能不同。此外,如果记录未同时开始或存在中断,则可能存在需要解决的同步问题。

我通常推荐的最简单的解决方案是人们将每个麦克风录制到一个临时文件中,然后再将它们混合。

如果您确实想即时混合它们,那么我会使用类似 BufferedWaveProvider 的东西来存储来自每个录音设备的音频。每当有新的音频记录缓冲区出现时,它就会被写入适当的 BufferedWaveProvider。然后,一旦所有 BufferedWaveProviders 中的音频都超过了某个阈值,就将该数量的音频混合到目标文件中。