RTMP协议简介
RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题。
RTMP协议是应用层协议,是要靠底层可靠的传输层协议(通常是TCP)来保证信息传输的可靠性的。在基于传输层协议的链接建立完成后,RTMP协议也要客户端和服务器通过“握手”来建立基于传输层链接之上的RTMP Connection链接。
Chunking(Message分块)
RTMP在收发数据的时候并不是以Message为单位的,而是把Message拆分成Chunk发送,而且必须在一个Chunk发送完成之后才能开始发送下一个Chunk。每个Chunk中带有MessageID代表属于哪个Message,接受端也会按照这个id来将chunk组装成Message。
为什么RTMP要将Message拆分成不同的Chunk呢?
通过拆分,数据量较大的Message可以被拆分成较小的“Message”,这样就可以避免优先级低的消息持续发送阻塞优先级高的数据,比如在视频的传输过程中,会包括视频帧,音频帧和RTMP控制信息,如果持续发送音频数据或者控制数据的话可能就会造成视频帧的阻塞,然后就会造成看视频时最烦人的卡顿现象。同时对于数据量较小的Message,可以通过对Chunk Header的字段来压缩信息,从而减少信息的传输量。
Chunk的默认大小是128字节,在传输过程中,通过一个叫做Set Chunk Size的控制信息可以设置Chunk数据量的最大值,在发送端和接受端会各自维护一个Chunk Size,可以分别设置这个值来改变自己这一方发送的Chunk的最大大小。大一点的Chunk减少了计算每个chunk的时间从而减少了CPU的占用率,但是它会占用更多的时间在发送上,尤其是在低带宽的网络情况下,很可能会阻塞后面更重要信息的传输。小一点的Chunk可以减少这种阻塞问题,但小的Chunk会引入过多额外的信息(Chunk中的Header),少量多次的传输也可能会造成发送的间断导致不能充分利用高带宽的优势,因此并不适合在高比特率的流中传输。在实际发送时应对要发送的数据用不同的Chunk Size去尝试,通过抓包分析等手段得出合适的Chunk大小,并且在传输过程中可以根据当前的带宽信息和实际信息的大小动态调整Chunk的大小,从而尽量提高CPU的利用率并减少信息的阻塞机率。
概念
RTMP 在音视频相关的协议中,它的突出特点是:
连接可靠、低延时
有效负载:
包含在每一个包中的数据,就像音视频样本或压缩后的视频数据。
包:
一个数据包是由固定的包头和有效的负载数据来组成的。
端口:
rtmp协议默认使用的是1935端口。
消息流:
一个通信的逻辑通道,让消息流通
消息流id:
每个消息拥有一个分配的id,标识消息流。
消息块:
消息的一个片段,一个完整的消息会被分割成小的片段,每个片段都是一个消息块。
消息块流:
一个通信的逻辑通道,允许消息块在一个特定方向流通,
例如:从客户端到服务器。
消息块流id:
每个消息块有一个分配的id用于识别跟随消息块流。
复合技术:
把分开的音视频数据组合成一条音视频流的过程。
逆复合技术:
复合的反向过程,交叉存取组装的音视频数据,使他们成为最初的音视频数据。
时间戳:
在rtmp消息块中的时间戳使用整数来表示,但是为毫秒。
时间戳必须是线性增加的,允许引用程序处理异步传输,带宽度量,检测,流控制。
rtmp协议握手过程
要建立一个有效的rtmp连接,首先经过”握手”阶段,规则如下:
客户端被指定依次向服务器发送C0,C1,C2三个chunk,服务器向客户端发送S0,S1,S2三个chunk。 详细发送要求:
客户端开始发送C0,C1;
客户端必须收到S1后,才发送C2;
客户端必须收到S2后才开始发送其他信息(控制信息和音视频数据) 服务器要等收到C0才能发送S0和S1;
服务器必须等C1后才能发送S2 服务器必须等收到C2之后才能发送其他数据(控制信息和音视频数据)
rtmp通信过程
简化如下:
client--> server : 发送一个创建流的请求 (C0、C1)。
server--> client : 返回一个流的索引号 (S0、S1、S2)。
client--> server : 开始发送 (C2)
client--> server : 发送音视频数据(这些包用流的索引号来唯一标识)
RTMP 的 HTTP 变种与防火墙
rtmp 有三个变种:
工作在TCP之上的明文协议,使用端口1935
RTMPT封装在HTTP请求之中,可穿越防火墙
RTMPS类似RTMPT,但使用的是HTTPS连接
穿越防火墙的意思是,可能出于安全考虑,互联网中某一些网络(比如小区、校园网)的防火墙限制了http/https以外的协议访问,只允许访问外网ip的 80 端口与 443 端口,或者还允许其他协议,而明文协议的 rtmp 默认端口 1935 不在防火墙开放访问的端口中,无法建立连接。出于现实考虑,使用 http/https 封装 rtmp 协议,增强兼容性。