RTMP协议相关知识

@TOC

1. RTMP协议简介

RTMP协议是一个互联网TCP/IP五层体系结构中应用层的协议。RTMP协议中基本的数据单元称为消息(Message)。当RTMP协议在互联网中传输数据的时候,消息会被拆分成更小的单元,称为消息块(Chunk)。RTMP 是目前主流的流媒体传输协议,广泛用于直播领域,可以说市面上绝大多数的直播产品都采用了这个协议。
RTMP协议就像一个用来装数据包的容器,这些数据可以是AMF格式的数据,也可以是FLV中的视/音频数据。一个单一的连接可以通过不同的通道传输多路网络流。这些通道中的包都是按照固定大小的包传输的。

  • 优点
  1. CDN 支持良好,主流的 CDN 厂商都支持
  2. 协议简单,在各平台上实现容易
  • 缺点
  1. 基于 TCP ,传输成本高,在弱网环境丢包率高的情况下问题显著
  2. 不支持浏览器推送
  3. Adobe 私有协议,Adobe 已经不再更新

2. RTMP协议基本概念

2.1 消息相关概念

RTMP传输的数据的基本单元为Message,但是实际上传输的最小单元是Chunk(消息块),因为RTMP协议为了提升传输速度,在传输数据的时候,会把Message拆分开来,形成更小的块,这些块就是Chunk。

2.1.1 消息

消息是RTMP协议中基本的数据单元。不同种类的消息包含不同的Message Type ID,代表不同的功能。RTMP协议中一共规定了十多种消息类型,分别发挥着不同的作用。

1-7的消息用于协议控制,这些消息一般是RTMP协议自身管理要使用的消息,用户一般情况下无需操作其中的数据
Message Type ID为8,9的消息分别用于传输音频和视频数据
Message Type ID为15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停等等
消息首部(Message Header)有四部分组成:标志消息类型的Message Type ID,标志消息长度的Payload Length,标识时间戳的Timestamp,标识消息所属媒体流的Stream ID

在这里插入图片描述

下面针对上图的消息结构体进行简要分析:

  • Message Type:它是一个消息类型的ID,通过该ID接收方可以判断接收到的数据的类型,从而做相应的处理。Message Type ID在1-7的消息用于协议控制,这些消息一般是RTMP协议自身管理要使用的消息,用户一般情况下无需操作其中的数据。
  • Message Type ID为8,9的消息分别用于传输音频和视频数据。Message Type ID为15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停等。
  • Playload Length: 消息负载的长度,即音视频相关信息的的数据长度,4个字节
  • TimeStamp:时间戳,3个字节。
  • Stream ID:消息的唯一标识。拆分消息成Chunk时添加该ID,从而在还原时根据该ID识别Chunk属于哪个消息。
  • Message Body:消息体,承载了音视频等信息。

2.1.2. 消息块

在网络上传输数据时,消息需要被拆分成较小的数据块,才适合在相应的网络环境上传输。RTMP协议中规定,消息在网络上传输时被拆分成消息块(Chunk)。
消息块首部(Chunk Header)有三部分组成:

  • 用于标识本块的Chunk Basic Header
  • 用于标识本块负载所属消息的Chunk Message Header
  • 以及当时间戳溢出时才出现的Extended Timestamp
在这里插入图片描述

在这里插入图片描述

通过上图可以看出,消息块在结构上与与消息类似,有Header和Body。
下面对图的每个部分简要介绍:

  • Basic Header:基本的头部信息,在头部信息里面包含了chunk stream ID(流通道Id,用来标识指定的通道)和chunk type(chunk的类型)。
  • Message Header:消息的头部信息,包含了要发送的实际信息(可能是完整的,也可能是一部分)的描述信息。Message Header的格式和长度取决于Basic Header的chunk type。
  • Extended TimeStamp:扩展时间戳。
  • Chunk Data:块数据。

