☰
RTP协议深度解析:从RTSP到WebRTC的抓包与排障实战
2026/10/21 15:15:25 网站建设 项目流程

干流媒体这行,最绕不开的就是RTP。我第一次系统啃完RTP协议(Real-time Transport Protocol),是在排查一路RTSP拉流画面卡顿的时候。满屏Wireshark过滤器和十六进制报文,sequence number乱跳、时间戳对不上时钟,翻协议文档翻了半天才看明白门道。后来又把WebRTC链路的RTP过了一遍,这才发现同一个协议在RTSP里和WebRTC里完全是两副面孔:一个是老实巴交的媒体搬运工,另一个是加密、扩展头、重传、冗余全武装的现代形态。

这篇文章把我折腾RTP协议过程中理解到的东西完整写下来,会从协议本身的设计初衷讲到RTSP、WebRTC两个实际场景里的数据形态,再用抓包实例把字段逐一看清楚,最后是实践中攒下来的排障经验。适合刚开始接触流媒体、被RTP/RTCP/SRTP这些名词搞混的新人,也适合已经在用RTSP或者WebRTC、但想系统补一遍协议细节的从业者。

1. RTP的定位与角色:为什么RTSP和WebRTC都离不开它

1.1 一个协议,解决实时传输的三个核心问题

RTP在RFC 3550中的定义是“实时应用的传输协议”,注意这个措辞——它是为了实时应用设计的传输协议,但它本身并不保证可靠性。它要解决的是实时媒体传输里的三个核心问题:

第一个是乱序。IP网络里数据包走不同路径到达,先发的包可能后到。视频编码数据一旦顺序错了,解码器直接罢工。RTP给每个包编一个序号,接收端按序号重排就能拿到原始顺序。

第二个是时间关系。音频采样的时间间隔,视频帧率的节奏,这些是媒体数据的内在时间属性。TCP传文件无所谓时间,但播放必须按采样的时间节奏来。RTP用时间戳字段把这个节奏记录了下来。

第三个是来源标识。一个网络通话里可能有多个参与者、多路媒体流,得让接收端分清“这个包是哪路流的”。RTP的SSRC字段就是流的身份证。

这三个需求,恰恰是UDP不提供、TCP又不适合的。TCP保证可靠和有序,但代价是重传造成的延迟不可控,实时音视频等不起这种不确定的阻塞。裸UDP速度够快,但丢包、乱序、无时间标识,应用层啥都要自己干。RTP正好站在中间:基于UDP传输,自己补上序号、时间戳、同步源标识这些元信息。

1.2 RTSP和WebRTC里RTP的不同“待遇”

把RTP放进RTSP和WebRTC两个链路里看,它的角色定位差异非常大。

在RTSP体系里,RTSP本身只负责会话控制——DESCRIBE拿媒体描述、SETUP建立传输通道、PLAY控制播放,相当于流媒体的“遥控器”。真正搬运音视频数据的,是RTP。这里的RTP形态相对“原生态”:能走UDP就走UDP,偶尔为了穿防火墙走TCP内嵌封装。负载通常是H.264、AAC、G.711这些标准编码数据,封包规则由各自的RTP payload格式规范定义。

在WebRTC里,RTP依然是媒体传输的绝对主力,但被裹上了一层又一层的“装备”:

  • 每个RTP包必须经过SRTP加密,防止窃听和篡改;
  • 头部可以带扩展字段,用于传输绝对时间、音频电平、媒体流ID等信息;
  • 丢包时会有专门的RTX重传包,携带原始包的序号;
  • 弱网下还有RED冗余编码和FEC前向纠错,用额外数据抵抗丢包。

可以说,RTSP场景里你看到的是RTP的“出厂设置”,WebRTC场景里是RTP的“全副武装形态”。理解了这一点,后面抓包分析时看到同一字段在不同场景下的表现差异,就不会懵。

1.3 RTP和RTCP:媒体面的“数据流”和控制面的“反馈流”

RTP从来不是单独使用的,它的老搭档是RTCP(RTP Control Protocol)。二者在同一个会话中并行工作,通常RTP走偶数端口,RTCP走相邻的奇数端口。

  • RTP负责传送媒体数据本身,是“数据面”;
  • RTCP负责周期性地交换统计信息,是“控制面”。

