SRS4.0之RTMP转WebRTC08 ---- SDP详解

详细参考:WebRTC SDP 详解和剖析

这里已一个webrtc的offer和answer为例研究一下:

offer

v=0
o=- 2661928673431850918 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=extmap-allow-mixed
a=msid-semantic: WMS
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:PA7e
a=ice-pwd:F1o3tHlhk6OPBtXo8IdhZCRH
a=ice-options:trickle
a=fingerprint:sha-256 D4:50:20:EA:EE:A6:86:59:77:3B:88:84:95:69:8A:AE:79:1A:C0:35:D9:25:EE:3F:0E:02:CB:2B:AF:99:F5:9E
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=recvonly
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 122 102 121 127 120 125 107 108 109 35 36 124 119 123 118 114 115 116 37
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:PA7e
a=ice-pwd:F1o3tHlhk6OPBtXo8IdhZCRH
a=ice-options:trickle
a=fingerprint:sha-256 D4:50:20:EA:EE:A6:86:59:77:3B:88:84:95:69:8A:AE:79:1A:C0:35:D9:25:EE:3F:0E:02:CB:2B:AF:99:F5:9E
a=setup:actpass
a=mid:1
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:13 urn:3gpp:video-orientation
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:11 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=recvonly
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:96 VP8/90000
a=rtcp-fb:96 goog-remb
a=rtcp-fb:96 transport-cc
a=rtcp-fb:96 ccm fir
a=rtcp-fb:96 nack
a=rtcp-fb:96 nack pli
a=rtpmap:97 rtx/90000
a=fmtp:97 apt=96
a=rtpmap:98 VP9/90000
a=rtcp-fb:98 goog-remb
a=rtcp-fb:98 transport-cc
a=rtcp-fb:98 ccm fir
a=rtcp-fb:98 nack
a=rtcp-fb:98 nack pli
a=fmtp:98 profile-id=0
a=rtpmap:99 rtx/90000
a=fmtp:99 apt=98
a=rtpmap:100 VP9/90000
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=fmtp:100 profile-id=2
a=rtpmap:101 rtx/90000
a=fmtp:101 apt=100
a=rtpmap:122 VP9/90000
a=rtcp-fb:122 goog-remb
a=rtcp-fb:122 transport-cc
a=rtcp-fb:122 ccm fir
a=rtcp-fb:122 nack
a=rtcp-fb:122 nack pli
a=fmtp:122 profile-id=1
a=rtpmap:102 H264/90000
a=rtcp-fb:102 goog-remb
a=rtcp-fb:102 transport-cc
a=rtcp-fb:102 ccm fir
a=rtcp-fb:102 nack
a=rtcp-fb:102 nack pli
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a=rtpmap:121 rtx/90000
a=fmtp:121 apt=102
a=rtpmap:127 H264/90000
a=rtcp-fb:127 goog-remb
a=rtcp-fb:127 transport-cc
a=rtcp-fb:127 ccm fir
a=rtcp-fb:127 nack
a=rtcp-fb:127 nack pli
a=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
a=rtpmap:120 rtx/90000
a=fmtp:120 apt=127
a=rtpmap:125 H264/90000
a=rtcp-fb:125 goog-remb
a=rtcp-fb:125 transport-cc
a=rtcp-fb:125 ccm fir
a=rtcp-fb:125 nack
a=rtcp-fb:125 nack pli
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=125
a=rtpmap:108 H264/90000
a=rtcp-fb:108 goog-remb
a=rtcp-fb:108 transport-cc
a=rtcp-fb:108 ccm fir
a=rtcp-fb:108 nack
a=rtcp-fb:108 nack pli
a=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f
a=rtpmap:109 rtx/90000
a=fmtp:109 apt=108
a=rtpmap:35 AV1X/90000
a=rtcp-fb:35 goog-remb
a=rtcp-fb:35 transport-cc
a=rtcp-fb:35 ccm fir
a=rtcp-fb:35 nack
a=rtcp-fb:35 nack pli
a=rtpmap:36 rtx/90000
a=fmtp:36 apt=35
a=rtpmap:124 H264/90000
a=rtcp-fb:124 goog-remb
a=rtcp-fb:124 transport-cc
a=rtcp-fb:124 ccm fir
a=rtcp-fb:124 nack
a=rtcp-fb:124 nack pli
a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f
a=rtpmap:119 rtx/90000
a=fmtp:119 apt=124
a=rtpmap:123 H264/90000
a=rtcp-fb:123 goog-remb
a=rtcp-fb:123 transport-cc
a=rtcp-fb:123 ccm fir
a=rtcp-fb:123 nack
a=rtcp-fb:123 nack pli
a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f
a=rtpmap:118 rtx/90000
a=fmtp:118 apt=123
a=rtpmap:114 red/90000
a=rtpmap:115 rtx/90000
a=fmtp:115 apt=114
a=rtpmap:116 ulpfec/90000
a=rtpmap:37 flexfec-03/90000
a=rtcp-fb:37 goog-remb
a=rtcp-fb:37 transport-cc
a=fmtp:37 repair-window=10000000
View Code

answer:

v=0
o=SRS/4.0.161(Leo) 41744832 2 IN IP4 0.0.0.0
s=SRSPlaySession
t=0 0
a=ice-lite
a=group:BUNDLE 0 1
a=msid-semantic: WMS live/livestream
m=audio 9 UDP/TLS/RTP/SAVPF 111
c=IN IP4 0.0.0.0
a=ice-ufrag:8p42d118
a=ice-pwd:ok61un195fg8q8083yy06247w0xg483s
a=fingerprint:sha-256 06:5D:44:D5:6A:62:A9:2E:5F:C5:5E:1E:99:3A:9F:11:20:7B:71:B1:D3:DF:CA:70:2D:82:0F:7D:AC:DC:0C:CC
a=setup:passive
a=mid:0
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=sendonly
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=ssrc:216302819 cname:85n6wsoy1t00k452
a=ssrc:216302819 label:audio-68w76144
a=candidate:0 1 udp 2130706431 10.151.3.77 8000 typ host generation 0
m=video 9 UDP/TLS/RTP/SAVPF 125
c=IN IP4 0.0.0.0
a=ice-ufrag:8p42d118
a=ice-pwd:ok61un195fg8q8083yy06247w0xg483s
a=fingerprint:sha-256 06:5D:44:D5:6A:62:A9:2E:5F:C5:5E:1E:99:3A:9F:11:20:7B:71:B1:D3:DF:CA:70:2D:82:0F:7D:AC:DC:0C:CC
a=setup:passive
a=mid:1
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=sendonly
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:125 H264/90000
a=rtcp-fb:125 transport-cc
a=rtcp-fb:125 nack
a=rtcp-fb:125 nack pli
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=ssrc:216302820 cname:85n6wsoy1t00k452
a=ssrc:216302820 label:video-35j24601
a=candidate:0 1 udp 2130706431 10.151.3.77 8000 typ host generation 0
View Code

 

WebRTC 使用 Offer-Answer 模型交换 SDP,Offer 中有 SDP,Answer 中也有。SDP主要分为如下几个部分:

  1. 会话级别描述
  2. 媒体级别描述
  3. 网络描述
  4. DTLS描述
  5. ICE策略

具体可以通过在谷歌浏览器中输入chrome://webrtc-internals/调试

会话级别描述

会话级别的 SDP 描述字段包括:v、o、s、c、b、t。

v(version):SDP 协议版本,值固定为 0。

o(origin):代表会话的发起者。

o=<username><sess-id><sess-version><nettype><addrtype><unicast-address>

各字段含义如下:

username:发起者的⽤户名,不允许存在空格,如果应⽤不⽀持⽤户名,则为-。

sess-id:会话id,由应⽤⾃⾏定义,规范的建议是NTP(Network Time Protocol)时间戳。

sess-version:会话版本,⽤途由应⽤⾃⾏定义,只要会话数据发⽣变化时(⽐如编码),sessversion

随着递增就⾏。同样的,规范的建议是NTP时间戳。

nettype:⽹络类型,⽐如IN表示Internet。

addrtype:地址类型,⽐如IP4、IV6

unicast-address:域名,或者IP地址。

o=- 7298280855354507719 2 IN IP4 127.0.0.1

