It seems to me that you need to do this in three steps:
- Check the input aspect ratio
- Scale videos with a DAR > 7/4 width-wise (change the width to 700, and scale the height to keep the aspect ratio), and scale those with DAR < 7/4 height-wise
- Pad the video so that it fits in the 700:400 space.
FFmpeg/avconv can do the scaling/padding with video filters in a single step, transcoding only once. For example, to take a 16:9 video, scale it width-wise, and then letterbox the results:
ffmpeg -i input.avi -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
-c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k output.mp4
...but for the first step (detecting the aspect ratio and comparing it to the 7:4 you require) you'll have to use a script of some kind.
ffprobe input.avi 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0-9]*\)].*/\1/p'
...will get you the video's aspect ratio, which will look like '16:9' or '4:3'. In a bash script, I'd use something like:
#!/bin/bash
## Get the aspect ratio in the form x/y
dar=$(ffprobe test0.mp4 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0:9]*\)].*/\1/p' | sed 's|:|/|')
## use bc to do x/y*100 (bash can't handle floats)
DAR=$(bc <<< 'scale=2; $dar*100')
## ${DAR%.00} will remove the trailing .00 left by bc
if [ ${DAR%.00} -ge 175 ]; then
ffmpeg -i "$1" -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
-c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
else
ffmpeg -i "$1" -filter:v 'scale=-1:400,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
-c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
fi
exit 0
Obviously you'll have to adapt it to your needs.
1As the owner of the accepted answer I'd suggest you un-accept my post and accept LordNeckbeard's answer instead, as it is the most recent and much simpler. – slhck – 2016-11-07T15:15:30.017
@slhck, I was considering it, with your blessing, I'll make it so. – Jamie Taylor – 2016-11-07T15:54:34.977
4I'll write up an answer later, but I thought I'd mention the following: Re-encoding a video just to add fixed pillar- or letterboxing is a terrible idea. Not only will you lose quality in that process (or unnecessarily increase file size), you will also make it impossible to get rid of the bars later. Ideally your player should simply take care of that and resize the video while displaying it. What is your use case if I may ask? – slhck – 2013-02-06T12:05:55.553
We stash the original file in an S3 bucket, so that's no problem, and we're re-encoding anyway as we accept a large scope of video types, all of these have to end up as h.264 mp4 files suitable for streaming through a browser. So you'd suggest resizing the video and then making html/css pillar/letterboxes? Thanks – Jamie Taylor – 2013-02-06T12:23:02.620