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

如何正确终止调用ffmpeg的循环式yt-dlp Python脚本?

解决yt-dlp调用ffmpeg时无法响应Ctrl+C/优雅终止的问题

问题背景

使用Python脚本结合yt-dlp下载直播流,因格式限制yt-dlp会调用ffmpeg执行下载。为处理直播中断(如Web服务器返回403错误),脚本设置了无限循环:下载失败则等待10秒后重试,同时通过捕获KeyboardInterrupt终止脚本。

但存在以下问题:

  • 本地运行时,单次按下Ctrl+C仅终止ffmpeg进程,快速按第二次会触发脚本重试;只有长按Ctrl+C才能同时终止ffmpeg和Python脚本
  • 通过script-server远程启动脚本时,无法正常终止脚本

需求:让Python主脚本优先捕获中断信号,同时优雅关闭ffmpeg以避免数据丢失。

原代码片段

while LOOP:
    ydl_opts = {
    "hls_use_mpegts" : True,
    "hls_prefer_native" : False,
    "outtmpl" : f"{datetime.now():%Y%m%d_%H%M%S%z}-{EVENT_NAME}.ts",
    "quiet": True
    }
    try:
        ydl = YoutubeDL(ydl_opts)
        ydl.download(URLS)

    except utils.DownloadError:
        print(f"Download error, retrying in {SLEEP_FOR} seconds")
        time.sleep(SLEEP_FOR)

    except KeyboardInterrupt:
        LOOP = False

解决方案(适配Linux+script-server)

尝试过守护进程方法,在Windows可行但Linux环境下失效。最终通过捕获SIGTERM信号实现可靠终止,在循环前添加以下代码:

import os
import signal

def sigterm_handler(s, frame):
    global LOOP
    LOOP = False
    p = os.getpid()
    os.kill(p, signal.SIGINT)

signal.signal(signal.SIGTERM, sigterm_handler)

原理说明

script-server会向运行中的脚本发送SIGTERM信号,自定义的信号处理器做了两件事:

  1. 将循环控制变量LOOP设为False,确保脚本不会在终止后重新进入下载循环
  2. 向自身进程发送SIGINT信号,触发ffmpeg的优雅关闭流程,保证已录制的视频数据不会丢失

内容的提问来源于stack exchange,提问作者Eugene O.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 15:03:30