说起RTMP协议,相信很多人都比较陌生,这个协议相对HTTP、HTTPS、TCP等我们常见的协议而言,我们在工作中确实较少接触它,但是对现在如火如荼的直播行业,RTMP是一个重要的协议,它在实时音视频场景中使用非常广泛,而且目前市占率很高。

本文的主要内容是分析RTMP的协议,当然不是纯理论分析,这样没多大意思,还是结合实践抓包文件来具体分析,这样才能较好地理解RTMP的内涵。具体如何抓包见本文末尾的“Android抓包”模块。希望你阅读完本章之后,自己也能简单地动手操作一下,这样理解深刻一下。

RTSP/RTMP推流分析

RTMP基础介绍

RTMP协议的主要特点:

  • RTMP协议是应用层协议,是要靠底层可靠的传输层(TCP)
  • 协议(通常是TCP)来保证信息传输的可靠性的。在基于传输层协议的链接建立完成后,RTMP协议也要客户端和服务器通过“握手”来建立基于传输层链接之上的RTMP Connection链接。播放一个RTMP协议的流媒体需要经过以下几个步骤:握手,建立网络连接,建立网络流,播放。服务器和客户端之间只能建立一个网络连接,但是基于该连接可以创建很多网络流。


这儿埋下一个小疑问?为什么传输层已经建立了TCP连接,RTMP还需要再次建立一个连接,有这个必要吗?

RTMP协议传输时会对数据做自己的格式化,这种格式的消息我们称之为RTMP Message,而实际传输的时候为了更好地实现多路复用、分包和信息的公平性,发送端会把Message划分为带有Message ID的Chunk,每个Chunk可能是一个单独的Message,也可能是Message的一部分,在接受端会根据chunk中包含的data的长度,message id和message的长度把chunk还原成完整的Message,从而实现信息的收发。

RTMP握手

RTMP基于TCP,已知TCP需要3次握手才可以建立连接,在TCP3次握手成功之后,应用层的RTMP也是需要握手的,就是认证过程。具体的认证过程如下:

  • 客户端发送 C0、C1、 C2,服务器发送 S0、 S1、 S2。
  • 首先,客户端发送 C0 表示自己的版本号,不必等对方的回复,然后发送 C1 表示自己的时间戳。
  • 服务器只有在收到 C0 的时候,才能返回 S0,表明自己的版本号,如果版本不匹配,可以断开连接。
  • 服务器发送完 S0 后,也不用等什么,就直接发送自己的时间戳 S1。客户端收到 S1 的时候,发一个知道了对方时间戳的 ACK C2。同理服务器收到 C1 的时候,发一个知道了对方时间戳的 ACK S2。
  • 握手建立完成。

现在回答上面提出的问题,为什么RTMP还需要单独建立一个连接?

因为它们需要商量一些事情,保证以后的传输能正常进行。主要就是两个事情,一个是版本号,如果客户端、服务器的版本号不一致,则不能工作。另一个就是时间戳,视频播放中,时间是很重要的,后面的数据流互通的时候,经常要带上时间戳的差值,因而一开始双方就要知道对方的时间戳。

光讲纯理论,没意思,还是抓包看一下具体的流程吧。

1.首先TCP 3次握手

2.RTMP握手过程

我们发现真实发包是C0+C1一起发;S0、S1、S2一起发。但是发送的时候还是会严格按照时序来控制的,这样才能真正校验好版本号等字段。

拉流

RTMP拉流的核心流程如下:

1.建立网络连接

客户端发送命令消息中的“连接”(connect)到服务器,请求与一个服务应用实例建立连接。

StreamID是每个消息的唯一标识,划分成Chunk和还原Chunk为Message的时候都是根据这个ID来辨识是否是同一个消息的Chunk的,这里面为0说明这个消息是初始的0消息。

Chunk stream ID:一个RTMP message会拆分成多个chunk,同一个Chunk Stream ID必然属于同一个Message。这样在传送过程中发过来的chunk就是通过chunk stream ID最终组装成功我一个完成的message数据的。

