簡體   English   中英

如何使用 NAudio 從 UDP 數據包播放音頻 stream?

[英]How do I play an audio stream from UDP packets using NAudio?

我從 Voicemeeter 本地接收數據,它使用 VBAN 協議發送字節的 stream。

我正在嘗試使用 NAudio 解碼字節並使用 WaveOutEvent 播放音頻。 我的實現與 NAudioDemo 中的 The NetworkChatDemo 幾乎相同,查看此鏈接以了解有關 NAudio 的更多信息,它是一個很棒的音頻庫,非常感謝 Mark Heath。

我的實現:

private readonly ILogger<AudioController> _logger;
        private NetworkAudioPlayer player;
        private readonly INetworkChatCodec _codec;


        public AudioController(ILogger<AudioController> logger)
        {
            _logger = logger;
            _codec = new ALawChatCodec();
        }

        [HttpGet]
        [Route("start")]
        public IActionResult Start()
        {

            var receiver = new UdpAudioReceiver(6980);
            player = new NetworkAudioPlayer(_codec, receiver);

            return Ok("Hello");
        }

網絡音頻播放器:

private readonly INetworkChatCodec codec;
    private readonly IAudioReceiver receiver;
    private readonly IWavePlayer waveOut;
    private readonly BufferedWaveProvider waveProvider;

    public NetworkAudioPlayer(INetworkChatCodec codec, IAudioReceiver receiver)
    {
        this.codec = codec;
        this.receiver = receiver;
        receiver.OnReceived(OnDataReceived);

        waveOut = new WaveOutEvent();
        waveProvider = new BufferedWaveProvider(codec.RecordFormat);
        waveProvider.BufferDuration = TimeSpan.FromSeconds(300);
        waveOut.Init(waveProvider);
        waveOut.Play();
    }

    void OnDataReceived(byte[] compressed)
    {
        byte[] decoded = codec.Decode(compressed, 0, compressed.Length);
        waveProvider.AddSamples(decoded, 0, decoded.Length);
    }

    public void Dispose()
    {
        receiver?.Dispose();
        waveOut?.Dispose();
    }

我在這個實現中遇到了兩個問題:

  • 首先,我無法將 BufferDuration 設置為無限值,因為它是實時的 stream。
  • 其次,我什么都聽不到,只有噪音。

如何將 BufferDuration 設置為無限?
如何正確播放音頻?

更新:我能夠通過將 bufferPorivider 的 DiscardOnBufferOverflow 的值設置為 true 來解決第一個問題。

關於噪音問題,我已經從這個問題中找到了解決方案,Mark Heath 提到

另外,您確定接收到的網絡數據包中沒有周圍的元數據嗎? 如果是這樣,則需要將其剝離,否則會產生噪音。

所以,在將樣本添加到 BufferProvider 時,我將 offset 的值更改為等於 28,這會導致異常:

  void OnDataReceived(byte[] compressed)
        {
            var l = compressed.Length;
            waveProvider.AddSamples(compressed, 28, compressed.Length);
        }

堆棧跟蹤:

    > 
> System.ArgumentException
  HResult=0x80070057
  Message=Source array was not long enough. Check the source index, length, and the array's lower bounds. (Parameter 'sourceArray')
  Source=System.Private.CoreLib
  StackTrace:
   at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length, Boolean reliable)
   at System.Array.Copy(Array sourceArray, Int32 sourceIndex, Array destinationArray, Int32 destinationIndex, Int32 length)
   at NAudio.Utils.CircularBuffer.Write(Byte[] data, Int32 offset, Int32 count)
   at NAudio.Wave.BufferedWaveProvider.AddSamples(Byte[] buffer, Int32 offset, Int32 count)
   at POC.AudioStreaming.AudioManagers.NetworkAudioPlayer.OnDataReceived(Byte[] compressed) in C:\dev\POC.AudioStreaming\POC.AudioStreaming\AudioManagers\NetworkAudioPlayer.cs:line 41
   at POC.AudioStreaming.AudioManagers.UdpAudioReceiver.ListenerThread(Object state) in C:\dev\POC.AudioStreaming\POC.AudioStreaming\AudioManagers\UdpAudioReceiver.cs:line 38
   at System.Threading.QueueUserWorkItemCallback.<>c.<.cctor>b__6_0(QueueUserWorkItemCallback quwi)
   at System.Threading.ExecutionContext.RunForThreadPoolUnsafe[TState](ExecutionContext executionContext, Action`1 callback, TState& state)
   at System.Threading.QueueUserWorkItemCallback.Execute()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

如何解決此異常?

我已經通過使用 Skip function 從收到的數據包中修剪前 28 個字節來解決異常:

 void OnDataReceived(byte[] compressed)
    {
        byte[] buffer = compressed.Skip(28).ToArray();
        waveProvider.AddSamples(buffer, 0, buffer.Length);
    }

通過解決異常,我能夠很好地聽到音頻。 另外,我已經回答了我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM