3

It blew my mind when I recently came across something new about FFmpeg despite having used it for years - the fact that it comes out of the box with advanced conditionals like if statements and lt/gt for filters. To me this has to be its most underrated feature, or at least it would be if the documentation mentioned anything about them and how they worked.

I want to take advantage of them in my FFmpeg scripts to upscale videos intelligently based on their height: if a video's height is less than 720 pixels, to upscale it to -1:720 (that is, a height of 720 and a proportional width that maintains its aspect ratio), and to leave it unchanged if it's 720 pixels or greater. What would a scale filter to do this with if and lt/gt look like?

Hashim Aziz
  • 12,732
  • Some of this (the functions) is covered in the docs here: ( https://ffmpeg.org/ffmpeg-utils.html#Expression-Evaluation ). What is lacking is how/where the variables are set for the filters themselves. I know that iw and ih are input widht and input height for the scale filter, but I don't see how people know this on a quick scan of the documentation. Admittedly, I have not read the docs "cover to cover" – Yorik Sep 02 '21 at 18:28
  • I take that back: https://ffmpeg.org/ffmpeg-filters.html#Options-1 has constants listed for scale. That doc covers a wide array of filters. – Yorik Sep 02 '21 at 18:31
  • https://superuser.com/questions/566998/how-can-i-fit-a-video-to-a-certain-size-but-dont-upscale-it-with-ffmpeg – Yorik Sep 02 '21 at 18:32
  • @Yorik Great find, I had searched the docs for everything but "expression". I have come across that before but its use of the pad filter worries me because I'm not sure from slhck's wording in what situation the padding is actually applied, and it sounds like it will end up either padding or cropping my videos. – Hashim Aziz Sep 02 '21 at 18:35
  • I would take a very small subset of vids, make some very short clips, suitable to rapidly test the decision tree, and then run them through. The linked stack Q is only one of many to examine as examples. Padding could also be addressed using evaluation. – Yorik Sep 02 '21 at 18:41
  • @Yorik I just took a closer look at that example from slhck and it does what most other examples do - scale down if higher than a certain width and height - which is very different to what I'm trying to do here. I would also actually like to know how to accomplish it with if and lt and whether they would make for a simpler command. – Hashim Aziz Sep 02 '21 at 18:50

1 Answers1

3

You can use max:

max(x, y)
Return the maximum between x and y.

Example:

ffmpeg -i input -vf "scale=-1:'max(720,ih)'" output

If I wanted to replace the -1 with a $width variable in my script, would there be a way to ensure that $width is only acted on when the right side (i.e. height) is also upscaled?

Example using if and lt:

ffmpeg -i input -vf "scale='if(lt(ih,720),$width,iw)':'max(720,ih)'" output
llogan
  • 59,497
  • 1
    +1 for the simplicity, I had a feeling max might do what I want but I didn't think it would be this simple. If I wanted to replace the -1 with a $width variable in my script, would there be a way to ensure that $width is only acted on when the right side (i.e. height) is also upscaled? – Hashim Aziz Sep 02 '21 at 19:36
  • @HashimAziz One method is to use if with lt / lte or gt / gte. – llogan Sep 03 '21 at 16:43
  • Perfect, thank you. To clarify, are the two versions with -1 and if...$width equivalent? So the -1 solution should also only upscale when the right side is upscaled? – Hashim Aziz Sep 04 '21 at 20:36
  • @HashimAziz To clarify, are the two versions with -1 and if...$width equivalent? Sorry, I don't understand this question. $width can be any arbitrary value. -1 is determined by the other dimension and aspect. So the -1 solution should also only upscale when the right side is upscaled? Yes. – llogan Sep 07 '21 at 16:11