共计 14186 个字符,预计需要花费 36 分钟才能阅读完成。
简介
在网络多媒体通话场景下,会议的参与者往往是用 SDP 协定来传递、协商媒体详细信息、网络地址和其余元数据。SDP 协定的全称是 session description protocol,含意是会话形容协定,它不是一种传输协定,而是由 ITEF 组织下的 MMusic 工作组设计的一种会话形容格局。
SDP 利用
SDP 最罕用于 RTC 实时通话的协商过程,在 WebRTC 中,通信单方在连贯阶段应用 SDP 来协商后续传输过程中应用的音视频编解码器 (codec)、主机候选地址、网络传输协定等。
在理论的利用过程中,通信单方能够应用 HTTP、WebSocket、DataChannel 等传输协定来互相传送 SDP 内容,这个过程称作 offer/answer 替换,也就是发起方发送 offer,接管方收到 offer 后回复一个 answer。例如在下图的服务端架构中,客户端将 offer 发送给信令服务器,信令服务器转发给媒体服务器,媒体服务器将 offer 和本身的能力进行比拟后失去 answer,信令服务器再将 answer 转发给客户端,随后客户端和媒体服务器就能够进行 RTP 通信。
SDP 格局
SDP 协定的设计能够参考 RFC4566 文档。它是一种具备非凡约定格局的纯文本形容文档,也就是它的内容都是由 UTF-8 编码的文本,有点相似于 JSON/XML。一个 SDP 会话形容包含若干行 type=value 模式的文本,其中 type 是一个辨别大小写的字母,例如 v、m 等,value 是一个结构化的文本,格局不固定。通常 value 由若干宰割符隔开的字段组成或者是一个字符串, 整个协定文本辨别大小写。”=” 两侧不容许有空格存在。
SDP 整体构造
SDP 由一个会话级形容(session level description)和多个媒体级形容(media level description)组成。会话级形容的作用域是整个会话,在 SDP 中,从 “v=” 行开始到第一个 “m=” 行之前都是属于会话级形容的内容。媒体级形容对某个媒体流的内容进行形容,例如某个音频流或者某个视频流,从某个 “m=” 行开始到下个 “m=” 行之前是属于一个媒体级形容的内容。如下图所示:
会话级形容次要形容了 SDP 的版本号、session 信息、是否启用端口复用等。每一个媒体级形容都形容了某种媒体的信息,包含所反对的 Codec、传输的时候应用的 SSRC、反对的 RTP 扩大头等。在会话级形容和媒体级形容可能会呈现雷同的内容,当这种状况呈现时,以媒体级形容的内容为准。
SDP 中字段的含意
SDP 中有的字段是必须的,有的字段是可选的,可选的字段在如下的示例中都应用 *
进行标记。SDP 中 type 呈现的程序是固定的,依照如下程序进行排列,这样能够加强解析器谬误检测的能力,另外也能够简化解析器的实现。
# 1. 会话级别的形容(及其字段)v= (protocol version)
o= (originator and session identifier)
s= (session name)
i=* (session information)
u=* (URI of description)
e=* (email address)
p=* (phone number)
c=* (connection information -- not required if included in all media)
b=* (zero or more bandwidth information lines)
# 2. 一个或多个工夫形容(字段参见下文)z=* (time zone adjustments)
k=* (encryption key)
a=* (zero or more session attribute lines)
# 3. 零个或多个媒体级别的形容(字段参见下文)# 工夫形容的字段有这些
t= (time the session is active)
r=* (zero or more repeat times)
# 媒体级别的形容字段有这些
m= (media name and transport address)
i=* (media title)
c=* (connection information -- optional if included at session level)
b=* (zero or more bandwidth information lines)
k=* (encryption key)
a=* (zero or more media attribute lines)
能够看到 type 都是单个小写字母,它们是不可扩大的,如果 SDP 解析器不能解析某个 type 则必须疏忽,”a=” 是 SDP 的次要扩大伎俩,来针对某中特定类型的媒体或利用做扩大。
有一个很好的网站:https://webrtchacks.com/sdp-a… 可用于学习 SDP,这个网站外面鼠标挪动到 SDP 某一行时,就会显示这一行 SDP 的具体含意。在这里简略介绍一下 SDP 协定中罕用的 type 以及对应的含意。
-
v: protocol version
v=0
v 的含意是 SDP 协定的版本号,目前 v 都是 0。
-
o: originator and session identifier
o=<username> <session-id> <session-version> <nettype> <addrtype> <unicast-address>
会话所有者无关的参数,包含用户名、session 信息,地址信息等。
(Owner/creator and session identifier)。
- username: 会话发起者的名称。如果不提供则用 ”-“ 示意,用户名不能蕴含空格;
- session-id: 主叫方的会话标识符;
- session-version: 会话版本号,个别为 0;
- nettype: 网络类型,目前仅应用 IN 来示意 Internet 网络类型;
- addrtype: 地址类型,能够是 IPV4 和 IPV6 两种地址类型;
- unicast-address:会话发起者的 IP 地址。
-
s: session name
s=<session name>
本次会话的题目或会话的名称(Session name)。
-
t: time the session is active
t=<start-time> <stop-time>
会话的起始工夫和完结工夫(Time session starts and stops),如果没有规定这两个工夫的话,都写为 0 即可。
-
m: media name
m=<media> <port>/<number of ports> <proto> <fmt> ...
媒体行,形容了发送方所反对的媒体类型等信息(Media information)。
- media:媒体类型,能够为 “audio”、”video”、”text”、”application”、”message”,示意音频类型、视频类型、文本类型、利用类型、音讯类型等,当前也可能扩大其余类型;
- port/number of ports:流传输端口号。示意在对应的本地端口上发送流;
-
proto:流传输协定。举例说明:
- RTP/SAVPF 示意用 UDP 传输 RTP 包;
- TCP/RTP/SAVPF 示意用 TCP 传输 RTP 包;
- UDP/TLS/RTP/SAVPF 示意用 UDP 来传输 RTP 包,并且应用 TLS 加密;
-
最初的 SAVPF 还有其余几种值:AVP, SAVP, AVPF, SAVPF。
- AVP 意为 AV profile
- S 意为 secure
- F 意为 feedback
- fmt 示意媒体格式形容,它可能是一串数字,代表多个媒体,这个字段的含意与 proto 字段的类型相干。在前面,能够应用 ”a=rtpmap:”、”a=fmtp:”、”a=rtcp-fb” 等扩大字段来对 fmt 进行阐明。
-
c: connection data
c=<nettype> <addrtype> <connection-address>
一个会话形容必须在每个媒体层都蕴含“c=”字段或者在会话层蕴含一个“c=”字段。如果这两个层都呈现的话,则媒体层呈现的“c=”会笼罩会话层呈现的“c=”字段的值。
- nettype: 是一个文本字符串,目前只定义了“IN”,示意“Internet”,将来会定义其余值。
- addrtype: 目前只定义了 IP4 和 IP6。
- connection-address: 标记连贯的地址。取决于 addrtype 字段的不同,在 connection-address 之后可能也会追随其余的字段。
- b: bandwidth
b=<bwtype>:<bandwidth>
这个字段的意思是本会话或者媒体所需占用的带宽。bwtype 能够为 “CT” 或者 “AS”,给出了 bandwidth(单位 kbps)数字所代表的含意:
CT:示意会话所占的所有的带宽的大小。当用于 RTP 会话时,示意所有的 RTP 会话所占用的带宽。
AS:这个带宽类型是针对特定利用的。通常,这示意某利用所占用的最大带宽。当用于 RTP 会话时,示意繁多 RTP 会话所占用的带宽.
能够了解为 CT 代表的是整个通话过程的带宽,AS 代表的是某个流的带宽。
- Encryption Keys (“k=”)
k=<method>
k=<method>:<encryption key>
如果在一个平安的信道上传输 SDP 音讯,那么 SDP 之中也能够携带密钥,携带的形式就是采纳字段 “k=”。当然这种形式目前曾经不举荐了。
字段 “k=” 能够是全局的,也能够是放在某个 “m=” 中的,别离代表利用于所有的媒体流,或者独自利用于某条媒体流。定义格局有如下几种:
- k=clear:<encryption key>
在这种办法中,密钥是没有通过任何转换的。除非传输通道是相对平安的,否则不该当应用这种办法。
- k=base64:<encoded encryption key>
在这种办法中,密钥通过 base64 的编码。除非保障传输通道相对平安,否则不该当应用这种办法。
- k=uri:<URI to obtain key>
在这种办法中,给出一个 URI。通过这个 URI,能够取得密钥,拜访 URI 的过程中可能还须要认证。
- k=prompt
在这种办法中,没有给出密钥。然而加上这个字段后,当用户退出会话时会提醒其输出密钥。这种形式目前也不举荐。
- a: attributes
a=<attribute>
a=<attribute>:<value>
a 示意的是属性。a 字段是扩大 SDP 的次要形式,有会话层属性和媒体层属性。会话层的属性利用于所有的媒体流,媒体层的属性只利用于以后的媒体流。
属性有两种形式:
- 个性属性,a=<flag> 示意,例如:”a=recvonly”
- 值属性,以 a =<attribute>:<value> 示意,例如 ”a=ice-ufrag:khLS”
罕用的属性列表如下:
表列 A | 表列 B | 表列 C |
---|---|---|
a=rtpmap: | RTP/AVP(Audio Video Profile) list | m=audio 54278 RTP/SAVPF 111 103 104 0 8 106 105 13 126 a=rtpmap:111 opus/48000/2 |
a=fmtp: | Format transport | a=fmtp:111 minptime=10 |
a=rtcp: | Explicit RTCP port (and address) | a=rtcp:54278 IN IP4 180.6.6.6 |
a=mid: | Media identification grouping | a=mid:audio |
a=ssrc: | “ssrc” indicates a property (known as a”source-level attribute”) of a media source (RTP stream) within an RTP session | a=ssrc:189858836 msid:GUKF430Khp9jEQiPrdYe0LbTAALiNAKAIfl2 ea392930-e126-4573-bea3-bfba519b4d59 |
a=ssrc-group: | Ssrc identification grouping | a=ssrc-group:SIMULCAST 32040 32142 a=ssrc:32040 imageattr:96 [x=1280,y=720] a=ssrc:32142 imageattr:96 [x=640,y=480] |
a=ice-ufrag: | a=ice-pwd: The “ice-ufrag” and “ice-pwd” attributes convey the username fragment and password used by ICE for message integrity | a=ice-ufrag:kwlYyWNjhC9JBe/V a=ice-pwd:AU/SQPupllyS0SDG/eRWDCfA |
a=ice-pwd: | ||
a=fingerprint: | A certificate fingerprint is a secure one-way hash of the DER (distinguished encoding rules) form of the certificate. | a=fingerprint:sha-256 D1:2C:BE:AD:C4:F6:64:5C:25:16:11:9C:AF:E7:0F:73:79:36:4E:9C:1E:15:54:39:0C:06:8B:ED:96:86:00:39 |
a=candidate: | It contains a transport address for a candidate that can be used for connectivity checks. | a=candidate:4022866446 1 udp 2113937151 192.168.0.197 36768 typ host generation 0 |
a=ptime: | Length of time in milliseconds for each packet | a=ptime:20 |
a=recvonly | Receive only mode | a=recvonly |
a=sendrecv | Send and receive mode | a=sendrecv |
a=sendonly | Send only mode | a=sendonly |
a=type: | Type of conference | |
a=sdplang: | Language for the session description | |
a=framerate: | Maximum video frame rate in frames per second | a=framerate:15 |
a=inactive | Inactive mode | a=inactive |
SDP 协商过程
SDP 协商过程对应的 RFC 文档是 RFC3264。在 WebRTC 通信过程中,连贯的两端通过 offer/answer 替换过程来相互进行 SDP 协商,发起方发送 offer 给接管方,其中蕴含了发起方的媒体能力和其余信息(包含 ICE、DTLS fingerprint,SSRC 等),接管方收到 offer 后和本人反对的能力进行比拟取出交加,回复 answer 给发起方,其中蕴含了协商之后的媒体能力和其余信息(ICE、DTLS fingerprint,SSRC 等),要留神这个过程中只有媒体能力是协商的,也就是发起方和接管方独特反对的媒体能力,例如反对的编解码格局,以及是否反对 RTX、FEC、TCC 等 QoS 性能,而 ICE、DTLS、SSRC 的信息是间接给出告诉对方,是连贯单方各自的信息。在 offer/answer 替换实现之后,单方就能够应用这些独特反对的媒体能力进行通信。
协商的过程如下图所示:
A 向服务器发送 offer 携带本人的 SDP 信息,包含:
- 地址信息是 UDP 10.124.17.11:32132,A 通过这个地址来和服务端进行媒体通信;
- ICE 信息,服务器通过 ICE 信息来验证客户端 A 的身份;
- 在接下来的媒体通信过程,客户端 A 只发不收 RTP;
- A 音频反对 48kHz 的双声道 Opus 编解码,应用 SSRC=1111 来发送;
- A 视频反对 VP8 或者 VP9 或者 H264 或者 H265 编解码,应用 SSRC=2222 来发送;
服务器在收到 A 的 offer 后,回复给 A 一个 answer,这是单方协商进去的媒体能力:
- 地址信息是 UDP 10.108.27.64:8888,服务器通过这个地址来和 A 进行媒体通信;
- ICE 信息,A 通过 ICE 信息来验证服务器的身份;
- 在接下来的媒体通信过程,服务器对于 A 来说只收不发 RTP;
- 协商进去的音频能力是 48kHz 的双声道 Opus 编解码;
- 协商进去的视频能力是 H264 编解码。
B 向服务器发送 offer 携带本人的 SDP 信息,包含:
- 地址信息是 UDP 192.168.1.1:32222,B 通过这个地址来和服务端进行媒体通信;
- ICE 信息,服务器通过 ICE 信息来验证客户端 B 的身份;
- 在接下来的媒体通信过程,客户端 A 须要收发 RTP;
- B 音频反对 48kHz 的双声道 Opus 编解码或者 G711 编解码,应用 SSRC=1234 来进行发送;
- A 视频反对 H264,应用 SSRC=4567 来进行发送;
服务器在收到 B 的 offer 后,回复给 B 一个 answer,这是单方协商进去的媒体能力:
- 地址信息是 UDP 10.108.27.64:8888,服务器通过这个地址来和 B 进行媒体通信;
- ICE 信息,B 通过 ICE 信息来验证服务器的身份;
- 在接下来的媒体通信过程,服务器对于 B 来说能够收发 RTP;
- 协商进去的音频能力是 Opus 编解码、48KHz,双声道,应用 SSRC=1122 进行发送;
- 协商进去的视频能力是 H264 编解码,应用 SSRC=3344 能够发送。
从以上两个 offer/answer 替换过程中能够看出,上图中的媒体服务器音频反对 Opus 编解码,但不反对 G711 编解码;视频反对 H264 编解码,但不反对 VP8、VP9、H265 编解码。
SDP 样例
在介绍完 SDP 的文本构造和 SDP 的协商过程中后,这里咱们举一个理论传输的 SDP 内容来帮忙了解。理论工程中,客户端和服务端都会反对好几种音视频媒体编解码,并且可能反对好几种能力,例如 FEC、NACK、TCC 等等,所以理论工程中的 SDP 都会十分长。为了不便浏览,下文将间接在 SDP 中每一行上方的正文中解释其含意。这个 SDP 中包含了 audio 和 video 两种流,video 的内容有局部也在 audio 中呈现过,因而不再反复解释。
发布者 Offer
// SDP 版本信息
v=0
// session 信息
// o=<username> <session-id> <session-version> <nettype> <addrtype> <unicast-address>
o=- 1873022542326151139 2 IN IP4 127.0.0.1
// s=<session name>
s=-
// t=<start-time> <stop-time>,如果不规定开始和完结工夫,两个都填 0 即可
t=0 0
// 应用 "a=" 来扩大的 bundle 属性,其含意是 audio 和 video 应用同一个端口发送 / 接管,具体能够参考下方的 RFC 文档:// https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-54
a=group:BUNDLE audio video
// 指明了 media stream ID 为 34b34ced3c5623ea4213vx3
// 参考 RFC 文档: https://tools.ietf.org/html/draft-ietf-mmusic-msid-17
a=msid-semantic: WMS 34b34ced3c5623ea4213vx3
// m=<media> <port> <proto> <fmt> ...
// port=10 无理论含意,真正通信应用的端口由 ICE Candidate 指定
// proto=UDP/TLS/RTP/SAVP 示意用 UDP 来传输 RTP 包,并应用 DTLS 加密
// 前面的一串数字是 fmt,示意所有 codec 的 payloadtype
m=audio 10 UDP/TLS/RTP/SAVPF 111 114 115 116 123 124 125
// c=<nettype> <addrtype> <connection-address>
c=IN IP4 0.0.0.0
// a=rtcp:<port> [nettype addrtype connection-address]
a=rtcp:9 IN IP4 0.0.0.0
// ICE 信息,参考 RFC 文档: https://tools.ietf.org/html/rfc5245#section-15.4
a=ice-ufrag:aZ/b
a=ice-pwd:3tFwvgPAA2PK3pPWoJjVz4FJ
a=ice-options:trickle renomination
// DTLS 信息,参考 RFC 文档: https://tools.ietf.org/html/rfc4572#section-5
a=fingerprint:sha-256 5F:78:37:05:D7:83:46:05:F7:3F:17:35:2A:7E:81:D3:2D:26:71:87:8B:9F:57:02:53:30:E3:3E:B6:3E:49:D5
// a=setup:<role>
// role 可选 active/passive/actpass/holdconn,// 别离示意端点将发动一个传出连贯、端点将承受传入连贯、// 端点违心承受传入连贯或启动传出连贯、端点临时不想建设连贯
// 参考 rfc: https://tools.ietf.org/html/rfc4145#section-4
a=setup:actpass
// a=mid:<token>
// 这个 token 在 a=group 那一行中也有呈现,// 也就是说这里形容的媒体正是须要被 bundle 的
// 参考 rfc: https://tools.ietf.org/html/rfc5888#section-6
a=mid:audio
// 以下是这个媒体反对的所有 RTP 扩大头,// 参考 rfc: https://tools.ietf.org/html/rfc8285
// a=extmap:<value>["/"<direction>] <URI> <extensionattributes>
// value=ID
// direction 可选 sendonly/recvonly/sendrecv/inactive,默认值 sendrecv
// URI 就是这个扩大头的 URI,通信单方能够通过 URI 表明扩大头的含意让单方都能了解
// ID=1 的扩大头是 audio level 扩大头,示意 RTP 包中会携带音频包音量大小
// 参考 https://tools.ietf.org/html/rfc6464#section-4
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
// rtp stream 信息,参考 rfc: https://tools.ietf.org/html/draft-ietf-avtext-rid-09
a=extmap:13 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
// 流的方向,sendrecv 示意能够收也能够发
// 参考 rfc:https://tools.ietf.org/html/rfc3264
a=sendrecv
// 这一行示意 rtcp 和 rtp 复用一个端口,// 参考 rfc:https://tools.ietf.org/html/rfc5761
// 和 rfc:https://tools.ietf.org/html/rfc8035
a=rtcp-mux
// a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>]
// opus codec 的 payload,
// 表明 fmt=111 就是用来传输 opus 数据的
// 参考 rfc: https://datatracker.ietf.org/doc/html/rfc7587
a=rtpmap:111 opus/48000/2
// a=rtcp-fb:<payload type> [...]
// 示意反对的 rtcp 反馈报文类型
// 这个反馈报文是 tcc 带宽探测用的
// 参考 https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=rtcp-fb:111 transport-cc
// nack,示意 fmt=111 反对 nack 重传包
a=rtcp-fb:111 nack
// a=fmtp 用来形容 codec 的一些个性,例如这里示意冀望的 opus 最小打包工夫是 10ms,并且应用 inbandfec
a=fmtp:111 minptime=10;useinbandfec=1
// 指明了音频 RTX 包的 payloadtype
// 参考 rfc:https://tools.ietf.org/html/rfc4588#section-8.6
a=rtpmap:114 rtx/48000/2
// apt 示意 fmt=114 的 RTX 包是用来重传 fmt=111 音频的
a=fmtp:114 apt=111
// 指明了 rsfec 包的 payloadtype
a=rtpmap:123 rsfec/48000/2
// 指明了 red 包的 payloadtype
// 参考 https://tools.ietf.org/html/rfc2198
a=rtpmap:124 red/48000/2
// 指明了音频 RTX 包的 payloadtype
a=rtpmap:125 rtx/48000/2
// apt 示意 fmt=125 的 RTX 包是用来重传 fmt=124 的 red 包的
a=fmtp:125 apt=124
// ssrc-group 指明了一组 ssrc 之间的关系,FID 表明后一个 ssrc 是前一个 ssrc 的 rtx
// https://tools.ietf.org/html/rfc5576#section-4.2
a=ssrc-group:FID 2952055605 1713037948
// cname 的内容是一个 16 位 Base64 字符串,含意是传输级的标识符,同一个 PeerConnection 的值雷同
// 参考 https://datatracker.ietf.org/doc/html/rfc8834#section-4.9
a=ssrc:2952055605 cname:vqdagKn92E0lhuXn
// 前一个 49b56cad1c6074ef96622fa0 是 media stream id,后一个是 sender track id
// media stream 次要用于音视频同步,每个 track 以 media stream id 作为 sync label 进行同步
// 参考 https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-msid
a=ssrc:2952055605 msid:49b56cad1c6074ef96622fa0 49b56cad1c6074ef96622fa0a0
// media stream id
a=ssrc:2952055605 mslabel:49b56cad1c6074ef96622fa0
// sender track id
a=ssrc:2952055605 label:49b56cad1c6074ef96622fa0a0
// video media
m=video 9 UDP/TLS/RTP/SAVPF 96 97 101 102 103
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:aZ/b
a=ice-pwd:3tFwvgPAA2PK3pPWoJjVz4FJ
a=ice-options:trickle renomination
a=fingerprint:sha-256 5F:78:37:05:D7:83:46:05:F7:3F:17:35:2A:7E:81:D3:2D:26:71:87:8B:9F:57:02:53:30:E3:3E:B6:3E:49:D5
a=setup:actpass
a=mid:video
// 传输工夫偏移扩大头
// 参考 https://datatracker.ietf.org/doc/html/rfc5450
a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
// abs-send-time 扩大头,gcc 带宽探测用的
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
// 视频朝向扩大头
// 参考 https://datatracker.ietf.org/doc/html/rfc6184
a=extmap:4 urn:3gpp:video-orientation
// transport-cc 扩大头,tcc 带宽探测用的
a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
// 扩大头的内容是对播放提早限度的值
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
// 视频内容类型扩大头
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
// 这个扩大头用于传输每帧的工夫信息
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
// 视频的色域空间扩大头
a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/color-space
// 传输视频 SDES 信息的扩大头
// 参考:https://datatracker.ietf.org/doc/html/draft-ietf-avtext-rid-06
a=extmap:13 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
// 指明 fmt=96 就是用来传输 H264 编码的视频的
a=rtpmap:96 H264/90000
// remb 反馈报文,gcc 带宽探测用的
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
// FIR(残缺帧内申请)反馈报文
// 参考 https://datatracker.ietf.org/doc/html/rfc5104
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
// PLI NACK 反馈报文
// 参考 https://datatracker.ietf.org/doc/html/rfc5104
a=rtcp-fb:96 nack pli
// 前面的是一些 H264 的参数
a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96;packetization-mode=1
a=rtpmap:101 red/90000
a=fmtp:101 packetization-mode=1
a=rtpmap:102 rtx/90000
a=fmtp:102 apt=101;packetization-mode=1
a=rtpmap:103 rsfec/90000
a=fmtp:103 packetization-mode=1
// ssrc-group:SIM 示意前面的这些 ssrc 是同一个流的 simulcast
a=ssrc-group:SIM 2955842370 1032318052
a=ssrc-group:FID 2955842370 521905126
a=ssrc-group:FID 1032318052 1492521545
a=ssrc:2955842370 cname:vqdagKn92E0lhuXn
a=ssrc:2955842370 msid:49b56cad1c6074ef96622fa0 49b56cad1c6074ef96622fa0v0
a=ssrc:2955842370 mslabel:49b56cad1c6074ef96622fa0
a=ssrc:2955842370 label:49b56cad1c6074ef96622fa0v0
a=ssrc:1032318052 cname:vqdagKn92E0lhuXn
a=ssrc:1032318052 msid:49b56cad1c6074ef96622fa0 49b56cad1c6074ef96622fa0v0
a=ssrc:1032318052 mslabel:49b56cad1c6074ef96622fa0
a=ssrc:1032318052 label:49b56cad1c6074ef96622fa0v0
a=ssrc:521905126 cname:vqdagKn92E0lhuXn
a=ssrc:521905126 msid:49b56cad1c6074ef96622fa0 49b56cad1c6074ef96622fa0v0
a=ssrc:521905126 mslabel:49b56cad1c6074ef96622fa0
a=ssrc:521905126 label:49b56cad1c6074ef96622fa0v0
a=ssrc:1492521545 cname:vqdagKn92E0lhuXn
a=ssrc:1492521545 msid:49b56cad1c6074ef96622fa0 49b56cad1c6074ef96622fa0v0
a=ssrc:1492521545 mslabel:49b56cad1c6074ef96622fa0
a=ssrc:1492521545 label:49b56cad1c6074ef96622fa0v0
// 应用的 rsfec 的版本
a=rsfec-version:1
总结
SDP 协定是 WebRTC 通信的重要组成部分,它使得不同版本的 WebRTC 服务端、客户端之间可能兼容。能够从文中列出的理论的 SDP 样例中发现 SDP 还是很简单的,而且波及到了各种音视频传输中的概念,弄懂 SDP 对深刻学习 WebRTC 很有帮忙。
参考文档
- SDP 格局规定,RFC4566:https://datatracker.ietf.org/…
- offer/answer 替换过程,RFC3264:https://datatracker.ietf.org/…
- SDP 各字段解释示例:https://webrtchacks.com/sdp-a…