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

Ubuntu服务器Python调用ffmpeg推流5分钟中断,Bash运行正常如何解决?

问题原因

你使用subprocess.Popen启动ffmpeg进程时,指定了stdout=subprocess.PIPE和stderr=subprocess.PIPE捕获进程输出,但后续代码从未读取这两个管道的内容。Linux系统的管道默认缓冲区大小有限,ffmpeg运行过程中持续输出的日志会逐步填满缓冲区,缓冲区满后ffmpeg的写操作会被系统阻塞,无法继续发送推流数据,最终导致连接超时中断。
直接在Bash中执行ffmpeg命令时,输出直接打印到终端,不存在缓冲区堆满的问题,因此可以正常运行,该问题和你猜测的网络超时、bufsize参数无关。

修复方案

根据你是否需要留存ffmpeg运行日志,可选择对应方案:

  • 方案1:不需要保留ffmpeg输出日志,直接将输出重定向到空设备,关闭管道捕获
    修改subprocess.Popen参数即可:
process = subprocess.Popen(command,
                           stdout=subprocess.DEVNULL,
                           stderr=subprocess.DEVNULL)
  • 方案2:需要留存ffmpeg日志,新增独立线程读取管道内容,避免缓冲区堆积
    完整示例代码如下:
import time
import subprocess
import os
import threading

def read_output(pipe):
    # 循环读取管道内容,可自行修改将内容写入日志文件
    for line in iter(pipe.readline, b''):
        print(line.decode('utf-8', errors='ignore'))

if __name__ == "__main__":
    file = '/root/app2/m4.avi'

    command = [
        'ffmpeg',
        '-re',
        '-nostdin',
        '-i', file,
        '-vcodec', 'libx264',
        '-preset:v', 'medium',
        '-b:v', '3000k','-maxrate', '10000k','-bufsize', '200000k',
        '-acodec', 'aac',
        '-f', 'flv', 'rtmp://live.twitch.tv/app/live______',
    ]

    process = subprocess.Popen(command,
                                    stdout=subprocess.PIPE,
                                    stderr=subprocess.PIPE)
    
    # 启动两个子线程分别读取标准输出和标准错误
    threading.Thread(target=read_output, args=(process.stdout,), daemon=True).start()
    threading.Thread(target=read_output, args=(process.stderr,), daemon=True).start()

    st=time.time()
    while time.time()-st<100*60:
        print(time.time()-st)
        time.sleep(1)
  • 临时缓解方案:给ffmpeg命令添加-loglevel error参数,仅输出错误级别的日志,减少日志产生量。该方案仅能延长中断时间,无法彻底解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:57:05