一、概念与摘要

视频直播源码的RTMP协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频、视频和互动内容)。RTMP提供了一套全双工的可靠的多路复用消息服务,类似于TCP协议[RFC0793],用来在一对结点之间并行传输带时间戳的音频流,视频流,数据流。通常情况下,不同类型的消息会被分配不同的优先级,当网络传输能力受限时,优先级用来控制消息在网络底层的排队顺序。

二、RTMP块流

视频直播源码的实时消息传递协议块流(RTMP块流)。它作为一款高级多媒体流协议提供了流的多路复用和打包服务。RTMP块流被设计用来传输实时消息协议,它可以使用任何协议来发送消息流。每个消息都包含时间戳和有效类型标识。RTMP块流和RTMP适用于各种视听传播的应用程序,包括一对一的,和一对多的视频直播、点播服务、互动会议应用程序。

当使用一个可靠的传输协议如TCP[RFC0793]时,RTMP块流提供了一种可以在多个流中,基于时间戳的端到端交付所有消息的方法。RTMP块流不提供任何优先级或类似形式的控制,但可以使用更高级别的协议来提供这样的优先级。例如,一个视频服务器可以根据发送的时间或确认每个消息的时间,来决定为一个网络差的用户丢弃视频信息,以确保音频信息的及时接收。

RTMP块流不仅包含了自己的协议控制信息,同时也提供了一个更高级别的协议机制,用来嵌入用户控制信息。

消息格式

视频直播源码的消息格式可以被分割成多个块,用来在更高的协议中支持多路复用。在创建块消息格式时,应该包含以下字段:

时间戳
消息的时间戳。这个字段占用4字节。

长度
消息的有效长度。如果消息头不能被忽略,它应该包括长度。这个字段在块头中占用3字节。

类型ID
各种类型的协议控制消息的ID。这些消息使用RTMP块流协议和更高级别的协议来传输信息。所有其他类型的ID可以用在高级协议,这对于RTMP块流来说,是不透明的。事实上,RTMP块流中没有要求使用这些值作为类型;所有(无协议的)消息可能是相同的类型,或者应用程序使用这个字段来区分多个连接,而不是类型。这个字段在块头中占用1字节。

消息流ID
消息流ID可以是任意值。当同一个块流被复用到不同的消息流中时,可以通过消息流ID来区分它们。另外,对于RTMP块流而言,这是一个不透明值。该字段占用4字节,使用小端序。

握手

RTMP连接从握手开始。它包含三个固定大小的块,不像其他的协议,是由头部大小可变的块组成的。

客户端(初始化连接的一端)和服务端发送同样的三个块。为了方便描述,客户端发送的三个块命名为C0,C1,C2;服务端发送的三个块命名为S0,S1,S2。  

握手序列

客户端通过发送C0和C1消息来启动握手过程。客户端必须接收到S1消息,然后发送C2消息。客户端必须接收到S2消息,然后发送其他数据。

服务端必须接收到C0或者C1消息,然后发送S0和S1消息。服务端必须接收到C1消息,然后发送S2消息。服务端必须接收到C2消息,然后发送其他数据。

C0和S0格式

C0和S0包由一个字节组成,下面是C0/S0包内的字段:

1

2

3

4

5

0 1 2 3 4 5 6 7

+-+-+-+-+-+-+-+-+

|   version     |

+-+-+-+-+-+-+-+-+

 C0 and S0 bits

版本(8比特)
在C0包内,这个字段代表客户端请求的RTMP版本号。在S0包内,这个字段代表服务端选择的RTMP版本号。此文档使用的版本是3。版本0-2用在早期的产品中,现在已经被弃用;版本4-31被预留用于后续产品;版本32-255(为了区分RTMP协议和文本协议,文本协议通常以可打印字符开始)不允许使用。如果服务器无法识别客户端的版本号,应该回复版本3。客户端可以选择降低到版本3,或者中止握手过程。

C1和S1格式

C1和S1包长度为1536字节,包含以下字段:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

0                   1                   2                   3

 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|                        time (4 bytes)                         |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|                        zero (4 bytes)                         |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|                        random bytes                           |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|                         random bytes                          |

|                            (cont)                             |

|                             ....                              |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                         C1 and S1 bits

