当前位置: 首页 > news >正文

RTMP 协议解析 1

介绍

📖 什么是 RTMP?

RTMP协议(Real-Time Messaging Protocol,实时消息传输协议)是由Adobe公司(最初由Macromedia开发)设计的一种用于实时传输音频、视频和数据流的网络协议,主要用于直播和流媒体传输,最初是为了让 Flash Player 和 Flash Media Server 之间进行音视频和数据的实时传输。

现在虽然 Flash 被淘汰了,但 RTMP 这个协议因为其简单、低延迟、稳定的特点,依然在直播领域广泛应用,比如 OBS 推流、斗鱼、Bilibili、Twitch 都在用。

•	作用:RTMP用来实现音视频数据的实时传输,比如直播视频、在线音频等。它让客户端(如播放器)和服务器之间能快速、连续地交换多媒体数据。
•	工作层级:RTMP是应用层协议,依赖底层的传输层协议(通常是TCP)来保证数据可靠传输。
•	默认端口:通常使用TCP的1935端口进行通信,也有变种支持通过HTTP端口(80、443)传输以穿透防火墙。
•	多路复用和分包:RTMP会把数据分成许多小块(称为Chunk),每个Chunk带有标识信息,接收端再把这些Chunk组装成完整的消息,实现多路复用和高效传输。
•	双向通信:客户端和服务器之间可以相互发送命令和数据,比如客户端发出“播放”、“暂停”命令,服务器则推送视频流。

RTMP 播放,浏览器端已经不支持(需要 Flash,已经淘汰)。

🛠️ RTMP 的核心特点

特点说明
低延迟通常能做到 1-2 秒,非常适合直播
分块传输大文件(比如视频流)会被切成小块,实时传输
支持音视频同步可以同时传输音频、视频、文字数据,保持同步
基于 TCP传输可靠,不会丢包,但速度比 UDP 稍慢一点
持久连接建立一次连接后长时间保活,适合流式数据

📦 RTMP 的数据流程

RTMP 整个通信过程可以分为三步:

  1. Handshake(握手阶段)
    • 建立 TCP 连接后,客户端和服务器通过握手确认彼此协议版本,完成初始化。
  2. Connect(连接阶段)
    • 客户端发送一个 connect 命令,请求推流或拉流,比如指定应用名(app)、流名(streamName)、认证信息(token)等。
  3. Stream(数据传输阶段)
    • 开始音视频数据传输,比如推送 h264 编码的视频流、AAC 编码的音频流,还有一些控制消息(比如 pause、seek、metadata 更新)。

🔥 常见的 RTMP 使用场景

场景示例
直播推流OBS 推流到斗鱼、虎牙、B站
直播拉流播放器从服务器拉 RTMP 流
流媒体服务器内部通信Nginx-RTMP、SRS、Red5、Wowza 等服务器使用
实时弹幕推送用 RTMP 的 data message 功能

📡 RTMP URL 的格式

rtmp://服务器地址:端口号/app/stream

🔍 RTMP 的几个子协议

协议说明
RTMPT把 RTMP 封装成 HTTP 请求(端口80,穿防火墙)
RTMPS加密版 RTMP,用 SSL/TLS
RTMPEAdobe 自己的加密版 RTMP,半开源

⚡ 现在最流行的一种组合是:

  • 推流用 RTMP(客户端推到服务器)
  • 播放用 HLS 或 WebRTC(服务器转码输出给观众 HTTP-FLV)

软件播放

这里主要针对mac 平台的播放软件:

  1. VLC Media Player

  2. Live Stream Player

提供两个可以测试的 rtmp 流地址

rtmp://liteavapp.qcloud.com/live/liteavdemoplayerstreamid

rtmp://ns8.indexforce.com/home/mystream

📦 (标准直播系统):

主播 → RTMP 推流 → 直播服务器(比如 SRS) → 转码 + 分发 → → HTTP-FLV/HLS(观众拉流,单向)→ WebSocket(观众互动消息,双向)→ WebRTC(连麦,双向音视频)

流程链路

1. 🔥 建立 TCP 连接

首先,RTMP 是基于 TCP 的,所以:

  • 客户端(比如 OBS、推流SDK)通过 TCP 连接到 RTMP 服务器(比如 SRS、Nginx-RTMP、Wowza)。
  • 默认端口是 1935(可以改成443/80穿透)。
Client → TCP三次握手 → Server

2. 🔥 RTMP 握手(Handshake)

