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

Ubuntu下Python+FFmpeg推RTMP流遇BrokenPipeError[Errno32]求助

解决Ubuntu下Python+FFmpeg推RTMP流出现BrokenPipeError的问题

你的脚本在Windows正常运行但Ubuntu上报错,核心原因是环境差异导致FFmpeg进程异常退出,进而触发管道写入错误。以下是针对性修复方案:

1. 移除shell=True并捕获FFmpeg错误输出

Ubuntu下使用shell=True会额外启动shell进程,容易引发管道异常,且无法获取FFmpeg的错误日志,不利于排查问题。修改子进程启动代码:

# 去掉shell=True,同时捕获stdout/stderr以便查看FFmpeg运行日志
p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

2. 禁用cv2.imshow(无头服务器环境适配)

Ubuntu服务器通常没有图形界面,cv2.imshow因无法创建窗口会直接报错,中断整个推流流程。直接删除以下两行代码:

# cv2.imshow('frame', frame)
# cv2.waitKey(1)

3. 匹配实际帧率并调整编码预设

脚本中强制指定-r 30,但实际摄像头帧率可能与该值不符,会导致FFmpeg帧处理速度不匹配引发管道中断。同时preset slow在服务器上CPU占用过高,容易导致进程卡顿退出:

# 替换为实际捕获的帧率,编码预设改用ultrafast降低CPU负载
command = ['ffmpeg',
           '-y',
           '-f', 'rawvideo',
           '-vcodec', 'rawvideo',
           '-pix_fmt', 'bgr24',
           '-s', "{}x{}".format(width, height),
           '-r', str(fps),  # 使用摄像头实际帧率
           '-i', '-',
           '-c:v', 'libx264',
           '-pix_fmt', 'yuv420p',
           '-preset', 'ultrafast',  # 服务器实时推流推荐用该预设
           '-threads', '0',
           '-f', 'flv',
           rtmp_url]

4. 捕获管道异常并清理资源

当FFmpeg进程异常退出后,写入管道会触发BrokenPipeError,需要捕获该异常并及时清理子进程:

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("读取帧失败")
        break

    try:
        p.stdin.write(frame.tobytes())
        p.stdin.flush()  # 强制刷新管道,确保数据及时写入
    except BrokenPipeError:
        print("FFmpeg进程已退出,终止推流")
        # 打印FFmpeg错误日志排查问题
        stderr_output = p.stderr.read()
        if stderr_output:
            print("FFmpeg错误详情:\n", stderr_output.decode('utf-8', errors='ignore'))
        break

# 循环结束后释放所有资源
cap.release()
if p.poll() is None:
    p.stdin.close()
    p.terminate()
p.wait()

5. 检查摄像头设备权限

如果使用本地摄像头(path=0),需要确保当前用户有权限访问/dev/video0:

# 将当前用户加入video组
sudo usermod -aG video $USER
# 注销后重新登录生效

修改后的完整脚本

import subprocess
import cv2

rtmp_url = "rtmp://..."
path = 0
cap = cv2.VideoCapture(path)

# 采集视频基础信息
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推流命令
command = ['ffmpeg',
           '-y',
           '-f', 'rawvideo',
           '-vcodec', 'rawvideo',
           '-pix_fmt', 'bgr24',
           '-s', f"{width}x{height}",
           '-r', str(fps),
           '-i', '-',
           '-c:v', 'libx264',
           '-pix_fmt', 'yuv420p',
           '-preset', 'ultrafast',
           '-threads', '0',
           '-f', 'flv',
           rtmp_url]

# 启动FFmpeg子进程
p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        print("读取帧失败")
        break

    try:
        p.stdin.write(frame.tobytes())
        p.stdin.flush()
    except BrokenPipeError:
        print("FFmpeg进程异常退出,停止推流")
        err_msg = p.stderr.read().decode('utf-8', errors='ignore')
        if err_msg:
            print("FFmpeg错误日志:\n", err_msg)
        break

# 释放资源
cap.release()
if p.poll() is None:
    p.stdin.close()
    p.terminate()
p.wait()

内容的提问来源于stack exchange,提问作者Loc Bui Nhien

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 17:03:15