message type id(消息的类型id):表示实际发送的数据的类型,如8代表音频数据、9代表视频数据。如下面的两张图,这样看上去是不是好理解一点了。


是chunk type。共有4种不同的格式,其中第一种格式字段为0,可以表示其他三种表示的所有数据,但由于其他三种格式是基于对之前chunk的差量化的表示,因此可以更简洁地表示相同的数据,实际使用的时候还是应该采用尽量少的字节表示相同意义的数据。因为type 0是表示不同数据,其他是差量,所以可以想象如果搜不到type 0的包说明这个流肯定有问题。可以通过“rtmpt.header.format == 0”过滤。

2.建立一个网络流

网络流代表了发送多媒体数据的通道。服务器和客户端之间只能建立一个网络连接,且多个网络流可以复用这一个网络连接。这个在上面已经反复说过。

客户端向服务器请求创建流:

服务器收到请求后向客户端发送_result(),对创建流的消息进行响应。此时NetStream创建完成。

3.Play 播放

客户端发送命令消息中的“播放”(play)命令到服务器。

接收到播放命令后,服务器发送设置块大小(ChunkSize)协议消息。 服务器发送用户控制消息中的“streambegin”,告知客户端流ID。

播放命令成功的话,服务器发送命令消息中的“响应状态” NetStream.Play.Start,告知客户端“播放”命令执行成功。

我们发现执行了3个动作,分别如下:



共用一个Stream ID,并且在可以播放消息回来之后,已经解析出视频的基本属性。

推流

分析完拉流的所有操作,启示推流也是类似的,区别在Play —> Publishing了。

Android抓包

  • 进入网站:www.androidtcpdump.com/android-tcp… tcpdump工具,现在最新版本是4.9.3
  • 找一个root的手机,将下载好的tcpdump文件先push到/sdcard/ 下面,adb push tcpdump /sdcard/tcpdump
  • adb shell进入手机adb 模式下,cp -rf /sdcard/tcpdump /data/local/,将tcpdump拷贝到/data/local/目录下
  • chmod 777 /data/tcpdump,赋予tcpdump完全的执行权限
  • ./data/local/tcpdump -i any -p -s 0 -w /sdcard/capture.pcap
  • 然后开始访问rtmp的请求,访问完成后,会在/sdcard/目录下生成capture.pcap文件
  • adb pull /sdcard/capture.pcap ,本地使用wireshare分析capture.pcap文件
  • rtmp的测试源提供一个:rtmp://58.200.131.2:1935/livetv/hunantv

FFmpeg/WebRTC/RTMP音视频流媒体高级开发 学习资料、教学视频和学习路线图 免费分享有需要的可以自行添加学习交流群973961276

