RTMP协议学习——从握手到播放
从客户端发起播放请求,到rtrmp视频流开始播放,大致经过了握手->建立连接->创建流->播放这几步比较重要的步骤。下面我将结合wireshark的抓包,对其中的每个流程进行分析和学习。
握手
RTMP协议基于TCP,TCP建立连接有三次握手。在TCP连接建立以后,会再进行一次RTMP协议层次的握手。
TCP握手
TCP建立连接的三次握手如图所示:


从wireshark的抓包中,也可以看到TCP的三次握手。


RTMP握手
在TCP建立连接成功后,rtmp会再进行三次握手。


可以通过在wireshark的过滤器中输入rtmpt来过滤RTMP协议的数据,如图所示:


客户端首先发送C0、C1到服务器。其中C1的大小是固定的,为1536个字节。服务端收到C0,C1后,发送S0,S1给客户端,S1的大小和C1一样,为1536个字节。服务端收齐C0,C1后,发送S2给客户端,客户端收齐S0,S1后,发送C2给服务端。C2和S2的大小也为1536个字节。可以看出来,rtmp协议握手交换数据报文的大小是固定的。
下图是引自wiki,可以很清晰的看到客户端和服务端的交互流程和包之间的关系:


C0 and S0
C0和S0都是单一的八位字节,里面包含着客户端要求的RTMP版本号




C1 and S1
C1和S1的长度都是1536个字节,里面包含着时间戳,4个字节的0和1528个字节随机生成的数据




C2 and S2
C2和S2的长度是1536个字节,其中的数据包括:
- time:终端在 S1 (给 C2) 或者 C1 (给 S2) 发的 timestamp。
- time2:终端先前发出数据包 (S1 或者 C1) timestamp。
- random echo:终端发的 S1 (给 C2) 或者 S2 (给 C1) 的随机数据。




connect
客户端
握手完成后,客户端会发送connect命令到服务端,请求连接一个服务器应用的实例。
connect消息组成如下:


其中Command Object包含了多个字段,来帮助客户端和服务端的连接。
Command Object包含的字段如下:


- app:客户端连接到服务器应用端的名字
- flashver:Flash Player 版本号。和ApplicationScript getversion() 方法返回的是同一个字符串。
- swfUrl:进行当前连接的 SWF 文件源地址。
- tcUrl:服务器 URL。
- fpad:代理标志,如果使用了代理就是 true。
- audioCodecs:表明客户端所支持的音频编码。
- videoCodecs:表明支持的视频编码。
- videoFunction:表明所支持的特殊视频方法。
- pageUrl:SWF 文件所加载的网页 URL。
- objectEncoding:AMF 编码方法。
总的来说,就是包含了版本,流名称,url,音视频编码等后面播放视频流时所用的信息,以保证后续服务端发送的视频数据可以正常播放。
wireshark抓包如下:


服务端
服务端收到connect命令后,发送了几条消息给客户端。如下图所示:


Window Acknowledgement size
Window Acknowledgement size的结构如下:


Window Acknowledgement size是服务器端用来通知对端发送和应答之间窗口大小的。
此例子中发送的窗口大小为2500000。
Set Peer Bandwidth
该消息里限制对端输出带宽。


限制类型取以下值之一:
0 - Hard:对端应该限制其输出带宽到指示的窗口大小。
1 - Soft:对端应该限制其输出带宽到知识的窗口大小,或者已经有限制在其作用的话就取两者之间的较小值。
2 - Dynamic:如果先前的限制类型为 Hard,处理这个消息就好像它被标记为 Hard,否则的话忽略这个消息。
Set Chunk Size
设置块大小,以通知对端新的最大块大小,默认为128字节。


Chunk是消息的一段。消息在网络发送之前被拆分成很多小的部分。Chunk可以确保端到端交付所有消息有序 timestamp,即使有很多不同的流。Chunk的格式如下:
createStream
在connect完成后就可以创建或者访问RTMP流了。


从抓包数据可以看到,服务端向客户端发送了三条命令,分别是Window Acknowledgement size,createStream和_checkbw。
- Window Acknowledgement size是对之前服务端发送的Set Peer Bandwidth消息的应答。
- _checkbw用于检查带宽,来评估与服务器的连接质量和带宽。
主要的消息是creatStream,客户端发送此消息到服务端,创建一个逻辑通道,用于消息通信。音频、视频、元数据均通过createStream创建的数据通道进行交互。createStream消息的结构如下:


客户端发送createStream请求之后,服务端会反馈一个结果给客户端,如果成功,则返回_result,如果失败,则返回_error。
wireshark抓包数据如下:


在服务端返回的数据中,最后一个字段为Stream ID,作为该Stream的唯一标识。此例子中返回的是1,后续的视频或音频的Stream ID就是1。
至此,客户端和服务端的通道已经建立完成,接下来就可以进行数据的传输了。
play
createStream成功后,客户端发送play命令,通知服务端开始播放视频流。
play消息有7个字段,其中最后3个为可选字段。
- Command Name: String类型,命令的名称,为“play”。
- Transaction ID: Number类型,事务ID。
- Command Object:命令信息不存在。设为 null 类型。
- Stream Name: String类型,要播放流的名字。
- Start(可选): Number类型,以秒为单位定义开始时间,默认值为 -2,表示用户首先尝试播放流名字段中定义的直播流。
- Duration(可选): Number类型,以秒为单位定义了回放的持续时间。默认值为 -1。-1 值意味着一个直播流会一直播放直到它不再可用或者一个录制流一直播放直到结束。
- Reset(可选): Boolean类型,定义了是否对以前的播放列表进行 flush。
wireshark抓包数据为:


