从 UDP 接收到的消息播放音频,点击声音(Naudio API)
Posted
技术标签:
【中文标题】从 UDP 接收到的消息播放音频,点击声音(Naudio API)【英文标题】:Playing Audio from UDP received message, Clicking sound (Naudio API) 【发布时间】:2021-02-26 15:31:55 【问题描述】:我正在创建一个具有用于语音聊天的 UDP 的聊天客户端,但是当我将音频(以字节为单位)发送到其他客户端时,客户端播放的音频一切都很清晰,但我听到后面有随机的点击声地面。我认为这可能是因为它是 UDP 而不是检查数据是否正确,但不是。即使我通过 TCP 发送,我仍然可以听到背景中的点击声。
要重新创建的代码:
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace QuestionStack
public partial class Form1 : Form
UdpClient UDPc;
private NAudio.Wave.WaveIn sourceStream;
IPEndPoint ep;//where the client will send the udp data from recording
public Form1()
InitializeComponent();
/// <summary>
/// client clicks when he wants to start connection with other client
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StartAudioButton_Click(object sender, EventArgs e)
UDPc = new UdpClient(Int32.Parse(MyPortTextBox.Text));
ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), Int32.Parse(OtherUserTextBoxPort.Text)); // endpoint where other clienr is listening
UDPc.Connect(ep);
UDPc.BeginReceive(new AsyncCallback(ReceiveUdpMessage), null);
Thread.Sleep(100);
StartAudioRecording();
/// <summary>
/// where the client takes the audio in bytes, he got from otehr client to convert and play the audio
/// </summary>
/// <param name="ar"></param>
private void ReceiveUdpMessage(IAsyncResult ar)
try
byte[] bytesRead = UDPc.EndReceive(ar, ref ep);
BufferedWaveProvider provider = new BufferedWaveProvider(new WaveFormat(44100, 16, 2));
provider.DiscardOnBufferOverflow = true;
provider.AddSamples(bytesRead, 0, bytesRead.Length);
DirectSoundOut _waveOut = new DirectSoundOut();
_waveOut.Init(provider);
_waveOut.Play();
UDPc.BeginReceive(new AsyncCallback(ReceiveUdpMessage), null);
catch (Exception ex)
MessageBox.Show(ex.ToString());
/// <summary>
/// starts recording and sents to other client if check box to only listen is not on
/// </summary>
public void StartAudioRecording()
if (!checkBoxOnlyListen.Checked)
sourceStream = new NAudio.Wave.WaveIn();
sourceStream.DeviceNumber = 0;
sourceStream.WaveFormat = new NAudio.Wave.WaveFormat(44100, NAudio.Wave.WaveIn.GetCapabilities(0).Channels);
sourceStream.DataAvailable += new EventHandler<NAudio.Wave.WaveInEventArgs>(sourceStream_DataAvailable);
sourceStream.StartRecording();
/// <summary>
/// if got recording, sends it to other client
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void sourceStream_DataAvailable(object sender, NAudio.Wave.WaveInEventArgs e)
if (sourceStream == null) return;
try
UDPc.Send(e.Buffer, e.BytesRecorded);//sending data UPD
catch (Exception ex)
MessageBox.Show(ex.ToString());
FormsPicture 所以如果数据没问题,我翻译和播放它的方式就会导致问题。 我检查了,是否在方法之外创建 Wave out 对象并不重要。 我尝试了一百万种不同的方法来修复它。我不知道该怎么做。如果有人知道更好的翻译或修复方法,那将是我的一周。
提前致谢。
【问题讨论】:
请阅读how-to-ask page 和How to create a Minimal, Complete, and Verifiable example 以改进您的问题并帮助我们了解您的问题。 44Khz PCM 在没有压缩的情况下进行流式传输实在是太疯狂了。这可能只是延迟(网络跟不上实时)。如果您改为保存到磁盘,然后稍后再播放,听起来可能还不错。 但是,如果你保存到磁盘不会导致高延迟(我希望它是像不和谐这样的实时语音聊天),即使我将 PCM 降低到 11k 它仍然会产生点击 【参考方案1】:您应该创建一个输出设备和一个BufferedWaveProvider
,并在收到任何音频之前开始播放。然后在接收函数中,您唯一需要做的就是将接收到的音频添加到BufferedWaveProvider
。但是,如果通过网络接收音频的速度不够快,您仍然会获得点击,这意味着您收到的音频会丢失。
【讨论】:
谢谢你的回答和API以上是关于从 UDP 接收到的消息播放音频,点击声音(Naudio API)的主要内容,如果未能解决你的问题,请参考以下文章
从 socket.io 收到消息时从客户端播放音频 - node.js
播放音乐时,我的音频应用程序中没有收到通知或消息的声音 | AV音频播放器