3. Procedures (规程)
本节描述如何将表示 MediaStreamTrack 的媒体描述关联到 MediaStream 内, 如 [W3C-WebRTC] 所定义.
在该规范描述的 Javascript API 中, 每个 MediaStream 与 MediaStreamTrack 都有一个 id 属性, 类型为 DOMString.
MSID 中的 msid-id 字段的值由 MediaStream 的 id 属性构成, 如 MediaStream 的 WebIDL 规范 [WEBIDL] 所定义. 特殊值 - 表示「无 MediaStream」.
MSID 中的 msid-appdata 字段 (若存在) 由 MediaStreamTrack 的 id 属性构成, 如 MediaStreamTrack 的 WebIDL 规范所定义.
当 SDP 会话描述被更新时, 特定的 msid-id 值继续指向同一 MediaStream, 特定的 msid-appdata 指向同一 MediaStreamTrack. 除当前有效的 SDP 描述外不存在其他记忆; 若某 MSID「标识符」值从 SDP 中消失并在后续协商中再次出现, 将被视为指向新的 MediaStream.
若 msid 属性不符合本文给出的 ABNF, 则应该忽略.
以下是对处理 SDP 更新的规则的高层描述. 详细规程见第 3.2 节.
-
当会话描述中出现新的 MSID「标识符」值且该值不是
-时, 接收方可以向其应用信令表明已添加新的 MediaStream. -
当会话描述被更新为包含具有某一 MSID「标识符」值以及一个或多个不同
appdata值的媒体描述时, 接收方可以向其应用信令表明已添加新的 MediaStreamTrack, 并注明它们被添加到了哪个 MediaStream. 这对每个不同的 MSID「标识符」值都要执行, 包括特殊值-, 表示已添加没有对应 MediaStream 的 MediaStreamTrack. -
若出现没有
appdata值的 MSID「标识符」值, 表示发送方未向接收方告知所希望的 MediaStreamTrack 标识符, 接收方将自行指定所创建 MediaStreamTrack 的id值. 假定媒体段中所有没有appdata值的 MSID 指向同一 MediaStreamTrack. -
当会话描述被更新为在特定媒体描述上不再列出任何
msid属性时, 接收方可以向其应用信令表明相应的 MediaStreamTrack 已结束.
除了在 SDP 中 msid 属性消失时信令轨道结束外, 当所有关联的 SSRC 按照 [RFC3550] 第 6.3.4 节 (收到 BYE 分组) 与第 6.3.5 节 (超时) 的规则消失时, 或当通过将端口号置零而禁用相应媒体描述时, 轨道也会被信令为已结束. 更改媒体描述的方向 (通过设置 sendonly, recvonly 或 inactive 属性) 不会结束 MediaStreamTrack.
SSRC 与媒体描述之间的关联在 [RFC8829] 中规定.
3.1. Handling of Nonsignaled Tracks (未信令轨道的处理)
未使用本文档所述机制的实体不会发送 msid 属性, 因而不会发送允许将 RTP 分组映射到 MediaStream 的信息. 这意味着对某些入向 RTP 分组, 接收方没有预定义的 MediaStream ID 值.
请注意, 下述处理由入向 RTP 分组触发, 而非由 SDP 协商触发.
在与使用 MSID 机制的实体通信时, 入向 RTP 分组在没有关联 MediaStream ID 值的情况下能够被接收的唯一情形是: 在初始协商之后, 执行一次协商, 应答方 (answerer) 在已建立的连接上添加 MediaStreamTrack, 并在提议方 (offerer) 收到应答之前开始发送数据. 对于初始协商, 在交互式连接建立 (Interactive Connectivity Establishment, ICE) 候选与指纹交换完成之前分组不会流动, 因此不存在此问题.
这些分组的接收方将执行下列步骤:
-
在最初收到 RTP 分组时, 将根据媒体类型 (由 PayloadType 承载) 创建适当的 MediaStreamTrack, 并使用 MID RTP 头扩展 [RFC8843] (若存在) 将 RTP 分组与特定媒体段关联.
-
若连接不处于 RTCSignalingState
stable, 则在此等待. -
当连接处于 RTCSignalingState
stable时, 将分配 ID 值.
分配 ID 值时执行下列步骤:
-
若存在
msid属性, 将使用该属性填充 MediaStreamTrack 及关联 MediaStreams 的id字段, 如上所述. -
若不存在
msid属性, MediaStreamTrack 的标识符将设为随机生成的字符串, 并信令其属于 WebIDLlabel属性设为Non-WebRTC stream的 MediaStream. -
在决定应用于 MediaStreamTrack 的
id字段后, 将向用户信令该轨道.
上述过程在进入 stable 状态之前可能涉及大量缓冲. 若实现希望限制该缓冲, 必须向用户信令媒体已被丢弃.
由上可知, 「默认」MediaStream 中的 MediaStreamTrack 不能通过移除 msid 属性来关闭; 应用必须在 SSRC 消失时 (按照 [RFC3550] 第 6.3.4 与 6.3.5 节的规则, 或通过将端口置零禁用媒体描述) 将这些轨道信令为已关闭.
3.2. Detailed Offer/Answer Procedures (详细的 Offer/Answer 规程)
这些规程按 [RFC3264] 建议的各节给出. 它们以 MediaStream 与 MediaStreamTrack 描述应采取的动作; 不包括应用内部的事件信令, 后者在 JavaScript 会话建立协议 (JavaScript Session Establishment Protocol, JSEP) [RFC8829] 中描述.
3.2.1. Generating the Initial Offer (生成初始 Offer)
对提议 (offer) 中的每个媒体描述, 若存在关联的出站 MediaStreamTrack, 提议方为该 MediaStreamTrack 所关联的每个 MediaStream 在该段添加一条 a=msid 属性. 属性的 identifier 字段设为 MediaStream 的 WebIDL id 属性. 若发送方希望为 MediaStreamTrack 信令标识符, 则将 appdata 字段设为 MediaStreamTrack 的 WebIDL id 属性; 否则省略.
3.2.2. Answerer Processing of the Offer (应答方对 Offer 的处理)
对提议中的每个媒体描述以及该媒体描述中的每条 a=msid 属性, 提议的接收方将执行下列步骤:
-
提取
a=msid属性的appdata字段 (若存在). -
若
appdata字段存在: 检查是否已存在 WebIDLid属性与appdata字段相同且未处于ended状态的 MediaStreamTrack. 若未找到这样的 MediaStreamTrack, 则创建它. -
若
appdata字段不存在, 且没有 MediaStreamTrack 与该媒体段关联, 则创建 MediaStreamTrack 并将其与该媒体段关联以供后续使用. -
提取
a=msid属性的identifier字段. -
检查是否已存在 WebIDL
id属性相同的 MediaStream. 若不存在, 则创建. -
将 MediaStreamTrack 添加到 MediaStream.
-
向用户信令新的 MediaStreamTrack 可用.
3.2.3. Generating the Answer (生成 Answer)
应答 (answer) 的生成方式与提议完全相同. 提议中的 a=msid 值不影响应答.
3.2.4. Offerer Processing of the Answer (提议方对 Answer 的处理)
应答的处理方式与对提议的处理完全相同.
3.2.5. Modifying the Session (修改会话)
在后续交换中, 遵循与初始 offer/answer 完全相同的规程, 但在解析提议与应答时增加一步:
-
对于因先前 offer/answer 交换而创建且未处于
ended状态的每个 MediaStreamTrack, 检查当前 SDP 中是否仍存在appdata字段与该轨道的 WebIDLid属性相同的a=msid属性. -
若未找到这样的属性, 则停止 MediaStreamTrack. 这将使其状态变为
ended.
3.3. Example SDP Description (SDP 描述示例)
下列 SDP 描述展示了一个具有两个 MediaStream 的 WebRTC PeerConnection 的表示, 每个 MediaStream 各有一条音频轨道和一条视频轨道. 仅显示与 MSID 相关的部分.
为清晰起见添加了换行, 空行与注释. 它们不是 SDP 的一部分.
# First MediaStream - id is 4701...
m=audio 56500 UDP/TLS/RTP/SAVPF 96 0 8 97 98
a=msid:47017fee-b6c1-4162-929c-a25110252400
f83006c5-a0ff-4e0a-9ed9-d3e6747be7d9
m=video 56502 UDP/TLS/RTP/SAVPF 100 101
a=msid:47017fee-b6c1-4162-929c-a25110252400
b47bdb4a-5db8-49b5-bcdc-e0c9a23172e0
# Second MediaStream - id is 6131....
m=audio 56503 UDP/TLS/RTP/SAVPF 96 0 8 97 98
a=msid:61317484-2ed4-49d7-9eb7-1414322a7aae
b94006c5-cade-4e0a-9ed9-d3e6747be7d9
m=video 56504 UDP/TLS/RTP/SAVPF 100 101
a=msid:61317484-2ed4-49d7-9eb7-1414322a7aae
f30bdb4a-1497-49b5-3198-e0c9a23172e0