问题描述
我正在创建一个具有用于语音聊天的 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,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 对象是在方法之外创建的,这并不重要。 我尝试了一百万种不同的方法来修复它。我不知道该怎么做。如果有人知道翻译或修复它的更好方法,那将是我的一周。
提前致谢。
解决方法
您应该创建一个输出设备和一个 BufferedWaveProvider
,并在收到任何音频之前开始播放。然后在接收函数中,您唯一需要做的就是将接收到的音频添加到 BufferedWaveProvider
。但是,如果通过网络接收音频的速度不够快,您仍然会获得点击次数,这意味着您在接收的音频中存在丢失。