rtmp 时间戳_流媒体传输协议之RTMP

本文深入探讨RTMP协议,包括时间戳定义、块流处理、消息格式、握手流程、分块与协议控制消息。RTMP协议用于可靠传输音频、视频和数据,支持多路复用,确保消息按时间戳顺序传输。文章通过实例解析了RTMP消息结构、握手过程及流媒体应用,旨在帮助读者理解流媒体传输的细节。
摘要由CSDN通过智能技术生成

引言

本系列文章将整理各路流媒体传输协议,包括RTP/RTCP,RTMP,希望通过深入理解各个流媒体传输协议的设计细节,对今后流媒体部分的开发工作有一定的启发。

简介

RTMP在可靠流式传输(TCP)的基础上提供了双向的消息多路复用服务,在通讯双方之间传输与时间相关的并行流数据,如音频,视频和数据消息。协议实现方通常为不同的消息类型指定不同的优先级,这样在网络带宽受限时能改变底层传输顺序。

定义

  • 负载:包中所承载的数据。例如音频或视频数据。
  • 包:一个数据包由固定头部和所承载的数据组成。一些底层协议可能需要定义数据包的封装格式。
  • 端口:在一个计算机中用于区分不同目标的抽象定义。在TCP/IP协议中用一个小的正整数来表示端口。OSI传输层的传输选择器就相当于端口。
  • 传输地址:标识一个传输终端的网络地址和端口的组合,例如IP地址和TCP端口的组合。
  • 消息流:允许消息传播的逻辑通道。
  • 消息流ID:每个消息都会有一个对应的ID,用于标识其所在的消息流。
  • 块:消息的一个片段。消息在传输之前会被分割成更小的片段,因为每一块都很小,以至于可以给不同的块指定各自的优先级,通过这种方式保证多个流中数据可以按照时间戳的顺序传输。
  • 块流:块向某一确定方向传播的逻辑通道。可以是客户端到服务端,也可以是服务端到客户端。
  • 块流ID:每个块都会有一个对应的ID,用于标识其所在的块流。
  • 复用:将独立的音频/视频数据整合为统一的音视频流,可以使多个音视频流同步传输。
  • 复用分离:复用的逆向过程。将合并的音视频数据分离为原始的音频和视频数据。
  • 远程过程调用:客户端或服务端调用另一端的功能。
  • 元数据:媒体数据的描述信息。
  • 应用实例:服务器上可以和Client建立连接的应用。
  • 动作消息格式:一个可用于序列化ActionScript对象图的紧凑的二进制格式。
  • 字节序:字节的顺序,即多字节类型的数据在内存中的存放顺序。TCP/IP各层协议将字节序定义为大端字节序,因此TCP/IP协议中使用的字节序通常称之为网络字节序。
  • 大字节序:高位字节排放在内存的低地址,低位字节排放在内存的高地址。
  • 小字节序:低位字节排放在内存的低地址,高位字节排放在内存的高地址。

字节序,校准,时间格式

所有整数都是以网络字节序来表示的。除非另行说明,本文中的所有数字都是十进制数。 在没有特殊说明的情况下,RTMP中的数据都是字节对齐的。如果有填充的话,填充字节应该用0。 RTMP中的时间戳是用一个整数来表示的,代表相对于一个起始时间的毫秒数。通常每个流的时间戳都从0开始,但这不是必须的,只要通讯双方使用统一的起始时间就可以了。要注意的是,跨流的时间同步(不同主机之间)需要额外的机制来实现。 由于时间戳的长度只有32位,所以只能在50天内循环(49天17小时2分钟47.296秒)。而流是可以不断运行的,可能多年才会结束。所以RTMP应用在处理时间戳是应该使用连续的数字算法,并且应该支持回环处理。例如:一个应用可以假设所有相邻的时间戳间隔不超过2^31-1毫秒,在此基础上,10000在4000000000之后,3000000000在4000000000之前。 时间戳增量也是以毫秒为单位的无符号整数。时间戳增量可能会是24位长度也可能是32位长度。

RTMP块流

块流为上层流媒体协议提供复用和分包的功能。RTMP块流是为配合RTMP协议而设计,但它可以使用在任何发送消息流的协议中。每个消息包含时间戳和负载类型信息。RTMP块流和RTMP协议组合可以适用于多种音视频应用,从一对一或一对多直播到视频会议都能很好的满足。 当使用可靠传输协议(如TCP)时,RTMP块流为所有消息提供了可靠的跨流端对端按时间戳顺序发送的机制。RTMP块流不提供优先级控制,但是可以由上层协议提供这样的优先级。例如:当某个客户端网络比较慢时,可能会选择抛弃一些视频消息来保证声音消息能够及时接收。 RTMP块流除自身内置的协议控制消息外,还为上层协议提供了用户控制消息的机制。

消息格式

