youtbe-dl несколько загрузок одновременно - PullRequest
0 голосов
/ 06 мая 2018

У меня есть приложение на Python, где у меня есть переменная, которая содержит несколько URL.

В данный момент я использую что-то вроде этого:

for v in arr:
        cmd = 'youtube-dl -u ' + email + ' -p ' + password + ' -o "' + v['path'] + '" ' + v['url']

        os.system(cmd)

Но так я загружаю только одно видео за другим. Как я могу скачать, скажем, 3 видео одновременно? (Не с YouTube, поэтому нет плейлиста или каналов)

Мне не нужно многопоточность в python, но чтобы вызывать youtube-dl несколько раз, разбивая массив. Таким образом, с точки зрения Python может быть в потоке.

Ответы [ 2 ]

0 голосов
/ 04 мая 2019

Я добился того же, используя библиотеку 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()

0 голосов
/ 06 мая 2018

Используйте 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.Pool - это облегченная основанная на потоках версия Pool, которая больше подходит здесь, поскольку рабочие задачи только запускают подпроцессы.

Обратите внимание, что вместо os.system, subprocess.check_call, что предотвращает уязвимость , вызывающую инъекцию команд * в вашем предыдущем коде.

Также обратите внимание, что выходные шаблоны youtube-dl действительно мощные. В большинстве случаев вам не нужно самим определять имена файлов и управлять ими.

...