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
RTMPE Adobe 自己的加密版 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)        |

点赞一下

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