RTCP的报文类型主要有:

  • SR(Sender Report):发送端报告。包含发送者累计发了多少包、多少字节,更重要的是记录了一个NTP时间和RTP时间戳的映射关系,这是播放器做音画同步的关键依据;
  • RR(Receiver Report):接收端报告。包含丢包数、累计丢包率、抖动估计、往返时延等信息;
  • SDES:源描述,主要携带CNAME等标识信息;
  • BYE:会话结束通知。

RTCP的发送频率有讲究,RFC 3550建议RTCP带宽不超过会话带宽的5%,这样统计数据本身不会反噬媒体传输。接收端根据RR报文的往返时延计算,就能反推网络质量,进而调整码率或者触发重传。

表面上看,RTCP似乎是“附带品”,但在排障时它比RTP本身还重要——很多丢包、抖动、音画不同步的问题,都是先从RTCP的统计里看出端倪的。

2. RTP包结构:从每包固定的12字节说起

2.1 头部结构逐字节拆解

RTP包的固定头部是12字节。抓包的时候,前12字节就是协议核心,每个字段都有具体含义。

以十六进制直观展示一段RTP头:

80 E0 20 15 10 C4 00 01 48 36 12 04

逐字段拆开看:

  • V(2bit):版本号,RTP目前固定为二进制10,也就是数字2。抓到版本不是2的包,基本可以判断为非法或者根本没有正确解析;
  • P(1bit):填充标志,置1时表示包尾有填充字节用于对齐,多用于加密场景。真正的填充长度由负载最后一个字节给出;
  • X(1bit):扩展标志,置1时在固定头之后紧跟着一个头部扩展段。WebRTC的RTP包经常会置这一位;
  • CC(4bit):CSRC计数,表示后面还有多少个CSRC标识符(每个32bit)。这在普通点对点场景下通常为0,只有多人混音时才大于0;
  • M(1bit):Marker标记位,具体语义由payload类型定义,比如H.264视频流中一帧的最后一个分片会置M;G.711语音流中可能用于标记讲话开始;
  • PT(7bit):负载类型,最重要的字段之一,告诉接收端“这个包里的数据是什么编码格式”。0是G.711 μ-law,8是G.711 A-law,96到127是动态类型,具体映射由SDP的a=rtpmap指定;
  • Sequence Number(16bit):包的序号,每发送一个RTP包就递增1,接收端据此判断丢包、乱序、重排;
  • Timestamp(32bit):时间戳,媒体采样时钟的累积值,音频通常等于采样率,视频常用90000Hz;
  • SSRC(32bit):同步源标识,随机生成但同一会话内固定,用于唯一标识一路媒体流。

这里注意,头部扩展、CSRC列表都不是每包必有的,但12字节固定头是底线。解析RTP时先算好这12字节,再根据X和CC位决定跳过多长的扩展和CSRC,才能找到真正的payload起始位置。这个偏移算错,后面所有解析全完。

2.2 序列号和时间戳:两个最容易踩坑的关键字段

先说序列号。它看似简单,每发一包加1,但坑在于它是16位的,范围0到65535,发到65535之后会回绕到0。实际传输中,如果只做“当前序号大于上一个序号”的判断,回绕瞬间会把正常的包误判为乱序,甚至触发大量重传。正确的做法是用有符号的16位模运算判断序列号偏移。

再说时间戳。RTP时间戳的单位不是毫秒,而是“时钟频率的倒数”。音频场景下,时间戳频率通常就是采样率:

  • G.711语音采样率8000Hz,20ms一帧,那么每帧的时间戳增量是8000 × 0.02 = 160;
  • Opus编码常见48kHz采样率,20ms一帧的增量是48000 × 0.02 = 960。

视频场景的时间戳频率,H.264、VP8、VP9这些几乎统一使用90000Hz。这个数字是MPEG时代定下来的标准,选它是因为90000可以被常见的帧率整除:

  • 30fps的帧间隔是90000 ÷ 30 = 3000个时间戳单位;
  • 25fps是90000 ÷ 25 = 3600个时间戳单位。

我用一个实际场景验证过这个逻辑:抓一段30fps的H.264视频流,同一SSRC的RTP时间戳依次递增3000,非常规律。如果中间出现异常跳跃,要么是编码器丢帧,要么是封装层做了静音帧填充,要么就是打包逻辑有bug——这个检查方法在排障里特别好用。

