问题:
我有从 websocket 发送的 ArrayBuffer 或 Uint8Array 格式的音频二进制数据。我们将其命名为
wsAudioData
。
我想将这个
wsAudioData
传输到我的 webrtc 服务器,我可以通过利用 RTCPeerConnection.addTrack(track: MediaStreamTrack, ...streams: MediaStream[]): RTCRtpSender
api 来实现这一点。
但是,
addTrack
接受曲目和流,即MediaStreamTrack
和MediaStream[]
。
所以我必须先将我的wsAudioData
转换为MediaStream
。
这是我尝试过的:
我尝试了
AudioContext
和audioContext.createMediaStreamDestination
。
this.audioContext = new AudioContext({ sampleRate: sampleRate });
this.mediaStreamDestination = this.audioContext.createMediaStreamDestination();
当收到
wsAudioData
时,我会尝试播放这个音频数据。
const bufferSource = this.audioContext.createBufferSource();
const audioBuffer = convertUint8ArraysToFloat32Array(wsAudioData);
const buffer = this.audioContext.createBuffer(
1,
audioBuffer.length,
this.audioContext.sampleRate,
);
buffer.copyToChannel(audioBuffer, 0);
bufferSource.buffer = buffer;
// Connect sourceNode to MediaStreamDestinationNode
bufferSource.connect(this.mediaStreamDestination);
bufferSource.start();
当 websocket 打开时,我将使用我的peerConnection 连接 mediaStreamDestination:
this.peerConnection.addTrack(
this.mediaStreamDestination.stream.getAudioTracks()[0],
this.mediaStreamDestination.stream,
);
我的上述解决方案的问题:
wsAudioData
时,可能会同时播放多个音频。 (我可以通过使用缓存数组来部分解决这个问题,当数组的长度在大约500ms内保持不变时,我播放缓存数组中的所有音频数据)还有其他方法可以将 wsAudioData 无缝转换为 MediaStream 吗?感谢您的阅读。
如果您不介意使用仅限 Chromium 的 API,则可以使用
MediaStreamTrackGenerator
来创建 MediaStreamTrack
,而不使用 AudioContext
。
const mediaStreamTrackGenerator = new MediaStreamTrackGenerator('audio');
那个
mediaStreamTrackGenerator
可以像任何其他MediaStreamTrack
一样使用。您可以使用 WritableStream
向其推送数据
通过其 writable
属性暴露。
它期望数据采用 Web Codecs 定义的
AudioData
格式。