深入了解音视频开发直播协议RTMP相关推荐

  1. 音视频开发——通信直播协议和视频推流丨RTMP-RTSP

    近年来直播已成为互联网行业的大热话题,直播答题.游戏直播.竞赛直播,抖音直播,直播教育等层出不穷,直播早已成为人们耳熟能详的技术.事实上直播的兴起不仅与新时代人们要求为自己代言的心理有关,同时也得益于 ...

  2. 音视频开发 RTMP协议发送H.264编码及AAC编码的音视频(C++实现)

    RTMP(Real Time Messaging Protocol)是专门用来传输音视频数据的流媒体协议,最初由Macromedia 公司创建,后来归Adobe公司所有,是一种私有协议,主要用来联系F ...

  3. JavaCV音视频开发宝典:JavaCV实现mp3音频直播FM在线电台服务,无需流媒体服务,浏览器原生audio标签直接播放mp3,支持rtsp/rtmp/flv/hls/本地音视频源直接转码到mp3

    <JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 ​ 前言 之前写过使用JavaCV实现webm直播的文章: <JavaCV音视频 ...

  4. JavaCV音视频开发宝典:使用JavaCV和springBoot实现http-flv直播服务,无需流媒体服务,浏览器网页flv.js转封装方式播放rtsp,rtmp和桌面投屏实时画面

    <JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 ​ 前言 自从2021年初开始,各个浏览器开始禁用flash插件,以前直播中经常使用的 ...

  5. 【音视频开发系列】盘点音视频直播RTSP/RTMP推流一定会遇到的各种坑,教你快速解决

    聊聊RTSP/RTMP推流那些坑 1.推流架构分析 2.推流缓存队列的设计 3.FFmpeg函数阻塞问题分析 [音视频开发系列]盘点音视频直播一定会遇到的各种坑,教你快速解决 更多精彩内容包括:C/C ...

  6. JavaCV音视频开发宝典:无需流媒体服务也无需转码,使用JavaCV和springBoot实现http-flv转封装直播服务,浏览器网页flv.js直接播放rtp、rtsp、rtmp实时视频

    <JavaCV音视频开发宝典>专栏目录导航 <JavaCV音视频开发宝典>专栏介绍和目录 前言 本章代码除了在<JavaCV音视频开发宝典:使用JavaCV和spring ...

  7. 网页测试本地服务器_音视频开发搭建一个直播服务器

    现在抖音.快手等直播实在是太火了,因此对音视频的开发非常感兴趣.查阅了相关资料,使用Nginx搭建一个简单的直播跟点播流媒体服务器,能够实时推流到服务器,同时在网页端播放直播的视频. 先上效果 使用O ...

  8. Android音视频点/直播模块开发

    前言 随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式 ...

  9. 音视频开发系列(16)技术解码 | SRT和RIST协议综述

    概要 近些年来,互联网行业出现了几波和音视频相关的热潮:VR.短视频.直播等.除了VR因技术成熟度问题,还在蓄势待发,短视频和直播持续热度不减,以各种方式进入新的行业应用领域.视频直播方向,RTMP仍 ...

最新文章

  1. MyEclipse 10 中安装Android ADT 22插件的方法
  2. 序列化中的[NonSerialized]字段 -转
  3. 【Linux】一步一步学Linux——alias命令(205)
  4. D04——C语言基础学PYTHON
  5. Oracle入门(五D)之如何设置show parameter显示隐含参数
  6. iOS modal view的关闭和显示问题
  7. 某高校计算机系举办了一场,国家二级MS+OFFICE高级应用机试(操作题)-试卷25
  8. 理解Linux中断 (3)【转】
  9. MariaDB数据库介绍之一、备份(mysqldump、lvm2快照、xtrabackup)
  10. VS2005中ajax安装指南
  11. plecs / plexim 学习随笔
  12. 最大子段和问题(3种方法)
  13. 基础知识 字节、KB、MB、GB 之间的换算关系
  14. 回顾2022,展望2023,笔耕不辍,钟情翰墨
  15. python理财基金数据分析可视化系统
  16. [conda报错 已解决]An unexpected error has occurred. Conda has prepared the above report.
  17. Linux内存管理专题
  18. 【Python爬虫实战】查找企业股东有哪些关联公司
  19. 大数据营销的优势和核心
  20. JUC(二):Java 线程预备知识

热门文章

  1. 在一个excel里面直接批量从谷歌地图抓取经纬度(vba部分)
  2. 动态canvas 相册简单效果展示
  3. 华为手机备忘录资料备份
  4. RJ-45双绞线的制作和测试-网络实验1
  5. 下载视频-you-get
  6. 【19调剂】北京航空航天大学苏州创新研究院培养基地非全日制硕士研究生招生说明(校内)...
  7. 推荐 :一文带你了解协同过滤的前世今生
  8. java项目导入jre不识别_Eclipse中的Java项目:无法解析类型java.lang.Object。 从所需的.class文件间接引用它...
  9. matlab怎样删除全部NAN值
  10. ubuntu服务器的安装(转载)