Rtmp协议简单分析(二)——协议交互过程
来源:互联网 发布:up to date数据库介绍 编辑:程序博客网 时间:2024/04/30 09:07
具体传输的过程是这样的,首先双方先进行握手,握手过程官方文档上有说明,但是在flash10.1之后,adobe公司改了握手,文档上那个握手不能用了,至少播放AVC和ACC不能用,这东西太坑人了,改了又不说一声,而且一个本来简单的握手改的很是复杂,居然要依赖openssl加密,有必要吗。网上找不到有关文章,我只有看rtmpserver开源项目源码来弄。
握手步骤没有变,但内容完全不一样,以前叫sample handshake,现在叫复杂握手(complex handshake)。
它的步骤是由三个固定大小的块组成,而不是可变大小的块加上头。握手开始于客户端发送C0,C1块。在发送C2之前客户端必须等待接收S1。在发送任何数据之前客户端必须等待接收S2。服务端在发送S0和S1之前必须等待接收C0,也可以等待接收C1。服务端在发送S2之前必须等待接收C1。服务端在发送任何数据之前必须等待接收C2。
网上有一个人说出了complex handshake的方式,http://blog.csdn.net/winlinvip/article/details/7714493,以下是他的说明:
scheme1和scheme2这两种方式,是包结构的调换。
key和digest的主要算法是:C1的key为128bytes随机数。C1_32bytes_digest = HMACsha256(P1+P2, 1504, FPKey, 30) ,其中P1为digest之前的部分,P2为digest之后的部分,P1+P2是将这两部分拷贝到新的数组,共1536-32长度。S1的key根据C1的key算出来,算法如下:
在Rtmpserver的sources\thelib\src\protocols\rtmp\inboundrtmpprotocol.cpp中有握手的代码,看他的说明也马马虎虎,我也看源码后才清楚具体过程。具体过程和他说的差不多,只是有些计算要用到openssl加密,所以要安装openssl,我也是从rtmpserver上面扣出来的代码然后自己改一下。
握手之后就开始一些交互信令,这个如果按照文档上的来,根本不行,文档上省略的一些东西,坑人。
我的交互过程是按照抓的FMS3.5的包来做的。握手之后首先client会发送一个connect消息过来。另外,RTMP交互的消息格式官方说明上有,还是比较清楚的。
字段名
类型
描述
命令名
字符串
命令名。设置为”connect”
传输ID
数字
总是设为1
命令对象
对象
含有名值对的命令信息对象
可选的用户变量
对象
任何可选信息
下面是在连接命令的命令对象中使用的名值对的描述:
属性
类型
描述
示例值
App
字符串
客户端要连接到的服务应用名
Testapp
Flashver
字符串
Flash播放器版本。和应用文档中getversion()函数返回的字符串相同。
FMSc/1.0
SwfUrl
字符串
发起连接的swf文件的url
file://C:/ FlvPlayer.swf
TcUrl
字符串
服务url。有下列的格式。protocol://servername:port/appName/appInstance
rtmp://localhost::1935/testapp/instance1
fpad
布尔值
是否使用代理
true or false
audioCodecs
数字
指示客户端支持的音频编解码器
SUPPORT_SND_MP3
videoCodecs
数字
指示支持的视频编解码器
SUPPORT_VID_SORENSON
pageUrl
字符串
SWF文件被加载的页面的Url
http:// somehost/sample.html
objectEncoding
数字
AMF编码方法
kAMF3
上图中app的vod就是请求文件的路径。
表示使用amf0编码格式传输命令,如果是3就是表示用amf3。
之后server回复windows acknowledgement size- set peer bandwidth- user control message(begin 0)- result(connect response)
User control message (用户控制信息)的格式官方文档上有,消息数据的头两个字节用于标识事件类型,0表示Stream Begin。事件类型之后是事件数据。事件数据字段是可变长的,此时的数据时00。
在发送了windows acknowledgement size之后client会回一个windows adknowledgement size,此时需要接收
然后server接收client发的一个create stream过来
接收到之后server返回一个_result
Server接收client发来的recv set buffer length - play commcand from
Client发的play命了中包含的请求的文件名,上图是1(string ‘1’ 这个数据)。
然后server发送set chunk size - user control message(stream is recorded) - onstatus-play reset (AMF0 Command) - user control message(begin1) - onstatus-play start (AMF0 Command) - RtmpSampleAccess (AMF0 Data) –空audio数据 - onstatus-data start (AMF0 Data)
Set chunk size这里就是改默认128字节的消息,这里改成了4096,当然也可以不发次消息。注意,在改之前发送的消息如果超过了128bytes都要分块发送的之后就可以每块大小事4096了。
Begin这里,这个前2bytes是0,表示stream begin,和上面的begin是个类型,只是数据段是1,这个抓包有点问题,没有显示数据段而已,此begin 1之后,所有的包头里面的streamID都是1了,之前的都是0
字段类型描述命令名字符串命令名。如果播放成功,则命令名设为响应状态。描述字符串如果播放命令成功,则客户端从服务端接收NetStream.Play.Start状态响应消息。如果指定的流没有找到,则接收到NetStream.Play.StreamNotFound响应状态消息。
这里的加载amf数据和解析amf数据(也就是交互的消息)可以用我写的一个amf0的解析模块来做。
然后就发送flv的元数据(metadata)了,如果没有也可以不发这个。之后再发音视频的配置信息项。最后就可以发送音视频数据了。
发送音视频数据的时候可以用以前的方式发:包头的AMFType是8或者9,数据是flv的 tag data(没有tag header)
也可以按照新的类型amf type为0x16,数据就是一个tag (header + data)来发。
要注意下就是rtmp都是大端模式,所以发送数据,包头、交互消息都要填成大端模式的,但是只有streamID是小端模式,这个也是文档没有说明,rtmp坑人的地方。
参考资料:
1、rtmp协议简单解析以及用其发送h264的flv文件
- Rtmp协议简单分析(二)——协议交互过程
- Rtmp协议简单分析(一)——协议数据
- rtmp 协议分析及交互过程
- RTMP协议过程分析
- rtmplib rtmp协议过程分析
- rtmplib rtmp协议过程分析
- rtmplib rtmp协议过程分析
- 流媒体-RTMP交互过程及协议解析
- RTMP协议详解(二)
- 25协议简单交互过程
- RTSP 协议 简单交互过程
- RTSP 协议 简单交互过程
- 0141 rtmplib rtmp协议过程分析
- DHCP协议交互过程分析
- 流媒体协议—RTMP
- RTMP协议分析 二、AMF数据
- RTMP协议分析 二、AMF数据
- RTMP协议分析 二、AMF数据
- 黑马程序员_异常
- jsoup 学习笔记
- delphi 7编写的代码查看编辑器对注释的着色
- Opencv鼠标绘图程序
- 点双连通模版 求割点,点双缩点
- Rtmp协议简单分析(二)——协议交互过程
- 在VirtualBox中安装QTP10破解报CRC ERROR!
- CareerCup Eliminate all ‘b’ and ‘ac’ in an array of characters
- IOCP完成端口资料整理——"高大上",够全,够详细
- JavaMailSendTest
- Opencv轮廓检测
- innerText
- 集训记录
- JavaMailHtmlSendTest