从抓包数据可以看到,此次事务ID为5;流的名称为“test”;start为-2000ms,即-2s,用户首先尝试播放流名字段中定义的直播流。
客户端发送play命令来播放指定流后,就开始传输音视频数据。后面就是客户端按照流程对接收到的数据进行解协议,解封装,解码..........
........此处省略一万字...........
RTMP协议学习——从握手到播放的更多相关文章
- rtmp协议分析
最近需要做一个rtmp服务器,着手分析一下rtmp协议,开干. rtmp握手 这个推荐一篇文章讲解得比较透彻http://blog.sina.com.cn/s/blog_676e11660102v8b ...
- RTMP流媒体播放过程:握手,建立连接,建立流,播放
本文讲述从打开一个RTMP流媒体到视音频数据开始播放的整个过程. 播放一个流媒体有两个前提步骤: 第一步,建立一个网络连接(NetConnection): 第二步,建立一个网络流(NetStream) ...
- 推荐下:开源ckplayer 网页播放器, 跨平台(html5, mobile),flv, f4v, mp4, rtmp协议. webm, ogg, m3u8 !
视频播放, 原本是想h5 自带视频播放,使用很简单,结果现实很骨感. <video controls="controls" preload="auto" ...
- iOS直播-播放基于RTMP协议的视频
iOS直播-播放基于RTMP协议的视频 流媒体协议介绍 1. 伪流媒体: 渐进式下载 : 边下边存, 文件会保存 使用http协议,也能够实现视频播放, 也能快进快退等, 体验上跟流媒体很像. 优酷, ...
- 调试libRTMP代码来分析RTMP协议
RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写.该协议基于TCP,是一个协议族,常用在视频直播领域.RTMP协议的默认端口是1935. 学习一个协议 ...
- (转)RTMP协议从入门到放弃
转载自: http://blog.csdn.net/shangmingyang/article/details/50837852 RTMP协议是Real Time Message Protocol( ...
- rtmplib rtmp协议过程分析
转自:http://chenzhenianqing.cn/articles/1009.html 写的很好,收藏如下,向作者致敬! 没事碰到了librtmp库,这个库是ffmpeg的依赖库,用来接收,发 ...
- 玩转直播系列之RTMP协议和源码解析(2)
一.背景 实时消息传输协议(Real-Time Messaging Protocol)是目前直播的主要协议,是Adobe公司为Flash播放器和服务器之间提供音视频数据传输服务而设计的应用层私有协议. ...
- 网络协议学习笔记(九)CDN和数据中心
概述 上一篇给大家介绍了DNS协议和HttpDns协议,现在给大家介绍一下CDN和数据中心相关的知识. CDN:你去小卖部取过快递么? 如果你去电商网站下单买个东西,这个东西一定要从电商总部的中心仓库 ...
- RTMP协议中文翻译(首发)(转)
Adobe公司的实时消息传输协议 摘要 此备忘录描述了 Adobe公司的实时消息传输协议(RTMP),此协议从属于应用层,被设计用来在适合的传输协议(如TCP)上复用和打包多媒体传输流(如音频.视频和 ...
随机推荐
- 学好Linux的必经之路
学好Linux的必经之路 学习动机的培养对于一个人学习习惯的形成有着重要的作用.当我们在学习某一个事物时,建立属于我们自己的学习方法,以此培养我们学习Linux系统的学习动机. 当前,Linux系统属 ...
- [FreeSWITCH]简单配置fifo呼入队列
拨号计划 <?xml version="1.0"?> <include> <context name="inboundcall"& ...
- .NET5从零基础到精通:全面掌握.NET5开发技能【第二章】
章节: 第一章:https://www.cnblogs.com/kimiliucn/p/17613434.html 第二章:https://www.cnblogs.com/kimiliucn/p/17 ...
- 群晖DS218+部署PostgreSQL(docker)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 起因是懒 最近在开发中要用到PostgreSQL数据库 ...
- Three.js中实现碰撞检测
1. 引言 碰撞检测是三维场景中常见的需求,Three.js是常用的前端三维JavaScript库,本文就如何在Three.js中进行碰撞检测进行记述 主要使用到的方法有: 射线法Raycaster ...
- Web安全漏洞解决方案
1.已解密的登录请求 推理: AppScan 识别了不是通过 SSL 发送的登录请求. 测试请求和响应: 1.1.1 产生的原因 登录接口,前端传入的密码参数没有经过md5的加密就直接传给了后端 1. ...
- WPF-利用装饰器实现控件的自由拖动
在项目中经常会遇到类似如下要求的需求,创建允许自由拖动的控件,这样的需求可以使用WPF的装饰器Adorner来实现. 一.什么是装饰器? 装饰器是一种特殊类型的FrameworkElement,装饰器 ...
- Set Concept
集合(Set)就是一种用来装事物的容器(或者称为结构),它所装的东西叫元素.集合这个容器的逻辑性很强,可以说是现在比较严谨的工具. 集合里的元素,它们可以是任何类型的数学对象:数字.符号.变量.空间中 ...
- 《Kali渗透基础》01. 介绍
@ 目录 1:渗透测试 1.1:安全问题的根源 1.2:安全目标 1.3:渗透测试 1.4:标准 2:Kali 2.1:介绍 2.2:策略 2.3:安装 3:Kali 初步设置 3.1:远程连接 3. ...
- WPF学习 - 动画基础(2)
上一篇文章粗略的介绍了一下Animation类.本篇介绍一下Storyboard. Storyboard,姑且翻译成"故事板"吧.实际上它是一个Animation对象的容器,可以容 ...

