How can I download just thumbnails using youtube-dl?
Asked Answered
E

4

16

I've been trying to download the thumbnails of a list of URL's (youtube videos) I have.

I've been using youtube-dl and I've worked it out to this so far:

     import os

     with open('results.txt') as f:
          for line in f:
              os.system("youtube-dl " + "--write-thumbnail " + line)

Like this I'm able to download the thumbnails but I'm forced to downloading the youtube videos as well.

How can I just download the thumbnail?

Eaglestone answered 21/9, 2016 at 2:7 Comment(3)
docs.python.org/3.8/library/subprocess.html is nicer for launching commandsIntercom
You know youtube-dl is written in python, right?Doctrinaire
You can use online tool to get YouTube thumbnail workversatile.com/youtube-thumbnail-downloaderMoldau
K
0

It looks like passing --list-thumbnails will return the url to the thumbnail images, but it will just output to the screen when calling os.system().

The following isn't the prettiest, but it's a quick working example of getting the output of youtube-dl into a string using subprocess, parsing it to get the url, and downloading with requests:

import re
import requests
import subprocess

with open('results.txt') as f:
    for line in f:
        proc = subprocess.Popen(['youtube-dl', '--list-thumbnails', line], stdout=subprocess.PIPE)
        youtubedl_output, err = proc.communicate()
        imgurl = re.search("(?P<url>https?://[^\s]+)", youtubedl_output).group('url')
        r = requests.get(imgurl)
        if r.status_code == 200:
            with open(imgurl.split('/')[4] + '.jpg', 'wb') as file:
                for chunk in r.iter_content(1024):
                    file.write(chunk)

Hope this helped!

Kooima answered 21/9, 2016 at 4:25 Comment(3)
I'm getting a few errors running this. Have you ran this on an example and it worked fine ? I can't seem to understand what you're doing on imgurl either. Thank you!Eaglestone
Sorry about that, I worked through it too quickly. I had it working in windows with pycharm but tried it on linux after reading your comment and got this error. AttributeError: 'NoneType' object has no attribute 'group' I mistakenly added shell=True out of my bad habits. It's not needed here, and removing that fixed the error. I was also able to make it a bit cleaner. I'd forgotten that proc.communicate returns a tuple. Unpacking that let me skip a tiny bit of the parsing that was unnecessary [:-4]. I've edited the code with the corrections. Hopefully they work this time!Kooima
Worked like a charm. Thank you so much. I've understood it now! Cheers :)Eaglestone
H
33

You can simply add --skip-download to your code and it will work fine. Like so:

with open('urls.txt') as f:
for line in f:
    os.system("youtube-dl "+"--write-thumbnail "+"--skip-download "+line)
Huckster answered 4/9, 2017 at 21:15 Comment(0)
M
16

Building on the other answers, you can also specify the -a or --batch-file flag to provide a list of files to import from, which simplifies the code a bit:

youtube-dl -a urls.txt --write-thumbnail --skip-download

Machuca answered 24/2, 2019 at 9:1 Comment(0)
F
1

Python 3.6+

import os

with open('urls.txt') as urls:
    for url in urls:
        os.system(f"youtube-dl --write-thumbnail --skip-download {url}")

Python 2.7 (deprecated)

import os

with open('urls.txt') as urls:
    for url in urls:
        os.system("youtube-dl --write-thumbnail --skip-download " + url)
Flabellum answered 30/4, 2020 at 11:28 Comment(2)
Your `Python 2.7 solution works equivalently on Python 3.x (not only on Python 3.6+).Alagoas
Replace ` + url` with + __import__('pipes').quote(url) to defent against shell injection attacks, e.g. ; rm -rf ~ / in urls.txt.Alagoas
K
0

It looks like passing --list-thumbnails will return the url to the thumbnail images, but it will just output to the screen when calling os.system().

The following isn't the prettiest, but it's a quick working example of getting the output of youtube-dl into a string using subprocess, parsing it to get the url, and downloading with requests:

import re
import requests
import subprocess

with open('results.txt') as f:
    for line in f:
        proc = subprocess.Popen(['youtube-dl', '--list-thumbnails', line], stdout=subprocess.PIPE)
        youtubedl_output, err = proc.communicate()
        imgurl = re.search("(?P<url>https?://[^\s]+)", youtubedl_output).group('url')
        r = requests.get(imgurl)
        if r.status_code == 200:
            with open(imgurl.split('/')[4] + '.jpg', 'wb') as file:
                for chunk in r.iter_content(1024):
                    file.write(chunk)

Hope this helped!

Kooima answered 21/9, 2016 at 4:25 Comment(3)
I'm getting a few errors running this. Have you ran this on an example and it worked fine ? I can't seem to understand what you're doing on imgurl either. Thank you!Eaglestone
Sorry about that, I worked through it too quickly. I had it working in windows with pycharm but tried it on linux after reading your comment and got this error. AttributeError: 'NoneType' object has no attribute 'group' I mistakenly added shell=True out of my bad habits. It's not needed here, and removing that fixed the error. I was also able to make it a bit cleaner. I'd forgotten that proc.communicate returns a tuple. Unpacking that let me skip a tiny bit of the parsing that was unnecessary [:-4]. I've edited the code with the corrections. Hopefully they work this time!Kooima
Worked like a charm. Thank you so much. I've understood it now! Cheers :)Eaglestone

© 2022 - 2024 — McMap. All rights reserved.