一:JSEP
WebRTC在设计接口遵循了JSEP协议,因此了解JSEP协议对理解WebRTC接口有很大的帮助。
JSEP 中文翻译: https://github.com/aggresss/spec/blob/master/RFC/RFC8829_zh-CN.md
二:JSEP交互流程:
规范
-
JSEP 没有指定特定的会话描述(SDP)交换模型,不过大家一般都使用RFC3264] (offer/answer),让会话双方在媒体协商后进行音视频通信。
offer、answer模型
- 发起端通过调用 createOffer API 来创建 offer, 然后应用程序使用这个 offer 通过 setLocalDescription API 来设置其本地配置。
- offer 最终通过信令机制(如 websocket)发送到远端;在收到 offer 后,远端使用 setRemoteDescription API 来设置这个 offer。
- 远端使用 createAnswer API 生成适应的应答,使用 setLocalDescription API 来应用它,并通过信令通道将应答发送回发起方。
- 当发起方获得这个应答时,它使用 setRemoteDescription API 应用它,初始化就完成了
- 上述过程可以重复多次。
注意: 不同的 RFC 对 offer 和 answer 的格式提出了不同的条件。例如,offer 可以提出任意数量的 m-section(即,媒体描述如 [RFC4566],5.14 节所述),但 answer 必须包含与offer完全相同的数量及类型。如m-section不能删除,只能复用。
-
offer、answer 状态转移
三:重要的结构
PeerConnection
PeerConnection 与 SDP 的 Session Level 相对应,PeerConnection 构造函数允许应用程序为媒体会话指定全局参数,例如在收集候选对象时使用的 STUN/TURN 服务器和凭证,以及初始 ICE 候选策略和池大小,以及使用的 bundle 策略,常用的属性包括:
- iceTransportPolicy
- bundlePolicy
- rtcpMuxPolicy
RtpTransceiver
RtpTransceiver 与 SDP 中的 m-section 存在一一映射关系,每个 RtpTransceiver 有一个 RtpSender 和一个RtpReceiver,Offer/Answer 机制使用 SDP 作为会话描述方式的精华就是 SDP 的一个 m-section 可以描述双向媒体流,而 RtpTransceiver 就作为 m-section 在 JSEP 接口层面的映射。
RtpTransceiver 存在两个状态,关联状态 (associated) 和游离状态 (disassociated),分别对应当前 RtpTransceiver 是否与 SDP 中一个 m-section 关联,判断的依据是它的 mid 属性是否为 null。由此可以理解在 Unified Plan SDP 中,为什么 a=mid 是每个 m-section 的必须存在属性行。
有三种方式生成 RtpTransceiver,分别为:
- addTrack
- setRemoteDescription
- addTransceiver
PeerConnection 中 addTrack 时如果没有指定附加的 RtpTransceiver 则会自动创建;setRemoteDescription 操作时如果存在新增 remote track,则会自动创建 RtpTransceiver 。这两种方法都是隐式方式创建,JSEP 中显示创建 RtpTransceiver 的方式是 addTransceiver,手动创建 RtpTransceiver 的使用场景:
- 生成 offer 时,需要一个 direction 为 recvonly 的 m-section;
- 先生成 transceiver ,再将 track 附加到该 transceiver 的 RtpSender;
- 可以看出,手动控制 RtpTransceiver 在常规场景下并不是必须的,也可以理解 RtpTransceiver 操作是比 track 更接近底层的操作。
与 addTrack/removeTrack 接口不同,JSEP 并没有定义 removeTransceiver ,而只是在 RtpTransceiver 对象中增加了 stop 方法,这是因为 RtpTransceiver 是 SDP 中 m-section 的映射导致的,因为在 SDP 中,m-section 的索引顺序是固定的,类似于数组模式,所以 m-section 只能 append 或者 replace,而不可以 remove。
SDP m-section 重用
由于 SDP 中 m-section 是索引关联的,即 m-section 不可以删除但可以重用,JSEP 实现会在生成 offer 时检索可重用的 m-section 进行重用,可重用的 m-section 只要满足类型兼容 (audio/video/application) 即可重用。通常以下情况可以使 m-section 变为可重用状态:
- RtpTransceiver Close
当调用 RtpTransceiver.close() 并经过一次协商后,RtpTransceiver 将变为游离状态,原关联的 m-section 将变为可重用状态。 - Remote Answer Reject
SDP 规定 answer 中 m-line 为 0 表示拒绝对应的 m-section ,所以当 Remote Answer 中对应的 m-section 中 m-line 等于 0 时,则认为该 m-section 为可重用状态。