注意: RTMP在传输数据的时候,发送端会把需要传输的媒体数据封装成消息,然后把消息拆分成消息块,再一个一个进行传输。接收端收到消息块后,根据Message Stream ID重新将消息块进行组装、组合成消息,再解除该消息的封装处理就可以还原出媒体数据。由此可以看出,RTMP收发数据是以Chunk为单位,而不是以Message为单位。需要注意的是,RTMP发送Chunk必须是一个一个发送,后面的Chunk必须等前面的Chunk发送完成。

2.1.3. 消息分块

在消息被分割成几个消息块的过程中,消息负载部分(Message Body)被分割成大小固定的数据块(默认是128字节,最后一个数据块可以小于该固定长度),并在其首部加上消息块首部(Chunk Header),就组成了相应的消息块。消息分块过程如图5所示,一个大小为307字节的消息被分割成128字节的消息块(除了最后一个)。

RTMP传输媒体数据的过程中,发送端首先把媒体数据封装成消息,然后把消息分割成消息块,最后将分割后的消息块通过TCP协议发送出去。接收端在通过TCP协议收到数据后,首先把消息块重新组合成消息,然后通过对消息进行解封装处理就可以恢复出媒体数据。

在这里插入图片描述

2.2. RTMP中的逻辑结构

RTMP协议规定,播放一个流媒体有两个前提步骤

第一步,建立一个网络连接(NetConnection)
第二步,建立一个网络流(NetStream)。

其中,网络连接代表服务器端应用程序和客户端之间基础的连通关系。网络流代表了发送多媒体数据的通道。服务器和客户端之间只能建立一个网络连接,但是基于该连接可以创建很多网络流。他们的关系如图所示:

在这里插入图片描述

2.5.

2.6.

2.7.

3. RTMP协议流程

总的流程图如下:


在这里插入图片描述

3.1. 连接流程

播放一个RTMP协议的流媒体需要经过以下几个步骤:

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

RTMP连接都是以握手作为开始的。建立连接阶段用于建立客户端与服务器之间的“网络连接”;建立流阶段用于建立客户端与服务器之间的“网络流”;播放阶段用于传输视音频数据。

下面来详细分析一下这几个过程都做了一些什么东东

3.1.1.握手

在rtmp连接建立后,服务端与客户端需要通过3次交换报文完成握手,握手其他的协议不同,是由三个静态大小的块,而不是可变大小的块组成的,客户端与服务器发送相同的三个chunk,客户端发送c0,c1,c2,服务端发送s0,s1,s2。

  • 发送规则

握手开始于客户端发送 C0,C1 块。
在发送 C2 之前客户端必须等待接收 S1 。
在发送任何数据之前客户端必须等待接收 S2。
服务端在发送 S0 和 S1 之前必须等待接收 C0,也可以等待接收 C1。
服务端在发送 S2 之前必须等待接收 C1。
服务端在发送任何数据之前必须等待接收 C2。

  • 数据格式

C0与S0

C0和S0的长度是一个字节,在 S0 中这个字段表示服务器选择的 RTMP 版本。rtmp1.0规范所定义的版本是 3;0-2 是早期产品所用的,已被丢弃;4-31保留在未来使用;32-255 不允许使用(为了区分其他以某一字符开始的文本协议)。如果服务无法识别客户端请求的版本,应该返回 3 。客户端可以选择减到版本 3 或选择取消握手。

C1与S1

C1 和 S1 有 1536 字节长,由下列字段组成:
时间:4 字节 本字段包含时间戳。该时间戳应该是发送这个数据块的端点的后续块的时间起始点。可以是 0,* 或其他的 任何值。为了同步多个流,端点可能发送其块流的当前值。
零:4 字节 本字段必须是全零。
随机数据:1528 字节。 本字段可以包含任何值。 因为每个端点必须用自己初始化的握手和对端初始化的握 手来区分身份,所以这个数据应有充分的随机性。但是并不需要加密安全的随机值,或者动态值

C2与S2