时间(4字节)
本字段包含一个时间戳,客户端应该使用此字段来标识所有流块的时刻。时间戳取值可以为零或其他任意值。为了同步多个块流,客户端可能希望多个块流使用相同的时间戳。

零(4字节)
本字段必须为零。

随机数据(1528字节)
本字段可以包含任意数据。由于握手的双方需要区分另一端,此字段填充的数据必须足够随机(以防止与其他握手端混淆)。不过没必要为此使用加密数据或动态数据。

C2和S2格式

C2和S2包长度为1536字节,作为C1和S1的回应,包含以下字段:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

0                   1                   2                   3

 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|                        time (4 bytes)                         |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|                       time2 (4 bytes)                         |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|                        random echo                            |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|                         random echo                           |

|                            (cont)                             |

|                             ....                              |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                         C2 and S2 bits

时间(4字节)
本字段必须包含对端发送的时间戳。

时间(4字节)
本字段必须包含时间戳,取值为接收对端发送过来的握手包的时刻。

随机数据(1528字节)
本字段必须包含对端发送过来的随机数据。握手的双方可以使用时间1和时间2字段来估算网络连接的带宽和/或延迟,但是不一定有用。

三、RMTP握手

握手过程示意图

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

+-------------+                           +-------------+

|    Client   |       TCP/IP Network      |    Server   |

+-------------+            |              +-------------+

      |                    |                     |

Uninitialized              |               Uninitialized

      |          C0        |                     |

      |------------------->|         C0          |

      |                    |-------------------->|

      |          C1        |                     |

      |------------------->|         S0          |

      |                    |<--------------------|

      |                    |         S1          |

 Version sent              |<--------------------|

      |          S0        |                     |

      |<-------------------|                     |

      |          S1        |                     |

      |<-------------------|                Version sent

      |                    |         C1          |

      |                    |-------------------->|

      |          C2        |                     |

      |------------------->|         S2          |

      |                    |<--------------------|

   Ack sent                |                  Ack Sent

      |          S2        |                     |

      |<-------------------|                     |

      |                    |         C2          |

      |                    |-------------------->|

 Handshake Done            |               Handshake Done

      |                    |                     |

          Pictorial Representation of Handshake

                     握手示意图

下面是握手示意图中提到的状态:

未初始化
协议版本号在此阶段发送。客户端和服务器均处于未初始化状态。客户端发送携带协议版本号的C0包。如果服务器支持此版本,回复S0和S1包。如果服务器不支持此版本,使用适当的动作回复。在RTMP协议中,此动作是中止连接。
注: 在”C0和S0格式”章节中提及,如果服务器不支持客户端的版本号,可以选择降到版本3或中止。

发送版本
视频直播源码客户端和服务器双方在未初始化状态后,会进入发送版本状态。之后,视频直播源码客户端等待S1包,服务器等待C1包。待接收到数据包,视频直播源码客户端发送C2包,服务器发送S2包。然后,双方都进入答复状态。客户端等待C2的答复,服务器等待S2的答复。

握手完成
视频直播源码客户端和服务器交换消息。

本文转载自网络,感谢原作者的分享,转载仅为分享干货知识,如有侵权欢迎联系作者进行删除处理。

