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

Python从MQTT接收JPG帧转RTSP流报错问题排查

问题分析与解决方案

错误原因

你遇到的CAP_IMAGES: can't find starting number错误,本质是OpenCV默认的VideoWriter不支持直接向RTSP服务器推流。它会把你传入的RTSP URL误判为图片序列的文件名模板(比如img_%03d.jpg这种带编号的格式),自然找不到起始编号而报错。

解决步骤

1. 确认环境依赖

  • 安装带FFmpeg支持的OpenCV:如果用pip安装,优先选择opencv-python-headless,或确保编译OpenCV时包含FFmpeg模块。
  • 确认RTSP服务器(如rtsp-simple-server)已正常启动并监听8554端口。

2. 修改VideoWriter配置

必须指定FFmpeg作为后端,并添加RTSP推流的必要参数,同时统一帧尺寸(你的代码中初始帧尺寸与VideoWriter设置的(640,480)不匹配,会导致写入失败)。

3. 修改后的完整代码

import base64
import cv2 as cv
import numpy as np
import paho.mqtt.client as mqtt


MQTT_BROKER = "0.0.0.0"
MQTT_PORT = 15883
MQTT_RECEIVE = "test/cam"

# 初始化帧尺寸与实际接收帧保持一致
frame = np.zeros((240, 320, 3), np.uint8)
frame_width, frame_height = frame.shape[1], frame.shape[0]
size = (frame_width, frame_height)

# RTSP推流地址
rtsp_url = 'rtsp://127.0.0.1:8554/test'

# 配置VideoWriter:指定FFmpeg后端,设置RTSP传输协议和编码
fourcc = cv.VideoWriter_fourcc(*"H264")
out = cv.VideoWriter(
    rtsp_url,
    cv.CAP_FFMPEG,
    fourcc,
    20.0,
    size,
    True
)
# 设置RTSP为TCP传输,避免UDP丢包
out.set(cv.CAP_PROP_RTSP_TRANSPORT, cv.RTSP_TRANSPORT_TCP)


def on_connect(client, userdata, flags, rc):
    print("Connected with result code "+str(rc))
    client.subscribe(MQTT_RECEIVE)


def on_message(client, userdata, msg):
    global frame, frame_width, frame_height, size
    img = base64.b64decode(msg.payload)
    npimg = np.frombuffer(img, dtype=np.uint8)
    frame = cv.imdecode(npimg, 1)
    # 更新帧尺寸(适配摄像头分辨率变化)
    frame_height, frame_width = frame.shape[:2]
    size = (frame_width, frame_height)
    # 尺寸变化时重新初始化VideoWriter
    if out.get(cv.CAP_PROP_FRAME_WIDTH) != frame_width or out.get(cv.CAP_PROP_FRAME_HEIGHT) != frame_height:
        out.release()
        out = cv.VideoWriter(
            rtsp_url,
            cv.CAP_FFMPEG,
            fourcc,
            20.0,
            size,
            True
        )
        out.set(cv.CAP_PROP_RTSP_TRANSPORT, cv.RTSP_TRANSPORT_TCP)


client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect(MQTT_BROKER, MQTT_PORT)
client.loop_start()

while True:
    if frame is not None:
        cv.imshow("Stream", frame)
        # 确保写入帧尺寸与VideoWriter一致
        resized_frame = cv.resize(frame, size)
        out.write(resized_frame)
    if cv.waitKey(1) & 0xFF == ord('q'):
        break

cv.destroyAllWindows()
client.loop_stop()
out.release()

关键修改点

  • 给VideoWriter添加cv.CAP_FFMPEG参数,强制使用FFmpeg后端处理RTSP协议。
  • 统一帧尺寸,避免因尺寸不匹配导致的写入失败。
  • 设置RTSP为TCP传输,降低丢包概率。

替代方案(OpenCV推流仍异常时)

如果上述方法无效,可直接用FFmpeg命令行推流:将解码后的帧写入管道,通过FFmpeg推送到RTSP服务器,示例代码片段:

import subprocess
# 初始化FFmpeg推流进程
ffmpeg_cmd = [
    'ffmpeg',
    '-y',
    '-f', 'rawvideo',
    '-vcodec', 'rawvideo',
    '-pix_fmt', 'bgr24',
    '-s', f'{frame_width}x{frame_height}',
    '-r', '20',
    '-i', '-',
    '-c:v', 'libx264',
    '-preset', 'ultrafast',
    '-f', 'rtsp',
    rtsp_url
]
process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE)

# 在循环中写入帧
process.stdin.write(frame.tobytes())

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 16:43:13