webrtc拉流抓包分析
1、整个webrtc交互一般需要 信令服务,ICE(stun+turn)中继打洞服务;以及两个端测;
1.1打洞服务:
Coturn 的核心功能 STUN(Session Traversal Utilities for NAT):提供客户端检测自己的公共 IP 地址和端口。 TURN(Traversal Using Relays around NAT):中继流量,当点对点连接不可用时,Coturn 会接管通信。 负载均衡:支持与多服务器集群配合,实现高并发处理。 认证机制:支持多种身份验证方式(如 long-term credentials)。 日志和监控:提供详细的日志和流量统计。
1.2 信令服务,交换两个peer的offer和answer

整体拓扑如下:

以前的信令交互,以SDP进行交互,走HTTP;后边随着新标准的丰富,增加了基于whep,whip的协议交互;
2、现实情况,没有额外的服务器,就只有两个端测程序,以及传输的网络;下边以简单的webrtc(无whep,whip协议的交互)抓包进行分析
2.1信令交互直接peer对peer(以ZLMediakit转包分析)
使用SDP协议传输,SDP并非传输协议,是文本描述协议,只是规定内容的格式,使用的字段和前缀含义等;
下图抓包,peerA【1.3.22.185】(客户端,拉流端)发送一个HTTP播放请求给peerB【1.11.22.205】(服务端,另一个客户端,被拉流的数据源端),携带offer;这是一个直接发送给对端的Http 请求;
POST /index/api/webrtc?app=live&stream=c1354&type=play HTTP/1.1
Host: 1.11.22.205:580 //js网页部署在peerB端
Connection: keep-alive
Content-Length: 5631
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: application/json, text/plain, */*
Content-Type: text/plain;charset=UTF-8
Origin: http://1.11.22.205:580
Referer: http://1.11.22.205:580/webrtc/index.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: Version-Token={%22version%22:%225.3.28904.TC%22}; License-Token={%22input%22:2000%2C%22output%22:1000%2C%22aiCompressOutput%22:0%2C%22aiAnalyzeOutput%22:0%2C%22startTime%22:%222024-08-22%22%2C%22endTime%22:%222124-12-23%22%2C%22effect%22:true%2C%22uuid%22:%227784ac6fc02c1c5ce84decab9967752d%22%2C%22uuids%22:[%227784ac6fc02c1c5ce84decab9967752d%22]%2C%22isBGRestore%22:false%2C%22enableRecordDelete%22:false%2C%22enableAIPC%22:false%2C%22recordKeepTime%22:7}
//下边的就是offer信息
v=0
o=- 6938902533582319796 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
a=extmap-allow-mixed
a=msid-semantic: WMS
m=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 35 36 37 38 102 103 104 105 106 107 108 109 127 125 39 40 41 42 43 44 45 46 47 48 112 113 114 115 116 117 118 49
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:OlVl //使用ICE进行穿透,ICE用户名
a=ice-pwd:mE1TRluhS+XLym18o/0TbdVp //ICE密码
a=ice-options:trickle
a=fingerprint:sha-256 53:FA:DC:D9:05:BB:4F:32:46:A3:34:5B:E4:31:40:72:E9:87:4E:67:31:EB:F2:4D:05:D9:BD:75:40:44:54:7B
a=setup:actpass //希望对方主动发起连接
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:toffset
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 urn:3gpp:video-orientation
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 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:9 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 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:35 VP9/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=fmtp:35 profile-id=1
a=rtpmap:36 rtx/90000
a=fmtp:36 apt=35
a=rtpmap:37 VP9/90000
a=rtcp-fb:37 goog-remb
a=rtcp-fb:37 transport-cc
a=rtcp-fb:37 ccm fir
a=rtcp-fb:37 nack
a=rtcp-fb:37 nack pli
a=fmtp:37 profile-id=3
a=rtpmap:38 rtx/90000
a=fmtp:38 apt=37
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:103 rtx/90000
a=fmtp:103 apt=102
a=rtpmap:104 H264/90000
a=rtcp-fb:104 goog-remb
a=rtcp-fb:104 transport-cc
a=rtcp-fb:104 ccm fir
a=rtcp-fb:104 nack
a=rtcp-fb:104 nack pli
a=fmtp:104 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f
a=rtpmap:105 rtx/90000
a=fmtp:105 apt=104
a=rtpmap:106 H264/90000
a=rtcp-fb:106 goog-remb
a=rtcp-fb:106 transport-cc
a=rtcp-fb:106 ccm fir
a=rtcp-fb:106 nack
a=rtcp-fb:106 nack pli
a=fmtp:106 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f
a=rtpmap:107 rtx/90000
a=fmtp:107 apt=106
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: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=1;profile-level-id=4d001f
a=rtpmap:125 rtx/90000
a=fmtp:125 apt=127
a=rtpmap:39 H264/90000
a=rtcp-fb:39 goog-remb
a=rtcp-fb:39 transport-cc
a=rtcp-fb:39 ccm fir
a=rtcp-fb:39 nack
a=rtcp-fb:39 nack pli
a=fmtp:39 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d001f
a=rtpmap:40 rtx/90000
a=fmtp:40 apt=39
a=rtpmap:41 H264/90000
a=rtcp-fb:41 goog-remb
a=rtcp-fb:41 transport-cc
a=rtcp-fb:41 ccm fir
a=rtcp-fb:41 nack
a=rtcp-fb:41 nack pli
a=fmtp:41 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=f4001f
a=rtpmap:42 rtx/90000
a=fmtp:42 apt=41
a=rtpmap:43 H264/90000
a=rtcp-fb:43 goog-remb
a=rtcp-fb:43 transport-cc
a=rtcp-fb:43 ccm fir
a=rtcp-fb:43 nack
a=rtcp-fb:43 nack pli
a=fmtp:43 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=f4001f
a=rtpmap:44 rtx/90000
a=fmtp:44 apt=43
a=rtpmap:45 AV1/90000
a=rtcp-fb:45 goog-remb
a=rtcp-fb:45 transport-cc
a=rtcp-fb:45 ccm fir
a=rtcp-fb:45 nack
a=rtcp-fb:45 nack pli
a=fmtp:45 level-idx=5;profile=0;tier=0
a=rtpmap:46 rtx/90000
a=fmtp:46 apt=45
a=rtpmap:47 AV1/90000
a=rtcp-fb:47 goog-remb
a=rtcp-fb:47 transport-cc
a=rtcp-fb:47 ccm fir
a=rtcp-fb:47 nack
a=rtcp-fb:47 nack pli
a=fmtp:47 level-idx=5;profile=1;tier=0
a=rtpmap:48 rtx/90000
a=fmtp:48 apt=47
a=rtpmap:112 H264/90000
a=rtcp-fb:112 goog-remb
a=rtcp-fb:112 transport-cc
a=rtcp-fb:112 ccm fir
a=rtcp-fb:112 nack
a=rtcp-fb:112 nack pli
a=fmtp:112 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f
a=rtpmap:113 rtx/90000
a=fmtp:113 apt=112
a=rtpmap:114 H264/90000
a=rtcp-fb:114 goog-remb
a=rtcp-fb:114 transport-cc
a=rtcp-fb:114 ccm fir
a=rtcp-fb:114 nack
a=rtcp-fb:114 nack pli
a=fmtp:114 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=64001f
a=rtpmap:115 rtx/90000
a=fmtp:115 apt=114
a=rtpmap:116 red/90000
a=rtpmap:117 rtx/90000
a=fmtp:117 apt=116
a=rtpmap:118 ulpfec/90000
a=rtpmap:49 flexfec-03/90000
a=rtcp-fb:49 goog-remb
a=rtcp-fb:49 transport-cc
a=fmtp:49 repair-window=10000000
//---------------------------------------------------------------------------------------------------------------------
这个SDP的生成是js里边做的;手机本地的网页信息等;
源码中包含创建peerconnection,以及ICEservice的逻辑;这里对js不太了解,后续学习后补充
//----------------------------------------------------------------------------------------------------------------------
服务端回复:
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 1971
Content-Type: application/json
Date: Wed, Jan 15 2025 09:25:13 GMT
Keep-Alive: timeout=30, max=100
Server: Danghong Mediaserver
{
"code" : 0,
"id" : "zlm_25",
"sdp" : "v=0\r\no=- 6938902533582319796 2 IN IP4 10.11.22.205\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\n
a=msid-semantic: WMS\r\na=ice-lite\r\nm=video 8000 UDP/TLS/RTP/SAVPF 102 103\r\nc=IN IP4 10.11.22.205\r\n
a=rtcp:8000 IN IP4 10.11.22.205\r\na=ice-ufrag:zlm_25\r\n
a=ice-pwd:gzBCRSsApfdKD94vikcmSUSy\r\n
a=ice-options:trickle\r\n
a=fingerprint:sha-256 EE:5F:E6:F9:DA:FC:00:6F:90:BF:37:5A:9D:87:A8:58:80:32:F7:D7:1F:EE:09:A4:26:1C:29:89:76:EA:2C:C4\r\n
a=setup:passive\r\na=mid:0\r\na=ice-lite\r\na=extmap:1 urn:ietf:params:rtp-hdrext:toffset\r\n
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n
a=extmap:4 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\n
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\n
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\n
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\n
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\n
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\n
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=sendonly\r\n
a=rtcp-mux\r\na=rtpmap:102 H264/90000\r\na=rtcp-fb:102 ccm fir\r\na=rtcp-fb:102 goog-remb\r\n
a=rtcp-fb:102 nack\r\na=rtcp-fb:102 nack pli\r\na=rtcp-fb:102 transport-cc\r\n
a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\n
a=rtpmap:103 rtx/90000\r\na=fmtp:103 apt=102\r\na=msid:zlmediakit-mslabel zlmediakit-label-0\r\n
a=ssrc:1 cname:zlmediakit-rtp\r\na=ssrc:1 msid:zlmediakit-mslabel zlmediakit-label-0\r\n
a=ssrc:1 mslabel:zlmediakit-mslabel\r\na=ssrc:1 label:zlmediakit-label-0\r\n
a=ssrc:3 cname:zlmediakit-rtp\r\na=ssrc:3 msid:zlmediakit-mslabel zlmediakit-label-0\r\n
a=ssrc:3 mslabel:zlmediakit-mslabel\r\na=ssrc:3 label:zlmediakit-label-0\r\na=ssrc-group:FID 1 3\r\n
a=candidate:udpcandidate 1 udp 120 10.11.22.205 8000 typ host\r\n",
"type" : "answer"
}
播放端向数据源端发送绑定请求:走UDP协议;


数据源端向播放端回复绑定请求:


然后进行DTLS握手:

数据源端回复握手请求:并进行认证请求:



客户端(播放端)对数据源端的认证请求,响应校验信息


完成秘钥协商

完成上述协商后,进行UDP数据传输;RTP(ES)

浙公网安备 33010602011771号