如何设置超时规则,让youtube-dl下载YouTube音频超过指定时长后自动终止
问题根因
- 你创建
Process时给target传的是download(),末尾带括号会直接在主进程当场执行download函数,而非将函数作为对象传给子进程调度,子进程实际没有执行任务 - 你创建的
Timer没有调用.start()方法,定时器根本不会触发终止逻辑 - 就算正确终止了执行
download的子进程,因为你是通过os.command调用的youtube-dl,youtube-dl会作为独立的孙子进程运行,不会随父进程终止而退出
可行实现方案
方案1:直接管理youtube-dl进程(更简单,推荐)
直接用subprocess调用youtube-dl,不需要额外开Process,直接给youtube-dl进程加超时逻辑:
import subprocess import threading def download_audio(youtube_url): # 替换成你自己的youtube-dl下载音频的命令 cmd = ["youtube-dl", "-x", "--audio-format", "mp3", youtube_url] # 启动youtube-dl进程 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # 定义超时终止逻辑 def kill_proc(): if proc.poll() is None: # 进程还在运行的话就杀掉 proc.kill() print("下载超时,已终止任务") # 启动10秒定时器 timer = threading.Timer(10, kill_proc) try: timer.start() stdout, stderr = proc.communicate() if proc.returncode == 0: print("下载完成") else: print(f"下载出错,错误信息:{stderr.decode()}") finally: timer.cancel() # 正常完成的话取消定时器
方案2:修正原有多进程写法的问题
如果要保留你原来的多进程结构,需要修改3个核心点:
- Process的target传函数对象,不加括号
- 显式调用
start()启动Timer - 用进程组方式终止,连带杀死子进程启动的youtube-dl
from multiprocessing import Process from threading import Timer import os import signal import subprocess def download(youtube_url): # 这里用subprocess启动youtube-dl,设置进程组ID方便后续全组杀死 cmd = ["youtube-dl", "-x", "--audio-format", "mp3", youtube_url] proc = subprocess.Popen(cmd, preexec_fn=os.setpgrp) proc.wait() if __name__ == "__main__": # 注意target传函数名不加括号,参数通过args传入 p = Process(target=download, args=("你的Youtube视频链接",)) p.start() def kill_process_group(): if p.is_alive(): # 杀死整个进程组,包括子进程启动的youtube-dl os.killpg(os.getpgid(p.pid), signal.SIGKILL) print("超时已终止下载") # 启动定时器 t = Timer(10, kill_process_group) t.start() p.join() t.cancel()
内容的提问来源于stack exchange,提问作者teleriffr
相关产品推荐
相关产品推荐

