流媒体协议原理及应用

jc39
jc39
发布于 2026-06-14 / 3 阅读
0
0

流媒体协议原理及应用

本文包含 RTP/RTSP,私有协议(通信及流封装协议),MP4 内容。

RTP/RTCP

介绍

RTP/RTCP 的规范可以参考 RFC 1889。RTP(Real-time Transport Protocol,实时传输协议)主要用于为音视频数据包添加序列号和时间戳,提供丢包检测、乱序重组、播放时序管理、负载类型标识以及媒体流区分等功能。RTCP(RTP Control Protocol,RTP 控制协议)则与 RTP 配合使用,定期在会话中传输控制信息,用于反馈传输质量(如丢包率、抖动、时延)和同步不同媒体流(如音视频同步),从而实现对 RTP 传输质量的控制与监控。两者共同构成了实时通信中可靠的传输与反馈机制。在传输中,RTP/RTCP 通常运行在 UDP 之上,采用相邻的一对端口:偶数端口用于 RTP,下一个奇数端口用于 RTCP。

RTP 数据传输协议

参与角色

  • Mixer:从一个或多个源接收 RTP 包,混合后发送一个新的 RTP 包。会进行时序调整,更换 SSRC,并把源的 SSRC 写入 CSRC 中。
  • Translator:转发 RTP 包,或转换编码但不混合。保持 SSRC 不变,即时序不变。
  • Monitor:通过接收 RTCP 包监控媒体质量。

固定头部字段

RTP 固定头部具有以下格式:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X|  CC   |M|     PT      |       sequence number         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           timestamp                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           synchronization source (SSRC) identifier            |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
|            contributing source (CSRC) identifiers             |
|                             ....                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

每个 RTP 包都包含固定的前 12 字节,且只有 mixer 才会附带 CSRC 标识。字段含义如下:

  • version (V): 2 bit

    RTP 版本号,目前为 2。(值 1 用于 RTP 首个草案版本,值 0 用于“vat”音频工具。)

  • padding (P): 1 bit

    填充位,启用后在 RTP 包末尾填充若干随机字节,其中最后一个字节标明填充的总长度(包含该字节本身),因此最大填充长度为 255 字节。该机制主要用于满足加密算法要求输入数据为固定块大小的要求,或在单个底层协议数据单元中固定长度地封装多个 RTP 数据包。

  • extension (X): 1 bit

    扩展位,启用后在固定头部后面增加一个扩展头部。

  • CSRC count (CC): 4 bits

    贡献源计数,表示 CSRC 标识数量。

  • marker (M): 1 bit

    标记位,表示关键事件,与负载类型相关。比如当负载为 H.264 时,可以代表一帧结束。

  • payload type (PT): 7 bits

    负载类型,参考 RFC 3551,静态映射可直接使用,动态映射需要通过 SDP 等协议协商。

    PT      encoding    media type  clock rate   channels
            name                    (Hz)
    ______________________________________________________
    0       PCMU        A            8,000       1
    1       reserved    A
    2       reserved    A
    3       GSM         A            8,000       1
    4       G723        A            8,000       1
    5       DVI4        A            8,000       1
    6       DVI4        A           16,000       1
    7       LPC         A            8,000       1
    8       PCMA        A            8,000       1
    9       G722        A            8,000       1
    10      L16         A           44,100       2
    11      L16         A           44,100       1
    12      QCELP       A            8,000       1
    13      CN          A            8,000       1
    14      MPA         A           90,000       (see text)
    15      G728        A            8,000       1
    16      DVI4        A           11,025       1
    17      DVI4        A           22,050       1
    18      G729        A            8,000       1
    19      reserved    A
    20      unassigned  A
    21      unassigned  A
    22      unassigned  A
    23      unassigned  A
    dyn     G726-40     A            8,000       1
    dyn     G726-32     A            8,000       1
    dyn     G726-24     A            8,000       1
    dyn     G726-16     A            8,000       1
    dyn     G729D       A            8,000       1
    dyn     G729E       A            8,000       1
    dyn     GSM-EFR     A            8,000       1
    dyn     L8          A            var.        var.
    dyn     RED         A                        (see text)
    dyn     VDVI        A            var.        1
    24      unassigned  V
    25      CelB        V           90,000
    26      JPEG        V           90,000
    27      unassigned  V
    28      nv          V           90,000
    29      unassigned  V
    30      unassigned  V
    31      H261        V           90,000
    32      MPV         V           90,000
    33      MP2T        AV          90,000
    34      H263        V           90,000
    35-71   unassigned  ?
    72-76   reserved    N/A         N/A
    77-95   unassigned  ?
    96-127  dynamic     ?
    dyn     H263-1998   V           90,000
    
  • sequence number: 16 bits

    序列号,初始值随机,每发送一个 RTP 包加 1,接收端可用序列号来检测数据包丢失和恢复数据包顺序。

  • timestamp: 32 bits

    时间戳,初始值随机,代表 RTP 包中第一个字节的采样时间。时间戳的推进规律也就是时序。比如,8000Hz 的 PCMA 音频,采样间隔为 1 / 8000 = 125 μs,每秒时间戳增加 8000;90000Hz 30fps 的 H.264 视频,每秒时间戳增加 90000,每帧所需的时间戳为 90000 / 30 = 3000。此外,同一视频帧的多个 RTP 包可能时间戳相同,插帧可能导致时间戳不单调。

  • SSRC: 32 bits

    同步源,随机生成,RTP 会话内唯一,用于分别同一 RTP 会话中的同步源。

  • CSRC list: 0 to 15 items, 32 bits each

    贡献源,随机生成,RTP 会话内唯一,用于分别一个 mixer 混合的贡献源。