时间戳同样存在32位回绕问题。90000Hz下,32位时间戳大约13.25小时回绕一次。单看数值大小没意义,必须做模运算。

2.3 Payload Type与SDP的关联

PT字段是解码的第一把钥匙。静态PT值(0到95)由标准直接定义,比如:

  • 0:PCMU(G.711 μ-law,8kHz)
  • 3:GSM(13kbit/s语音)
  • 8:PCMA(G.711 A-law,8kHz)
  • 26:JPEG静态图像流
  • 31:H.261
  • 34:H.263

而96到127是动态PT区间。所谓“动态”,是说它没有全局固定含义,必须通过SDP协商后才知道。例如服务端可能把96对应为H.264,另一个服务端则可能把96对应为VP8。

所以实战中永远不要在代码里写死“PT=96就是H.264”,必须解析SDP的a=rtpmap行。我在排查黑屏问题时就遇到过:某类摄像头固件把H.264固定映射到PT 104,而播放器只盯着PT 96解析,结果什么都解不出来。

2.4 Marker位:关键帧和帧边界的信号

Marker位在不同负载格式里有不同的约定。最典型的是H.264的RTP封装(RFC 6184):

  • 当视频帧很大、被拆成多个RTP分片时,每个分片一个RTP包;
  • 一帧的最后一个分片会在RTP头里置M位为1;
  • 接收端看到M=1,就知道这一帧的payload收齐了,可以组装后送去解码。

对于G.711这种每包可能就是完整一帧的音频流,M位一般置0,没有实际意义。

排障中M位还有个用途:统计一帧被拆成了多少个RTP分片。如果H.264关键帧分片数异常多(比如上百片),往往说明编码器码率设置过高或者GOP配置不合理,网络一抖动整个画面就崩。

3. 在RTSP链路里观察RTP:从SDP到播放要盯住这几点

3.1 控制流与媒体流的两条通道

RTSP的标准端口是554,控制信令走TCP,负责OPTIONS、DESCRIBE、SETUP、PLAY、TEARDOWN这些命令。而媒体数据走RTP,有两种承载方式:

  • UDP承载:RTP/RTCP分别使用一对偶数/奇数端口,这是最常见的模式。客户端在SETUP请求中告诉服务器自己打算收流的RTP和RTCP端口,服务器回包时也会带上自己发送用的端口;
  • TCP内嵌承载:当客户端网络环境禁止UDP出站或者出现对称NAT问题时,RTP包会封装在RTSP的TCP连接里,这就是interleaved模式。

TCP内嵌模式下,RTP包会被加一个4字节封装头,格式为:

0x24('$') channel编号 长度高字节 长度低字节

channel编号是成对分配的,偶数对应RTP流,奇数对应对应RTCP流。举个例子,$ 00 05 DC表示channel 0、长度为1500字节的RTP包。

排查时需要注意:interleaved模式下,如果解析代码忘了跳过这4字节封装头,把整体的头部当成RTP头来解析,序号和PT绝对错乱。我在接手维护一个旧播放器时,就遇到国标码流的channel号并不总是从0开始,直接硬编码读取channel 0导致两路流串包的问题。

3.2 SDP就是RTP媒体的说明书

RTSP的DESCRIBE响应里,服务器会返回一份SDP文本,描述流里有哪些媒体、怎么解码、RTP参数怎么配。我举一个典型的SDP片段:

v=0 o=- 2890844526 2890844526 IN IP4 192.168.1.10 s=- c=IN IP4 192.168.1.10 t=0 0 m=video 5004 RTP/AVP 96 a=rtpmap:96 H264/90000 a=fmtp:96 profile-level-id=42C01F; packetization-mode=1

逐行看关键信息:

  • m=video 5004 RTP/AVP 96:媒体类型是视频,端口5004,传输配置RTP/AVP(即UDP承载的标准音频视频Profile),负载类型96;
  • a=rtpmap:96 H264/90000:PT 96对应H.264,时钟频率90000Hz;
  • a=fmtp:96 profile-level-id=42C01F; packetization-mode=1:H.264的具体参数,profile-level-id是编码档位标识,packetization-mode=1表示支持分片打包(FU-A)。

音频流则是另一种形态:

m=audio 5006 RTP/AVP 0 a=rtpmap:0 PCMU/8000

这里PT 0直接对应静态定义的PCMU,8000Hz。