RTMP的握手分成3步(C0、C1、C2 + S0、S1、S2):

阶段描述
C0 + C1客户端发送 1 字节版本号(C0) + 1536字节随机数据(C1)
S0 + S1 + S2服务器返回 1字节版本号(S0)+1536字节随机数据(S1),再返回一份确认(S2)
C2客户端最后发送一份确认

3. 🔥 连接请求(Connect)

握手成功后,客户端发送一个 connect 命令,告诉服务器:

  • 我要连哪个应用(app,比如 /live)
  • 使用什么流(stream key,比如 /live/stream123)
  • 包含了很多信息(版本号、URL、认证token、编码格式要求等等)

服务器收到 connect 请求后,回复一个 _result 或 _error。

4. 🔥 建立流(CreateStream)

  • 客户端再发 createStream 请求(可以理解成 “我要打开一个播放或推流通道”)
  • 服务器返回一个 stream_id
  • 这个 stream_id 后续用来标识当前的媒体流。

5. 🔥 推流或拉流(Publish / Play)

类型动作
推流(主播)发送 publish 命令(准备往服务器推送音视频)
拉流(观众)发送 play 命令(准备从服务器拉取音视频)

6. 🔥 音视频数据传输

这部分就是不停发 RTMP Message:

  • 音频帧(Audio Message)
  • 视频帧(Video Message)
  • 元数据(Metadata Message,比如宽高fps变化)

每个消息有自己的 header 和 payload,服务器和客户端之间基于 TCP 保持通信

📦 连接和释放的关系

🔥 连接建立流程(Connection Setup)

TCP连接 → RTMP握手 → connect命令 → createStream → publish或play → 推流或拉流

整个连接生命周期是绑定的!

  • 只要 TCP 连接存在,RTMP的 session 就存在。
  • 流(stream)是基于连接之上的一个资源(stream_id标识)。

🔥 连接释放流程(Connection Teardown)

场景触发条件
正常断开客户端发送 deleteStream 命令,告诉服务器我要关闭流;然后发送 close 命令断开连接;最后 TCP 四次挥手
异常断开客户端断电、崩溃、网络异常,TCP连接直接断掉
服务器踢出如果服务器检测到非法流、长时间空闲、认证失败,会强制关闭 TCP 连接
超时断开有些服务器设置 idle timeout,比如 60秒无数据,自动踢掉

一旦 TCP 断开,RTMP session 和所有相关 stream 都被清理。

如下图所示:

[Client]             [Server]|    TCP connect     ||------------------->||    RTMP handshake   ||<------------------->||    connect          ||------------------->||    _result          ||<-------------------||    createStream     ||------------------->||    _result(streamId)||<-------------------||    publish/play     ||------------------->||    start streaming  ||<===================>||    deleteStream     ||------------------->||    close connection ||------------------->||  (TCP close)        |

相关文章:

  • 摸鱼屏保神器工具软件下载及使用教程
  • AIGC在游戏开发中的革命:自动化生成3A级游戏内容
  • Vue3 组件通信与插槽
  • Qt开发:如何加载样式文件
  • 玩转Pygame绘图:从简单图形到炫酷精灵
  • 【开源飞控】调试
  • maven打包时配置多环境参数
  • 设置右键打开VSCode
  • MCP协议:AI与数据世界的“万能连接器“
  • [创业之路-390]:人力资源 - 社会性生命系统的解构与重构:人的角色嬗变与组织进化论
  • SpringBoot技术概述与应用实践
  • GPT系列模型-20250426
  • 《软件设计师》复习笔记(6.1)——信息安全及技术
  • 常见的机器视觉通用软件
  • 数据安全和合规性市场分析
  • Redis常见面试题——List对象
  • Redis 数据分片三大方案深度解析与 Java 实战
  • Python爬虫实战:获取高考资源网各学科精品复习资料
  • 蓝桥杯 8. 移动距离
  • Angular开发经常涉及到组件间传递参数,用原生js开发时,如何解决这些问题?
  • 一回合摘下“狮心”,张名扬霸气回应观众:再嘘一个我听听
  • 辽宁省信访局副局长于江调任辽宁省监狱管理局局长
  • 网络游戏用户规模和市场销售创新高,知识产权保护面临哪些挑战?
  • 日均新开三家“首店”,上海的“首发经济”密码是什么?
  • 当代视角全新演绎,《风雪夜归人》重归首都剧场
  • 观察|上海算力生态蓬勃发展,如何助力千行百业数智化转型升级