s(session name):会话的名称,每个 SDP 中有且仅能有一个 s 描述,其值不能为空。

s=-。

s=<session name>

c(connection data):携带了会话的连接信息,其实就是 IP 地址。
格式如下:

c=<nettype><addrtype><connection-address>

每个SDP⾄少需要包含⼀个会话级别的c=字段,或者在每个媒体描述后⾯各包含⼀个c=字段。

(媒体描述后的c=会覆盖会话级别的c=)

nettype:⽹络类型,⽐如IN,表示 Internet。

addrtype:地址类型,⽐如IP4、IP6。

connection-address:如果是⼴播,则为⼴播地址组;如果是单播,则为单播地址;

举例01:

c=IN IP4224.2.36.42/127

举例02:

c=IN IP4 host.anywhere.com

b(bandwidth):表示会话或媒体使用的建议带宽。

t(timing):指定了会话的开始和结束时间,如果开始和结束时间都为 0,那么意味着这次会话是永久的。

媒体级别描述

SDP可能同时包含多个媒体描述。格式如下:

m=<media><port><proto><fmt> ...

其中:

media:媒体类型。包括 video、audio、text、application、message等。

port:传输媒体流的端⼝,具体含义取决于使⽤的⽹络类型(在c=中声明)和使⽤的协议(proto,在m=中声明)。

proto:传输协议,具体含义取决于c=中定义的地址类型,⽐如c=是IP4,那么这⾥的传输协议运⾏在IP4之上。⽐如:

UDP:传输层协议是UDP。

RTP/AVP:针对视频、⾳频的RTP协议,跑在UDP之上。

RTP/SAVP:针对视频、⾳频的SRTP协议,跑在UDP之上。

RTP/AVPF: 应⽤场景为视频/⾳频的 RTP 协议,⽀持 RTCP-based Feedback。参考 RFC4585

RTP/SAVPF: 应⽤场景为视频/⾳频的 SRTP 协议,⽀持 RTCP-based Feedback。参考 RFC5124

fmt:媒体格式的描述,可能有多个。根据 proto 的不同,fmt 的含义也不同。⽐如 proto 为

RTP/SAVP 时,fmt 表示 RTP payload 的类型。如果有多个,表示在这次会话中,多种payload类

型可能会⽤到,且第⼀个为默认的payload类型。

附加属性:a=

作⽤:⽤于扩展SDP。

有两种作⽤范围:会话级别(session-level)、媒体级别(media-level)。

1. 媒体级别:媒体描述(m=)后⾯可以跟任意数量的 a= 字段,对媒体描述进⾏扩展。

2. 会话级别:在第⼀个媒体字段(media field)前,添加的 a= 字段是会话级别的。

有如下两种格式:

a=<attribute>

a=<attribute>:<value>

格式1举例:

a=recvonly

格式2举例:

a=rtpmap:0 PCMU/8000

  1. a=mid 属性可以认为是每个 M 描述的唯一 ID。比如 a=mid:audio,那么 audio 这个字符串就是这个 M 描述的 ID。有的时候 mid 属性值也可以用数字表示,比如 a=mid:0,那么 0 也是这个 M 描述的 ID。mid 值一般和 grouping 传输属性的 BUNDLE 策略结合来用,比如 a=group:BUNDLE audio video,代表本次会话将对 mid 为 audio 和 video 的 M 描述进行复用传输。

a=group:BUNDLE 0 1

a=mid:0

a=mid:1

  1. M line 的数字 9 代表该媒体类型的传输端口,在 RTC 场景中都是使用 ICE candidate 的地址信息进行数据传输,所以 M line 的 port 并没有用到。不过,在 SIP 的场景下,M line 的 port 就十分重要了,此时,port 代表 RTP 端口,而且必须是偶数。结合 SDP 会话级别描述中的 C line 中的 IP 地址,我们就可以知道 SIP 的这路媒体流的传输地址。

m=audio 9 UDP/TLS/RTP/SAVPF 111

  1. RTX 表示是重传,比如 video 的 97,就是 apt=96 的重传。也就是说如果用的是 97 这个编码格式,它是在 96(VP8) 基础上加了重传功能。

a=rtpmap:97 rtx/90000

