RTMP 协议

本文介绍了RTMP(实时消息协议)的基本概念,包括协议简介和RTMP Chunk(消息块)的处理,特别是消息分块的接收过程。此外,还探讨了AMF(Action Message Format)编码,包括AMF0和AMF3两种编码格式,强调其在大端法存储中的应用。通过阅读,读者将能够理解RTMP协议的握手过程和AMF编码的原理。
摘要由CSDN通过智能技术生成

RTMP 协议 (Real-Time Messaging Protocol)

协议简介

RTMP协议是一个互联网TCP/IP五层体系结构中应用层的协议.
RTMP协议中基本的数据单元称为消息(Message).
当RTMP协议在互联网中传输数据的时候,消息会被拆分成更小的单元,称为消息块(Chunk)

RTMP有几个变种版本
1.原始版本
    基于TCP,默认端口1935
2.RTMPS     RTMP over TLS/SSL
3.RTMPE
4.RTMPT     封装于HTTP请求中
5.RTMFP     RTMP over UDP


RTMP 将传输的流(stream)分成片段(fragment),其大小由服务器和客户端之间动态协商,
默认的fragment大小为: 
    音频数据:   64 bytes
    视频数据:   128 bytes

PS:以下内容如无特殊说明 数据 均为 大端表示法

RTMP Chunk(RTMP消息块)

数据的发送并不是以message为单位的,而是将message拆分成chunk(>=1),chunk按序发送,接收端再根据 MsgStreamID 还原成1个message
在网络上传输数据时,消息需要被拆分成数据块(Chunk).
    |                           ChunkHeader                             |
    +------------------------------------------------------------------------------------+
    |   ChunkBasicHeader    |   ChunkMsgHeader  |   ExtendedTimeStamp   |   ChunkData   |
    +-----------------------------------------------------------------------------------+
解释:
    ChunkBasicHeader:   块基本头, 包含 『块流ID』和『块类型』(4中类型),每种类型的块**必须包含**
        块基本头示意:
            +-----------------------------------+
            |   fmt(2 bits)     |   csid(变长)   |
            +-----------------------------------+
        ftm: 表示块类型  
        csid: chunk stream id (小端表示法)   块流ID    范围[3, 65599]    [0,2]为RTMP协议保留表示特殊信息
        块基本头长度可能为1、2、3字节

        1). ChunkBasicHeader 为 1 字节时, fmt占2 bits,csid占6 bits
            csid in [0, 63]
        2). ChunkBasicHeader 为 2 字节时, 第一字节除去fmt外全置0, 剩下 1 字节用来表示csid
            csid in [64, 2^8 + 64 = 319]
        3). ChunkBasicHeader 为 3 字节时,第一字节除去fmt外全置1, 剩下2字节用来表示csid
            csid in [64, 2^16 + 64 = 65599]

            对于出现重叠的情况,应当使用使header**尽可能小**的实现

        代码逻辑上可以这样处理:
        1).先接收1字节,分别取高两位和低六位保存起来,
        2).判断低六位是全0还是全1,如果是全0,表示ChunkBasicHeader长度为2字节,那么再接收1个字节,
        并且csid需要加上64,如果全为1,则表示长度为3字节,需要在接收2字节

    ChunkMsgHeader:     块消息头, 发送消息的信息,依据块基本头中的『块类型』分为4种:
        块类型0: 11 bytes  流开始的第一个块必须使用这种类型,流时间戳回退时也必须使用这种类型头(backward seek)
                +------------------------------------------------------------------------+
                |   TimeStamp(3 bytes)  |   MsgLength(3 bytes)  |   MsgTypeID(1 byte)    |
                +------------------------------------------------------------------------+
                |   MsgStreamID(4 bytes)|
                +-----------------------+
        块类型1: 7 bytes   省去了MsgStreamID 表示此chunk和上一次发送的chunk属于同一个流
             message大小变化的流的第一个消息块之后的每一个消息的第一个块应该使用这种头
                +-------------------------------------------------------------------------------+
                |   TimeStampDelta(3 bytes) |   MsgLength(3 bytes)  |   MsgTypeID(1 byte)   |
                +-------------------------------------------------------------------------------+
        块类型2: 3 bytes 表示此chunk和上一次发送的chunk的 MsgTypeID, MsgLength, MsgStreamID 相同,
               message大小不变的流的第一条message之后的每条message的第一个chunk
                +-------------------------------+
                |   TimeStampDelta(3 bytes)     |
                +-------------------------------+
        块类型3:   0 byte
            没有头 表示此chunk的 ChunkMsgHeader 和上一个完全一样, 表示此chunk时上一个chunk的分块

        TimeStamp:          时间戳
        MsgLength:          此chunk所属Message总长度,而非 ChunkData 长度
        MsgTypeID:          消息类型
        MsgStreamID:        消息流ID    (小端表示法)
        TimeStampDelta: 时间戳增量,溢出时该字段全置1并使用  ExtendedTimeStamp 字段 存储的是完整值
        ExtendedTimeStamp:  扩展时间戳,TimeStamp溢出时使用
        ChunkData:  块数据 大小在 [0, chunksize] 之间 chunksize由控制消息 set chunk size 决定(见后面描述)

消息分块

    消息过长时需要进行分块,消息负载(PayLoad)部分被分割成大小固定的数据块(Chunk)(128 by default),并在其首部加上消息块首部(ChunkHeader).
        1.分块前
                        |                               307                                 |
        +----------
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值