Recently, I came across a curious problem: an HD video recording that had the right aspect ratio (1920x1080 square pixels), but in which the actual content was encoded such that everything was squished a little.
Taking a screenshot of something that was supposed to be circular (a company logo during the end credits), I saw that the logo was 132 pixels wide by 144 pixels tall. Thus, the image was distorted to the tune of 12:11.
I wanted to correct this distortion and re-encode the resulting video using the standard 1920x1080 square pixels. My tool of choice, of course, was ffmpeg
, but I had to find the right combination of command-line parameters.
I consulted several Web sites [1-4], and eventually constructed the following command:
ffmpeg -i input.mp4 -vf "crop=1760:1080:80:0,scale=1920:1080,setdar=16:9" -c:a copy output.mp4
To explain: under the -vf
option, I specified several video filters. First, I cropped the video to 11/12th its original width, centering the crop rectangle horizontally. Then, I asked it to scale the video back to the standard 1920x1080 resolution, using the display aspect ratio of 16:9; this ensured square pixels. As for the audio, I asked it to simply copy the audio stream without re-encoding.
Then I realized that I still have the original transport stream (.ts
) file, from which the MPEG-4 video was produced. So rather than re-encode the MPEG-4 file, I decided to encode the TS file directly:
ffmpeg -i input.ts -vf "crop=1760:1080:80:0,scale=1920:1080,setdar=16:9" output.mp4
This time around, however, I did not specify the audio codec, because I wanted ffmpeg
to encode it with the MPEG-4 default.
I was still not happy with the result, however. The original, interlaced video was okay; the transcoded result, also interlaced, showed interlacing artifacts. So I decided to recode the video one more time, this time also deinterlacing it and opting for higher quality output:
ffmpeg -i input.ts -vf "crop=1760:1080:80:0,scale=1920:1080,setdar=16:9,yadif" \
-preset slow -crf 18 output.mp4
This time, the result was perfect, even though the transcoding was significantly more time consuming.
As usual, I found that ffmpeg
is insanely powerful but its command-line switches are insanely difficult to use. Every invocation of ffmpeg
, pretty much, becomes a bit of a research project on its own right.
[1] https://stackoverflow.com/questions/24087249/ffmpeg-change-resolution-of-the-video-with-aspect-ratio
[2] https://video.stackexchange.com/questions/9947/how-do-i-change-frame-size-preserving-width-using-ffmpeg
[3] https://www.bugcodemaster.com/article/changing-resolution-video-using-ffmpeg
[4] https://video.stackexchange.com/questions/4563/how-can-i-crop-a-video-with-ffmpeg
[5] https://video.stackexchange.com/questions/17396/how-to-deinterlacing-with-ffmpeg/17397
[6] https://trac.ffmpeg.org/wiki/Encode/H.264