a=fmtp:97 apt=96

  1. 协商方式:PlanB 只有一个 M(audio) 和 M(video),他们的编码要相同,多有多路媒体流时,则根据 SSRC 去区分,UnifiedPlan 则可以有多个 M(audio) 和 M(video),每路流都有自己的 M 描述。当只有一路音频流和一路视频流时,Plan B 和 UnifiedPlan 的格式是相互兼容的。
  2. SSRC 就包含了需要发送的媒体流,另外 Offer 和 Answer 中都可以包含 SSRC。⽐如客户端和 MediaSoup 通信时,MediaSoup 总是给客户端发 Offer,MediaSoup 的 Offer 包含了MediaSoup 要发送(转发其他客户端的流给客户端)的媒体流 SSRC,同时客户端的 Answer 中也包含了⾃⼰要推送的 SSRC 流,他们的类型都是 sendrecv。
  3. Bundle:⾳频和视频的复⽤

a=group:BUNDLE 0 1

a=mid:0

a=mid:1

  1. rtcp-mux:RTCP 和 RTP 的复⽤

a=rtcp-mux

  1. Stream Direction:媒体流方向

sendonly 表示只发送数据,⽐如客户端推流到 SFU,那么会在⾃⼰的 Offer(orAnswer) 中携带 sendonly属性

recvonly表示只接收数据,⽐如客户端向 SFU 订阅流,那么会在⾃⼰的 Offer(orAnswer) 中携带 recvonly 属性

sendrecv 表示可以双向传输,⽐如客户端加⼊到视频会议中,既要发布⾃⼰的流⼜要订阅别⼈的流,那么就需要在⾃⼰的 Offer(or Answer) 中携带 sendrecv 属性

inactive 表示禁⽌发送数据,⽐如在基于 RTP 的视频会议中,主持⼈暂时禁掉⽤户 A 的语⾳,那么⽤户 A 的关于⾳频的媒体级别描述应该携带 inactive 属性,表示不能再发送⾳频数据。

网络描述

offer:

a=ice-ufrag:PA7e

// 客户端用户名

a=ice-pwd:F1o3tHlhk6OPBtXo8IdhZCRH

// 客户端密码

a=ice-options:trickle

// trickle方式表示媒体信息和ice后选项的信息可以分开传输

 

answer

a=ice-lite

// SRS是Lite ICE,只需要响应客户端的Binding请求

a=ice-ufrag:8p42d118

// SRS端用户名

a=ice-pwd:ok61un195fg8q8083yy06247w0xg483s

// SRS端密码

a=candidate:0 1 udp 2130706431 10.151.3.77 8000 typ host generation 0

//  {foundation} {component} {protocol} {priority} {ip} {port} typ {type} {generation}

// 0 [foundation] : 标识符,用来识别两个candidate是否相等

// 1 [component] : 传输媒体类型 1表示RTP

// ubp [protocol] : 协议类型

// 2130706431 [priority] : 优先级

// 10.151.3.77 [ip] : ip地址

// 8000 [port] : 端口

// host [type] : host类型,表示这是真实的主机地址

// generation : 代数。初始值是0,然后会不断+1,大的代数会覆盖掉低代数的候选地址。更新candidate的时候会+1,替换老的candidate

DTLS⻆⾊

offer:
a=fingerprint:sha-256 D4:50:20:EA:EE:A6:86:59:77:3B:88:84:95:69:8A:AE:79:1A:C0:35:D9:25:EE:3F:0E:02:CB:2B:AF:99:F5:9E
a=setup:actpass

answer:
a=fingerprint:sha-256 06:5D:44:D5:6A:62:A9:2E:5F:C5:5E:1E:99:3A:9F:11:20:7B:71:B1:D3:DF:CA:70:2D:82:0F:7D:AC:DC:0C:CC
a=setup:passive

setup:

active,作为client,主动发起协商

passive,作为server,等待发起协商

actpass,作为client,主动发起协商;作为server,等待发起协商

fingerprint:证书的摘要签名,用来验证证书使用,DTLS收到证书后,基于相同的hash计算哈希值,同fingerprint比较,相等,则说明证书有效。

 

posted @ 2021-10-29 08:43  Vzf  阅读(719)  评论(0编辑  收藏  举报