RTMP协议分析
用私有的可以和YouTube直播的app,用wireShark去抓包分析RTMP的协议:
上面是抓包看到的具体过程,现在来详细分析一下。
rtmp握手的过程:
(图片从网上找来的,忘记出处了。)
具体过程如下所示:
-
首先是tcp握手建立client和server的连接通道;
-
之后client向server发起rtmp握手请求,发送c0+c1+c2,用于校验rtmp版本和协议的准确性;
server向client回s0+s1+s2包,用于确认和client端的协议版本; -
handshake完成之后,client向server发送自己的音视频编码信息等内容,server给client发送自己相应的Window Acknowlegement size和chunkSize的大小,前者是client每收到间隔Window Acknowlegement size大小的包时,需要给server回一个Acknowledgement,后者是server端分块的大小,同时,client也需要向server发送自己这边的Window Acknowlegement size大小。
-
通道建立之后,各方的信息也互相通知完毕,前期工作就算正式完成了。接下来,client向sever端发起user control消息,表明要开始推流了,如果上述的通信过程出现了任何问题, rtmp都在上层关闭socket连接。
下面是抓包信息:
Server to client 的方向来看:
然后中间有一些丢包重传,但是比较少。
Client to server方向来看:
Audio采集速度快一点,video慢一点,音频数据比视频数据多。最后由client发送停止推流的操作结束。
rtmp协议分析
rtmp适用于处理音视频直播,特点在于分块,这些块通过网络进行传输。在传输过程中,必须一个块发送完毕之后再发送下一个块。在接收端,将所有块根据块中的块流ID组装成消息。
块将上层协议的大消息分割成小的消息,保证大的低优先级消息(比如视频)不阻塞小的高优先级消息(比如音频或控制消息)。分块还能降低消息发送的开销,它在块头中包含了压缩的原本需要在消息中所包含的信息。块大小可以根据不同的情况制定,在128~4096之间,越大的块CPU使用率越低,但是在低带宽的情况下,大的写入会阻塞其他内容的写入;而小一些的块不适合高比特率的流。块大小在每个方向上保持独立。
块的格式:
代码中如何实现:
1.首先将camera传来的数据封装成rtmp包:
Header里面包含了rtmp所需要的各种信息如messageType,chunkType。
2. 将封装的rtmp包进行分块:
例如接收到9332大小的video数据,
那么将其分为9332 / 128 ≈72块。
- rtmp利用chunk Stream id来区分音视频信息以及控制信息,有些steam id有优先级高低区别,可以根据这个来选择发送顺序。
音频信息:
视频信息:
用户控制信息:
- wireShark分析包
例如现在发送一序列的音频数据包:
WireShark抓包数据:
可见Rtmp将拆分的包被组包过后再进行发送。