C# - 通过套接字连接进行实时流音频传输

3
我正在尝试通过TCP套接字连接从一台计算机向另一台计算机流式传输音频,单向。

计算机1 ---> 交换机 ---> 计算机2

计算机1是发送方/客户端,计算机2是接收方/服务器,用于播放音频。

我设法使其部分工作,但接收到很多噪声。

CSCore:

这是我目前使用的代码来发送数据:

CaptureInstance = new WasapiLoopbackCapture();
CaptureInstance.Initialize();
CaptureInstance.DataAvailable += (s, a) => onStart(s, a);
CaptureInstance.Start();

在 onStart 中,使用 BinaryWriter 将字节写入套接字的流中:

writer.Write(a.Data, a.Offset, a.ByteCount);

这是我目前在接收计算机上使用的代码来播放音频:
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);
}

NAudio:

在进一步搜索、试错之后,我使用NAudio拼凑出了一个新的解决方案,但它也存在同样的问题。有很多噪音,并且声音非常大。

客户端(发送方)在套接字连接时使用以下代码:

var capture = new WasapiLoopbackCapture();

capture.DataAvailable += (obj, args) =>
{
    stream.Write(args.Buffer, 0, args.BytesRecorded); // NetworkStream(socket)
    stream.Flush();
};

capture.StartRecording();

服务器(接收方)正在使用此内容:
// ---------------------------- Init --------------------------------
provider = new BufferedWaveProvider(new WaveFormat(48000, 32, 2));

WaveOut o = new WaveOut();
o.Init(provider);
o.Play();

// --------------------------- 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);

我尝试让提供者在播放前缓冲5-10秒钟,以防止缓冲问题,但没有成功。

我检查了WaveFormat,它在两台PC上都是48k、32位2通道。我尝试调整了一下数值,但失败了。

我尝试使用UdpClient,但情况变得更糟。如果需要,我可以展示那段代码。回放变慢了,而且如果不是更多的话,噪音也变多了。我使用了link来设置它。

我在客户端/服务器上运行了一个循环,显示每个块的接收/发送字节,打印出第一个和最后一个字节,它们似乎都很好并且有序,但在调试我之前使用MemoryStream的设置时,内存流的长度存在12个字节的差异(一个在客户端,写入相同的字节被发送到服务器,另一个在服务器,写入接收到的字节),并且一些字节错了。

在客户端录制15秒音频并立即播放是可以的。但是当发送到另一台计算机时,会变得非常嘈杂。

我认为问题可能出在我的套接字设置上,但我不太确定,而且我已经没有其他选择了。

简而言之,问题是什么导致这种严重的噪音?看起来NAudio/CSCore都遇到了同样的问题。结果相同。

或者我该如何继续排除这个问题?

1个回答

5
我搞定了。
new WaveFormat(48000, 32, 2)

这段代码创建了一个PCM编码格式,而Capture Instance的格式是Ieeefloat编码。

如果有人需要的话,请使用以下代码替换:

new WaveFormat(48000, 32, 2)

使用

WaveFormat.CreateIeeeFloatWaveFormat(48000, 2)

已解决该问题。

有关WaveFormat的更多信息,请到此处阅读。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接