如何在.NET Core 3.1 WPF应用中播放MixedReality-WebRTC接收的Unity音频
解决方案
问题解答
- 如何确定数组的大小?
数组字节长度计算公式:
字节长度 = sampleCount * channelCount * bitsPerSample / 8,除以8是将比特单位转换为字节单位,计算结果转换为Int32类型即可用于Marshal.Copy操作。
- 如果获取到字节数组或者流,如何在实时语音通话场景下播放它?
推荐使用NAudio库实现实时音频播放,它是.NET平台轻量的音频处理库,支持原始PCM音频流的低延迟播放,适配WPF和.NET Core 3.1环境,直接在NuGet包管理器搜索安装即可。
实现逻辑为:首次收到音频帧时根据帧参数初始化播放格式和播放设备,后续收到帧后将数据写入缓存队列,播放组件自动从队列取数据播放,缓存大小可根据延迟和卡顿需求调整。
- 播放音频是否真的需要从IntPtr中获取流或者字节数组?
不是必须,你可以直接调用底层Windows音频API对接IntPtr内存块避免拷贝,但对于新手来说转换为字节数组是最易维护、出错概率最低的方案,且单帧音频数据量极小(10ms帧通常仅几百字节),拷贝开销完全可以忽略,不会影响实时性。
- 如果需要的话该如何实现?
参考下方完整示例代码即可。
完整示例代码
首先在你的WPF窗口类中定义成员变量:
using NAudio.Wave; using System.Runtime.InteropServices; // 类成员变量 private IWavePlayer _audioPlayer; private BufferedWaveProvider _audioBuffer; private WaveFormat _playFormat; private readonly object _bufferLock = new object();
修改你的音频帧接收逻辑:
pc.AudioTrackAdded += (RemoteAudioTrack track) => { track.AudioFrameReady += (AudioFrame frame) => { // 首次收到帧时初始化播放设备和格式 if (_playFormat == null) { _playFormat = new WaveFormat( rate: (int)frame.sampleRate, bitsPerSample: (int)frame.bitsPerSample, channels: (int)frame.channelCount); _audioBuffer = new BufferedWaveProvider(_playFormat) { BufferDuration = TimeSpan.FromMilliseconds(500), // 缓存500ms数据,平衡延迟和抗卡顿能力 DiscardOnBufferOverflow = true // 实时场景下缓存溢出时丢弃旧数据,避免延迟累积 }; _audioPlayer = new WaveOutEvent(); _audioPlayer.Init(_audioBuffer); _audioPlayer.Play(); } // 计算当前帧字节长度 int frameByteLength = (int)(frame.sampleCount * frame.channelCount * frame.bitsPerSample / 8); // 从非托管内存拷贝到字节数组 byte[] audioBuffer = new byte[frameByteLength]; Marshal.Copy(frame.audioData, audioBuffer, 0, frameByteLength); // 线程安全写入播放缓存 lock (_bufferLock) { if (_audioBuffer != null) { _audioBuffer.AddSamples(audioBuffer, 0, frameByteLength); } } }; };
最后在窗口关闭时释放资源,避免内存泄漏:
protected override void OnClosed(EventArgs e) { base.OnClosed(e); lock (_bufferLock) { _audioPlayer?.Stop(); _audioPlayer?.Dispose(); _audioBuffer = null; _playFormat = null; } }
常见问题排查
- 播放出现杂音:检查字节长度计算是否正确,确认音频参数(采样率、位深、声道数)初始化和实际帧参数一致,WebRTC默认常用参数为16kHz采样率、16bit位深、单声道。
- 播放卡顿:可适当调大
BufferDuration到1000ms,降低丢包概率。 - 延迟过高:可适当调小
BufferDuration到200ms,减少缓存数据量。
内容的提问来源于stack exchange,提问作者macnmunasinghe
相关产品推荐
相关产品推荐

