使用 python youtube_dl 将数据直接下载到临时文件中

Downloading data directly into a temporary file with python youtube_dl

我正在使用 python 嵌入式 youtube_dl,我想将视频内容直接下载到一个临时文件中。我试图创建一个 NamedTemporaryFile 并让 youtube_dl 写入其中,但我总是收到文件已下载的提示(临时文件具有该名称,它认为下载已经发生)。

我还尝试让 youtube_dl 将下载的数据流式传输到 stdout 并将 stdout 重定向到临时文件,但我无法将 python 嵌入式版本获取到去做。它不会输出到 stdout 它只是创建一个名为 -.mp4.

的文件
import youtube_dl

ydl_opts = {
    "format": "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
    "merge-output-format": "mp4",
    "recode-video": "mp4",
    "outtmpl": "-",
    "verbose": True,
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    ydl.download(["https://www.youtube.com/watch?v=h3h035Eyz5A&ab_channel=Loku"])

总而言之,上面的代码不会覆盖 -.mp4 文件(如果它们已经存在)并且它不会将下载流式传输到 stdout 因此我可以将其重定向到临时文件。

需要临时文件,因为它是进一步处理的中间步骤。在这一点上,我觉得我需要将文件复制到临时文件并删除原始文件,或者我需要使用 youtube_dl 和一个感觉很傻的子进程。

我之前 运行 遇到过类似的问题。我发现一个很好的解决方法是使用 tempfile.TemporaryDirectory() 临时存储文件,然后使用 open() 检索文件。

查看 youtube_dl 代码库,看起来您想使用 extract_info 而不是直接使用 download 方法。

import tempfile

from youtube_dl import YoutubeDL
from youtube_dl.utils import DownloadError

with tempfile.TemporaryDirectory() as tempdirname:
  ydl_opts = {
      "format": "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
      "merge_output_format": "mp4",
      "outtmpl": f"{tempdirname}/%(id)s.%(ext)s",
      "noplaylist": True,
      "verbose": True,
  }
  ydl = YoutubeDL(ydl_opts)
  try:
    meta = ydl.extract_info(
      "https://www.youtube.com/watch?v=h3h035Eyz5A&ab_channel=Loku",
      download=True,
    )
  except DownloadError as e:
    raise e
  else:
    video_id = meta["id"]
    video_ext = meta["ext"]
    file = open(f"{tempdirname}/{video_id}.{video_ext}", "rb")
    # whatever else you gotta do bruh...
    # when the with statement finishes execution, the temp directory
    # will be cleaned up.

请注意,您应该使用 snake_case 作为参数(ydl_opts 中的键),因为您没有使用 cli。我还认为 recode-video 不是受支持的选项,但请检查 here 以确保。

另请注意,我假设您要下载一个视频。上面的代码没有考虑从临时目录中检索播放列表,我特意将 noplaylist 选项添加到 ydl_opts.