精华内容
下载资源
问答
  • Rtmp协议中文介绍

    2017-12-12 10:02:24
    消息块流是为 Rtmp协议设计的,他可以处理任何传送消息流的协议,每一个消息包含时间戳 合有效负载类型标示, 消息块流和 一起适用于多样性音视频应用程序,从一对一和一对 多向视频点播服务器直接广播到交互式会议...
  • RTMP协议中文.pdf

    2020-05-15 17:41:34
    Adobe公司的实时消息传输协议,RTMP协议官方说明文档,中文翻译。主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信
  • rtmp协议头分析

    千次阅读 2009-11-05 17:47:00
    以下是本人对rtmp协议的分析和理解,前阶段我在上网时看到有一位高手对rtmp协议部分进行详细剖析,此时本人正在做flex和java进行通讯的一个项目,其协议就用到了rtmp,经过我近段时间来对red5源代码的分析研究,觉得...

     以下是本人对rtmp协议的分析和理解,前阶段我在上网时看到有一位高手对rtmp协议部分进行详细剖析,此时本人正在做flexjava进行通讯的一个项目,其协议就用到了rtmp,经过我近段时间来对red5源代码的分析研究,觉得之前有些地方可能不太完善,还得进一步细化。

     

    第一步:建立rtmp协议

      要想建立rtmp协议,则在服务器必须要进行相应数据验证,flashflex(创建NetConnection连接过程中)客户端需要向服务器端发送13

     

    RTMP协议概述

    介绍:
    RTMP
    协议是被Flash用于对象,视频,音频的传输.该协议建立在TCP协议或者轮询HTTP协议之上.
    RTMP
    协议就像一个用来装数据包的容器,这些数据可以是AMF格式的数据,也可以是FLV中的视/音频数据.
    一个单一的连接可以通过不同的通道传输多路网络流.这些通道中的包都是按照固定大小的包传输的.
    var nc:NetConnection = new NetConnection();
    var connected:Boolean = nc.connect("rtmp:/localhost/roomapp")

     

    握手

    Client → Server :
    向服务器发出握手请求.这不属于协议包一部分,该握手请求第一个字节为(0×03),其后跟着1536个字节.

     Server → Client :服务器向客户端回应握手请求.这部分的数据仍然不属于RTMP协议的部分.该回应的其实字节仍然为(0x03),但是后边跟着个长度为1536个字节 (一共为3072 )的包块.第一个1536块看上去似乎可以是任意内容,甚至好像可以是Null都没有关系.第二个1536的代码块,是上一步客户端向服务器端发送的握手 请求的内容.
    Client→Server:
    把上一步服务器向客户端回应的第二块1536个字节的数据块.
    至此客户端与服务器端的握手结束,下面将发送RTMP协议的包内容.
    Client → Server :
    向服务器发送连接包.
    Server → Client :
    服务器回应.
    ... ....
    等等... ...

     

    引用如下(红色背景为我更正信息)

    RTMP协议封包 由一个包头和一个包体组成,包头可以是4种长度的任意一种:12, 8, 4,  1 byte(s).完整的RTMP包头应该是12bytes,包含了时间戳,AMFSize,AMFType,StreamID信息, 8字节的包头只纪录 了时间戳,AMFSize,AMFType,其他字节的包头纪录信息依次类推 。包体最大长度默认为128字节,通过chunkSize可改变包体最大长 度,通常当一段AFM数据超过128字节后,超过128的部分就放到了其他的RTMP封包中,包头为一个字节.
    完整的12字节RTMP包头每个字节的含义:

    用途

    大小(Byte)

    含义

    Head_Type

    1

    包头

    TiMMER

    3

    时间戳

    AMFSize

    3

    数据大小

    AMFType

    1

    数据类型

    StreamID

    4

    ID

     

     

    一、Head_Type
    第一个字节Head_Type的前两个Bit决定了包头的长度.它可以用掩码0xC0进行""计算:
    Head_Type
    的前两个Bit和长度对应关系:

    Bits

    Header Length

    00

    12 bytes

    01

    8 bytes

    10

    4 bytes

    11

    1 byte

     

    三、AMFSize
    AMFSize
    占三个字节,这个长度是AMF长度,可超过RTMP包的最大长度128字节。如果超过了128字节,那么由多个后续RTMP封包组合,每个后续RTMP封包的头只占一个字节。

    四、AMFType
    AMFSize占三个字节,这个长度是AMF长度,可超过RTMP包的最大长度128字节。
    AMFType
    是包的类型

    0×01

    Chunk Size

    changes the chunk size for packets

    0×02

    Unknown

     

    0×03

    Bytes Read

    send every x bytes read by both sides

    0×04

    Ping

    ping is a stream control message, has subtypes

    0×05

    Server BW

    the servers downstream bw

    0×06

    Client BW

    the clients upstream bw

    0×07

    Unknown

     

    0×08

    Audio Data

    packet containing audio

    0×09

    Video Data

    packet containing video data

    0x0A-0x0E

    Unknown

     

    0x0F

    FLEX_STREAM_SEND

    TYPE_FLEX_STREAM_SEND

    0x10

    FLEX_SHARED_OBJECT

    TYPE_FLEX_SHARED_OBJECT

    0x11

    FLEX_MESSAGE 

    TYPE_FLEX_MESSAGE 

    0×12

    Notify

    an invoke which does not expect a reply

    0×13

    Shared Object

    has subtypes

    0×14

    Invoke

    like remoting call, used for stream actions too.

     
      
      

    red5代码分析如下:

    Head_Type

    我看到代码red5与以上分析有些出入.

    Head_Type的前两个Bit和长度对应关系分析没有错.

    red5代码中计算头字节公式如下(头字节不一定是一个字节,有可能是两个字节或三个字节,需要说明的头字节计算结果最终会影响ChannelId)

    1.Head_Byte & 0x3F=0,headerValue= ((int) headerByte & 0xff) << 8| ((int) in.get() & 0xff)

    此时读出字节头为两个字节

    2.Head_Byte & 0x3F=1时,headerValue = ((int) headerByte & 0xff) << 16

                     | ((int) in.get() & 0xff) << 8 | ((int) in.get() & 0xff)

    此时读出字节头为三个字节

    3.如果以上两个条件都不满足,则headerValue = (int) headerByte & 0xff;

    channelId计算公式为:

    1. 如果头为一个字节,则channelId = (headerValue & 0x3f)

    2. 如果头为两个字节,channelId = 64 + (headerValue & 0xff)

    3. 如果头为三个字节,则channelId = 64 + ((headerValue >> 8) & 0xff) + ((headerValue & 0xff) << 8)

     

    Head_Type的后面6BitStreamID决定了ChannelID  StreamIDChannelID对应关系:StreamID=(ChannelID-4)/5+1 参考red5

    ChannelID

    Use

    02

    PingByteRead通道

    03

    Invoke通道 我们的connect() publish()和自字写的NetConnection.Call() 数据都是在这个通道的

    04

    AudioVidio通道

    05 06 07

    服务器保留,经观察FMS2用这些Channel也用来发送音频或视频数据

     

    以下是用一个截包工具获取原始二进制数据。

    03 00 00 00 00 01 30 14 00 00 00 00 02 00 07 63 6F 6E 6E 65 63 74 00 3F F0 00 00 00 00 00 00 03 00 03 61 70 70 02 00 08 72 6F 6F 6D 2F 30 30 31 00 08 66 6C 61 73 68 56 65 72 02 00 0E 57 49 4E 20 31 30 2C 30 2C 31 32 2C 33 36 00 06 73 77 66 55 72 6C 06 00 05 74 63 55 72 6C 02 00 1C 72 74 6D 70 3A 2F 2F 31 39 32 2E 31 36 38 2E 31 2E 31 38 2F 72 6F 6F 6D 2F 30 30 31 00 04 66 70 61 64 01 00 00 0C 63 61 70 61 62 69 6C 69C3 74 69 65 73 00 40 2E 00 00 00 00 00 00 00 0B 61 75 64 69 6F 43 6F 64 65 63 73 00 40 A8 EE 00 00 00 00 00 00 0B 76 69 64 65 6F 43 6F 64 65 63 73 00 40 6F 80 00 00 00 00 00 00 0D 76 69 64 65 6F 46 75 6E 63 74 69 6F 6E 00 3F F0 00 00 00 00 00 00 00 07 70 61 67 65 55 72 6C 06 00 0E 6F 62 6A 65 63 74 45 6E 63 6F 64 69 6E 67 00 40 08 00 00 00 00 00 00 00 00 09 02 00 0F 30 38 31 32 31 31C3 30 39 32 30 32 32 32 32 32 02 00 02 33 34 02 00 0D 31 39 35 2E 31 36 38 2E 31 34 2E 32 32 02 00 03 30 30 31 02 00 01 30 02 00 01 38 02 00 01 30

    1.      下面我们来对鲜绿色背景头数据进行分析

    从上面剖析包头说明判断可以第一个字节0x03,此包头有12个字节.

    Head_Type=03

    TiMMER=00 00 00

    AMFSize=00 01 30 表示经过组合之后AMF的总字节长度(默认情况下每个RTMP包为128字节,由C3字节得知,以上包有3rtmp封包)

    AMFType=14 表示接下来第一个字符串为远程调用方法名称

     

    02 00 07 63 6F 6E 6E 65 63 74  02字节表示字符串类型 00 07表示该字符串长度为7个字节63 6F 6E 6E 65 63 74connect远程方法

    StreamID=00 00 00  

    以后我还会陆续讲解rtmp协议中如何传输数组,map,List,Bean对象,以及基本数据类型

    展开全文
  • [RTMP协议]RTMP块头报文

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

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

    消息头MessageHeader

    在这里插入图片描述

    1. 消息类型:1byte,Message Type ID取值含义:
      在这里插入图片描述
    • A协议控制消息,Message Type ID = 1~6,主要用于协议内的控制。

    • 1,Set Chunk Size 设置块的大小,通知对端用使用新的块大小,共4 bytes

    • 2,Abort Message 取消消息,用于通知正在等待接收块以完成消息的对等端,丢弃一个块流中已经接收的部分并且取消对该消息的处理,共4 bytes。

    • 3,Acknowledgement 确认消息,客户端或服务端在接收到数量与窗口大小相等的字节后发送确认消息到对方。窗口大小是在没有接收到接收者发送的确认消息之前发送的字节数的最大值。服务端在建立连接之后发送窗口大小。本消息指定序列号。序列号,是到当前时间为止已经接收到的字节数。共4 bytes。

    • 4,User Control Message 用户控制消息,客户端或服务端发送本消息通知对方用户的控制事件。本消息承载事件类型和事件数据。消息数据的头两个字节用于标识事件类型。事件类型之后是事件数据。事件数据字段是可变长的。

    • 5,Window Acknowledgement Size 确认窗口大小,客户端或服务端发送本消息来通知对方发送确认(致谢)消息的窗口大小,共4 bytes.

    • 6,Set Peer Bandwidth 设置对等端带宽,客户端或服务端发送本消息更新对等端的输出带宽。发送者可以在限制类型字段(1 bytes)把消息标记为硬(0),软(1),或者动态(2)。如果是硬限制对等端必须按提供的带宽发送数据。如果是软限制,对等端可以灵活决定带宽,发送端可以限制带宽?。如果是动态限制,带宽既可以是硬限制也可以是软限制。

    • B数据消息,Message Type ID = 8 9 18;8: Audio 音频数据;9: Video 视频数据;18: Metadata 包括音视频编码、视频宽高等信息

    • C命令消息Message Type ID为15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停等

    1. 消息负载长度:3byte,消息负载的长度。
    2. 时间戳:4byte,单位毫秒。超过最大值后会翻转。
    3. 消息流ID:3byte,Message Stream ID,用于区分不同流的消息。每个消息的唯一标识,划分成Chunk和还原Chunk为Message的时候都是根据这个ID来辨识是否是同一个消息的Chunk的,4个字节,并且以小端格式存储

    消息块头MessageChunkHeader

    在这里插入图片描述
    块头由块基本头、块消息头和扩展时间戳组成。

    1. timestamp:3个字节,因此它最多能表示到16777215=0xFFFFFF=2^24-1, 当它的值超过这个最大值时,这三个字节都置为1,实际的timestamp会转存到Extended Timestamp字段中,接受端在判断timestamp字段24个位都为1时就会去Extended timestamp中解析实际的时间戳。
    2. message length:3个字节,表示实际发送的消息的数据如音频帧、视频帧等数据的长度,单位是字节。注意这里是Message的长度,也就是chunk属于的Message的总数据长度,而不是chunk本身Data的数据的长度。
    3. message type id:1个字节,表示实际发送的数据的类型,如8代表音频数据、9代表视频数据。就是上面的消息头的MessageType值。
    4. msg stream id:4个字节,表示该chunk所在的流的ID,和Basic Header的CSID一样,它采用小端存储的方式。

    块基本头

    在这里插入图片描述
    fmt取值决定了整个包头header的长度(以下表现的长度均不包含Basic header的长度)

    两位的fmt取值为 0~3,分别代表的意义如下:

    • case 0:chunk Msg Header长度为11;
    • case 1:chunk Msg Header长度为7;
    • case 2:chunk Msg Header长度为3;
    • case 3:chunk Msg Header长度为0;

    cs id: 是chunk stream id的缩写,同一个RTMP消息拆成的 chunk 块拥有相同的 cs id, 用于区分chunk所属的RTMP消息, chunk basic header 的类型cs id占用的字节数来确定。0、1、2作为保留。

    1. csid在3~63的范围内时
    2. csid在64~319的范围内时,第二个字节+64
    3. csid在64~65599的范围内时,第三个字节*256+第二个字节+64

    消息头与块头关系

    在这里插入图片描述分块例子

    • 在拆分到多个Chunk中的时候,第一个Chunk携带完整的Message Header信息
    • 因为一个流当中可以传输多个Chunk,那么多个Chunk怎么标记同属于一个Message的呢?
    • 是通过Chunk Stream ID区分的,同一个Chunk Stream ID必然属于同一个Message
      在这里插入图片描述
    展开全文
  • 本资源包含两个 pdf 文档,一本官方最新版的 rtmp_specification_1.0.pdf,一个中文翻译的 rtmp_specification_1.0_cn.pdf
  • 流媒体协议:RTMP协议(中文)详解 流媒体协议:RTMP协议(中文)详解 流媒体协议:RTMP协议(中文)详解
  • RTMP协议框架完美实现

    2018-06-15 17:02:17
    rtmpdump是一个优秀的rtmp框架,功能强大,大家可以下载并集成到自己的项目中。
  • linux版本-nginx 1.6.3.tar.gz下载,是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。附件包含nginx搭建rtmp协议流媒体服务器
  • RTMP协议

    千次阅读 2018-08-06 12:24:11
    RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题。 RTMP消息块流和...

    目录

    简介

    概念

    rtmp协议握手过程

    rtmp通信过程


    简介

    RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题。          

    RTMP消息块流和RTMP一起适用于多样性音视频应用程序,从一对一和一对 多向视频点播服务器直接广播到交互式会议应用程序。          

    RTMP协议是应用层协议,是要靠底层可靠的传输层协议(通常是TCP)来保证信息传输的可靠性的。在基于传输层协议的链接建立完成后,RTMP协议也要客户端和服务器通过“握手”来建立基于传输层链接之上的RTMP Connection链接。

     

    概念

    有效负载:

              包含在每一个包中的数据,就像音视频样本或压缩后的视频数据。

    包:

            一个数据包是由固定的包头和有效的负载数据来组成的。

    端口:

          rtmp协议默认使用的是1935端口。

    消息流:

          一个通信的逻辑通道,让消息流通

    消息流id:

         每个消息拥有一个分配的id,标识消息流。

    消息块:

        消息的一个片段,一个完整的消息会被分割成小的片段,每个片段都是一个消息块。

    消息块流:

        一个通信的逻辑通道,允许消息块在一个特定方向流通,例如:从客户端到服务器。

    消息块流id:

         每个消息块有一个分配的id用于识别跟随消息块流。

    复合技术:

          把分开的音视频数据组合成一条音视频流的过程。

    逆复合技术:

         复合的反向过程,交叉存取组装的音视频数据,是他们成为最初的音视频数据。

    时间戳:

         在rtmp消息块中的时间戳使用整数来表示,但是为毫秒。时间戳必须是线性增加的,允许引用程序处理异步传输,带宽度量,检测,流控制。

     

    rtmp协议握手过程

           要建立一个有效的rtmp连接,首先经过”握手”阶段,规则如下:

       

       客户端被指定依次向服务器发送C0,C1,C2三个chunk,服务器向客户端发送S0,S1,S2三个chunk。 详细发送要求:

    • 客户端开始发送C0,C1;
    • 客户端必须收到S1后,才发送C2;
    • 客户端必须收到S2后才开始发送其他信息(控制信息和音视频数据) 服务器要等收到C0才能发送S0和S1;
    • 服务器必须等C1后才能发送S2 服务器必须等收到C2之后才能发送其他数据(控制信息和音视频数据)

     

    rtmp通信过程

    简化如下:     

    • client--> server   : 发送一个创建流的请求  (C0、C1)。     
    • server--> client   : 返回一个流的索引号 (S0、S1、S2)。   
    •  client--> server   : 开始发送 (C2)    
    •  client--> server   : 发送音视频数据(这些包用流的索引号来唯一标识)

     

    握手第一阶段:     

            C0和S0都是rtmp版本包,大小1字节                                                                  

            版本:8比特,C0:客户端需求的rtmp版本,S0:服务器选择的rtmp版本,如图:

    握手第二阶段:

          客户端发送C1包,C1包大小1536字节,格式如下图:

         

          time:包含了一个时间戳,为了同步多个消息块流,     发送端会期望这个值是其他消息块的块流时间。 

    C1:S2: C2:

          服务器应答,发送S1包,S1数据和C1完全相同。

     

    握手第三阶段:  

              客户端发送C2包:C2包,包大小1536字节,包格式如图:     

                

             时间:4byte,这个字段必须对应发送的时间戳(C2:S1, S2:C1);     时间2:4byte,这个包含先前的每一个包被读的时间戳,     以及1528字节。

     

    握手完成

           消息分块:握手完成,复合多个消息分块,每个消息块有一个唯一分配的消息块流id,消息块流在网络上传输。 一个消息块发送完,才能发送下一个消息块。服务器接收完,基于消息块流id,复合成消息。

     

    拆分的意义

         消息块格式:   

                消息块的默认大小128字节。通过set Chunk size 设置块的最大值。     格式如图:

             

     

    参考:https://www.yuque.com/docs/share/6d5357b8-33a9-42e2-9b9d-6bf72805716a

    展开全文
  • 支持rtmp协议的ijkplayer

    2019-08-09 10:01:15
    自己编译的Android ijkplayer,支持播放rtmp地址的流。支持x86、armv7a、armv5、arm64
  • rtmp协议抓包分析

    2015-01-17 21:42:11
    rtmp协议抓包分析
  • 基于rtmp协议android端推流Demo 直接设置IP推流到rtmp流媒体服务器
  • plugin-rtmp the rtmp protocol plugin for...实现了RTMP协议的播放,可供rtmp协议播放器拉流播放。 插件名称 RTMP 配置 [RTMP] ListenAddr = ":1935" ChunkSize = 512 ListenAddr 代表监听的端口号 ChunkSize 分包大小
  • RTMP协议详解

    2018-07-30 15:20:35
    流媒体协议:RTMP协议(中文)详解 流媒体协议:RTMP协议(中文)详解
  • RTMP协议规范中文翻译

    2017-11-14 17:14:44
    RTMP协议RTMP协议完整的中文翻译手册,便于学习RTMP协议
  • RTMP协议官方文档

    2013-03-07 17:25:07
    RTMP协议官方文档 文档为英文版,从官方网站下载,希望对你有帮助
  • rtmp 协议规范文档,中文+英文+txt格式, 内附rtmp视频推送数据抓包H264, H265,可供开发参考;
  • rtmp协议详解

    千次阅读 2019-03-23 17:55:32
    最近在学习rtmp协议,在看官方文档的时候总是懵懵懂懂,硬生生看了两天,现在基本上了解rtmp协议了,想用自己觉得比较清晰的方式来讲解rtmp协议,希望能够对向我一样的初学者有所帮助。 本文将通过以下四部分讲解...

    前言

    最近在学习rtmp协议,在看官方文档的时候总是懵懵懂懂,硬生生看了两天,现在基本上了解rtmp协议了,想用自己觉得比较清晰的方式来讲解rtmp协议,希望能够对向我一样的初学者有所帮助。

    本文将通过以下四部分讲解rtmp协议。

    • 1、消息
    • 2、块
    • 3、rtmp的消息类型
    • 4、实例分析rtmp传输过程

    一、消息

    消息是rtmp的基本数据单元,服务端和客户端通过在网络上发送RTMP消息进行通讯。消息可能包含音频,视频,数据,或其他的消息。

    消息格式

    RTMP消息头和载荷两部分。

    消息头
    长度含义
    message type1byte表示消息类型
    payload length3byte表示载荷的字节数,big-endian格式
    timestamp4byte表示消息的时间戳,big-endian格式
    stream id3byte表示消息流ID,big-endian格式
    • 消息类型:

    1-7的消息ID用于协议控制消息

    8、9的消息分别用于传输音频和视频数据

    15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停

    载荷

    载荷中消息中包含的真实数据。例如,它可以是音频样本或压缩的视频数据。

    二、块

    消息是rtmp协议的基本数据单元,在网络传输时,消息会被重新封装成块进行传输,每个块都有固定的大小,如果消息大小大于块的大小,消息就会被拆分成几个块发送。

    块格式

    块由头和载荷组成

    块头结构
    长度含义
    basic header1byte或2byte或3byte块基本头
    chunk msg header11byte或2byte或3byte块消息头
    extended timestamp4byte扩展时间戳
    a、块基本头(basic header)
    • 基本头第一个字节的结构:
    长度含义
    fmt2bit块格式
    cs id6bit块流ID
    • fmt的含义
    含义
    0表示块消息头是类型0
    1表示块消息头是类型1
    2表示块消息头是类型2
    3表示块消息头是类型3
    • cs id的含义
    含义
    0块基本头2个字节,块流ID计算方法(第2个字节+64),范围(64-319)
    1块基本头3个字节,块流ID计算方法(第3个字节*255+第2个字节+64),范围(3-65599)
    2块基本头1个字节,2表示低层协议消息
    3-64块基本头1个字节,该数表示块流ID,范围(3-64)

    本协议支持65597种流,ID从3-65599。ID 0、1、2作为保留。

    b、块消息头(chunk msg header)
    • 类型0

    类型0总共11byte,格式如下:

    长度含义
    timestamp3byte时间戳
    message length3byte载荷的长度
    message type id1byte消息类型id
    message stream id4byte消息流id
    • 类型1

    类型1总共7byte,格式如下:

    长度含义
    timestamp3byte时间戳
    message length3byte载荷的长度
    message type id1byte消息类型id
    • 类型2

    类型1总共3byte,格式如下:

    长度含义
    timestamp3byte时间戳
    • 类型3

    类型3的块没有头。流ID,消息长度,时间戳都不出现。这种类型的块使用与先前块相同的数据。当一个消息被分成多个块,除了第一块以外,所有的块都应使用这种类型。

    c、扩展时间戳(extended timestamp)

    扩展时间戳总共4个字节,只有当块消息头中的普通时间戳设置为0x00ffffff时,本字段才被传送。如果普通时间戳的值小于0x00ffffff,那么本字段一定不能出现。

    上面已经详解讲解了rtmp的数据格式了,下面来讲解具体的rtmp协议内容。

    载荷

    块的载荷就是消息的载荷内容。

    总结一下:消息是rtmp的基本数据单元,块是用于将消息重新封装在网络上传输。

    三、rtmp的消息类型

    rtmp的消息类型可分为三大类:协议控制消息、用户控制消息、RTMP命令消息

    1、协议控制消息

    1.1.设置块大小消息(Message Type=1)

    设置块大小,被用来通知对方新的最大块大小。
    默认最大块大小为128字节,客户端和服务器可以使用此消息来修改默认的块大小。例如,假设客户端想要发送的音频数据大小为131字节,而块大小为128字节。在这种情况下,客户端可以通知服务器新的块大小为131字节,然后就可以使用一个块来发送完整的音频数据了。

    最大的块大小建议至少为128字节,但必须至少为1字节。通信的每一个方向(例如从客户端到服务器)拥有独立的块大小设置。最大的块大小由通信双方 (服务器或者客户端) 自行维护。

    设置块大小消息载荷一共4个字节,格式如下:

    长度含义
    01bit第一位必须为0
    chunk size31bit新的最大块大小值
    1.2.终止消息(Message Type=2)

    终止消息,用于通知对端,如果正在等待一条消息的部分块(已经接收了一部分),那么可以丢弃之前已经接收到的块。对端将接收到的块流ID作为当前协议控制消息的有效负载。应用程序可能会在关闭的时候发送这个消息以指示不需要进一步对这个消息的处理了。

    终止消息载荷一共4个字节,格式如下:

    长度含义
    chunk stream id4byte块流id,该块流的消息会别丢齐
    1.3.确认消息(Message Type=3)

    客户端或者服务器在接收到等同于窗口大小的字节之后必须发送给对端一个确认消息。窗口大小是指发送者在没有收到接收者确认消息之前发送的最大字节数。这个消息定义了序列号,也就是到目前为止接收到的字节数。

    确认消息载荷一共4个字节,格式如下:

    长度含义
    sequence number4byte目前为止接收到的字节数
    1.4.确认窗口大小消息(Message Type=5)

    客户端或服务端发送本消息来通知对方发送确认(致谢)消息的窗口大小。例如,服务端希望每当发送的字节数等于窗口大小时从客户端收到确认(致谢)。服务端在成功处理了客户端的连接请求后向客户端更新窗口大小。

    确认窗口大小消息载荷一共4个字节,格式如下:

    长度含义
    acknowledge window size4byte确认窗口的大小
    1.5.设置对端带宽消息(Message Type=6)

    客户端或服务端发送本消息更新对等端的输出带宽。输出带宽值与窗口大小值相同。如果对等端在本消息中收到的值与窗口大小不相同,则发回确认(致谢)窗口大小消息。

    长度含义
    acknowledge window size4byte确认窗口的大小
    limit type1byte限制类型字段
    • limit type:

    发送者可以在限制类型字段把消息标记为硬(0),软(1),或者动态(2)。如果是硬限制对等端必须按提供的带宽发送数据。如果是软限制,对等端可以灵活决定带宽,发送端可以限制带宽。如果是动态限制,带宽既可以是硬限制也可以是软限制。

    2、用户控制消息(Message Type=4)

    RTMP使用消息类型ID 4表示用户控制消息。这些消息包含RTMP流传输层所使用的信息。协议控制消息使用的ID为 1、2、3、5 和 6 (前面已经介绍过了)。
    用户控制消息应该使用消息流ID 0 (以被认为是控制流),并且以RTMP块流发送时以块流ID为2。协议控制消息接收立即生效;解析时,时间戳字段被忽略。

    客户端或者服务器端发送这个消息来通知对端一些用户控制事件。

    这一消息携带有事件类型和事件数据,格式如下:

    长度含义
    event type2byte事件类型
    event data?事件数据
    • event type
    事件描述
    Stream Begin (=0)服务器发送这个事件来通知客户端一个流已就绪并可以用来通信。默认情况下,这一事件在成功接收到客户端的连接命令之后以ID=0发送。事件数据为4字节,代表了已就绪流的流ID。
    Stream EOF (=1)服务器发送这一事件来通知客户端请求的流的数据回放已经结束。在发送额外的命令之前不再发送任何数据。客户端将丢弃接收到的这个流的消息。事件数据为4字节,代表了回放已结束的流的流 ID。
    StreamDry (=2)服务器发送这一事件来通知客户端当前流中已没有数据。当服务器在一段时间内没有检测到任何消息,它可以通知相关客户端当前流已经没数据了。这一事件数据为4字节,代表了已没数据的流的流 ID。
    SetBuffer Length (=3)客户端发送这一事件来通知服务器缓冲区大小 (以毫秒为单位),这个缓冲区用于缓存来自流的任何数据。此事件在服务器开始处理流之前就发送。事件数据的前4个字节代表了流ID,紧接其后的4个字节代表了以毫秒为单位的缓冲区的长度。
    Streams Recorded (=4)服务器发送这一事件来通知客户端当前流是一个录制流。事件数据为4字节,代表了录制流的流 ID。
    PingRequest (=6)服务器端发送这一事件用于测试客户端是否可达。事件数据是为一个4字节的时间戳,代表了服务器端发送这一命令时的服务器本地时间。客户端在接收到这一消息后会立即发送 PingResponse 回复。
    PingResponse(=7)客户端发送这一事件用于回复服务器的PingRequest。事件数据是为一个4字节的时间戳,该时间戳是从接收到的PingRequest的事件数据中获取的。

    3、RTMP命令消息

    3.1.数据消息(Message Type=18或15)

    客户端或服务端通过本消息向对方发送元数据和用户数据。元数据包括数据的创建时间、时长、主题等细节。消息类型为18的用AMF0编码,消息类型为15的用AMF3编码。

    3.2.共享对象消息 (Message Type=19或16)

    共享对象是跨多个客户端,实例同步的FLASH对象(名值对的集合)。消息类型kMsgContainer=19用AMF0编码,kMsgContainerEx=16用AMF3编码,这两个消息用于共享对象事件。每个消息可包含多个事件。

    格式如下:
    在这里插入图片描述

    事件描述
    Use (=1)客户端发送这个事件通知服务端创建一个命名的共享对象。
    Release (=2)当客户端删除共享对象时,发送这个事件通知服务端。
    Requeset change (=3)当请求改变一个共享对象的某个命名参数的关联的值时,客户端发送本消息。
    Change (=4)当某个命名参数的关联值被改变时,服务端发送本事件给所有的客户端。
    Success (=5)当接受请求改变事件后,服务端向发请求的客户端响应本消息。
    SendMessage (=6)客户端向服务端发送本事件广播一个消息。接收到本事件后服务端向包括发送本事件在内的所有客户端广播一个消息。
    Status (=7)针对一个错误状态,服务端向客户端发送本事件。
    Clear (=8)服务端向客户端发送本事件,清除一个共享对象。本事件也作为客户端在连接时发送use事件的响应。
    Remove (=9 )服务端发送本事件使客户端删除一个插槽。
    Request Remove (=10)客户端删除一个插槽时向服务端发送本事件。
    Use Success(=11)当连接成功时服务端向客户端发送本事件。
    3.3.音频消息 (Message Type=8)

    客户端和服务端使用该消息向对端发送音频数据。

    3.4.视频消息 (Message Type=9)

    客户端和服务端使用该消息向对端发送视频数据。

    3.5.聚合消息(Message Type=22)

    聚合消息是包含一系列子消息的单个消息。

    格式如下:

    在这里插入图片描述

    聚合消息的消息流ID将覆盖消息聚合内的子消息的流ID。
    聚合消息与第一条子消息时间戳的区别是偏移量,它用于将子消息的时间戳重新归一到流时间表。偏移量被添加到每个子消息的时间戳以达到归一化流时间。 第一个子消息的时间戳应该与聚合消息的时间戳相同,所以偏移应该为零。
    返回指针包含前一个消息的大小,包括它的消息头。 包含消息头是为了与FLV文件的格式相匹配和用于向后查找

    3.6.命令消息(Message Type=20或17)

    命令消息承载用AMF编码的客户端与服务端之间的命令。消息类型为20的用AMF0编码,消息类型为17的用AMF3编码。

    这些消息用于在远端实现连接,创建流,发布,播放和暂停等操作。状态,结果等命令消息用于通知发送者请求命令的状态。命令消息由命令名,传输ID,和包含相关参数的命令对象组成。客户端或服务端可以使用命令消息向远端请求远程过程调用。

    a.NetConnection相关命令
    • connect
    • call
    • close
    • createStream
    b.NetStream相关命令
    • play
    • play2
    • deleteStream
    • closeStream
    • receiveAudio
    • receiveVideo
    • publish
    • seek
    • pause
    • 服务器使用"onStatus"命令向客户端发送NetStream状态:

    四、实例分析rtmp传输过程

    这部分将介绍rtmp传输过程,并且使用wireshark抓包,分析实例。

    • 握手
    • 建立网络连接
    • 建立流
    • 播放

    1、握手

    (1)握手开始于客户端发送C0,C1块。

    (2)服务端在接收到C0后发送S0,S1块。

    (3)客户端接收到S0,S1块后,发送C2块,服务端接收到C0,C1块后发送S2块。

    (4)当客户端接收到S2,服务端接受到C2,分别校验后握手成功。

    示意图如下:

    在这里插入图片描述

    C0、S0的只有1个字节,格式如下:

    长度含义
    version1byte版本号

    C1、S1有1526个字节,格式如下:

    长度含义
    time4byte时间戳
    zero4byte
    random bytes1528byte本字段用于校验使用

    C2和S2的消息格式

    C2和S2的消息个事和C1、S2一样,C2是对S1的拷贝,S2是对C1的拷贝。

    服务端在接受到C2后会与S1对比。

    客户端在接受到S2后会与C1对比。

    rtmp通过这种手段来判断握手是否成功。

    实例分析:

    (1)握手开始于客户端发送C0,C1块:

    在这里插入图片描述

    03:这个字节是C0,表示版本号。
    
    之后的1536个字节都是C1
    ff fd fe b4:时间戳
    00 00 00 00:四个零
    
    之后1528个字节都是随机数
    

    (2)服务端在接收到C0后发送S0,S1块:

    在这里插入图片描述

    03:这个字节是S0,表示版本号。
    
    之后的1536个字节都是S1
    ff fd fe b4:时间戳
    00 00 00 00:四个零
    
    之后1528个字节都是随机数
    

    (3)客户端接收到S0,S1块后,发送C2块,服务端接收到C0,C1块后发送S2块。

    下图是服务端发送的S2:
    在这里插入图片描述

    可以看出,数据是与C1相同的。

    下图是客户端发送的C2:

    在这里插入图片描述

    可以看出,数据是与S1相同的。

    到此握手完成。

    2、建立网络连接

    (1)客户端发送"connect消息"请求连接。

    (2)服务收到"connect"请求后,发送一个"确认窗口大小消息"。

    (3)服务端发送"设置带宽消息"到客户端。

    (4)客户端处理"设置带宽消息"后,发送"确认窗口大小消息"到服务端(设置带宽消息的值与窗口大小不相同才会发送此消息)。

    (5)服务器发送用户控制消息中的“流开始(Stream Begin)消息“到客户端。

    (6)服务器发送“命令消息”中的”结果“(_result),通知客户端连接的状态。

    示意图如下:

    在这里插入图片描述

    实例分析:

    客户端向服务端发送命令消息的"connect命令":

    在这里插入图片描述

    03:bit[7:8]表示fmt为0,bit[0:6]表示块流ID为3(如果是0,则表示有一个扩展字节;如果是1,则表示有两个扩展字节,如果是2则表示底层协议控制消息和命令)
    因为fmt为0,所以接下来的块消息头有11个字节
    00 00 00:timestamp
    00 00 5f:message length
    14:message type,十进制为20,表示消息数据类型使用AMF0编码
    00 00 00 00:msg stream id
    接下来是块数据
    
    02:amf type(表示字符串)
    00 07:string length(表示字符串长度)
    63 6f 6e 6e 65 63 74:string("connect")
    
    00 :amf type(表示double型)
    3f f0 00 00 00 00 00 00:val
    
    03:amf type(表示Object型)
    
    key:
    00 03:string length(表示字符串长度)
    61 70 70:string("app")
    value:
    02:amf type(表示字符串)
    00 04:string length(表示字符串长度)
    74 79 70 65:string("live")
    key:
    00 04:string length(表示字符串长度)
    74 79 70 65:string("type")
    val:
    02:amf type(表示字符串)
    00 0a:string length(表示字符串长度)
    6e 6f 6e 70 72 69 76 61 74 65:string("nonprivate")
    key:
    00 05:string length(表示字符串长度)
    74 63 55 72 6c:string("tcUrl")
    val:
    02:amf type(表示字符串)
    00 1f:string length(表示字符串长度)
    72 74 6d 70 3a 2f 2f 31 39 32 2e 31 36 38 2e 31 36 38 2e 31 36 2e 31 32 38 3a 38 30 30 31 2d 6c 69 76 65:string("rtmp://192.168.16.128:8001/live")
    
    00 00 09:表示结束
    

    服务端向客户端发送确认窗口消息:

    在这里插入图片描述

    02:bit[7:8]表示fmt为0,bit[0:6]表示块流ID为2(2表示底层协议控制消息和命令)
    因为fmt为0,所以接下来的块消息头有11个字节
    00 00 00:timestamp
    00 00 54:message length
    05:message type(5表示确定窗口大小事件)
    00 00 00 00:msg stream id
    00 4c 4b 40:window size
    

    此后服务端又向客户端发送了三条消息,这里和文档说的有点不大一样,我也不太理解,希望有大佬能够解释解释:

    在这里插入图片描述

    该块流包含几条消息

    • 第一条消息为设置对端带宽消息
    02:bit[7:8]表示fmt为0,bit[0:6]表示块流ID为2(2表示底层协议控制消息和命令)
    因为fmt为0,所以接下来的块消息头有11个字节
    00 00 00:timestamp
    00 00 05:message length
    06:message type(6表示设置对端带宽消息)
    00 00 00 00:msg stream id
    00 4c 4b 40:window size(带宽为5M)
    02 :limit type
         0 - Hard:对端应该限制其输出带宽不超过指定的窗口大小。
        1 - Soft:对端应该限制其输出带宽不超过指定的窗口大小,或者已经有限制在起作用的话,就取两个窗口大小之间的较小值。
        2 - Dynamic:如果先前的限制类型为 Hard,则这条消息的也被视为Hard消息,否则的话忽略这条消息。
    
    • 第二条消息为设置块大小消息
    02:bit[7:8]表示fmt为0,bit[0:6]表示块流ID为2(2表示底层协议控制消息和命令)
    因为fmt为0,所以接下来的块消息头有11个字节
    00 00 00:timestamp
    00 00 04:message length
    01:message type(1表示设置块大小消息)
    00 00 00 00:msg stream id
    00 00 10 00
    
    • 第三条消息为connect回复消息
    03:bit[6:7]表示fmt为0,bit[0:5]表示块流ID为1(3表示块流ID)
    因为fmt为0,所以接下来的块消息头有11个字节
    00 00 00:timestamp
    00 00 be:message length
    14:message type(十进制为20,表示消息数据以AMF0格式编码)
    00 00 00 00:msg stream id
    
    02:amf type(表示字符串)
    00 07:string length(表示字符串长度)
    5f 71 65 73 75 6c 74:string("_resulte")
    00:amf type(表示double)
    3f f0 00 00 00 00 00 00:val(double型)
    
    03:amf type(表示Object类型)
    key:
    00 06:string length(表示字符串长度)
    66 6d 73 56 65 72:string("fmsVer")
    val:
    02:amf type(表示字符串)
    00 0d:string length(表示字符串长度)
    46 4d 53 2f 33 2c 30 2c 30 2c 31 2c 31 32 33:string("FMS/2,0,1,123")
    ...
    00 00 09:end
    

    3、建立流

    (1)客户端发送"命令消息"中的"创建流命令(createStream)"到服务端。

    (2)服务端接受到消息之后,发送"命令消息"中的"结果(_result)"。

    示意图如下:

    在这里插入图片描述

    实例分析:

    (1)客户端向服务端发送"命令消息"中的"createStream命令":

    在这里插入图片描述

    (2)服务端向客户端发送"命令消息"中的"结果(_result)":

    在这里插入图片描述

    4、发布音视频数据

    (1)客户端发送"命令消息"中的"publish命令"。

    (2)服务端接受到消息之后发送用户控制消息中的“streambegin”。

    (3)客户端开始发送音视频数据。

    示意图如下:

    在这里插入图片描述

    实例分析:

    客户端发送"命令消息"中的"publish命令":

    在这里插入图片描述

    服务端回复:

    在这里插入图片描述

    客户端发送多媒体信息:

    在这里插入图片描述

    客户端发送多媒体数据:

    在这里插入图片描述

    展开全文
  • 详细的RTMP协议介绍,包括RTMP的交互过程和报文的详细构成。
  • rtmp 协议规范 中文版

    千次下载 热门讨论 2013-11-16 20:06:29
    rtmp的协议规范,中文版的,学习RTMP协议的好资源。
  • RTMP完整协议

    2019-04-25 15:24:54
    目前rtmp版本定义为3,0-2是早期的专利产品所使用的值,现已经废弃,4-31是预留值,32-255是禁用值(这样做是为了区分基于文本的协议,因为这些协议通常都是以一个可打印的字符开始),如果服务端不能识别客户请求的版本,...
  • RTMP协议分析

    2018-01-05 07:28:04
    RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司提出的一种应用层的协议,用来解决多媒体数据传输流的多路复用(Multiplexing)和分包(packetizing)的问题
  • 拉流播放器采用b站的ijkplayer,推流rtmp协议代码封装完全java代码实现,除了使用yuv图片操作的一个第三方c库来提高效率。全部开源,全部免费。不需要任何商业付费。 运行环境:win10+android studio 3.4.1 服务器端...
  • ​之前文章,我们介绍过基于rtmp的直播环境的搭建,接下来,我们一起来学习一下Rtmp协议的细节,由于协议本身比较琐碎,小编会将rtmp协议拆解为一个个的小的模块,通过本公号推送rtmp协议的系列文章,欢迎诸位关注,...
  • rtp协议往rtmp协议转换

    2014-06-16 13:21:16
    这是一篇论文,描述了如何从rtp协议往rtmp协议转换的实现细节和意义。
  • RTMP协议封 包 由一个包头和一个包体组成,包头可以是4种长度的任意一种:12, 8, 4, 1 byte(s).完整的RTMP包头应该是12bytes,包含了时间戳,AMFSize,AMFType,StreamID信息, 8字节的包头只纪录 了时间戳,AMFSize,AMFType...
  • rtmp协议文档.7z

    2019-10-11 17:56:26
    RTMP文档1.0版本,包括中文翻译等,是学习RTMP协议的必读内容。
  • rtmp协议测试

    2019-05-03 22:27:06
    librtmp 测试 #include <stdio.h> #include <stdlib.h>...#include "librtmp/rtmp.h" #include "librtmp/log.h" /* flv 格式简单分析参考: https://blog.csdn.net/weixin_33962621/a...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,978
精华内容 7,591
关键字:

rtmp协议头