Chi Long Qua
Chi Long Qua

Reputation: 17

How can I use ffmpeg and youtube-dl to download the first frame of every video in a playlist?

I'm trying to download only the first frame of every video in a large playlist on YouTube. Does anybody know how I can use ffmpeg and youtube-dl to do this?

Upvotes: 0

Views: 1606

Answers (2)

Flint
Flint

Reputation: 1711

Due to the nature of video encoding, you need to download a small segments of each streams first.

yt-dlp -I 0:5 -f '(bestvideo+bestaudio/best)[protocol!*=dash]' \
--external-downloader ffmpeg \
--external-downloader-args "ffmpeg_i:-ss 0 -t 1" \
"https://youtu.be/channel/UCpVm7bg6pXKo1Pr6k5kxG9A"

option -I will limit the playlist range. If an other playlist is found in a playlist, it will also download the items found inside of it and so on.

The same will work on a unique video.

Then you can convert every of them to images.

IFS=$'\n'; for files in $(ls *); do 
  ffmpeg -i "$files" -ss 0 -frames:v 1  $files-frames%03d.png; 
done;

Play with the options -ss if you need to skip seconds. Several frames are also possible.

This might fail on vp9 encoding and live streams.

Alternatively, you can also use the following to download one file and convert a segment to images:

ffmpeg $(yt-dlp -g 'https://youtu.be/watch?v=oHg5SJYRHA0' | sed "s/.*/-i &/") \
       -ss 1 -frames:v 1 -q:v 2  frames%03d.png

Here the piping through sed prefixes multiple streams, possibly presents in the input, usually one audio and one video, each with -i. You can also save multiple frames over a segment this way.

This doesn't requires a reencoding, so depending on the size of the video and your download speed it might or might not be faster than the first solution.

Upvotes: 0

Ridwan
Ridwan

Reputation: 385

First you need to take the playlist ID of the youtube playlist and download the full playlist of the thumbnails you want to get like this:

youtube-dl -i PLwJ2VKmefmxpUJEGB1ff6yUZ5Zd7Gegn2

Then you use the following script, which will extract the first frame of the all the videos, (do note that after downloading the full playlist all of the videos are in the same directory):

i=1
for avi in *.mp4; do
    name=`echo $avi | cut -f1 -d'.'`
    jpg_ext='.jpg'
    echo "$i": extracting the first frame of the video "$avi" into "$name$jpg_ext"
    ffmpeg -loglevel panic -i $avi -vframes 1 -f image2 "$name$jpg_ext"
    i=$((i+1))
 done

Upvotes: 1

Related Questions