You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ffmpeg将ROS订阅话题接收的图像流直接转换为视频

ROS实时图像帧无本地缓存直接生成视频方案

核心思路是通过subprocess启动ffmpeg子进程,建立标准输入管道,将转换好的OpenCV图像帧直接写入管道,全程不会生成临时图片文件。

前置依赖

  • 系统已安装ffmpeg
  • Python环境已安装subprocess(标准库无需额外安装)

完整修改后代码

import cv2
from cv_bridge import CvBridge
import rospy
from sensor_msgs.msg import Image
import numpy as np
import subprocess
import atexit

# 全局参数配置,根据实际情况修改
FRAME_WIDTH = 640  # 你的ROS图像实际宽度
FRAME_HEIGHT = 480 # 你的ROS图像实际高度
FPS = 30 # 你的ROS图像话题实际帧率
OUTPUT_PATH = "output.mp4" # 输出文件名,改后缀为.mkv即可生成mkv格式

# 初始化ffmpeg子进程
ffmpeg_cmd = [
    'ffmpeg',
    '-y', # 自动覆盖已存在的输出文件
    '-f', 'rawvideo',
    '-vcodec', 'rawvideo',
    '-pix_fmt', 'bgr24', # OpenCV默认BGR格式,对应bgr24
    '-s', f'{FRAME_WIDTH}x{FRAME_HEIGHT}',
    '-r', str(FPS),
    '-i', '-', # 从标准输入读取数据
    '-c:v', 'libx264', # H.264编码,兼容性好
    '-pix_fmt', 'yuv420p',
    '-preset', 'fast', # 编码速度等级,fast/medium/slow,越慢压缩率越高
    '-f', 'mp4' if OUTPUT_PATH.endswith('.mp4') else 'matroska',
    OUTPUT_PATH
]
ffmpeg_process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)

# 注册退出回调,确保ffmpeg正常关闭
def cleanup():
    ffmpeg_process.stdin.close()
    ffmpeg_process.wait()
atexit.register(cleanup)

def callback(data):
    br = CvBridge()
    rospy.loginfo("receiving video frame")
    current_frame = br.imgmsg_to_cv2(data)
    # 确保帧分辨率和配置一致,可根据需要加resize逻辑
    if current_frame.shape[0] != FRAME_HEIGHT or current_frame.shape[1] != FRAME_WIDTH:
        current_frame = cv2.resize(current_frame, (FRAME_WIDTH, FRAME_HEIGHT))
    # 将帧写入ffmpeg标准输入
    ffmpeg_process.stdin.write(current_frame.tobytes())
    cv2.imshow("camera", current_frame)
    cv2.waitKey(1)

def listener():
    rospy.init_node("video_sub_py", anonymous=True)
    rospy.Subscriber("video_frames", Image, callback)
    rospy.spin()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    listener()

配置说明

  • 生成mkv格式只需将OUTPUT_PATH的后缀改为.mkv即可,代码会自动适配输出格式
  • 如果你的ROS图像是灰度格式,将ffmpeg参数里的pix_fmt改为gray8即可
  • 编码速度可调整-preset参数,可选参数从快到慢为:ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow,速度越快生成的视频文件体积越大

常见问题排查

  • 视频花屏:检查配置的分辨率是否和实际图像分辨率一致,或像素格式是否匹配
  • 生成的视频无法打开:确保程序正常退出触发cleanup回调,强制中断进程会导致ffmpeg未写视频索引,文件损坏

内容的提问来源于stack exchange,提问作者techyidiot

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 10:36:04