youtbe-dl同时进行多次下载

时间:2018-05-06 08:18:16

标签: python python-3.x youtube-dl

我有一个python应用程序,我有一个包含多个网址的变量。

此刻我使用的是这样的东西:

WSASend

但是这样我只下载了一个又一个视频。我如何下载,让我们同时说3个视频? (不是来自youtube所以没有播放列表或频道)

我不需要python中的多线程,但多次调用youtube-dl,拆分数组。所以从python的角度来看可以在线程上。

2 个答案:

答案 0 :(得分:2)

使用Pool

import multiprocessing.dummy
import subprocess

arr = [
    {'vpath': 'example/%(title)s.%(ext)s', 'url': 'https://www.youtube.com/watch?v=BaW_jenozKc'},
    {'vpath': 'example/%(title)s.%(ext)s', 'url': 'http://vimeo.com/56015672'},
    {'vpath': '%(playlist_title)s/%(title)s-%(id)s.%(ext)s',
     'url': 'https://www.youtube.com/playlist?list=PLLe-WjSmNEm-UnVV8e4qI9xQyI0906hNp'},
]

email = 'my-email@example.com'
password = '123456'

def download(v):
    subprocess.check_call([
        'echo', 'youtube-dl',
        '-u', email, '-p', password,
        '-o', v['vpath'], '--', v['url']])


p = multiprocessing.dummy.Pool(concurrent)
p.map(download, arr)

multiprocessing.dummy.PoolPool的基于线程的轻量级版本,在这里更合适,因为工作任务只是启动子进程。

请注意,而不是os.systemsubprocess.check_call,这会阻止您之前代码中的command injection vulnerability

另请注意,youtube-dl output templates非常强大。在大多数情况下,您实际上并不需要自己定义和管理文件名。

答案 1 :(得分:1)

我使用threading库实现了同样的目的,该库考虑了一种生成新进程的简便方法。

假设:

  • 每个任务会将视频下载到另一个目录。
import os
import threading
import youtube_dl

COOKIE_JAR = "path_to_my_cookie_jar"

def download_task(videos, output_dir):

    if not os.path.isdir(output_dir):
        os.makedirs(output_dir)

    if not os.path.isfile(COOKIE_JAR):
        raise FileNotFoundError("Cookie Jar not found\n")

    ydl_opts = { 
        'cookiefile': COOKIE_JAR, 
        'outtmpl': f'{output_dir}/%(title)s.%(ext)s'
    }

    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        ydl.download(videos)


if __name__ == "__main__":

    output_dir = "./root_dir"

    threads = []
    for playlist in many_playlists:
        output_dir = f"{output_dir}/playlist.name"
        thread = threading.Thread(target=download_task, args=(playlist, output_dir)
        threads.append(thread)

    # Actually start downloading
    for thread in threads:
        thread.start()

    # Wait for all the downloads to complete
    for thread in threads: 
        thread.join()