RTMP(Real-Time Messaging Protocol)
RTMP(Real-Time Messaging Protocol)是一种用于实时音视频和数据传输的协议,常见于直播和流媒体应用。
一 RTSP 协商消息
一、消息类型(Message Types)
RTMP消息分为多种类型,通过Message Type ID标识,主要包括:
- 控制消息(Control Messages,Type ID 1-7):
- Set Chunk Size (ID=1):设置分块大小。
- Window Acknowledgement Size (ID=5):设置确认窗口大小。
- Set Peer Bandwidth (ID=6):协商带宽限制。
- 数据消息(Data Messages):
- AMF0 (ID=18) 或 AMF3 (ID=19):传输元数据或命令(如
onMetaData)。
- AMF0 (ID=18) 或 AMF3 (ID=19):传输元数据或命令(如
- 音视频数据:
- 音频数据 (ID=8)、视频数据 (ID=9):传输原始音视频流。
- 用户控制消息 (ID=4):如流开始/结束事件。
二、元数据(Metadata)
元数据用于描述流的基本信息,通常以onMetaData命令形式通过AMF0/AMF3编码发送。包含字段如:
- 视频宽度、高度、帧率、编码格式。
- 音频采样率、编码类型、时长等。
- 示例AMF0命令格式:
"onMetaData" + { duration: 60, width: 1280, ... }。
三、消息分块(Message Chunking)
RTMP将消息拆分为多个Chunk传输,以提升实时性。分块规则如下:
- Chunk Header:
- Basic Header:1-3字节,包含Chunk Stream ID和Chunk Type。
- Message Header:根据Chunk Type(0-3)决定包含字段(时间戳、消息长度、Type ID等)。
- Extended Timestamp(可选):当时间戳≥0xFFFFFF时启用。
- 分块示例:
- 若块大小设为128字节,300字节的消息会被分为3个Chunk(128+128+44)。
四、客户端与服务端协商过程
1. 握手(Handshake)
- C0/S0:交换版本号(通常为3)。
- C1/S1:交换随机数据和时间戳。
- C2/S2:确认随机数据,完成握手。
2. 参数协商(Post-Handshake)
握手后,通过控制消息协商传输参数:
- Set Chunk Size (Type=1):
- 双方发送此消息确定Chunk大小(默认128字节,可设为4096等)。
- Window Acknowledgement Size (Type=5):
- 设置接收方确认窗口大小(流量控制)。
- Set Peer Bandwidth (Type=6):
- 协商带宽限制,接收方需确认模式(硬限/动态/软限)。
3. 连接与流创建
- Connect Command:客户端发送连接请求,包含应用名称、传输参数等。
- CreateStream Command:创建逻辑流,服务端返回Stream ID。
- 发布/播放流:传输音视频数据及元数据(
onMetaData)。
五、关键流程示例
- 客户端发送
connect:| Chunk Stream ID=3 | AMF0 Command="connect" | Transaction ID=1 | App="live" | ... | - 服务端响应
Window Ack Size和Set Chunk Size:| Chunk Stream ID=2 | Control Message (Type=5, Ack Size=2500000) | | Chunk Stream ID=2 | Control Message (Type=1, Chunk Size=4096) | - 发送元数据
onMetaData:| Chunk Stream ID=4 | AMF0 Data (Type=18) | "onMetaData" + { width: 1280, ... } |
总结
- 协商内容:块大小、带宽、确认窗口等,通过控制消息动态调整。
- 元数据:通过AMF数据消息传输,描述流属性。
- 分块机制:提升传输效率,适应网络波动。
- 流程顺序:握手 → 参数协商 → 连接 → 流创建 → 数据传输。
通过上述机制,RTMP实现了低延迟、自适应的流媒体传输,适用于实时性要求高的场景。
RTMP 协议在客户端与服务器建立会话后,通过以下机制维护连接的稳定性,并在断开时进行相应处理:
二 会话维护
一、会话维护机制
1. 心跳机制(Keep-Alive)
RTMP 使用 User Control Messages (Type=4) 中的 Ping/Pong 机制作为心跳:
- Ping (Event=6):服务器或客户端主动发送,携带时间戳(4字节)。
- Pong (Event=7):接收方需立即响应,返回相同的 Ping 时间戳。
- 作用:
- 检测连接活性:若未及时收到 Pong,则认为连接已断开。
- 默认间隔:通常为 5-10 秒(具体由实现决定)。
2. 流量控制与确认机制
- Window Acknowledgement Size (Type=5):
- 接收方告知发送方可发送的最大未确认字节数(例如 2500000 字节)。
- 发送方需在达到该阈值后暂停发送,直到收到确认(Ack)。
- Acknowledgment (Type=3):
- 接收方定期发送已接收字节数的确认,帮助发送方调整传输速率。
- 作用:
- 避免网络拥塞,同时间接检测连接状态(若无 Ack 返回,可能连接异常)。
3. TCP 层保活(Keep-Alive)
- 依赖 TCP 协议的 Keep-Alive 机制(默认间隔通常较长,如 2 小时)。
- RTMP 更多依赖应用层(Ping/Pong)而非 TCP 保活,因后者响应不够实时。
4. 超时检测
- 服务器/客户端设定 空闲超时时间(如 30 秒):
- 若在超时时间内未收到任何数据包或心跳响应,则主动断开连接。
二、断开后的处理逻辑
1. 检测断开
- 主动检测:通过心跳超时(未收到 Pong)或 TCP 连接异常事件(如
ECONNRESET)。 - 被动检测:发送数据时发现写入失败(如
Broken Pipe错误)。
2. 客户端处理
- 自动重连:
- 关闭旧连接,重新发起握手(C0-C2/S0-S2)。
- 重新协商参数(Chunk Size、带宽等)。
- 重新创建流(
createStream)并发布/播放。
- 重试策略:
- 指数退避:首次立即重试,失败后等待 1s、2s、4s… 避免频繁请求。
- 最大重试次数:例如 3 次后放弃,通知用户。
3. 服务端处理
- 清理资源:
- 释放与连接关联的流(Stream)和会话(Session)资源。
- 通知其他订阅者该流已终止(如发送
onStatus事件)。
- 日志与告警:
- 记录断开原因(超时、主动关闭、网络错误等)。
- 触发监控告警(如大量异常断开)。
4. 应用层容错
- 会话恢复:
- 若支持,客户端重连后可尝试恢复之前的流(需服务端支持会话续传)。
- 例如,通过唯一 Session ID 关联旧流(非 RTMP 标准,需自定义实现)。
- 状态同步:
- 重连后重新发送关键元数据(如
onMetaData),确保播放端状态一致。
- 重连后重新发送关键元数据(如
三、示例流程
1. 正常心跳交互
Server -> Client: User Control Message (Ping, Time=1000)
Client -> Server: User Control Message (Pong, Time=1000)
2. 心跳超时导致断开
Server -> Client: Ping (Time=2000)
[Client未响应]
Server检测超时(30秒)-> 关闭连接,释放资源。
3. 客户端重连
1. 客户端检测断开 -> 触发重连逻辑。
2. 重新握手(C0-C1-C2/S0-S1-S2)。
3. 发送 Set Chunk Size、Window Ack Size 等参数。
4. 发送 createStream 创建新流。
5. 重新发布/播放流并发送元数据。
四、优化实践
- 合理配置超时时间:
- 心跳间隔:5-10 秒,超时时间:3 倍间隔(如 15-30 秒)。
- 冗余设计:
- 客户端实现断线重连队列,缓存未发送的数据(如直播推流的最后几秒数据)。
- 快速失败与降级:
- 若多次重连失败,切换备用服务器或通知用户检查网络。
- 服务端负载均衡:
- 使用集群避免单点故障,客户端支持故障转移(Failover)。
总结
RTMP 通过 应用层心跳(Ping/Pong)、流量控制确认 和 超时检测 维护会话活性。断开后,客户端和服务端需协作清理资源并尝试恢复,通常需应用层逻辑支持完整重连流程。实际开发中需结合业务场景优化重试策略和容错机制,以提升用户体验。
相关文章:
RTMP(Real-Time Messaging Protocol)
RTMP(Real-Time Messaging Protocol)是一种用于实时音视频和数据传输的协议,常见于直播和流媒体应用。 一 RTSP 协商消息 一、消息类型(Message Types) RTMP消息分为多种类型,通过Message Type ID标识&a…...
docker容器部署jar应用导入文件时候报缺少字体错误解决
如题,在导入文件时候报错如下: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager 经查是缺少对应字体,解决办法有两张: 第一种:…...
贪吃蛇解析
目录 文章结尾有代码可自取 Win32API 光标的隐藏 获取按键信息 控制光标位置 游戏开始前的准备 游戏准备及介绍 加载和欢迎界面 打印游戏指南 运行游戏 打印墙体和说明 设置蛇的各个信息 初始化及打印蛇 创造食物 运行游戏 1)打印得分情况 2&#…...
vue非组件的初学笔记
1.创建Vue实例,初始化渲染的核心 准备容器引包创建Vue实例new Vue() el用来指定控制的盒子data提供数据 2.插值表达式 作用利用表达式插值,将数据渲染到页面中 格式{{表达式}} 注意点 表达式的数据要在data中存在表达式是可计算结果的语句插值表达式…...
LeetCode 热题 100_单词搜索(60_79_中等_C++)(深度优先搜索(回溯))(初始化二维vector的大小)
LeetCode 热题 100_单词搜索(60_79) 题目描述:输入输出样例:题解:解题思路:思路一(深度优先搜索(回溯)): 代码实现代码实现(思路一&am…...
js闭包,跨域
js闭包,跨域 闭包 想象一下,你家有个大仓库(函数),仓库里放着各种东西(变量)。一般情况下,你从仓库外面是看不到也拿不到仓库里的东西的。但是,闭包就像是你在仓库里留…...
算法练习(力扣-BFS)——102. 二叉树的层序遍历
题目描述(简要概括) 题目链接:102. 二叉树的层序遍历 - 力扣(LeetCode) 题目要求对给定的二叉树进行层序遍历(从上到下,从左到右),并返回遍历的结果。层序遍历是一种基…...
Jetson Agx Orin平台preferred_stride调试记录--1924x720图像异常
1.问题描述 硬件: AGX Orin 在Jetpack 5.0.1和Jetpack 5.0.2上测试验证 图像分辨率在1920x720和1024x1920下图像采集正常 但是当采集图像分辨率为1924x720视频时,图像输出异常 像素格式:yuv_uyvy16 gstreamer命令如下 gst-launch-1.0 v4l2src device=/dev/video0 ! …...
nlp|微调大语言模型初探索(2),训练自己的聊天机器人
前言 上篇文章记录了具体的微调语言大模型步骤,以及在微调过程中可能遇见的各种报错,美中不足的是只是基于开源数据集的微调,今天来记录一下怎么基于自己的数据集去微调大语言模型,训练自己的智能机器人!!&…...
win11安装wsl报错:无法解析服务器的名称或地址(启用wsl2)
1. 启用wsl报错如下 # 查看可安装的 wsl --install wsl --list --online此原因是因为没有开启DNS的原因,所以需要我们手动开启DNS。 2. 按照如下配置即可 Google的DNS(8.8.8.8和8.8.4.4) 全国通用DNS地址 (114.114.114.114) 3. 运行以下命令来重启 WSL…...
Gentleman:优雅的Go语言HTTP客户端工具包
gentlemen介绍,特点等 插件驱动架构:Gentleman的核心特点是其插件系统,允许用户注册和重用各种自定义插件,如重试策略或动态服务器发现,以增强HTTP客户端的功能。 中间件层:项目内置了一个上下文感知的层次…...
解锁豆瓣高清海报(三)从深度爬虫到URL构造,实现极速下载
脚本地址: 项目地址: Gazer PosterBandit_v2.py 前瞻 之前的 PosterBandit.py 是按照深度爬虫的思路一步步进入海报界面来爬取, 是个值得学习的思路, 但缺点是它爬取慢, 仍然容易碰到豆瓣的 418 错误, 本文也会指出彻底解决旧版 418 错误的方法并提高爬取速度. 现在我将介绍…...
IDEA单元测试插件 SquareTest 延长试用期权限
SquareTest是一款强大的IDEA单元测试生成插件工具,具体使用方法就不过多介绍了,这里主要介绍变更试用期,方便大家使用 配置信息 我的电脑安装前提配置条件 IntelliJ IDEA 2023.2windows 系统 软件安装 IntelliJ IDEA 直接安装插件Squar…...
PLC的五个学习步骤
五个学习步骤详解: 1. 夯实电气基础 (第一步) 核心思想: PLC控制技术是建立在传统电气控制技术之上的,因此扎实的电气基础至关重要。学习内容: 电气元件原理: 深入理解继电器、接触器、按钮、三相异步电机等常用电气元件的工作原理。这是理解电气控制回…...
深度学习05 ResNet残差网络
目录 传统卷积神经网络存在的问题 如何解决 批量归一化BatchNormalization, BN 残差连接方式 残差结构 ResNet网络 ResNet 网络是在 2015年 由微软实验室中的何凯明等几位大神提出,斩获当年ImageNet竞赛中分类任务第一名,目标检测第一名。获得CO…...
卷积神经网络CNN
目录 一、CNN概述 二、图像基础知识 三、卷积层 3.1 卷积的计算 3.2 Padding 3.3 Stride 3.4 多通道卷积计算 3.5 多卷积核卷积计算 3.6 特征图大小计算 3.7 Pytorch 卷积层API 四、池化层 4.1 池化计算 4.2 Stride 4.3 Padding 4.4 多通道池化计算 4.5 Pytorc…...
Android:播放Rtsp视频流的两种方式
一.SurfaceView Mediaplayer XML中添加SurfaceView: <SurfaceViewandroid:id"id/surface_view"android:layout_width"match_parent"android:layout_height"match_parent"/> Activity代码: package com.android.rtsp;impor…...
web信息泄露 ctfshow-web入门web1-web10
01做题思路 判断做题的思路是读取,写入,还是执行判断大概的类型,有登录逻辑就尝试sql注入,有下载逻辑就尝试文件读取,有源码就做源码审计 02信息泄露及利用 robots.txt 以ctfshow的web1为例,访问robots…...
Log4j在Spring项目中的应用与实践
在现代Java开发中,日志记录是不可或缺的一部分。它不仅帮助开发者调试和监控应用程序的运行状态,还能在出现问题时快速定位原因。今天,我们就来探讨如何在Spring项目中使用Log4j进行日志管理,并通过具体的实例来展示其强大的功能。…...
docker安装mysql:8.0
1.docker源 目前docker国内的源基本上用不了了,建议去淘宝找一找,我整了一个大概是10R一个月。 2.拉取镜像 docker pull mysql:8.0 3.启动容器 命令如下: docker run \-p 3306:3306 \-e MYSQL_ROOT_PASSWORD123456 \-v /home/data/mysq…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
