Youtube Video to Giphy
yt-dlp with ffmpeg to create a gif and host it for free
introduction
Back in 2020 Firefox write a blog post which introduced a series of relaxing video meant to be played in a loop in the (then) new “picture-in-picture” mode.
Here’s an example:
yt-dlp
yt-dlp is a CLI to download video but you could also pipe the video as stream straight into ffmpeg:
yt-dlp -f "bv*[ext=mp4][height<1080]" "https://youtu.be/r45aZe_OtuM?si=Ta58dCZTI4QCrerG" -o - \
| ffmpeg -i pipe:0 -c copy output.mp4- one of the best thing about
yt-dlpis the filter for expressively picking the right stream to download1. Here with-f "bv*[ext=mp4][height<1080]"we are selecting the best quality mp4 stream that’s less than 1080 pixel in height - the
-o -option tellsyt-dlpto write the outputs to stdout - to read the output from
yt-dlpinffmpeg, we need the option-i pipe:0
gifski
gifski makes the highest quality GIFs. Think of it as the opposite of gifsicle which is great for compressing GIFs.
How much better?
gifski demo
The best part is that gifski play nicely with ffmpeg also. Let’s say I want to crop a gif while keeping the highest quality:
ffmpeg -i source.gif -vf "crop=iw:ih*0.9:0:0" -pix_fmt yuv420p -f yuv4mpegpipe -
| gifski -o output.gif -- in
ffmpegwe use-f yuv4mpegpipe -to format the output properly to stdout forgifski - for gif input source, you will need to specify the pixel format with
-pix_fmt yuv420pforffmpegto figure out how to combine with-f yuv4mpegpipe -
yt-dlp to ffmpeg to gifski
okay so to create the highest quality 5-second gif from Figure 1 without having to download the video:
yt-dlp -f "bv*[ext=mp4][height<1080]" "https://youtu.be/r45aZe_OtuM?si=Ta58dCZTI4QCrerG" -o - \
| ffmpeg -i pipe:0 -ss 10 -t 5 -vf "crop=iw:ih*0.85:0:0" -f yuv4mpegpipe - \
| gifski -o tree.gif -- since the input to ffmpeg is a stream the
-ss 10option has to come after the input, otherwise you might run into the “partial file” error - our filter
-vf "crop=iw:ih*0.85:0:0"crop out the bottom 15% of the frame
“Hosting” on giphy
the last step is to “host” it on giphy.
Our uploaded tree.gif lives at https://giphy.com/gifs/da0KMpaD7t6psYvV3Y
But that’s just a link to a page on giphy. To get the actual gif URL is more complicated, but thanks to Eric’s tip we know that the gif URL format is:
https://i.giphy.com/media/{gif_hash}/giphy.gifSo for our tree.gif it would be https://i.giphy.com/media/da0KMpaD7t6psYvV3Y/giphy.gif