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

OpenCV处理RTSP流推RTMP时subprocess写入报Broken pipe错误如何解决

问题原因与解决方案

核心错误原因

你当前使用的-c copy是流复制模式,仅适合直接转发已编码的视频流,不能处理OpenCV输出的原始未编码帧。FFmpeg无法识别你通过stdin传入的原始BGR像素数据,直接异常退出,导致写入管道时报Broken pipe错误。

需要修改的配置

  • 调整FFmpeg启动参数,明确指定输入原始帧的格式、分辨率、帧率等信息,替换流复制模式为实时编码模式
  • 调整帧处理逻辑顺序,先判断帧读取是否成功,再执行后续处理操作

修改后的完整代码

import sys
import subprocess
import cv2

rtmp_url = "rtmp://127.0.0.1:1935/live/test"
cap = cv2.VideoCapture("rtsp://10.0.1.7/media.sdp")

# 采集视频信息用于ffmpeg配置
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 修正后的ffmpeg命令:明确输入格式为原始bgr24帧,编码为h264输出flv
command = [
    'ffmpeg',
    '-y', # 自动覆盖输出
    '-f', 'rawvideo',
    '-vcodec','rawvideo',
    '-pix_fmt', 'bgr24', # OpenCV默认像素格式
    '-s', f'{width}x{height}', # 分辨率
    '-r', str(fps), # 帧率
    '-i', '-', # 从stdin读取输入
    '-c:v', 'libx264', # 用h264编码
    '-pix_fmt', 'yuv420p', # 兼容RTMP的像素格式
    '-preset', 'veryfast', # 编码速度优先,降低延迟
    '-f', 'flv',
    rtmp_url
]

p = subprocess.Popen(command, stdin=subprocess.PIPE, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)

font = cv2.FONT_HERSHEY_SIMPLEX
while cap.isOpened():
    ret, frame = cap.read()
    # 先判断帧读取是否成功
    if not ret:
        print("frame read failed")
        break
    # 叠加水印
    cv2.putText(frame, 'TEXT ON VIDEO', (50, 50), font, 1, (0, 255, 255), 2, cv2.LINE_4)
    # 本地预览
    cv2.imshow('video', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    # 写入ffmpeg子进程
    try:
        p.stdin.write(frame.tobytes())
    except Exception as e:
        print(e)
        break

cap.release()
cv2.destroyAllWindows()
p.stdin.close()
p.wait()

额外说明

如果需要排查FFmpeg端的报错,可以把启动参数里的stderr=subprocess.DEVNULL改成stderr=subprocess.PIPE,再读取FFmpeg的错误日志定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 17:24:04