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…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

Vue3 PC端 UI组件库我更推荐Naive UI
一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用,前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率,还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库(Naive UI、Element …...