当前位置: 首页 > news >正文

详细介绍:从 ROS 订阅视频话题到本地可视化与 RTMP 推流全流程实战

一、背景介绍

在机器人系统中,摄像头采集的视频数据通常以 ROS 话题的形式发布,例如:

/camera/image_raw

但是:

  • 如果我们希望在浏览器或其他终端设备上实时观看,需要将 ROS 图像转换为网络可访问的视频流;
  • 而如果希望在局域网或服务器上做视频转发或云端监控,就需要进一步将视频流推送到 RTMP 服务(如 Nginx)

本篇将完整讲解以下三步流程:

[ROS Topic] → [Flask + OpenCV 本地视频流] → [FFmpeg 推流到 RTMP (Nginx)]

最终效果是:

✅ 你可以在浏览器打开
http://192.168.1.200:5000/stream 看到实时视频流;
✅ 同时,在另一台机器(例如 192.168.1.201)上通过
rtmp://192.168.1.201/live/stream 也能看到相同的视频。


其实是感知主控没网,下载不了web-server;而运控端有网,但不让下载ros。所以只能通过这种方式来实现视频流的迁移。这是无可奈何的方法

二、系统架构图

┌──────────────────────────────┐
│          ROS Node             │
│  └── 订阅 /camera/image_raw   │
└──────────────┬───────────────┘│▼
┌──────────────────────────────┐
│ Flask Web Server              │
│  └── 使用 OpenCV 转 MJPEG 流  │
│  └── 提供 http://192.168.1.200:5000/stream │
└──────────────┬───────────────┘│▼
┌──────────────────────────────┐
│ FFmpeg 推流模块              │
│  └── 读取 MJPEG 流           │
│  └── 编码为 H.264 (x264)     │
│  └── 推送到 RTMP (Nginx)     │
│      rtmp://192.168.1.201/live/stream │
└──────────────────────────────┘

⚙️ 三、从 ROS 话题获取视频并发布本地 HTTP 流

首先,用 Python 写一个 ROS + Flask 节点:

#!/usr/bin/env python3
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
import cv2
from flask import Flask, Response
app = Flask(__name__)
bridge = CvBridge()
frame = None
def image_callback(msg):
global frame
frame = bridge.imgmsg_to_cv2(msg, "bgr8")
@app.route('/stream')
def stream():
def generate():
global frame
while True:
if frame is None:
continue
ret, jpeg = cv2.imencode('.jpg', frame)
if not ret:
continue
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + jpeg.tobytes() + b'\r\n\r\n')
return Response(generate(), mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
rospy.init_node('video_stream_node')
rospy.Subscriber('/camera/image_raw', Image, image_callback)
app.run(host='0.0.0.0', port=5000)

保存为 ros_stream.py,运行后即可访问:

http://192.168.1.200:5000/stream

在浏览器中会显示实时视频画面 。


四、部署 Nginx RTMP 服务器

在另一台主机(192.168.1.201)上安装并配置 RTMP 服务:

1️⃣ 安装 Nginx + RTMP 模块

sudo apt install nginx libnginx-mod-rtmp

2️⃣ 修改配置文件 /etc/nginx/nginx.conf

http {} 外层添加:

rtmp {server {listen 1935;chunk_size 4096;application live {live on;record off;}}
}

重启 nginx:

sudo systemctl restart nginx

验证端口是否监听:

sudo netstat -tulnp | grep 1935

若输出:

tcp 0 0 0.0.0.0:1935 0.0.0.0:* LISTEN nginx: master

说明 RTMP 服务正常启动 ✅


五、FFmpeg 推流到 RTMP 服务器

在 ROS 视频流所在的机器 (192.168.1.200) 上执行:

ffmpeg -fflags nobuffer -flags low_delay -framedrop \
-i "http://192.168.1.200:5000/stream" \
-c:v libx264 -preset ultrafast -tune zerolatency \
-r 25 -g 25 -keyint_min 25 -sc_threshold 0 \
-f flv "rtmp://192.168.1.201/live/stream"

解释:

参数作用
-fflags nobuffer禁用输入缓冲,提高实时性
-flags low_delay启用低延迟模式
-tune zerolatencyx264 零延迟调优
-preset ultrafast最高速编码,适合实时推流
-g 25每 25 帧插入关键帧
-f flv指定 RTMP 推流使用 FLV 容器

六、在客户端查看视频流

现在你已经完成推流,可以通过多种方式观看:

✅ VLC

打开网络串流:

rtmp://192.168.1.201/live/stream

✅ 浏览器 HLS 播放(可扩展)

nginx.conf 中开启 HLS 输出:

application live {live on;hls on;hls_path /tmp/hls;hls_fragment 1;
}

然后通过:

http://192.168.1.201/hls/stream.m3u8

即可在网页中播放。


⚡ 七、降低延迟的优化技巧

优化点方法
FFmpeg 编码缓冲使用 -tune zerolatency + -preset ultrafast
HTTP 输入缓冲添加 -fflags nobuffer
关键帧间隔设置 -g 25-sc_threshold 0
降低分辨率/帧率-s 1280x720 -r 20 可减少 CPU 延迟
关闭 B 帧x264 默认无 B 帧时延更低
RTMP 客户端缓冲VLC 中设置最小缓冲 100~300ms

实际测试结果:

实际测试效果其实并不好,大概会延迟8s左右,如果要实现实时性,这篇文档并不能给出好的效果,建议还是用背景中写的一些方法。


八、完整流程总结

阶段工具协议功能
Step 1ROS + cv_bridgeROS Topic获取相机视频
Step 2Flask + OpenCVHTTP MJPEG发布网页流
Step 3FFmpegRTMP (FLV)推送至流媒体服务器
Step 4Nginx RTMPRTMP/HLS提供局域网访问

最终形成一个低延迟、可扩展的视频传输链路:

ROS Topic → Flask (MJPEG) → FFmpeg (H.264) → RTMP Server → VLC/网页播放

✨ 九、结语

通过上述方法,我们成功实现了:

  • 从 ROS 摄像头话题实时采集视频;
  • 在本地搭建 HTTP 视频流可视化;
  • 使用 FFmpeg 转码推送至局域网 RTMP 服务器;
  • 并最终实现低延迟的多端观看。

这一方案在智能机器人、远程监控、室内导航测试等场景中非常实用。

http://www.jsqmd.com/news/328617/

相关文章:

  • 用React Native开发OpenHarmony应用:Overlay点击关闭
  • 现在app开始往深度发展
  • UniDBGrid 锁定第一列代码
  • 给app添加:分享到抖音+分享到朋友圈功能
  • 阿尔珐公司员工管理系统毕业论文+PPT(附源代码+演示视频)
  • CentOS 7 初始化脚本
  • 因为我的app生活小病模块已经覆盖了高血压所以不再独立开发
  • Java毕设项目:基于Java web的电影院选票系统(源码+文档,讲解、调试运行,定制等)
  • Kubernetes+Golang智能体工作流全栈部署指南
  • 2026.2
  • 当你为未来而焦虑,你是一个认真对待自己生命旅程的行者。
  • 盘前低吸分析
  • 拥抱“务实的乐观主义”的知识体系
  • 如何在LLM大语言模型上微调来优化数学推理能力? - 教程
  • 当物价水平持续、普遍上涨时,加息是抑制通胀的主要武器。
  • 被社会时钟、同龄人进度或自我 deadline 所追赶的知识体系
  • ue metahuman 绑定资产 鞋子,衣服
  • 408真题解析-2010-28-操作系统-连续分配管理方式
  • 基于wiringPi库写的一些代码(二)
  • 一份不可多得的 《 Redis 》教程 | 8K字
  • c++ 操作蓝图变量实战
  • 基于J2EE的智慧篮球馆预约(11858)
  • 计算机网络经典问题透视:RTS/CTS是强制使用还是选择使用?
  • 基于Java EE的高校排课系统(11859)
  • 8%转化率背后的真相:那些被你忽略的“愤怒点击”与“幽灵数据”
  • 基于BS架构的学科竞赛系统(11856)
  • 基于HTML的影剧网页制作(11857)
  • 开源作者必备:4套无敌Issue回复话术,体面甩锅+完美护短
  • 2026年热门的午休课桌椅/学生课桌椅厂家推荐及选购参考榜
  • 运行 OpenClaw 的最佳模型