头部扩展字段

不推荐使用扩展头部,额外字段最好在负载中实现。

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |      defined by profile       |           length              |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                        header extension                       |
 |                             ....                              |

如果 RTP 固定头部中的 X 位为 1,则在 RTP 固定头部之后附加一个可变长度的头部扩展。如果存在 CSRC,头部扩展将放在 CSRC 之后。头部扩展的头部包含 16 位类型,16 位头部扩展长度(头部扩展中 32 位字的数量,不包括 32 位头部扩展的头部,故可为 0)。每个 RTP 包只有一个头部扩展。

RTCP 包格式

基本类型

  • SR(PT = 200):发送端报告,用于正在主动发送媒体数据的参与者,上报发送与接收统计信息。包括:64 位 NTP 时间戳(高 32 位为秒,低 32 位为小数秒)、32 位 RTP 时间戳、32 位累计发送 RTP 包数、32 位累计发送 RTP 包负载字节数、以及 RR 内容。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |V=2|P|    RC   |   PT=SR=200   |             length            | header
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                         SSRC of sender                        |
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    |              NTP timestamp, most significant word             | sender
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ info
    |             NTP timestamp, least significant word             |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                         RTP timestamp                         |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                     sender's packet count                     |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                      sender's octet count                     |
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    |                 SSRC_1 (SSRC of first source)                 | report
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
    | fraction lost |       cumulative number of packets lost       |   1
    -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |           extended highest sequence number received           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                      interarrival jitter                      |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                         last SR (LSR)                         |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                   delay since last SR (DLSR)                  |
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    |                 SSRC_2 (SSRC of second source)                | report
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
    :                               ...                             :   2
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    |                  profile-specific extensions                  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
  • RR(PT = 201):接收端报告,用于并未主动发送媒体数据的参与者,上报其接收统计信息。包括:8 位丢包率、24 位累计丢包数、32 位序列号(还是 RTP 的序列号,但避免回绕)、32 位网络抖动、32 位最近收到的 SR 时间戳的中间 32 位,以及 32 位从该时间戳到当前时刻经过的时间(单位为 1/65536 秒)。

     0                   1                   2                   3
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |V=2|P|    RC   |   PT=RR=201   |             length            | header
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                     SSRC of packet sender                     |
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    |                 SSRC_1 (SSRC of first source)                 | report
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
    | fraction lost |       cumulative number of packets lost       |   1
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |           extended highest sequence number received           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                      interarrival jitter                      |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                         last SR (LSR)                         |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                   delay since last SR (DLSR)                  |
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    |                 SSRC_2 (SSRC of second source)                | report
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
    :                               ...                             :   2
    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
    |                  profile-specific extensions                  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    
  • SDES(PT = 202):源描述项,包括 CNAME。因为 SSRC 可变,所以用 CNAME 固定值给 SSRC 命名,比如电话号码、地理位置等。

  • BYE(PT = 203):表示参与结束。

  • APP(PT = 204):应用特定功能。

