如何在Python中获取youtube-dl的信息?

19 投票
3 回答
39350 浏览
提问于 2025-04-18 06:56

我正在用 tkinterpython 为 youtube-dl 制作一个 API,我想知道:

  • 如何实时获取 youtube-dl 的信息,比如下载速度、完成百分比、文件大小等等?

我尝试过:

import subprocess
def execute(command):
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)

    # Poll process for new output until finished
    while True:
        nextline = process.stdout.readline()
        if nextline == '' and process.poll() != None:
            break
        sys.stdout.write(nextline.decode('utf-8'))
        sys.stdout.flush()

    output = process.communicate()[0]
    exitCode = process.returncode

    if (exitCode == 0):
        return output
    else:
        raise ProcessException(command, exitCode, output)

execute("youtube-dl.exe www.youtube.com/watch?v=9bZkp7q19f0 -t")

来自 这个问题

但是它必须等到下载完成后才能给我这些信息;也许有办法从 youtube-dl 的源代码中获取这些信息。

3 个回答

5

我知道这个问题已经很久了,但youtube-dl有一些功能,可以让你很简单地实时提取这些信息。

这里是相关的文档:

progress_hooks:    A list of functions that get called on download
                       progress, with a dictionary with the entries
                       * status: One of "downloading", "error", or "finished".
                                 Check this first and ignore unknown values.
                       If status is one of "downloading", or "finished", the
                       following properties may also be present:
                       * filename: The final filename (always present)
                       * tmpfilename: The filename we're currently writing to
                       * downloaded_bytes: Bytes on disk
                       * total_bytes: Size of the whole file, None if unknown
                       * total_bytes_estimate: Guess of the eventual file size,
                                               None if unavailable.
                       * elapsed: The number of seconds since download started.
                       * eta: The estimated time in seconds, None if unknown
                       * speed: The download speed in bytes/second, None if
                                unknown
                       * fragment_index: The counter of the currently
                                         downloaded video fragment.
                       * fragment_count: The number of fragments (= individual
                                         files that will be merged)
                       Progress hooks are guaranteed to be called at least once
                       (with status "finished") if the download is successful.

使用方法:

def download_function(url):
    ydl_options = {
        ...
        "progress_hooks": [callable_hook],
        ...
    }
    with youtube_dl.YoutubeDL(ydl_options) as ydl:
        ydl.download([url])

def callable_hook(response):
    if response["status"] == "downloading":
        speed = response["speed"]
        downloaded_percent = (response["downloaded_bytes"]*100)/response["total_bytes"]
        ...
8
  1. 最好避免使用 subprocess,你可以像平常使用Python模块一样直接使用这个模块;可以参考这个链接:使用youtube-dl模块。这需要下载源代码,而不仅仅是安装应用程序到系统中。
  2. 如果你还是想继续使用 subprocess,你应该添加以下参数:

详细程度 / 模拟选项:

-q, --quiet              activates quiet mode

-s, --simulate           do not download the video and do not write anything to disk

--skip-download          do not download the video

-g, --get-url            simulate, quiet but print URL

-e, --get-title          simulate, quiet but print title

--get-thumbnail          simulate, quiet but print thumbnail URL

--get-description        simulate, quiet but print video description

--get-filename           simulate, quiet but print output filename

--get-format             simulate, quiet but print output format
  1. 关于你的代码,我觉得错误出在返回的那一行,你选择返回 sys.output 的最后一行,这是通过 communicate 返回的;我建议你试试这个简单但未经测试的例子:

def execute(command):

    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)

    #Poll process for new output until it is finished

    while True:

        nextline = process.stdout.readline()

        if nextline == '' and process.poll() != None:

             break

        yield nextline 

我在以下地方使用过它:

for i in execute("sudo apt-get update"):
    print i 

在任何情况下,别忘了更新你的版本。

45

试试这样做:

from youtube_dl import YoutubeDL

video = "http://www.youtube.com/watch?v=BaW_jenozKc"

with YoutubeDL(youtube_dl_opts) as ydl:
      info_dict = ydl.extract_info(video, download=False)
      video_url = info_dict.get("url", None)
      video_id = info_dict.get("id", None)
      video_title = info_dict.get('title', None)

你可能现在已经明白了,但这可能对其他人有帮助。

撰写回答