【发布时间】:2020-04-17 13:47:01
【问题描述】:
我开发了一个聊天系统,它使用 WebRTC 让同伴互相发送视频。聊天中只有两个用户。我已经对其进行了编码,因此为每个聊天创建了两个 RtcPeerConnections;一个连接用于传出视频,一个用于传入视频。
我使用以下代码来处理需要重新协商连接(添加新曲目、网络更改等)的情况,并且我怀疑我的方法是否会导致聊天系统继续出现稳定性问题。为了简洁起见,我在下面的代码中省略了 ICE 候选人交换和一堆其他内容 - 希望它仍然足够有意义:
navigator.mediaDevices.getUserMedia(mediaConstraints)
.then(stream => {
// outgoingPcContainer/incomingPcContainer encapsulates the RtcPeerConnection for the outgoing video
outgoingPcContainer.pc = new RTCPeerConnection(iceServers);
outgoingPcContainer.pc.onnegotiationneeded = () => {
if (outgoingPcContainer.isNegotiating) return;
outgoingPcContainer.isNegotiating = true;
outgoingPcContainer.pc.createOffer({
offerToReceiveAudio: true,
offerToReceiveVideo: true,
});
.then((offer) => {
return outgoingPcContainer.pc.setLocalDescription(offer);
})
.then(() => {
// Send SDP to the other user via signalling channel
invokeSignalRMethod('sendConnectionOffer', recipientId, outgoingPcContainer.pc.localDescription);
})
.finally(() => {
outgoingPcContainer.isNegotiating = false;
});
};
stream.getTracks().forEach(track =>
outgoingPcContainer.pc.addTrack(track, stream));
}
请注意,此事件处理程序仅受传出(提供者)RtcPeerConnection 的约束。
收件人收到此优惠并回复回复:
chatHub.on('connectionOffered', (offererId, desc) => {
incomingPcContainer.pc = new RtcPeerConnection(iceServers);
incomingPcContainer.pc.setRemoteDescription(desc)
.then(() => incomingPcContainer.pc.createAnswer(answer))
.then(answer => incomingPcContainer.pc.setLocalDescription(answer))
.then() => {
// send back the answer to the offerer
invokeSignalRMethod('sendConnectionOfferAnswer', offererId, incomingPcContainer.pc.localDescription);
});
});
最后,提供者收到接收者的答复:
chatHub.on('connectionOfferAnswered', (answererId, desc) => {
outgoingPcContainer.pc.setRemoteDescription(new RTCSessionDescription(desc))
});
上面的代码基于关于 onnegotiationneeded here 的评论假设 RtcPeerConnection 的远程端永远不需要处理 onnegotiationneeded:
此协商应作为提议者进行,因为某些会话更改无法作为应答者进行协商。
我将此解释为连接的原始提供者只需要重新协商连接。另一种解释是,双方都可以重新谈判,但无论哪一方这样做,它都应该成为报价方。如果是后者,那么上面的代码将无法在应答者处理重新协商时正确处理。
那么,onnegotiationneeds 可以从应答者一方开火吗?在我的测试中,我没有看到这一点,我正在努力了解规范在这方面的规定。
【问题讨论】:
标签: webrtc