RTMP协议
计算机知识

RTMP协议

JACIN13 分钟阅读
AI 摘要

这篇内容围绕 RTMP 协议在直播与流媒体链路中的作用展开,先说明它是 Adobe/Macromedia 设计的实时消息传输协议,运行在应用层并通常依赖 TCP 1935 端口提供可靠传输。文章把 RTMP 的使用价值放在直播场景中解释:推流端如 OBS 或推流 SDK 将音视频送入 SRS、Nginx-RTMP、Wowza 等服务器,服务器再面向观众侧转成 HTTP-FLV、HLS 或 WebRTC 等更适合播放和互动的协议。正文重点梳理了完整连接流程,从 TCP 三次握手、C0/C1/C2 与 S0/S1/S2 的 RTMP 握手,到 connect 指定 app、stream key 和认证信息,再到 createStream 获取 stream_id,最后通过 publish 或 play 进入推流、拉流阶段。数据传输部分强调 RTMP 通过 Chunk 分块与消息机制持续传递音频帧、视频帧和 metadata,并借助持久连接实现低延迟、多路复用和音视频同步。文章也补充了 RTMP URL 结构、RTMPT、RTMPS、RTMPE 等变体,以及 macOS 下可用 VLC、Live Stream Player 配合测试流地址进行验证。需要注意的是,浏览器端已不再原生适合播放 RTMP,因为 Flash 已被淘汰;同时 RTMP session 与底层 TCP 连接绑定,正常断开需经历 deleteStream、close 和 TCP 释放,异常断开或服务器踢出则会清理相关 stream。整体适合想理解直播推拉流入口协议、服务器接入流程和连接生命周期的后端、音视频与运维开发者。

目录#

[[toc]]

介绍#

📖 什么是 RTMP?#

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

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

text
•	作用: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 的格式#

python
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

📦 (标准直播系统):

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

流程链路#

1. 🔥 建立 TCP 连接#

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

  • 客户端(比如 OBS、推流SDK)通过 TCP 连接到 RTMP 服务器(比如 SRS、Nginx-RTMP、Wowza)。
  • 默认端口是 1935(可以改成443/80穿透)。
python
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)

python
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 都被清理。

如下图所示:

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

评论

还没有评论,来发第一个吧