ama*_*iKy 3 c# sockets audio naudio cscore
我正在尝试通过 tcp 套接字连接将音频从一台计算机单向流式传输到另一台计算机。
计算机 1 ---> 交换机 ---> 计算机 2
计算机 1 是发送方/客户端,计算机 2 是播放音频的接收方/服务器。
我设法让它发挥作用,但收到了很多噪音。
CS核心:
这是我目前用来发送数据的代码:
CaptureInstance = new WasapiLoopbackCapture();
CaptureInstance.Initialize();
CaptureInstance.DataAvailable += (s, a) => onStart(s, a);
CaptureInstance.Start();
Run Code Online (Sandbox Code Playgroud)
其中 onStart 只是使用 BinaryWriter 将字节写入套接字的流:
writer.Write(a.Data, a.Offset, a.ByteCount);
Run Code Online (Sandbox Code Playgroud)
这是我目前在接收计算机上用于播放音频的代码:
int size = 3840;
WriteableBufferingSource src = new WriteableBufferingSource(new CSCore.WaveFormat(48000, 32, 2)) { FillWithZeros = true };
WasapiOut soundOut = new WasapiOut();
soundOut.Initialize(src);
soundOut.Play();
while (true)
{
byte[] bytes = reader.ReadBytes(size); // BinaryReader
src.Write(bytes, 0, size);
}
Run Code Online (Sandbox Code Playgroud)
NA音频:
经过进一步的搜索、试验和错误,我设法使用 NAudio 拼凑出一个新的解决方案,它也遇到了同样的问题。噪音很大,而且声音很大。
客户端(发送者)在套接字连接时使用以下代码:
var capture = new WasapiLoopbackCapture();
capture.DataAvailable += (obj, args) =>
{
stream.Write(args.Buffer, 0, args.BytesRecorded); // NetworkStream(socket)
stream.Flush();
};
capture.StartRecording();
Run Code Online (Sandbox Code Playgroud)
服务器(接收者)正在使用这个:
// ---------------------------- Init --------------------------------
provider = new BufferedWaveProvider(new WaveFormat(48000, 32, 2));
WaveOut o = new WaveOut();
o.Init(provider);
o.Play();
Run Code Online (Sandbox Code Playgroud)
// --------------------------- Callback -------------------------------
socket = (Socket)ar.AsyncState;
int received = socket.EndReceive(ar);
byte[] dataBuffer = new byte[received];
Array.Copy(buffer, dataBuffer, received);
provider.AddSamples(dataBuffer, 0, received);
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
Run Code Online (Sandbox Code Playgroud)
我尝试让提供商在播放前缓冲 5-10 秒,以防出现缓冲问题,但没有成功。
我检查了 WaveFormat,两台 PC 上都是 48k、32 位 2 通道。不管怎样,我玩弄了价值观,失败了。
我尝试使用 UdpClient,但情况更糟。如果需要的话我可以展示代码。播放速度变慢了,而且噪音也更大了。我使用此链接进行设置。
我在客户端/服务器上运行一个循环,显示每个块接收/发送的字节,打印出第一个和最后一个字节,它们似乎很好并且按顺序,但是在调试我之前使用 MemoryStream 进行的设置时,出现了内存流的长度存在 12 字节的差异(一个在客户端,写入发送到服务器的相同字节,另一个在服务器上,写入接收到的字节),并且某些字节已关闭。
在客户端上录制音频 15 秒并立即播放即可。当发送到另一台计算机时,它会变得非常吵闹。
我认为问题出在我的套接字设置上,但我不太确定,而且我已经没有选择了。
太长;博士;问题是:什么可能导致这种巨大的噪音?NAudio/CSCore 设置似乎都遇到了同样的问题。同样的结果。
或者我该如何继续解决问题?
我想到了。
new WaveFormat(48000, 32, 2)
Run Code Online (Sandbox Code Playgroud)
创建 PCM 编码格式,而捕获实例的格式是 Ieefloat 编码。
如果有人需要这个,替换
new WaveFormat(48000, 32, 2)
Run Code Online (Sandbox Code Playgroud)
和
WaveFormat.CreateIeeeFloatWaveFormat(48000, 2)
Run Code Online (Sandbox Code Playgroud)
解决了这个问题。
有关 WaveFormat 的更多内容请阅读此处