消息格式由上层协议定义,消息可以被分成多个块以支持多路复用。消息应该包含分块功能所需的所有字段,具体内容如下: - 时间戳(4-byte):消息的时间戳。 - 长度(3-byte):消息有效负载的长度,如果消息头不能被省略,则消息头的长度也应该包含在长度中。 - 类型ID(1-byte):消息类型ID。一些类型ID是为协议控制消息保留的,这些消息所表示的信息同时供RTMP块流协议和上层协议使用。所有其他类型ID都用于上层协议,RTMP块流对这些ID做不透明处理。实际上,RTMP块流不需要用这些值来区分类型,所有消息都可以是相同的类型,应用也可以用本字段来区分同步轨道而不是区分类型。 - 消息流ID(4-byte):消息流ID可以是任意值。被复合到同一个块流的消息流,依据消息流ID进行分离。另外,就相关的块流而言,这个值是不透明的。这个字段使用小字节序。

握手

RTMP连接以握手开始,它的握手过程可能和其他协议不同,这里的握手由3个固定大小的块组成,而不是可变大小的块加上固定大小的头。

握手流程

握手由客户端发送C0和C1块开始。 客户端必须等接收到S1之后才可以发送C2。客户端必须等接收到S2之后才可以发送其他数据。 服务器必须等接收到C0之后才可以发送S0和S1,也可能接收到C1之后发送。服务器必须等接收到C1之后才可以发送S2。服务器必须等接收到C2之后才可以发送其他数据。

C0和S0格式

C0和S0是单独的一个字节,可以当做一个8bit的整数字段来对待。

80485b58e78688d3af3ba88d80fc3648.png

以下是CO和S0包的字段解释: - 版本号(8位): 在C0包中,该字段表示客户端请求的RTMP版本。在S0中,该字段表示服务器选择的RTMP版本。本规范所定义的版本是3。可选值中,0-2是早期版本所用的,已被丢弃,4-31保留在未来使用,32-255不允许使用(为了区分其他以某一可见字符开始的文本协议)。如果服务器不能识别客户端请求的版本,应该返回3,客户端可能选择降级到版本3,也可能放弃握手。

C1和S1格式

C1和S1包固定为1536字节,包含以下字段:

dec032285ac09dac79a65b96c6ad8f45.png

- 时间戳(4字节):该字段承载一个时间戳,该时间戳应该作为发送端点所有后续块的时间戳起始时间。可以是0,也可以是其他的任意值。为了同步多个块流,端点可能会发送其他块流的当前时间戳。 - 零值(4字节):该字段所有值都必须为0。 - 随机数据(1528字节):该字段可以是任意值。通过这个字段来区分自己和连接的另一方,所以此数据应该有充分的随机性,但是没必要使用加密安全的随机值或动态值。

C2和S2格式

C2和S2包的长度也为1536字节,基本上是S1和C1的回传,包含以下字段:

ad3e435c5ba958d01cb5d2684dfb3fa7.png

- 时间戳(4字节):该字段必须包含对端发来的时间戳(对C2来说是S1, 对S2来说是C1)。 - 时间2(4字节):该字段必须包含先前发送的并被对端读取的包的时间戳。(对C2来说是C1,对S2来说是S1)。 - 随机数据回显(1528字节):该字段必须包含对端发送过来的随机数据字段值(对C2来说是S1, 对S2来说是C1)。任何一端都可以用时间戳和时间戳2两个字段值和当前时间戳来快速的估算带宽和延迟,但这样可能并不实用。

握手流程示意图

d958662bdd9857ed2220e0b2befafaa4.png

上图提到的状态的解释如下: - Uninitialized:未初始化状态。在该阶段发送协议版本。客户端在C0包中发送RTMP协议版本,如果服务器支持此版本,服务器将在响应中发送S0和S1。如果不支持,服务器采用适当的行为作为响应,在RTMP规范中是终止连接。 - Version Send:版本已发送状态。在未初始化状态之后客户端和服务端都进入版本已发送状态。客户端等待接收S1包,服务端等待接收C1包。收到所等待的包后,客户端发送C2包,服务端发送S2包。之后状态进入发送确认状态。 - Ack Send:客户端和服务端等待接收S2和C2包,收到后进入握手完成状态。 - Handshake Done:握手完成, 客户端和服务端开始交换消息。

分块

握手完成后,一个或多个块流可能会复用同一个连接,每个块流承载来自同一个消息流的同一类消息。每个块都有一个唯一的块流ID,这些块通过网络进行传输。在传输过程中,必须一个块发送完毕之后再发送下一个块。在接收端,将所有块根据块中的块流ID组装成消息。 分块将上层协议的大消息分割成小的消息,保证大的低优先级消息(比如视频)不阻塞小的高优先级消息(比如音频或控制消息)。 分块还能降低消息发送的开销,它在块头中包含了压

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值