SDP里容易忽略的是a=rtpmap中音频还有channel数,例如a=rtpmap:111 opus/48000/2中的/2表示双声道。解析时如果不处理channel数,时间戳和码率计算都会出错。

3.3 SETUP请求与Transport协商的坑

播放器通过SETUP请求把传输参数发给服务器,关键在Transport字段,例如:

Transport: RTP/AVP/UDP;unicast;client_port=5004-5005

表示客户端打算用UDP模式,RTP收在5004端口,RTCP收在5005端口。服务器的SETUP响应里会带上服务端的端口信息:

Transport: RTP/AVP/UDP;unicast;client_port=5004-5005;server_port=6004-6005

如果协商结果是TCP内嵌传输,Transport字段会变成:

Transport: RTP/AVP/TCP;interleaved=0-1

Transport字段与SDP的m=行必须一致。客户端若收到UDP的SETUP响应,说明协商成功,媒体流将从server_port对应端口发往client_port;若修改过防火墙或NAT规则,UDP入站被阻断,客户端一直收不到媒体包,但RTSP信令一切正常——这类“信令正常、媒体不通”的问题,排查重点就在Transport协商后的端口连通性上。

3.4 播放流程里RTP包的典型特征

一个完整的RTSP拉流流程是:

  1. OPTIONS:确认服务器支持哪些方法;
  2. DESCRIBE:拿到SDP,解析媒体参数;
  3. SETUP:协商传输通道和端口;
  4. PLAY:发送播放指令,服务器开始推送RTP;
  5. TEARDOWN:结束会话。

PLAY之后,接收端会看到同一SSRC的RTP包按时间戳节奏到达。H.264是关键帧(IDR)开头的话,首个包往往是较大体积的SPS/PPS数据或关键帧分片。之后按帧间隔规律排列。如果首屏迟迟不出,优先看SSRC和PT是否匹配SDP申明,再看关键帧分片是否完整——这两个是我在RTSP排障时命中率最高的原因。

4. 在WebRTC链路里观察RTP:全副武装的现代形态

4.1 WebRTC为什么也把宝押在RTP上

很多人疑惑:WebRTC追求极低时延,为什么不用更新的协议,而要继续用“老牌”RTP?

核心原因有两个:

第一,RTP的数据模型和实时音视频的需求高度吻合。它基于UDP,没有TCP那种队头阻塞;自带序号和时间戳,天然支持乱序重排、丢包检测、同步播放。这层能力WebRTC自身确实也需要。

第二,RTP的扩展性极强。头部扩展、动态PT、RTCP反馈机制这些设计,让WebRTC可以在“RTP框架”上叠加各种现代机制——SRTP加密、RTX重传、RED冗余、FEC纠错、带宽估计、拥塞控制反馈。与其说是WebRTC“选了RTP”,不如说RTP这个载体足够开放,能支撑WebRTC不断演进的实时传输需求。

如果完全裸用UDP,这些机制全要自己发明;直接上TCP,时延和队头阻塞就压不住。RTP是平衡后的最优解。

4.2 SRTP:默认强制加密,头字段仍是明文

WebRTC中的每个RTP包都必须用SRTP加密,它通过DTLS-SRTP完成密钥协商。SDP中的媒体行描述是:

m=video 9 UDP/TLS/RTP/SAVPF 96 97 98

这里的UDP/TLS/RTP/SAVPF完整缩写含义是:

  • UDP:底层传输是UDP;
  • TLS:传输层安全,用于DTLS握手;
  • RTP:承载的是RTP包;
  • SAVPF:Secure Audio/Video Profile with Feedback,表示带加密和反馈扩展的RTP Profile。

抓包看到WebRTC的RTP包,绝大多数负载区域是一坨密文,无法直接解码出视频数据。但注意,SRTP只加密RTP负载和部分扩展头,固定头部里的序列号、时间戳、SSRC仍是明文。所以哪怕加密了,依然可以用Wireshark做丢包率、乱序、时间戳连续性分析。记住这一点,即使抓的是WebRTC加密流量,排障手段也没断档。

4.3 RTP头部扩展、RTX重传、RED冗余、FEC

这四项是WebRTC里RTP最值得关注的“增强组件”。

