Signaling channel(信令通道)
a) 一种资源,使应用程序可以通过交换信令消息来发现,建立,控制和终止对等连接
b) 信令消息是两个应用程序相互交换以建立对等连接的元数据。该元数据包括本地媒体信息,例如媒体编解码器和编解码器参数,以及两个应用程序可能相互连接以进行实时流传输的可能的网络候选路径
c) 信令通道通常由信令服务器提供
Peer(对等节点)
a) 接入同一webrtc房间(逻辑划分的管理单元)的进行实时双向流传输的任何设备或应用程序
Session Traversal Utilities for NAT (STUN)
a) 一种协议,用于发现您的公共地址(公网IP)并确定路由器中可能阻止与对等方直接连接的任何限制条件
b) Stun服务由STUN服务器提供
Traversal Using Relays around NAT (TURN)
a) 通过打开与TURN服务器的连接并通过该服务器中继所有信息来绕过对称NAT限制的服务器
b) 当P2P链接建立失败,仍需要保证功能可用,这里就需要TURN服务器对所有数据进行中继。建立relay模式的链接
c) TURN服务由TURN服务器提供
relay模式即使用TURN服务
Session Description Protocol (SDP)
a) 一种描述连接的多媒体内容的标准,例如分辨率,格式,编解码器,加密等,以便一旦数据传输,两个对等方就可以相互理解
SDP Offer
a) 发起建立会话链接的SDP消息(主动发送方),生成会话描述以创建或修改会话
b) 比如想要和一个对等节点建立链接。首先就得告诉对端,自身终端信息(分辨率,格式,编解码器,加密),而为了描述自身终端信息产生SDP 就被称为SDP offer
SDP Answer
a) answer SDP由响应者响应邀约者发送的offer SDP
b) Answer主要包含终端协商结果(answer端终端信息)。例如,如果offer中的所有音频和视频流都被接受
Interactive Connectivity Establishment (ICE)
a) 一个允许您的Web浏览器(webrtc终端)与对等方连接的框架
ICE Candidate(Candidate)
a) 一种能与对等方用来通信的一种方法(方式)
- SDP offer包含有关A的应用程序想要建立的会话的信息,包括要使用的编解码器,这是音频还是视频会话等
- 还包含 ICE candidates,它们包含B应用程序尝试连接A应用程序需要用到的A的IP和port信息
b) A的应用程序向STUN服务器发出建立ICE候选者列表请求
- A的应用程序收集ICE候选
- 服务器返回发起请求的公共IP地址和端口对。A的应用程序将每对添加到ICE候选列表中
c) A的应用程序向STUN服务器发出建立ICE candidates请求
- A的应用程序收集ICE candidates
- 服务器返回发起请求A的公网 IP地址和端口对。A的应用程序将每对IP及端口 添加到 ICE candidates中
d) A的应用程序通过信令通道将SDP传递给B的应用程序
- WebRTC标准未指定用于此交换的传输协议。它可以通过HTTPS,安全WebSocket或任何其他通信协议执行
- 在此,B收到A的公网地址及端口
e) B的应用程序生成一个SDP Answer并发给A
- B的应用程序遵循上一步中A使用的步骤:收集ICE candidates等。然后B的应用程序需要将此SDP Answer通过信令服务器返回给A的应用程序
- 在此,A收到B的公网地址及端口
f) A和B执行一系列连接检查
- 每个应用程序中的ICE算法都从对方SDP中收到的列表中获取ICE candidates IP /端口对,并向其发送STUN请求
- 果另一个应用程序返回了响应,则原始应用程序认为检查成功,并将该IP /端口对标记为有效的ICE候选者
g) 开始数据传输
- 如果任何一个应用程序都找不到通过连通性检查的IP /端口对,它们将向TURN服务器发出STUN请求以获取媒体中继地址
- 中继地址是一个公共IP地址和端口,用于转发与应用程序之间接收到的数据包并设置中继地址。然后将该中继地址添加到候选列表,并通过信令通道进行交换
作用分类
a) 传输音视频数据相关协议:UDP、DTLS、RTP/SRTCP
b) 传输自定义应用数据相关协议:UDP、DTLS、SCTP
UDP、DTLS(加密信道建立)
a) DTLS是UDP协议的加密协议
RTP/SRTP、RTCP/SRTCP(音视频数据传输)
a) RTP(Realtime Transport Protocol):实时传输协议,主要用来传输对实时性要求比较高的数据,比如音视频数据
b) RTCP(RTP Trasport Control Protocol):RTP传输控制协议,主要用来监控数据传输的质量,并给予数据发送方反馈,比如监控传输的质量,并在会话双方之间进行同步,方便WebRTC根据传输质量进行动态调整,比如传输的速率、视频的码率等
c) SRTP:RTP包的加密
d) 音视频数据的发送过程:
- 通信双方:通过DTLS握手,协商生成一对密钥
- 数据发送方:将音视频数据封装成RTP包,将控制数据封装成RTCP包
- 数据发送方:利用加密密钥,对RTP包、RTCP包进行加密,生成SRTP包、SRTCP包
- 数据发送方:通过UDP传输SRTP包、SRTCP包
- 通信双方:通过DTLS握手,协商生成一对密钥
- 数据发送方:将自定义应用数据,通过密钥进行加密,生成SCTP包
- 数据发送方:通过UDP传输SCTP包
webRtc使用rtp来传输数据,使用rtcp传输控制指令
DTLS-SRTP
a) 是DTLS的一个扩展,将SRTP加解密与DTLS的key交换和会话管理相结合
b) 接收端使用 DTLS-SRTP;自DTLS下层的传输层收到报文之后,需要根据包头特征手动区分做demultiplexing,一般可以如下进行
检查第一个报文的第一个字节
- 是[0, 1]时,表示可能是STUN报文
- 是[128, 191]时,表示可能时RTP(SRTP)报文
- 是[20, 63]时,表示可能是DTLS record layer报文
1.发送端通过发送SR包告诉接收端发送端的信息,SR包分为三部分:头部header,发送者信息senderInfo和反馈块ReportBlock。
2.如果发送端也作为接收端,那么才会存在ReportBlock,当存在多个码流的时候就会反馈多个ReportBlock。
3.SR包的负载类型是200
4.详见:https://blog.csdn.net/momo0853/article/details/88051312
c) RR(Receiver Report RTCP Packet)
1.接收端通过RR包反馈接收端的接收情况,RR包分为两个部分:头部header和反馈块ReportBlock。
2.参考SR包,RR包的负载类型是201
3.结构如下:
4.其包含信息有:
(1).reporter ssrc:rr报告发送者的ssrc,也就是rtp报文接受者自己的ssrc.
(2).reportee ssrc:rr报告接受者的ssrc,也就是rtp报文发送者的ssrc.
(3).cumulative number of packet lost:累积报文丢失总数,该字段是一个24-bits的有符号整数
(4).Loss fraction:丢包率
(5).LSR:最新接收到SR报文的时间戳,具体值是,SR报文里64位NTP时间戳中的32位bit的时间戳。如果没有收到SR报文,该字段为0
(6).DLSR:接收到SR报文的时刻与发送该RR报文时刻的时间差值
(7).RTT:发送者计算的发送来回时间,发送者可以通过RR报文中的LSR和DLSR来计算RTT
格式为 m=<媒体类型> <端口号> <传输协议> <媒体格式 >
媒体类型:audio,表示这是一个音频流
端口号:9832,表示UDP发送的目的端口为9832
传输协议:RTP/AVP,表示RTP OVER UDP,通过UDP发送RTP包
媒体格式:表示负载类型(payload type),一般使用97表示AAC
格式为a=rtpmap:<媒体格式><编码格式>/<时钟频率> /[channel]
mpeg4-generic表示编码,44100表示时钟频率,2表示双通道
a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
a) profile-level-id=42001f
Profile: 66(hex: 42)
Level: 3.1(hex:1f)转成十进制,再除以10
b) packetization-mode=1,表示I帧会拆分成多个rtp包发送,对于264来说,rtp payload的第一个字节(0x7C)的低5bit为(11100),十进制为28,
代表此nalutype为FU-A,多包封装类型
a) FEC在发送端将数据包添加冗余纠错码,纠错码连同数据包一起发送到接收端;接收端根据纠错码对数据进行检查和纠正
b) NACK则在接收端检测到数据丢包后,发送NACK报文到发送端;发送端根据NACK报文中的序列号,在发送缓冲区找到对应的数据包,重新发送到接收端。NACK需要发送端发送缓冲区的支持
a) NACK是RTP层的反馈参数,在本端收集Codec属性时被一起收集,在SDP协商过程中,NACK属性被加到offer/answer中.
b) 接收端接收到offer后,跟随的NACK信息最终体现到jitterbuffer中,
c) NACK功能在SDP消息中的体现:a=rtcp-fb:125 nack(RTP报文丢失重传)
d) webRtc支持的其他丢包处理方法:a=rtcp-fb:104 nack pli(关键帧重传,当连续出现解码失败,或者长期没有解码输入,就通过RTCP报文发送请求IDR帧命令);
a=rtcp-fb:100 ccm fir(支持使用rtcp反馈机制来实现编码控制);
a=rtcp-fb:100 goog-remb(支持使用rtcp包来控制发送方的码流,goog-remb为google的拥塞控制处理算法)
e) 在webrtc中,重传包和正常包ssrc是不同的,两个ssrc可在SDP中体现,如:a=ssrc-group:FID 3463951252 1461041037(3463951252为正常的ssrc,后者为重传包的ssrc)
a) NACK报文类型为205,是RTCP的扩展反馈报文(详见:RFC4585)
b) PT=205,FMT=1,Packet identifier(PID)即为丢失RTP数据包的序列号,Bitmao of Lost Packets(BLP)指示从PID开始接下来16个RTP数据包的丢失情况。一个NACK报文可以携带多个RTP序列号,NACK接收端对这些序列号逐个处理
c) NACK报文构造完成以后,发送到网络层。NACK报文是RTCP报文的一种,因此其发送、接收和分析遵循RTCP报文处理的一般流程
a) 接收端收到NACK报文后调用resendPacketOnNack()进行RTP数据包重发
主动丢帧情况
a) 帧不完整(该帧数据有丢失)
b) 该帧参考帧缺失(GOP中I帧或其他P帧丢失)
c) 报文不连续
RTX重传
a) RTX:发送端在新的SSRC上发送重传包或者冗余包
b) NACK、RTX是WebRTC里丢包重传策略,两个策略之间有一定的联系
c) 两者均需要通过sdp协商开启
d) 在发送端收到NACK后,要重发接收端丢掉的包,发送的模式有两种
1.RTX模式:在接收端通过SDP使能发送端的RTX以后,重发的包封装到RTX包里发送,RTX包与原RTP有不同的SSRC,这样有助于避免SRTP的重放攻击,也能让接收端更好的估算带宽
2.普通模式:在没有使能RTX时,发送端只是简单的重发原来的RTP包,这种模式会影响接收端的RTCP统计,比如会出现负的丢包率
a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f
profile-level-id=42001f
Profile: 66(hex: 42)
Level: 3.1(hex:1f)转成十进制,再除以10
packetization-mode=1,表示I帧会拆分成多个rtp包发送,对于264来说,rtp payload的第一个字节(0x7C)的低5bit为(11100),十进制为28,
代表此nalutype为FU-A,多包封装类型
<type>=<value>
其中:
:大小写敏感的一个字符,代表特定的属性,比如v代表版本
:结构化文本,格式与属性类型有关,UTF8编码
= :两边不允许存在空格
=* :表示是可选的
o=<username> <sess-id> <sess-version> <nettype> <addrtype> <unicast-address>
各字段含义如下:
o=- 1552284039 2 IN IP4 127.0.0.1
格式如下:
c=<nettype> <addrtype> <connection-address>
每个SDP至少需要包含一个会话级别的c=字段,或者在每个媒体描述后面各包含一个c=字段
a) SDP可能同时包含多个媒体描述,格式如下:
m=<media> <port> <proto> <fmt> ...
其中:
- UDP:传输层协议是UDP
- RTP/AVP:针对视频、音频的RTP协议,跑在UDP之上
- RTP/SAVP:针对视频、音频的SRTP协议,跑在UDP之上
如:
m=video 9 UDP/TLS/RTP/SAVPF 122 102 100 101 124 120 123 119
表示:媒体类型是视频,以SRTP传输流媒体数据,RTP包的类型默认是122,可能是102、100…
b) 对于 RTP/SAVP,需要注意的是,payload type 又分静态和动态两种类型,
其中动态类型在a=fmtp:
字段里进行定义.
如:
m=audio 9 UDP/TLS/RTP/SAVPF 111
a=rtpmap:111 opus/48000/2
a=fmtp:111 minptime=10;useinbandfec=1
m=video 9 UDP/TLS/RTP/SAVPF 125
a=rtpmap:125 H264/90000
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
以上示例表示:
a=
字段表示该属性是会话级别的m=
字段后面可以跟任意数量的a=
字段来对媒体描述进行扩展b) 附加属性有两种格式
a=<attribute>
a=<attribute>:<value>
举例:
a=group:BUNDLE 0 1 2
a=msid-semantic: WMS myKvsVideoStream //出现在地一个媒体字段前,表示为会话属性
m=audio 9 UDP/TLS/RTP/SAVPF 111
a=msid:myKvsVideoStream myAudioTrack //在audio描述之后,表示为媒体属性
a=ssrc:1624028672 cname:y+nHd0EHIUVB/bhE
声明会话的开始、结束时间,格式如下:
t=<start-time> <stop-time>
如果是0,表示会话没有结束的边界,但是需要在之后会话才是活跃(active)的。如果是0,表示会话是永久的
v=0
o=- 1552284039 2 IN IP4 127.0.0.1
s=-
t=0 0
/* 音视频传输使用多路复用,用同一个RTP通道进行传输 */
a=group:BUNDLE 0 1 2
/* WMS是WebRTC Media Stram的缩写,这里给Media Stream定义了一个唯一的标识符。一个Media Stream可以有多个track(video track、audio track),这些track就是通过这个唯一标识符关联起来的,具体见下面的媒体行(m=)以及它对应的附加属性(a=ssrc:) */
a=msid-semantic: WMS myKvsVideoStream
/* 本次会话包含音频,端口为9,使用UDP传输RTP的加密包,并使用SRTCP反馈机制来提高传输质量 */
m=audio 9 UDP/TLS/RTP/SAVPF 111
c=IN IP4 127.0.0.1
/* 媒体流id和audio track id */
a=msid:myKvsVideoStream myAudioTrack
/* ssrc用来对媒体进行描述,格式为a=ssrc:<ssrc-id> <attribute>:<value> */
/* cname用来唯一标识媒体的数据源,一个cname可以对应多个ssrc */
/* a=ssrc-group:FID 790880351 2784909276,开启rtx机制会产生两个ssrc,前者是正常发送包的ssrc,后者是重发包的ssrc */
a=ssrc:1624028672 cname:y+nHd0EHIUVB/bhE
a=ssrc:1624028672 msid:myKvsVideoStream myAudioTrack
a=ssrc:1624028672 mslabel:myKvsVideoStream
a=ssrc:1624028672 label:myAudioTrack
/* RTCP采用的端口、IP地址 */
a=rtcp:9 IN IP4 0.0.0.0
/* ICE协商用到的认证信息 */
a=ice-ufrag:KfFz
a=ice-pwd:gHFDvX6WFLF3fItsoHnQouiB
/* 支持trickle,即sdp里面只描述媒体信息, 不会包含ice候选项的信息,
如果candidate信息包含在SDP中,会以ice-candidate属性的形式添加 */
a=ice-options:trickle
/* DTLS协商过程的指纹信息 */
a=fingerprint:sha-256 14:84:C6:68:91:EA:52:10:C0:3C:D9:2F:FA:6E:F7:80:B5:21:A5:4E:49:42:65:86:1C:13:98:85:32:0E:C0:D5
/* 当前客户端在DTLS协商过程中,既可以作为客户端,也可以作为服务端 */
a=setup:actpass
/* 当前媒体行的标识符(在a=group:BUNDLE 0 1 这行里面用到,这里0表示audio),mid是身份标识 */
a=mid:0
/* 音频通道既可以用于发送,也可以用于接收 */
a=sendrecv
/* 启用多路复用,RTP、RTCP共用同个通道 */
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:111 opus/48000/2
/* minptime表示最小打包时长为(ms),useinbandfec表示使用opus编码器内置的fec功能,在此还可以添加最大传输比特率、最大采样率等属性 */
a=fmtp:111 minptime=10;useinbandfec=1
/* 基于RTCP的反馈控制机制(NACK) */
a=rtcp-fb:111 nack
m=video 9 UDP/TLS/RTP/SAVPF 125
c=IN IP4 127.0.0.1
a=msid:myKvsVideoStream myVideoTrack
a=ssrc:1726440517 cname:y+nHd0EHIUVB/bhE
a=ssrc:1726440517 msid:myKvsVideoStream myVideoTrack
a=ssrc:1726440517 mslabel:myKvsVideoStream
a=ssrc:1726440517 label:myVideoTrack
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:KfFz
a=ice-pwd:gHFDvX6WFLF3fItsoHnQouiB
a=ice-options:trickle
a=fingerprint:sha-256 14:84:C6:68:91:EA:52:10:C0:3C:D9:2F:FA:6E:F7:80:B5:21:A5:4E:49:42:65:86:1C:13:98:85:32:0E:C0:D5
a=setup:actpass
a=mid:1
a=sendrecv
a=rtcp-mux
a=rtcp-rsize
a=rtpmap:125 H264/90000
/* h264格式的fmtp描述:
a) profile-level-id:
Profile: 66(hex: 42)
Level: 3.1(hex:1f)转成十进制,再除以10
b) packetization-mode=1:
表示I帧会拆分成多个rtp包发送,对于264来说,rtp payload的第一个字节(0x7C)的低5bit为(11100),
十进制为28,代表此nalutype为FU-A,多包封装类型
*/
a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtcp-fb:125 nack
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 127.0.0.1
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:KfFz
a=ice-pwd:gHFDvX6WFLF3fItsoHnQouiB
a=fingerprint:sha-256 14:84:C6:68:91:EA:52:10:C0:3C:D9:2F:FA:6E:F7:80:B5:21:A5:4E:49:42:65:86:1C:13:98:85:32:0E:C0:D5
a=setup:actpass
a=mid:2
a=sctp-port:5000
{"candidate":"candidate:0 1 udp 16777215 52.27.201.74 49642 typ relay raddr 0.0.0.0 rport 0 generation 0 network-cost 999","sdpMid":"0","sdpMLineIndex":0}
其中:foundation为0;
component id为1,表示媒体采用RTP协议;
transport为UDP;
priority为16777215;
公网映射地址为52.27.201.74:49642;
type为relay;
base为0.0.0.0:0;
sdpMid字段同SDP中a=mid:0属性,指定了与候选对象关联的媒体组件的媒体流标识标记;
sdpMLineIndex表示SDP中m行的索引,从0开始,用于描述与候选对象关联的媒体.