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…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