RTP Header Extension:允许在RTP头后追加自定义的16字节对齐扩展。WebRTC通过SDP的a=extmap协商具体要带哪些扩展,常见的有:

  • urn:ietf:params:rtp-hdrext:sdes:mid:媒体流ID,用于区分音频、视频等不同通道;
  • http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time:发送端的绝对时间,用于带宽估计和延迟计算;
  • urn:ietf:params:rtp-hdrext:ssrc-audio-level:音频电平;
  • urn:ietf:params:rtp-hdrext:playout-delay:播放延迟控制。

排障时如果抓到一个带扩展头的WebRTC RTP包,先解析扩展头在说什么,往往能直接定位到“是不是abs-send-time异常导致带宽估计崩了”这类深层次问题。

RTX重传(RFC 4588):丢包后,发送端会把丢失的那个RTP包单独复制一遍重传回来,这个重传的包走独立的PT和SSRC,但通过扩展头OSN(Original Sequence Number)记录原包的序号。接收端看到RTX包后,把OSN映射回原包的序号,就能补上丢包空缺。SDP里通过a=rtx:声明原始PT和RTX PT的配对关系。

RED冗余(RFC 2198):主要用于音频。一个RTP负载里可以携带多个冗余音频帧,比如先发一帧Opus数据,再带上前一个20ms的副本。即便当前帧丢失,接收端还能用前一帧的冗余恢复出丢失部分,听感连续性好很多。这是WebRTC音频在弱网下不掉字的关键机制。

FEC前向纠错(RFC 5109等):用额外的校验数据包,让接收端能在丢包时直接从FEC包里恢复出原始数据,不需要等重传。代价是增加带宽冗余,适合丢包率较高但时延敏感的链路。

在我实际调WebRTC弱网体验时,最直观的经验是:本地上行丢包5%以内,RTX+FEC基本能把接收端QoE维持住;丢包超过10%并伴随抖动,冗余包策略再多,画面马赛克和音频断续也压不住,这时候优先考虑降分辨率、降码率,而不是一味堆重传。

5. 抓包实操:把RTP协议拆开看

5.1 抓包准备与过滤

调试RTP必备的工具是Wireshark。抓包前建议先用简单拓扑确认链路节点,比如在PC上跑RTSP拉流客户端,抓包接口选连接服务器的那个网卡,添加过滤条件:

rtp || rtcp

如果抓的是WebRTC流量,媒体层可能显示为_ws.malformed或SRTP,此时关键过滤条件改成:

rtp || rtcp || srtp

我习惯同时打开Statistics -> RTP -> RTP Streams,这个窗口能快速显示所有RTP流的SSRC、丢包数、抖动值,比一个个翻包高效得多。

5.2 一个实际RTP包的完整解读

截取一段典型的RTP包解析信息:

Real-Time Transport Protocol 10.. .... = Version: RFC 1889 (2) ..0. .... = Padding: False ...0 .... = Extension: False .... 0000 = Contributing source identifiers count: 0 0... .... = Marker: False Payload type: 96 (H264) Sequence number: 8213 Timestamp: 529900 SSRC: 0x2244e (14034)

对应16进制头大概是:

80 60 20 15 10 C4 00 01 48 36 12 04

逐字段核对:

  • 第一个字节0x80:二进制1000 0000,V=2、P=0、X=0、CC=0;
  • 第二个字节0x60:二进制0110 0000,M=0、PT=1100000即96;
  • 第三、四字节0x20 0x15:大端16位,0x2015 = 8213,即序列号;
  • 第五到第八字节0x10 0xC4 0x00 0x01:时间戳0x10C40001 = 529900;
  • 最后四字节0x48 0x36 0x12 0x04:SSRC 0x48361204。

如果负载是H.264关键帧分片,payload里第一个字节是FU-A头,第二个字节是原始NAL头加FU indicator,这些再加一层解析就能判断是不是关键帧起点。

5.3 时间戳与序列号联动判断问题

拿到一串RTP包后,最先做的工作就是画一条时间线:

  1. 按序列号重排,统计乱序数;
  2. 计算相邻包时间戳差ΔT;
  3. 根据ΔT与帧间隔是否吻合,判断丢帧或异常填充。

30fps H.264流,ΔT应为3000。G.711 20ms帧,ΔT应为160。如果统计出来ΔT在3000、6000、9000之间交替,说明中间有帧被编码器跳过了;如果同一帧的分片ΔT为0,那是分片的时间戳正常表现,不要误判。

