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)上复用和打包多媒体传输流(如音频.视频和 ...
随机推荐
- .NET技术:懒惰与沉淀的平衡之道
在过去的很多年里,我一直默默搬砖,而我们聚在博客园,目的只有一个:沉淀并为更多的.NET开发者提供更好的帮助. 疫情3年,个人经历了太多事情,感觉懒惰是最大的敌人.然而,在这里,我收获了许多宝贵的经验 ...
- python实现创建一个银行类,这个类实现了两个方法,第一个方法可以将用户信息写入到文件中,第二个方法可以读取文件中的用户信息出来
class bank: def user_info(self): a=input('请输入用户信息:') # 不写encoding = 'utf-8'中文会乱码 with open('info.txt ...
- 利用IPV6随时访问家中影音Jellyfin
本文章主要记录通过ipv6实现家庭影音中心在互联网上的访问. 之前很多方案都是通过第三方进行内网穿透,实际体验不是很好.目前ipv6发展迅速,完全可以取代这种以ipv4为中心的内网资源外网访问的方式. ...
- MySQL 1130错误原因及解决方案
错误:ERROR 1130: Host 'http://xxx.xxx.xxx.xxx' is not allowed to connect to thisMySQL serve 错误1130:主机x ...
- Python中字符串截取
# 截取字符串时,如果位数不够,Python不会报错,而是返回空字符串 # 这是因为Python中的字符串是不可变的,所以当我们尝试访问一个不存在的索引时,Python会返回空字符串而不是报错 # 示 ...
- KVM下windows由IDE模式改为virtio模式蓝屏 开不开机
KVM安装Windows默认使用的是qemu虚拟化IDE硬盘模式,在这种情况下,IO性能比较低,如果使用virtio的方式可以提高虚拟机IO性能. 于是我想将这台虚拟机迁移到openstack中管理 ...
- 【路由器】OpenWrt 手动编译 ipk
目录 .ipk 文件 编译准备 编译 .ipk 文件 更新 feeds 配置平台 获取交叉编译链 添加需要编译的第三方软件包 参考资料 .ipk 文件 .ipk 文件是可以通过 OpenWrt 的包管 ...
- api接口的使用原理是什么?
随着互联网的发展和不同系统之间的交互越来越频繁,API接口的使用已经成为软件开发和集成中不可或缺的一部分.API接口的使用原理是通过预定义的接口规范,软件系统可以调用或提供API接口的服务,来实现 ...
- Lazada商品详情(代码封装)以及应用
编辑切换为居中 Lazada平台的分析可以从以下几个方面入手: 1. 市场分析:对Lazada平台市场进行分析,及时了解市场趋势和变化,调整企业的经营策略.可以监测Lazada平台上商品的销售量. ...
- Pycharm远程连接到服务器运行错误can‘t open file ‘tmp
Pycharm远程连接到服务器运行错误can't open file '/tmp/.../a.py': [Errno 2] No such file or directory 问题描述 win11 P ...

