如何将从websocket发送过来的ArrayBuffer转换为MediaStream,然后通过peerConnection.addTrack传输到webrtc服务器?

问题描述 投票:0回答:1

问题:

我有从 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,
);

我的上述解决方案的问题:

  • 转换是CPU密集型的,当运行此代码时,我可以感觉到我的M2 mac正在发热。
  • 当从 websocket 发送多个
    wsAudioData
    时,可能会同时播放多个音频。 (我可以通过使用缓存数组来部分解决这个问题,当数组的长度在大约500ms内保持不变时,我播放缓存数组中的所有音频数据)

还有其他方法可以将 wsAudioData 无缝转换为 MediaStream 吗?感谢您的阅读。

javascript websocket webrtc mediastream audiocontext
1个回答
0
投票

如果您不介意使用仅限 Chromium 的 API,则可以使用

MediaStreamTrackGenerator
来创建
MediaStreamTrack
,而不使用
AudioContext

const mediaStreamTrackGenerator = new MediaStreamTrackGenerator('audio');

那个

mediaStreamTrackGenerator
可以像任何其他
MediaStreamTrack
一样使用。您可以使用
WritableStream
向其推送数据 通过其
writable
属性暴露。

它期望数据采用 Web Codecs 定义的

AudioData
格式。

© www.soinside.com 2019 - 2024. All rights reserved.