Wireshark的Telephony -> RTP -> Stream Analysis会把每个RTP包的序号、时间戳、到达时间列成表,还能直接生成丢包分布图,是我最常用的“快速体检”工具。

5.4 用RTCP报告反推网络质量

媒体流跑起来后,RTCP包会自动出现。收到RR报文时,重点看三个值:

  • 丢包率:接收端统计的丢失包数占期望接收包数的比例;
  • 抖动:RTP时间戳到达间隔的平滑估计值;
  • 往返时延:根据LSR和DLSR字段计算。

计算公式是:

往返时延 = 当前NTP时间 - LSR - DLSR

其中LSR是RR包中指向前一个SR的NTP时间戳中间32位,DLSR是接收端从收到SR到发出RR之间的延迟。这个值能真实反映RTP链路的网络RTT,比ping测出的延迟更贴近媒体路径。

6. 常见故障与排查技巧

6.1 典型现象速查表

现象可能原因快速定位方法
画面黑屏、不出帧PT不匹配、SDP解析失败对比a=rtpmap申明和RTP包里的PT值
花屏、马赛克丢包导致分片不完整,且没有FEC/RTX恢复看RTP Streams里的丢包数,检查网络
音画不同步时间戳基准不一致看RTCP SR里的NTP与RTP时间戳映射关系
画面卡顿、跳帧RTP时间戳不连续统计相邻包ΔT是否符合帧间隔
WebRTC音频断续丢包但音视频RED冗余不够检查RTX和RED的SDP协商是否成功
通话质量整体下降带宽估计失效、abs-send-time异常看头部扩展里的abs-send-time序列
RTSP信令正常但收不到媒体UDP端口不通、NAT映射错误检查Transport协商的端口是否可达
RTSP TCP模式串包interleaved channel号解析错误核对$ channel length封装头

6.2 实践下来最容易踩的几个坑

第一个坑是动态PT写死。开发时本地测试某个编码PT是96,换了设备或固件后发现PT变成104,播放器就哑了。正确做法是每次SETUP之前都从SDP动态解析,并缓存为字典。

第二个坑是序列号回绕误判。16位序列号在高速率下几分钟就会回绕一次。判断丢包时必须用带符号的16位差值:

diff = (int16_t)(new_seq - last_seq)

diff为负数说明回绕或乱序,按模运算处理,不能简单用大于小于比较。

第三个坑是RTCP间隔不是实时的。RTCP大约每5秒甚至更久才发一次,不能指望它秒级反映丢包。排障时想要实时数据,直接用Wireshark的RTP统计,或者自己统计接收端收到的RTP包数量。

第四个坑是WebRTC抓包里的RTX会被看成普通RTP。RTX包有独立的PT,它的负载不是原始媒体,而是重传的原始包。如果不按SDP里的a=rtx映射关系处理,很容易把重传包误当成新的媒体流,导致乱序和丢包统计完全失真。

6.3 我的排查套路

我个人的习惯是三部曲:

第一步,看协商。RTSP就看SDP和Transport;WebRTC就先看ICE和DTLS是否成功,SDP里媒体行和编解码是否对齐。协商不通,后面没得玩。

第二步,看媒体流。打开RTP Streams窗口,确认SSRC、PT、时间戳是否符合SDP。重点检查同SSRC包的sequence是否连续、时间戳增量是否稳定。这一步能筛掉大半问题。

第三步,看反馈统计。翻RTCP SR/RR里的丢包率、抖动、往返时延,结合抓包结果判断问题根源是网络层还是封装层。

这套流程我从RTSP调到WebRTC,从局域网调到公网,命中率一直很稳定。最后再说一个省时间的技巧:调试WebRTC弱网问题时,如果客户端有开关,先把SRTP临时关掉或者换成明文的RTP/AVP profile,抓包能看到明文payload后,用H.264的分析插件直接检查帧结构,排查效率能提高一倍。这个方法在自测环境中非常好用,但生产环境务必保持加密,传输安全不能省。

RTP协议本身不复杂,复杂的是它和上层一堆扩展机制的组合。但只要把RTSP和WebRTC两条链路里的角色吃透,后面就算碰到新的媒体格式、新的传输场景,核心思路照样能套上。希望你读完这篇文章,也能少走我当年走过的弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询