Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get youtube animated thumbnail

Is there a way to embed the animated thumbnail from youtube in my website? I am not talking about the static thumbnail but the one that looks like an animated .gif of about 3 seconds.

like image 289
Guilherme Lopes Avatar asked Nov 02 '17 20:11

Guilherme Lopes


People also ask

Can you have animated YouTube thumbnails?

Videos have to be longer than 30 seconds to be eligible for an animated thumbnail, but YouTube also uses criteria like video topic and content to decide whether to show a preview or not.

Can YouTube thumbnail be animated GIF?

It will be used as the preview image in the embedded player. We recommend your custom thumbnails: Have a resolution of 1280x720 (with minimum width of 640 pixels). Be uploaded in image formats such as JPG, GIF, or PNG.


5 Answers

As of June 2019:

1. Getting static thumbnail images is straightforward

  • They're exposed through the YouTube API and, even better, they follow a very simple and uniform URL structure (more details here).

2. Youtube's animated thumbnails are supported in a limited number of browsers.

  • Apparently, desktop browsers Chrome and Opera (source)
  • The thumbnails, btw, are in WebP image format, which has a wider browser support.

3. Getting animated thumbails for a limited number of videos is relatively easy.

You can, for example, inspect the network activity in your browser dev tools (more details for Chrome).

With the network panel open, visit a page listing that includes the desired video, clear the network activity (you can also select 'Img' to display only activity related to images) and hover the desired video. Then just right click on the desired resource and copy the url.

In case an image helps...

enter image description here

The urls of the animated thumbnails look like the following:

https://i.ytimg.com/an_webp/zdOmNiXvM3w/mqdefault_6s.webp?du=3000&sqp=CPDloOgF&rs=AOn4CLD9rYflZAMK6qBIbYJDoQZLk9UARw

4. As far as I know, it is currently not possible to get the animated thumbnails programmatically (without webscraping)

  • In other words, given a video ID, it is currently not possible to get the animated thumbnail URL through the API or a defined URL pattern.

PS.: Hoping that somebody can prove me wrong on point #4, here are a few examples of those URLs:

https://i.ytimg.com/an_webp/zdOmNiXvM3w/mqdefault_6s.webp?du=3000&sqp=CPDloOgF&rs=AOn4CLD9rYflZAMK6qBIbYJDoQZLk9UARw

https://i.ytimg.com/an_webp/oIIDZq4nZpo/mqdefault_6s.webp?du=3000&sqp=CLyqoegF&rs=AOn4CLD9DyqMoxBTiOPTUX8FQJmUfiu8NA

https://i.ytimg.com/an_webp/X9tU8ybzcFs/mqdefault_6s.webp?du=3000&sqp=CLHroOgF&rs=AOn4CLAX8j6uWUko_54aPJLwkbAe_cUR3w

Changing the video ID or other parameters does not return a valid thumbnail.

like image 78
ludovico Avatar answered Oct 09 '22 01:10

ludovico


I don't know if it will help you

but when you go to search page in youtube you can access the object

window.ytInitialData

Here we have node called: window.ytInitialData.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents["0"].itemSectionRenderer.contents[2].videoRenderer.richThumbnail.movingThumbnailRenderer.movingThumbnailDetails.thumbnails["0"].url

Thumbanail gif youtube

maybe you can find a way to retrieve this data

access search page like this and: https://www.youtube.com/results?search_query=USPwv1zwWV4 What I have tried in console:

let videos = window.ytInitialData.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents["0"].itemSectionRenderer.contents;


if (!videos.length) { // includes other renderers i.e: "did you mean ..."
    console.log('no videos in search'); 
    //return;
}

let video = videos.filter( v => v.videoRenderer && v.videoRenderer.videoId == "USPwv1zwWV4")

if (!video.length) { 
    console.log('no video by that ID in search'); 
    //return;
}

let thumbs = video[0].videoRenderer.richThumbnail.movingThumbnailRenderer.movingThumbnailDetails.thumbnails;

if (!thumbs.length) { 
    console.log('no moving thumbs for that video'); 
    //return;
}

console.log(thumbs[0].url);
like image 34
Rafael Faria Avatar answered Oct 09 '22 02:10

Rafael Faria


Gifs.com has a free API for generating water-marked gifs from a media-related URL.

https://gifs.com/dashboard/api

It doesn't explicitly mention it but it does in fact accept Youtube URLs and generates a preview from them.

Here's an example of how to use it with cURL

curl -XPOST -H "Content-type: application/json" -d '{ "source": "https://www.youtube.com/watch?v=74KxwkLjE9E" }' 'https://api.gifs.com/media/import'

