完成一个简单的rtmp服务器之amf解析

写在前面:
  1,理论部分可以参考wiki和amf文档(网上很多资源)
  2,不熟悉ffmpeg的可以参考ffmpeg文档

直接进入正题
 下面是我使用ffmpeg推流是抓包获得的数据,就以此为例。
ffmpeg指令如下:

ffmpeg -re -i big_buck_bunny_720p_1mb.mp4 -c copy -f flv -rtmp_app live rtmp://1.111.1.1:9009

数据包如下:所有字符均为十六进制utf-8编码,服务器地址1.111.1.1是瞎写的,端口使用9009

		                 03 00 00 00 00 00 8b 14 00 00   ................
0040   00 00 02 00 07 63 6f 6e 6e 65 63 74 00 3f f0 00   .....connect.?..
0050   00 00 00 00 00 03 00 03 61 70 70 02 00 04 6c 69   ........app...li
0060   76 65 00 04 74 79 70 65 02 00 0a 6e 6f 6e 70 72   ve..type...nonpr
0070   69 76 61 74 65 00 08 66 6c 61 73 68 56 65 72 02   ivate..flashVer.
0080   00 24 46 4d 4c 45 2f 33 2e 30 20 28 63 6f 6d 70   .$FMLE/3.0 (comp
0090   61 74 69 62 6c 65 3b 20 4c 61 76 66 35 38 2e 34   atible; Lavf58.4
00a0   37 2e 31 30 30 29 00 05 74 63 55 72 6c 02 00 1a   7.100)..tcUrl...
00b0   72 74 6d 70 3a 2f 2f 31 2e 31 31 31 2e 31 2e 31   rtmp://1.111.1.1
00c0   3a 39 c3 30 30 39 2f 6c 69 76 65 00 00 09         :9.009/live...

  这是一个完整的connection命令,从头开始,第一个字节0x03,前两位是00,表示这个消息的头总长有12字节(basic header + message header),后六位是000011,表示使用一个字节表示basic header,接下来三个字节时间戳(0x00,0x00,0x00,),三个字节消息长度(0x00,0x00,0x8b),一个字节消息类型(0x14),四个字节的streamID,以上是消息的头。
  接下来是消息体,wiki中有不同字段类型对应的值,例如0x02表示string类型,此时紧接着的两位表示string的长度,在接下来0x00表示number类型,其值类型为double,长度固定为8字节,在接下来是0x03,这表示object类型,其实就是键值对,以0x03为开始,0x00 0x00 0x09三个字节为结尾,重点讲解一下这个object类型的格式。
 object类型的键统一为string类型,因此直接跟上长度,例中为0x00 0x03,即接下来的一个键长度为3(即为app),紧接着后面是键值对的值,这个就需要不同的类型了,例中为0x02也就是string类型,因此向后读两位(0x00,0x04),获取其长度为4,以此类推,接下来的键值对以此为:

"type": "nonprivate",
"flashVer": "FMLE/3.0 (compatible; Lavf58.47.100)",
"tcUrl": "rtmp://1.111.1.1:9009/live"

直到读取到0x00 0x00 0x09就可以判断为当前object结束了,接下来还可能有其它类型的字段,按上面的规则解析即可。
  值得注意的是例中”tcUrl“字段的值:”rtmp://1.111.1.1:9009/live“,实际的数据多了一个字节0xc3,这是因为rtmp协议里chunk size的默认长度为128(可以使用指令调整),超出部分就需要分块发送,这个0xc3就是第二个块的头,转换为二进制为:11000011,即前两位是11,表示消息头总长只有一个字节,后六位与前一个块相同,表示basic header有一个字节,也就是message header长度为0,即message header里面的信息和其前一个块完全相同,实际解析的时候需要将两个块合并在一起。
  至此,一个完整的connection命令就解析完成了,具体内容如下:

command name: "connect",
transaction_id: 0.0,//这里文档上说connect命令设置为1,但是我计算的是得到0,可能是我算错了,但不重要
object{
	"app": "live",
	"type": "nonprivate",
	"flashVer": "FMLE/3.0 (compatible; Lavf58.47.100)",
	"tcUrl": "rtmp://1.111.1.1:9009/live"
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值