Contents

WebRTC 问题排查

场景:H.264 预览无画面

搭建管线时没有显式指定 PT,导致协商和实际传输的 Payload Type 不一致。

示例(未指定 PT):

1
2
3
4
5
6
pt=103  # 期望 Payload Type 为 103

gst-launch-1.0 v4l2src device=/dev/video0 ! \
  capsfilter caps="video/x-h264,width=1920,height=1080,framerate=30/1" ! \
  rtph264pay ssrc=12345 pt=103 ! \
  webrtcbin name=webrtcbin

RTP 关键字段回顾

RTP(Real-time Transport Protocol)中:

  • SSRC(Synchronization Source Identifier):32 位随机数,用于唯一标识一个 RTP 流的发送源。
  • PT(Payload Type):8 位字段,表示 RTP 负载的媒体类型(如 H.264、Opus、PCMU)。

检查 SDP 协商结果

先打印两端视频媒体协商数据:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
远端SDP: v=0
o=- 8059321933707877926 2 IN IP4 127.0.0.1
s=-
t=0 0
m=video 9 UDP/TLS/RTP/SAVPF 103
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:yC1VGDMoil9yU82FQZr0FXtdQOFJzzMC
a=ice-pwd:4rnQgDvfbwZFjVeuffmL3luCeqtDqa/t
a=fingerprint:sha-256 3D:70:BB:54:C4:CD:85:D3:73:3F:51:47:E0:5F:BE:EA:4F:8E:FD:C7:E9:F7:5F:FC:14:10:A1:AE:8A:2F:10:53
a=setup:active
a=mid:0
a=sendonly
a=rtcp-mux
a=rtpmap:103 H264/90000
a=rtcp-fb:103 nack pli
a=rtcp-fb:103 ccm fir
a=rtcp-fb:103 transport-cc
a=fmtp:103 level-asymmetry-allowed=1;packetization-mode=1

可以看到:SDP 中约定的视频流 PT=103(H.264)

抓包分析实际 RTP 数据

抓包后的 Wireshark 截图:

./问题排查.assets/image-20250428150025046.png

可以看到 Payload Type 实际为:

1
Payload type: DynamicRTP-Type-96 (96)

结论:协商和实际传输不一致

  • SDP 协商:PT=103(H.264)
  • 实际 RTP:PT=96(H.264)

客户端按 PT=103 去解码,实际上收到的是 PT=96,导致解码失败、无画面

RTSP/SDP 中与播放相关的关键字段

RTSP/SDP 协议中影响 WebRTC 播放的核心字段包括:

  • 媒体声明m=video
  • 编码参数a=rtpmapa=fmtp
  • 控制路径a=control
  • SSRC/PT 绑定a=ssrc
  • 传输扩展a=rtcp-fb
  • 安全配置a=fingerprint

示例:

1
2
3
4
5
m=video 554 RTP/AVP 96
...
a=rtpmap:96 H264/90000
...
a=control:trackID=1

要点:

  • m=video:声明媒体类型为视频,WebRTC 端需支持对应解码器(如 H.264 / VP8)。若声明为 m=audio,WebRTC 会按音频处理,导致静音且无画面。
  • H264/90000:PT=96 对应 H.264 编码,时钟频率 90000Hz。
  • profile-level-id / packetization-mode:若与接收端预期不符,可能导致 RTP 包解析错误。
  • trackID=1:RTSP PLAY 请求 URI(如 rtsp://example.com/trackID=1);控制路径错误会导致卡在“连接中”状态。

问题解决:统一 PT 配置

在 GStreamer 管线中显式指定与 SDP 相同的 PT:

1
2
3
4
5
6
7
8
9
# 未显式指定 PT 的版本
PIPE_DESC_INSTA360_H264_1920_1080_30='v4l2src device=/dev/video0 ! \
  capsfilter name=capsfilter caps="video/x-h264,width=1920,height=1080,framerate=30/1" ! \
  rtph264pay name=rtph264pay ! webrtcbin name=webrtcbin'

# 修正后:rtph264pay 指定 pt=103(与 SDP 一致)
PIPE_DESC_INSTA360_H264_1920_1080_30='v4l2src device=/dev/video0 ! \
  capsfilter name=capsfilter caps="video/x-h264,width=1920,height=1080,framerate=30/1" ! \
  rtph264pay name=rtph264pay pt=103 ! webrtcbin name=webrtcbin'

修改后 Payload Type 与 SDP 协商值一致,视频即可正常播放:

./问题排查.assets/image-20250428151358861.png

参考