1,最近调试程序的时候发现抱一个错误
max-bundle configured but session description has no BUNDLE group
最后发现是一个参数设置错误
config.bundle_policy = webrtc::PeerConnectionInterface::BundlePolicy::kBundlePolicyMaxBundle;
2,rtcp-mux
传输时,可以复用媒体通道,一种是音频和视频的复用,一种是 RTCP 和 RTP 的复用。
RTCP 和 RTP 复用,表示 Sender 使用一个传输通道(单一端口)发送 RTP 和 RTCP:
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
a=rtcp-muxm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 123 127 122 125 107 108 109 124
a=rtcp-mux
此时,Receiver 必须准备好在 RTP 端口上接收 RTCP 数据,并需要预留一些资源,比如 RTCP 带宽。
音频和视频复用时,最后只会用一个 Candidate 传输,比如客户端自己的 SDP Offer,和两个 relay 的Candidates:
//音视频需要共用一个传输通道传输的媒体,如果没有这一行,音视频就会分别单独用一个udp端口来发送
a=group:BUNDLE audio videom=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
a=mid:audiom=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 123 127 122 125 107 108 109 124
a=mid:video
sdpMid: video, sdpMLineIndex: 1, candidate:150963819 1 udp 41885439 182.92.80.26 54400 typ relay raddr 42.120.74.91 rport 37714
sdpMid: audio, sdpMLineIndex: 0, candidate:150963819 1 udp 41885439 182.92.80.26 59241 typ relay raddr 42.120.74.91 rport 49618
这表示最终 audio 和 video 尽管可能有独立的 Candidate,但是如果对方也是 BUNDLE,那么最终只会用一个 Candidate。例如,如果对方的 Answer 是:
a=group:BUNDLE audio videom=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
a=mid:audiom=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 102 123 127 122 125 107 108 109 124
a=mid:video
sdpMid: audio, sdpMLineIndex: 0, candidate:150963819 1 udp 41885439 182.92.80.26 51542 typ relay raddr 42.120.74.91 rport 56380
最后它们只会用一个 Candidate 传输。如下图所示:
rtcp-mux 将 RTP 和 RTCP 复用到单一的端口进行传输,这简化了 NAT traversal,而 BUNDLE 又将多路媒体流复用到同一端口进行传输,这不仅使 candidate harvesting 等 ICE 相关的 SDP 属性变得简单,而且又进一步简化了 NAT traversal。
rtcp-mux 是与 RTC 传输相关的重要的 SDP 属性,关于它的 SDP 协商的原则如下:
- 如果 Offer 携带 rtcp-mux 属性,并且 Answer 方希望复用 RTP 和 RTCP 到单一端口,那么 Answer 必须也要携带该属性。
- 如果 Offer 没有携带 rtcp-mux 属性,那么 Answer 也一定不能携带 rtcp-mux 属性,而且 Answer 方禁止 RTP 和 RTCP 复用单一端口。
- rtcp-mux 的协商和使用必须是双向的。
举个例子。客户端去订阅服务器的流,客户端的 Offer 没有携带 rtcp-mux 属性,那么服务器会认为客户端不支持 rtcp-mux,也不会走 rtcp 复用的流程。相反,服务器会分别创建 RTP 和 RTCP 两个传输通道,只有当两个通道的 ICE 和 DTLS 都成功,才会认为本次订阅的传输通道建立成功,继而向客户端发流。
试想,如果因为你的疏忽导致 Offer 漏掉了 rtcp-mux 属性,那么你将永远等不到服务器 Ready 的那一天。所以,SDP 看似只是一些文本,很简单,但是只有在项目的实战中,多遇到几个坑,才能更深切的体会到 SDP 属性的含义以及这些属性是如何在 RTC 场景中去发挥作用的。
再或者漏掉了offer设置了kBundlePolicyMaxBundle,answer没有传group BUNDLE那就报
max-bundle configured but session description has no BUNDLE group