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

时间:2018-10-15 19:15:28

标签: c# naudio

我已经为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文件时,该函数似乎立即返回,而不是等待5秒钟过去。对我来说,一起录制音频的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

在录制音频时实时混合音频实际上是非常棘手的,因为缓冲区从每个录制设备到达的时间都不相同,并且可能不是相同的持续时间。另外,如果录制不是同时开始的,或者有丢失的话,则可能会解决潜在的同步问题。

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

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