RTMP协议分析

用私有的可以和YouTube直播的app,用wireShark去抓包分析RTMP的协议:

wireshark如何捕获rtp协议数据 wireshark rtmp_分块

上面是抓包看到的具体过程,现在来详细分析一下。

rtmp握手的过程:

wireshark如何捕获rtp协议数据 wireshark rtmp_直播_02


(图片从网上找来的,忘记出处了。)

具体过程如下所示:

  1. 首先是tcp握手建立client和server的连接通道;
  2. 之后client向server发起rtmp握手请求,发送c0+c1+c2,用于校验rtmp版本和协议的准确性;
    server向client回s0+s1+s2包,用于确认和client端的协议版本;
  3. handshake完成之后,client向server发送自己的音视频编码信息等内容,server给client发送自己相应的Window Acknowlegement size和chunkSize的大小,前者是client每收到间隔Window Acknowlegement size大小的包时,需要给server回一个Acknowledgement,后者是server端分块的大小,同时,client也需要向server发送自己这边的Window Acknowlegement size大小。
  4. 通道建立之后,各方的信息也互相通知完毕,前期工作就算正式完成了。接下来,client向sever端发起user control消息,表明要开始推流了,如果上述的通信过程出现了任何问题, rtmp都在上层关闭socket连接。

下面是抓包信息:

wireshark如何捕获rtp协议数据 wireshark rtmp_Android_03


Server to client 的方向来看:

wireshark如何捕获rtp协议数据 wireshark rtmp_协议分析_04


然后中间有一些丢包重传,但是比较少。

wireshark如何捕获rtp协议数据 wireshark rtmp_RTMP_05

Client to server方向来看:

wireshark如何捕获rtp协议数据 wireshark rtmp_Android_06


Audio采集速度快一点,video慢一点,音频数据比视频数据多。最后由client发送停止推流的操作结束。

wireshark如何捕获rtp协议数据 wireshark rtmp_直播_07

rtmp协议分析

rtmp适用于处理音视频直播,特点在于分块,这些块通过网络进行传输。在传输过程中,必须一个块发送完毕之后再发送下一个块。在接收端,将所有块根据块中的块流ID组装成消息。

块将上层协议的大消息分割成小的消息,保证大的低优先级消息(比如视频)不阻塞小的高优先级消息(比如音频或控制消息)。分块还能降低消息发送的开销,它在块头中包含了压缩的原本需要在消息中所包含的信息。块大小可以根据不同的情况制定,在128~4096之间,越大的块CPU使用率越低,但是在低带宽的情况下,大的写入会阻塞其他内容的写入;而小一些的块不适合高比特率的流。块大小在每个方向上保持独立。

块的格式:

wireshark如何捕获rtp协议数据 wireshark rtmp_分块_08


代码中如何实现:1.首先将camera传来的数据封装成rtmp包:

wireshark如何捕获rtp协议数据 wireshark rtmp_分块_09


Header里面包含了rtmp所需要的各种信息如messageType,chunkType。

2. 将封装的rtmp包进行分块:

wireshark如何捕获rtp协议数据 wireshark rtmp_分块_10

例如接收到9332大小的video数据,

wireshark如何捕获rtp协议数据 wireshark rtmp_直播_11


那么将其分为9332 / 128 ≈72块。

wireshark如何捕获rtp协议数据 wireshark rtmp_直播_12

  1. rtmp利用chunk Stream id来区分音视频信息以及控制信息,有些steam id有优先级高低区别,可以根据这个来选择发送顺序。
    音频信息:

    视频信息:

    用户控制信息:
  2. wireShark分析包
    例如现在发送一序列的音频数据包:

WireShark抓包数据:

wireshark如何捕获rtp协议数据 wireshark rtmp_Android_13


可见Rtmp将拆分的包被组包过后再进行发送。

wireshark如何捕获rtp协议数据 wireshark rtmp_RTMP_14