3

To get a 200x100 thumbnail from a video, I do ffmpeg -ss 100 -i /tmp/video.mp4 -frames:v 1 -s 200x100 image.jpg. But if the source video isn't in the same aspect ratio as 200x100, the thumbnail gets distorted (either stretched or squished, horizontally or vertically) and it looks bad.

Is there a way that ffmpeg can figure out for example that a 500x200 video is 100px too wide, and remove 50px from the right and 50px from the left, making the video 400x200? And because 400x200 is the same aspect ratio as 200x100, the thumbnail would have no distortion.

I know there are other tools that can do this to the thumbnails generated by ffmpeg, but I'd prefer doing it within ffmpeg and not having to process the thumbnails again.

user779159
  • 7,076
  • 9
  • 41
  • 69

2 Answers2

4

If your thumbnail size is 200x100 fixed, then run

ffmpeg -ss 100 -i /tmp/video.mp4 -vf "scale='if(gt(dar,200/100),100*dar,200)':'if(gt(dar,200/100),100,200/dar)',setsar=1,crop=200:100"  -frames:v 1 image.jpg

The scale filter checks the aspect ratio of the source and scale so that one dimension fits the 200x100 canvas and the other overshoots, unless it's a perfect match. Then the crop filter crops it to 200x100 from the center thus taking care of the out of bounds region.

Gyan
  • 63,018
  • 7
  • 100
  • 141
  • This can result in an output less than one of the requested dimensions and will cause crop to fail (using an input with a 115:87 SAR for example). – llogan Jan 11 '17 at 18:33
  • Yeah, the `-1` doesn't account for SAR. Corrected. – Gyan Jan 11 '17 at 18:56
4

You can use the force_original_aspect_ratio option in the scale filter.

ffmpeg -ss 100 -i /tmp/video.mp4 -frames:v 1 -q:v 2 -vf "scale=200:100:force_original_aspect_ratio=increase,crop=200:100" image.jpg
llogan
  • 87,794
  • 21
  • 166
  • 190
  • Would this work the same when the video is either taller or wider than the aspect ratio of the thumbnail you want? And if for example the video is 100px too wide for the aspect ratio, it would remove equal parts from the left and right (so 50px each)? – user779159 Jan 12 '17 at 08:25
  • @LordNeckbeard - the scaler preserves the SAR in the output, which is not obeyed by third-party apps. Photoshop, e.g. honors the SAR for JPGs but not PNGs. Firefox honors it for neither format. – Gyan Jan 12 '17 at 10:27
  • @user779159 It will crop the extra if it is too wide or too tall. The cropping will automatically be centered. See the [crop filter documentation](https://ffmpeg.org/ffmpeg-filters.html#crop) if you want to adjust cropping coordinates. – llogan Jan 12 '17 at 17:44
  • If the video is non-square, setsar=1 will produce wrong result. The scaling itself has to produce a raster which is non-distorted when treated as square-pixel. – Gyan Jan 12 '17 at 19:01
  • @Mulvya Ah, yes, I overlooked that. – llogan Jan 12 '17 at 19:05
  • @Mulvya, I'm confused by your last 2 comments to this answer as I'm a layman when it comes to this stuff. So do I need to add/remove something to LordNeckbeard's answer? – user779159 Jan 12 '17 at 21:58
  • 1
    LN's answer won't work if you are working with videos that have non-square pixels i.e. PAL, NTSC, HDV or anamorphic DVD files. For square pixel videos, like mobile camera videos or most web videos, you'll be fine. My command will work with all sources, – Gyan Jan 13 '17 at 04:31
  • @Mulvya Are `mp4` files always with square pixels, or does it depend on the specific mp4 file? – user779159 Jan 13 '17 at 08:38
  • Depends on specific file. Any codec in most formats can have non-square pixels. – Gyan Jan 13 '17 at 08:44
  • Is there some output from `ffprobe` or something I can use to see if a video has square pixels or not? – user779159 Jan 15 '17 at 09:31
  • Yes. `ffprobe -show_entries stream=sample_aspect_ratio video.mp4` – Gyan Jan 19 '17 at 05:13