C2 和 S2 消息有 1536 字节长。只是 S1 和 C1 的回复。本消息由下列字段组成。
时间:4 字节 本字段必须包含对等段发送的时间(对 C2 来说是 S1,对 S2 来说是 C1)。
时间 2:4 字节 本字段必须包含先前发送的并被对端读取的包的时间戳。
随机回复:1528 字节 本字段必须包含对端发送的随机数据字段(对 C2 来说是 S1,对 S2 来说是 C1) 。 每个对等端可以用时间和时间 2 字段中的时间戳来快速地估计带宽和延迟。 但这样做可 能并不实用。
RTMP握手的这个过程就是完成了两件事:1. 校验客户端和服务器端RTMP协议版本号,2. 是发了一堆数据,猜想应该是测试一下网络状况,看看有没有传错或者不能传的情况。

  • 流程图如下


    在这里插入图片描述

3.1.2. 建立网络连接

  • 流程图如下:


    在这里插入图片描述

下面对建立网络连接的流程简单介绍

  1. 客户端发送命令消息中的“连接”(connect)到服务器,请求与一个服务应用实例建立连接。
  2. 服务器接收到连接命令消息后,发送确认窗口大小(Window Acknowledgement Size)协议消息到客户端,同时连接到连接命令中提到的应用程序。
  3. 服务器发送设置带宽()协议消息到客户端。
  4. 客户端处理设置带宽协议消息后,发送确认窗口大小(Window Acknowledgement Size)协议消息到服务器端。
  5. 服务器发送用户控制消息中的“流开始”(Stream Begin)消息到客户端。
  6. 服务器发送命令消息中的“结果”(_result),通知客户端连接的状态。

注意

这里面的connect 命令消息,命令里面包含什么东西,协议中没有说,真实通信中要指定一些编解码的信息,这些信息是以AMF格式发送的, 其中audioCodecs和videoCodecs这两个指定音视频编码信息的不能少的。

Window Acknowledgement Size 是设置接收端消息窗口大小,一般是2500000字节,即告诉客户端你在收到我设置的窗口大小的这么多数据之后给我返回一个ACK消息,告诉我你收到了这么多消息。在实际做推流的时候推流端要接收很少的服务器数据,远远到达不了窗口大小,所以基本不用考虑这点。而对于服务器返回的ACK消息一般也不做处理,我们默认服务器都已经收到了这么多消息。
服务器返回的_result命令类型消息的payload length一般不会大于128字节,但是在最新的nginx-rtmp中返回的消息长度会大于128字节,所以一定要做好收包,组包的工作。

3.1.3. 建立网络流

  • 建立网络流过程简述
    创建完网络连接之后就可以创建网络流了

过程如下

  1. 客户端发送命令消息中releaseStream命令到服务器端
  2. 客户端发送命令消息中FCPublish命令到服务器端
  3. 客户端发送命令消息中的“创建流”(createStream)命令到服务器端。
  4. 服务器端接收到“创建流”命令后,发送命令消息中的“结果”(_result),通知客户端流的状态。

注意:解析服务器返回的消息会得到一个stream ID, 这个ID也就是以后和服务器通信的 message stream ID, 一般返回的是1,不固定。

  • 流程图如下:


    在这里插入图片描述

3.1.4. 播放流

图如下:


在这里插入图片描述
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容

  • RTMP协议是Real Time Message Protocol(实时信息传输协议)的缩写,它是由Adobe公司...
    iOS小肖阅读 3,483评论 0 4
  • 实时消息协议---流的分块 版权声明: 版权(c)2009 Adobe系统有限公司。全权所有。 摘要: 本备忘录描...
    一个人zy阅读 1,892评论 0 9
  • 版本记录 前言 大家都知道很多视频应用的app中都是使用RTMP格式的协议,这个是国际上共同使用的协议,我自己虽然...
    刀客传奇阅读 12,244评论 5 15
  • 个人翻译,转载请注明出处,谢谢! Adobe's Real Time Messaging Protocol 摘要 ...
    SniperPan阅读 2,729评论 1 17
  • RTMP传输基本流程 发送端 Step 1: 把数据封装成消息(Message)。 Step 2: 把消息分割成消...
    FlyingPenguin阅读 2,849评论 0 19