视频直播源码开发中的流媒体协议:rtmp协议的更多相关文章

  1. 带货直播源码开发采用MySQL有什么优越性

    MySQL是世界上最流行的开源关系数据库,带货直播源码使用MySQL,可实现分钟级别的数据库部署和弹性扩展,不仅经济实惠,而且稳定可靠,易于运维.云数据库 MySQL 提供备份恢复.监控.容灾.快速扩 ...

  2. 如何理解直播APP源码开发中的音视频同步

    视频 直播APP源码的视频的播放过程可以简单理解为一帧一帧的画面按照时间顺序呈现出来的过程,就像在一个本子的每一页画上画,然后快速翻动的感觉. 但是在实际应用中,并不是每一帧都是完整的画面,因为如果直 ...

  3. 直播带货APP源码开发为什么选择云服务器

    云服务器可以为直播带货APP源码提供弹性计算以及更高的运行效率,避免资源浪费,随着直播带货APP源码业务需求的变化,可以实时扩展或缩减计算资源.CVM支持按实际使用的资源计费,可以节约计算成本. 一. ...

  4. 近200篇机器学习&深度学习资料分享(含各种文档,视频,源码等)(1)

    原文:http://developer.51cto.com/art/201501/464174.htm 编者按:本文收集了百来篇关于机器学习和深度学习的资料,含各种文档,视频,源码等.而且原文也会不定 ...

  5. 基于vitamio的网络电视直播源码

    这个项目是基于vitamio的网络电视直播源码,也是一个使用了vitamio的基于安卓的网络直播项目源码,可能现在网上已经有很多类似这样的视频播放应用了,不过这个还是相对来说比较完整的,希望这个案例能 ...

  6. ios怎样实现快速将显卡中数据读出压缩成视频在cocos2dx扩展开发中

    如果解决ios怎样实现快速将显卡中数据读出压缩成视频在cocos2dx扩展开发中 手机平台性能是个关键问题. 压缩视频分成3个步骤: 读取显卡数据, 使用编码器压缩,保存文件. 使用libav 压缩的 ...

  7. dubbo源码分析4-基于netty的dubbo协议的server

    dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...

  8. 10┃音视频直播系统之 WebRTC 中的数据统计和绘制统计图形

    一.数据统计 在视频直播中,还有一项比较重要,那就是数据监控 比如开发人员需要知道收了多少包.发了多少包.丢了多少包,以及每路流的流量是多少,才能评估出目前用户使用的音视频产品的服务质量是好还是坏 如 ...

  9. iOS燃烧动画、3D视图框架、天气动画、立体相册、微信朋友圈小视频等源码

    iOS精选源码 iOS天气动画,包括太阳,云,雨,雷暴,雪动画. 较为美观的多级展开列表 3D立体相册,可以旋转的立方体 一个仪表盘Demo YGDashboardView 一个基于UIScrollV ...

随机推荐

  1. 【漏洞复现】Office远程代码执行漏洞(CVE-2017-11882)

    昨晚看到的有复现的文章,一直到今天才去自己复现了一遍,还是例行记录一下. POC: https://github.com/Ridter/CVE-2017-11882/ 一.简单的生成弹计算器的doc文 ...

  2. rm -rf /*真的能删掉所有文件吗?

    大佬们对于小白问的问题经常直接就是一个rm -rf /*丢过去(逃,被丢了很多次,所以印象深刻),但玩了这么久的梗,当我真正想删库的时候,这条命令却然并卵(滑稽,删库跑路都跑不成). 查看了下文件属性 ...

  3. 从0到1进行Spark history分析

    一.总体思路 以上是我在平时工作中分析spark程序报错以及性能问题时的一般步骤.当然,首先说明一下,以上分析步骤是基于企业级大数据平台,该平台会抹平很多开发难度,比如会有调度日志(spark-sub ...

  4. mycat的privileges标签

    参考https://blog.csdn.net/tornadojava/article/details/54948662 privileges标签 对用户的 schema以及表进行精细化的DML权限控 ...

  5. linux centos 05

    centos7安装mariadb 1.yum  得配置yum源,配置阿里云的 两个 yum源  ,阿里云的yum源中,会有 mariadb的软件包 阿里云的yum仓库中,mariadb版本如下 mar ...

  6. day15 Pyhton学习

    迭代器 掌握for循环 实际上for循环的本质,就是将一个可迭代的变成迭代器 每一次从中取值都相当于执行了一次next 如果是迭代器,那么只能取一次值 生成器 - 本质就是迭代器 生成器函数(返回值是 ...

  7. ES6之数组

    数组新增方法 map(可以理解为是映射,以一定规则修改数组每一项并返回全新数组) reduce(可以理解为是汇总,一堆出来一个) filter(可以理解为过滤,筛选的意思,以一定规则拿到符合的项并返回 ...

  8. 换掉7z-zip默认的ico图标,自定义压缩文件图标更美观。

    下图就是7z官网源代码里面的ico文件,如果有条件自己编译,可以直接替换下面的图标,然后编译一个你自己的7z工具就行.不过我比较懒,还是通过修改注册表的方式改成别的ico图标吧. 源码和可执行程序下载 ...

  9. selenium等待机制学习笔记

    转载至: https://blog.csdn.net/huilan_same/article/details/52544521 1. 强制等待 第一种也是最简单粗暴的一种办法就是强制等待sleep(x ...

  10. charles系列

    charles 手机抓包 教程:https://www.axihe.com/charles/charles/proxy-phone.html坑:https://www.cnblogs.com/1-43 ...