It takes about a minute or two to generate so if you store/cache the gifs with a server you could create your own personal preview generator.

Here's the archived link to the documentation https://web.archive.org/web/20190408212718/http://docs.gifs.com/docs/authentication-key

like image 2
Sam Carlton Avatar answered Oct 09 '22 01:10

Sam Carlton


You can use FRAMES thumbnails to create short animated thumbnail:

frame1: https://i.ytimg.com/vi/<YouTube_Video_ID_HERE>/1.jpg
frame2: https://i.ytimg.com/vi/<YouTube_Video_ID_HERE>/2.jpg
frame3: https://i.ytimg.com/vi/<YouTube_Video_ID_HERE>/3.jpg
like image 2
Sergey Gurin Avatar answered Oct 09 '22 01:10

Sergey Gurin


I typed a FFmpeg script. To get many variants of uncompressed YouTube moving thumbnail, you need to

  1. Download FFmpeg and extract FFmpeg.exe to a folder.
  2. Download required video from YouTube to the same folder and rename it as 'video' (if the video has 16:9 aspect ratio) or as 'sar' (if the video has another/special aspect ratio).
  3. Run cmd in the folder.
  4. Manually edit my script:

    • '00:00:00.0' in the line with 'CuttedFor1.mp4' = time (in downloaded video, hh:mm:ss.(1/10 part of a second)) of the frame that is shown on img.youtube.com/vi/(video's ID)/1.jpg.
    • '00:00:00.0' in the line with 'CuttedFor2.mp4' = time of the frame that is shown on img.youtube.com/vi/(video's ID)/2.jpg.
    • '00:00:00.0' in the line with 'CuttedFor3.mp4' = time of the frame that is shown on img.youtube.com/vi/(video's ID)/3.jpg.
    • Other '00:00:00.0' = time of 1st frame in original mqdefault_6s.webp (from the network tab).
  5. Run my script.

  6. Calculate the duration of each resulting webp (for example, using a stopwatch, manually view webp 100 times, and then divide it by 100) (perhaps automatic methods will appear at How to find the duration of an animated webp?).
  7. Manually edit my script so that setpts is equal to '1/((here you need to paste the duration of the appropriate webp obtained after the first run of the script)/3)*PTS[v]' and atempo is equal to '(here you need to paste the duration of the appropriate webp obtained after the first run of the script)/3[a]'.
  8. Delete all files obtained after the first run of the script.
  9. Run my script again.

Easy to read:

ffmpeg -i sar.mp4 -vf "crop=in_w:in_w/16*9" -c:a copy video.mp4
rem // If to obtain a 16: 9 aspect ratio, you need to crop the thumbnail from above and below.
ffmpeg -i sar.mp4 -vf "crop=in_h/9*16:in_h" -c:a copy video.mp4
rem // If to obtain a 16: 9 aspect ratio, you need to crop the thumbnail on the sides.
ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor0.mp4
ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormaxresdefault.mp4
ffmpeg -i SpeedChangedFormaxresdefault.mp4 -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 maxresdefault_6s.webp
ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForsddefault.mp4
ffmpeg -i SpeedChangedForsddefault.mp4 -vf "scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 sddefault_6s.webp
ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForhqdefault.mp4
ffmpeg -i SpeedChangedForhqdefault.mp4 -vf "scale=480:360:force_original_aspect_ratio=decrease,pad=480:360:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 hqdefault_6s.webp
copy hqdefault_6s.webp 0_6s.webp
ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormqdefault.mp4
ffmpeg -i SpeedChangedFormqdefault.mp4 -vf "scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 mqdefault_6s.webp
ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFordefault.mp4
ffmpeg -i SpeedChangedFordefault.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 default_6s.webp
ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor1.mp4
ffmpeg -i CuttedFor1.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor1.mp4
ffmpeg -i SpeedChangedFor1.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 1_6s.webp
ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor2.mp4
ffmpeg -i CuttedFor2.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor2.mp4
ffmpeg -i SpeedChangedFor2.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 2_6s.webp
ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor3.mp4
ffmpeg -i CuttedFor3.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor3.mp4
ffmpeg -i SpeedChangedFor3.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 3_6s.webp

Ready to execute:

Compressed for SAR (crop thumbnail from above and below):

ffmpeg -i sar.mp4 -vf "crop=in_w:in_w/16*9" -c:a copy video.mp4 && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor0.mp4 && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormaxresdefault.mp4 && ffmpeg -i SpeedChangedFormaxresdefault.mp4 -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 maxresdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForsddefault.mp4 && ffmpeg -i SpeedChangedForsddefault.mp4 -vf "scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 sddefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForhqdefault.mp4 && ffmpeg -i SpeedChangedForhqdefault.mp4 -vf "scale=480:360:force_original_aspect_ratio=decrease,pad=480:360:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 hqdefault_6s.webp && copy hqdefault_6s.webp 0_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormqdefault.mp4 && ffmpeg -i SpeedChangedFormqdefault.mp4 -vf "scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 mqdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFordefault.mp4 && ffmpeg -i SpeedChangedFordefault.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 default_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor1.mp4 && ffmpeg -i CuttedFor1.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor1.mp4 && ffmpeg -i SpeedChangedFor1.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 1_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor2.mp4 && ffmpeg -i CuttedFor2.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor2.mp4 && ffmpeg -i SpeedChangedFor2.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 2_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor3.mp4 && ffmpeg -i CuttedFor3.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor3.mp4 && ffmpeg -i SpeedChangedFor3.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 3_6s.webp

Compressed for SAR (crop thumbnail on the sides):

ffmpeg -i sar.mp4 -vf "crop=in_h/9*16:in_h" -c:a copy video.mp4 && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor0.mp4 && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormaxresdefault.mp4 && ffmpeg -i SpeedChangedFormaxresdefault.mp4 -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 maxresdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForsddefault.mp4 && ffmpeg -i SpeedChangedForsddefault.mp4 -vf "scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 sddefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForhqdefault.mp4 && ffmpeg -i SpeedChangedForhqdefault.mp4 -vf "scale=480:360:force_original_aspect_ratio=decrease,pad=480:360:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 hqdefault_6s.webp && copy hqdefault_6s.webp 0_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormqdefault.mp4 && ffmpeg -i SpeedChangedFormqdefault.mp4 -vf "scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 mqdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFordefault.mp4 && ffmpeg -i SpeedChangedFordefault.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 default_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor1.mp4 && ffmpeg -i CuttedFor1.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor1.mp4 && ffmpeg -i SpeedChangedFor1.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 1_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor2.mp4 && ffmpeg -i CuttedFor2.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor2.mp4 && ffmpeg -i SpeedChangedFor2.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 2_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor3.mp4 && ffmpeg -i CuttedFor3.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor3.mp4 && ffmpeg -i SpeedChangedFor3.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 3_6s.webp

Compressed for 16:9 ('video'):

ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor0.mp4 && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormaxresdefault.mp4 && ffmpeg -i SpeedChangedFormaxresdefault.mp4 -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 maxresdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForsddefault.mp4 && ffmpeg -i SpeedChangedForsddefault.mp4 -vf "scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 sddefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedForhqdefault.mp4 && ffmpeg -i SpeedChangedForhqdefault.mp4 -vf "scale=480:360:force_original_aspect_ratio=decrease,pad=480:360:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 hqdefault_6s.webp && copy hqdefault_6s.webp 0_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFormqdefault.mp4 && ffmpeg -i SpeedChangedFormqdefault.mp4 -vf "scale=320:180:force_original_aspect_ratio=decrease,pad=320:180:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 mqdefault_6s.webp && ffmpeg -i CuttedFor0.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFordefault.mp4 && ffmpeg -i SpeedChangedFordefault.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 default_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor1.mp4 && ffmpeg -i CuttedFor1.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor1.mp4 && ffmpeg -i SpeedChangedFor1.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 1_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor2.mp4 && ffmpeg -i CuttedFor2.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor2.mp4 && ffmpeg -i SpeedChangedFor2.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 2_6s.webp && ffmpeg -ss 00:00:00.0 -i video.mp4 -c copy -t 6 CuttedFor3.mp4 && ffmpeg -i CuttedFor3.mp4 -filter_complex "[0:v]setpts=1*PTS[v];[0:a]atempo=1[a]" -map "[v]" -map "[a]" SpeedChangedFor3.mp4 && ffmpeg -i SpeedChangedFor3.mp4 -vf "scale=120:90:force_original_aspect_ratio=decrease,pad=120:90:(ow-iw)/2:(oh-ih)/2" -vcodec libwebp -lossless 1 -loop 0 -an -vsync 0 3_6s.webp

To get many variants of compressed YouTube moving thumbnail, you need to rewrite my script so that it creates webp with a specified number of frames and, therefore, FPS (you can find it out in the original mqdefault_6s.webp), duration exactly 3000 ms, the last frame passes with its own time stamp, compressed images (or something similar, which creates the effect of sharpness or loss of colors, as in the picture below).

Frame extracted from the original webp: https://i.stack.imgur.com/Iow4N.png.

Frame extracted from the homemade webp: https://i.stack.imgur.com/Q3loy.png.

like image 1
Just_name Avatar answered Oct 09 '22 02:10

Just_name