往返时延

RTT(round-trip time)计算方法:

[10 Nov 1995 11:33:25.125]           [10 Nov 1995 11:33:36.5]
n                 SR(n)              A=b710:8000 (46864.500 s)
---------------------------------------------------------------->
                   v                 ^
ntp_sec =0xb44db705 v               ^ dlsr=0x0005.4000 (    5.250s)
ntp_frac=0x20000000  v             ^  lsr =0xb705:2000 (46853.125s)
  (3024992016.125 s)  v           ^
r                      v         ^ RR(n)
---------------------------------------------------------------->
                       |<-DLSR->|
                        (5.250 s)

A     0xb710:8000 (46864.500 s)
DLSR -0x0005:4000 (    5.250 s)
LSR  -0xb705:2000 (46853.125 s)
-------------------------------
delay 0x   6:2000 (    6.125 s)

传输间隔

推荐的传输方式,一个 UDP 包中包含多个 RTCP 包,若加密则首先是 32 位随机数,之后是一个 SR/RR,一个 SDES,若退出则再加上一个 BYE。

if encrypted: random 32-bit integer
 |
 |[------- packet -------][----------- packet -----------][-packet-]
 |
 |             receiver reports          chunk        chunk
 V                                    item  item     item  item
--------------------------------------------------------------------
|R[SR|# sender #site#site][SDES|# CNAME PHONE |#CNAME LOC][BYE##why]
|R[  |# report #  1 #  2 ][    |#             |#         ][   ##   ]
|R[  |#        #    #    ][    |#             |#         ][   ##   ]
|R[  |#        #    #    ][    |#             |#         ][   ##   ]
--------------------------------------------------------------------
|<------------------  UDP packet (compound packet) --------------->|

#: SSRC/CSRC

RTSP

介绍

RTSP 的规范可以参考 RFC 2326。RTSP(Real Time Streaming Protocol,实时流协议)主要用于控制音视频媒体的点播与直播,它采用类似 HTTP 的请求-响应模型,通过 C/S 架构使用 TCP(默认 554 端口)来建立会话并发送 PLAY、PAUSE、SETUP、TEARDOWN 等命令,从而实现对流媒体播放、暂停、定位等交互控制。但 RTSP 自身通常不传输媒体数据,而是依赖 RTP 承载实际音视频内容,并常配合 RTCP 进行质量反馈。

协议指令

RTSP 协议格式类似于 HTTP,但是 RTSP 是有状态的,使用 Session ID。具体指令如下:

OPTIONS

询问服务器支持哪些方法。

C->S:  OPTIONS rtsp://example.com/media.mp4 RTSP/1.0
       CSeq: 1
       Require: implicit-play // 服务器需支持 implicit-play, 即 SETUP 后自动 PLAY
       Proxy-Require: gzipped-messages // 中间代理需支持 gzip

S->C:  RTSP/1.0 200 OK
       CSeq: 1
       Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE

DESCRIBE

请求媒体描述信息。

C->S: DESCRIBE rtsp://example.com/media.mp4 RTSP/1.0
      CSeq: 2
      Accept: application/sdp, application/rtsl, application/mheg

S->C: RTSP/1.0 200 OK
      CSeq: 2
      Content-Base: rtsp://example.com/media.mp4
      Content-Type: application/sdp
      Content-Length: 376

      m=video 0 RTP/AVP 96
      a=control:streamid=0
      a=range:npt=0-7.741000
      a=length:npt=7.741000
      a=rtpmap:96 MP4V-ES/5544
      a=mimetype:string;"video/MP4V-ES"
      a=AvgBitRate:integer;304018
      a=StreamName:string;"hinted video track"
      m=audio 0 RTP/AVP 97
      a=control:streamid=1
      a=range:npt=0-7.712000
      a=length:npt=7.712000
      a=rtpmap:97 mpeg4-generic/32000/2
      a=mimetype:string;"audio/mpeg4-generic"
      a=AvgBitRate:integer;65790
      a=StreamName:string;"hinted audio track"

SETUP

建立 RTP 传输通道。使用 SDP 中的 streamid 区分 track。如果定义了 port 将覆盖 SDP 中的 port。

C->S: SETUP rtsp://example.com/media.mp4/streamid=0 RTSP/1.0
      CSeq: 3
      Transport: RTP/AVP;unicast;client_port=4588-4589 // 这里还可以附加很多种参数, 还是要参考 RFC 2326

S->C: RTSP/1.0 200 OK
      CSeq: 3
      Transport: RTP/AVP;unicast;client_port=4588-4589;server_port=6256-6257
      Session: 12345678

PLAY

开始播放。可以指定播放范围:

C->S: PLAY rtsp://example.com/media.mp4 RTSP/1.0
      CSeq: 4
      Session: 12345678
      Range: npt=5-20

S->C: RTSP/1.0 200 OK
      CSeq: 4

PAUSE

暂停播放。

C->S: PAUSE rtsp://example.com/media.mp4 RTSP/1.0
      CSeq: 5
      Session: 12345678

S->C: RTSP/1.0 200 OK
      CSeq: 5

TEARDOWN

关闭会话。

C->S: TEARDOWN rtsp://example.com/media.mp4 RTSP/1.0
      CSeq: 6
      Session: 12345678

S->C: RTSP/1.0 200 OK
      CSeq: 6

GET_PARAMETER

获取参数。

S->C: GET_PARAMETER rtsp://example.com/media.mp4 RTSP/1.0
      CSeq: 7
      Content-Type: text/parameters
      Session: 12345678
      Content-Length: 15

      packets_received
      jitter

C->S: RTSP/1.0 200 OK
      CSeq: 7
      Content-Length: 46
      Content-Type: text/parameters

      packets_received: 10
      jitter: 0.3838

SET_PARAMETER

设置参数。

C->S: SET_PARAMETER rtsp://example.com/media.mp4 RTSP/1.0
      CSeq: 8
      Content-length: 20
      Content-type: text/parameters

      barparam: barstuff

S->C: RTSP/1.0 451 Invalid Parameter
      CSeq: 8
      Content-length: 10
      Content-type: text/parameters

      barparam

ANNOUNCE

通知 SDP 变更。既可以由客户端发送给服务器,用来发布一个即将推送的媒体流,也可以由服务器发送给客户端,用于通知会话中发生了改变。

C->S: ANNOUNCE rtsp://example.com/media.mp4 RTSP/1.0
      CSeq: 9
      Date: 23 Jan 1997 15:35:06 GMT
      Session: 47112344
      Content-Type: application/sdp
      Content-Length: 332

      v=0
      o=mhandley 2890844526 2890845468 IN IP4 126.16.64.4
      s=SDP Seminar
      i=A Seminar on the session description protocol
      u=http://www.cs.ucl.ac.uk/staff/M.Handley/sdp.03.ps
      e=mjh@isi.edu (Mark Handley)
      c=IN IP4 224.2.17.12/127
      t=2873397496 2873404696
      a=recvonly
      m=audio 3456 RTP/AVP 0
      m=video 2232 RTP/AVP 31

S->C: RTSP/1.0 200 OK
      CSeq: 9

REDIRECT

通知客户端连接另一个服务器。客户端将先 TEARDOWN 当前会话,并 SETUP 与另一个服务器的新会话。

S->C: REDIRECT rtsp://example.com/media.mp4 RTSP/1.0
      CSeq: 10
      Location: rtsp://bigserver.com:8001
      Range: clock=19960213T143205Z- // 生效时间

RECORD

开始录制。可使用 Range 指定范围。

C->S: RECORD rtsp://example.com/media.mp4.bak RTSP/1.0
      CSeq: 11
      Session: 12345678

S->C: RTSP/1.0 200 OK
      CSeq: 11

通信流程

通信流程如下:

  C                            S
  |-------- OPTIONS    ------->|
  |<------- 200 OK     --------|
  |                            |
  |-------- DESCRIBE   ------->|
  |<------- SDP 信息   --------|
  |                            |
  |-------- SETUP      ------->|
  |<------- Session ID --------|
  |                            |
  |-------- PLAY       ------->|
  |<------- 200 OK     --------|
  |                            |
  |<======= RTP/RTCP   ========|
  |                            |
  |-------- PAUSE      ------->|
  |<------- 200 OK     --------|
  |                            |
  |-------- PLAY       ------->|
  |<------- 200 OK     --------|
  |                            |
  |<======= RTP/RTCP   ========|
  |                            |
  |-------- TEARDOWN   ------->|
  |<------- 200 OK     --------|

此外,需要定时发送 OPTIONS 或 GET_PARAMETER 维持连接活跃。理论上应该使用 GET_PARAMETER,但 OPTIONS 兼容性更好。

传输方式

通常,RTSP 流媒体数据通过 UDP 传输,但也支持基于 TCP 的“嵌入式(交错式)二进制数据”传输方式,即 RTP over RTSP(TCP)。其格式为:以 ASCII 字符 $(0x24)为起始标志,紧接着一个字节的信道标识符,随后是二进制数据的长度(以网络字节顺序表示的两个字节),最后是数据本身(无 CRLF,包含上层协议头)。每个 $ 块仅包含一个上层协议数据单元(例如一个完整的 RTP 包)。

C->S: SETUP rtsp://example.com/media.mp4/streamid=0 RTSP/1.0
      CSeq: 3
      Transport: RTP/AVP/TCP;interleaved=0-1 // 0-RTP 1-RTCP

S->C: RTSP/1.0 200 OK
      CSeq: 3
      Date: 05 Jun 1997 18:57:18 GMT
      Transport: RTP/AVP/TCP;interleaved=0-1
      Session: 12345678

C->S: PLAY rtsp://example.com/media.mp4/streamid=0 RTSP/1.0
      CSeq: 4
      Session: 12345678

S->C: RTSP/1.0 200 OK
      CSeq: 4
      Session: 12345678
      Date: 05 Jun 1997 18:59:15 GMT
      RTP-Info: url=rtsp://example.com/media.mp4/streamid=0;seq=232433;rtptime=972948234

S->C: $\000{2 byte length}{"length" bytes data, w/RTP header}
S->C: $\000{2 byte length}{"length" bytes data, w/RTP header}
S->C: $\001{2 byte length}{"length" bytes  RTCP packet}

私有协议(通信及流封装协议)

私有

MP4

介绍

MP4(MPEG-4 Part 14)是一种基于 ISO/IEC 14496-14 标准的多媒体容器格式,广泛用于存储视频、音频、字幕及元数据。它采用面向对象的文件结构,将数据组织为一系列称为“Box”或“Atom”的层次化数据块,支持高效的本地播放和流媒体渐进式下载。MP4 通常使用 H.264 或 H.265 进行视频编码,AAC 进行音频编码,具有高压缩率和良好的画质音质平衡。MP4 也是互联网和移动设备上最通用的视频格式之一,兼容 HTML5、iOS、Android 等主流平台。

结构

BOX 通用结构

+--------------------------+
| size           (4 bytes) |
+--------------------------+
| type           (4 bytes) |
+--------------------------+
| largesize      (8 bytes) | // size = 0 时, 附加
+--------------------------+
| extended_type (16 bytes) | // type = uuid 时, 附加
+--------------------------+
| version        (1 bytes) | // version 和 flags 可选
+--------------------------+ // 携带这两个的叫 FullBox
| flags          (3 bytes) | // FullBox 常用在 moov
+--------------------------+ // 用于版本升级与功能开关
| data / children          |
|                          |
+--------------------------+

BOX 嵌套结构

+-------------+ +-------------+ +-------------+
|             | |             | |     +-----+ |
|     BOX     | |     BOX     | | BOX | BOX | |
|             | |             | |     +-----+ |
+-------------+ +-------------+ +-------------+

MP4 文件结构

+-------------------+
| ftyp              | // file type and compatibility
+-------------------+
| free              | // free space
+-------------------+
| mdat              | // media data container
+-------------------+
| moov              | // container for all the metadata
|   + mvhd          | // movie header, overall declarations
|   + trak          | // container for an individual track or stream
|   |   + tkhd      | // track header, overall information about the track
|   |   + edts      | // edit list container
|   |   + mdia      | // container for the media information in a track
|   + trak          |
|   + udta          | // user-data
+-------------------+
  • ftyp (File Type Box):用于声明文件类型和兼容规范。播放器会通过它判断这是 MP4、MOV、ISOM 还是其他 BMFF 派生格式。
  • free (Free Space Box):预留的空闲空间。通常用于后续修改文件时避免整体移动数据,也可作为占位填充。
  • mdat (Media Data Box):存放真正的音视频数据。例如 H264/H265 码流、AAC 音频帧等通常都在这里。
  • moov (Movie Box):MP4 的核心元数据区域。相当于整个文件的“目录”。
    • mvhd (Movie Header Box):整个影片的全局信息。包括总时长、时间基(timescale)、播放速率等。
    • trak (Track Box):表示一个独立轨道。一个视频轨、音频轨、字幕轨通常各对应一个 trak。
      • tkhd (Track Header Box):当前轨道的基本属性。例如 track id、宽高、音量、显示层级等。
      • edts (Edit Box):定义轨道时间编辑规则。可用于控制起播时间、裁剪、延迟同步等。
      • mdia (Media Box):轨道的媒体信息容器。内部包含编码格式、时间信息、sample 索引等内容。
    • udta (User Data Box):用户自定义数据区域。可存储额外信息,例如标题、作者、设备信息、GPS、注释等。

fMP4

fMP4(Fragmented MP4,分片 MP4)是一种流式封装格式,它通过将原本完整的 MP4 文件切割为一系列更小的独立片段来优化流媒体传输效率。与普通 MP4 需要完整的 moov 索引框才能开始解码不同,fMP4 将元数据与媒体数据交替组织成若干对“moof + mdat”,其中 moof 包含当前片段的解码信息,mdat 存储实际的音视频帧,使得播放器在下载完第一个片段后即可立即开始播放,无需等待完整的文件。

+-------------------+
| ftyp              | // file type and compatibility
+-------------------+
| moov              | // container for all the metadata
+-------------------+
| styp (可选)       | // segment type
+-------------------+
| sidx (可选)       | // segment index
+-------------------+
| moof              | // movie fragment
|   + mfhd          | // movie fragment header
|   + traf          | // track fragment
|       + tfhd      | // track fragment header
|       + tfdt      | // track fragment decode time
|       + trun      | // track fragment run
+-------------------+
| mdat              | // media data container
+-------------------+
| styp (可选)       |
+-------------------+
| sidx (可选)       |
+-------------------+
| moof              |
+-------------------+
| mdat              |
+-------------------+
... repeat
+-------------------+
| mfra (可选)       | // movie fragment random access
+-------------------+
  • styp (Segment Type Box):分片级别的 ftyp,基本上与 ftyp 相同。
  • sidx (Segment Index Box):提供当前分片内各子片段的字节偏移和时长索引,使得客户端能够在不解析完整文件的情况下,快速定位特定时间范围对应的数据位置。
  • moof (Movie Fragment Box):负责存放一个分片内所有轨道片段的元数据。
    • mfhd (Movie Fragment Header Box):位于 moof 内部,记录当前分片的序列号(sequence number),用于唯一标识该分片在整体流中的顺序,便于播放器按序组装和解码连续片段。
    • traf (Track Fragment Box):包含在 moof 中,对应单个轨道的分片元数据,内部封装了 tfhd、tfdt 和 trun 等 Box,用于描述该轨道在当前分片内所有采样的具体属性和解码时序。
      • tfhd (Track Fragment Header Box):定义当前轨道片段的默认设置,如是否使用默认 base 偏移、默认采样大小、是否包含 sample duration 等标志位,为后续 trun 提供解析该片段数据的上下文基础。
      • tfdt (Track Fragment Base Media Decode Time Box):记录当前轨道分片中第一个采样的解码时间(以媒体时间坐标系为准),用于建立从片段序列号到实际解码时间戳的绝对映射,是音视频同步和连续播放的关键依据。
      • trun (Track Fragment Run Box):详细列出当前轨道分片中一个连续采样序列(run)的各项信息,包括每个采样的偏移量、大小、时长、关键帧标志等,是实际描述媒体数据如何填入 mdat 的核心索引表。
  • mfra (Movie Fragment Random Access Box):通常位于 fMP4 文件末尾,汇总所有分片的随机访问点(如关键帧)位置及其对应的字节偏移和时间戳。

虽然 mfra 提供了全局索引能力,但如果已发送 sidx,也可直接利用其实现跳转,因此两者通常只需使用其中一种。


评论