Hack 68. Resize a Video
Use the powerful transcode utility to resize videos completely from the command line.
Normally, I don't find myself resizing videos. After all, you end up losing video quality if you lower the resolution, and usually I want to watch a video in the highest possible quality. However, there are certain instances where it can be useful to resize a video. One main reason people resize videos is simply to lower the file size. Each pixel in a video takes up space, so resizing a video is one good method for lowering the file size. Also, more and more portable devices are now supporting video playback. Since these devices often have screen resolutions of 640 x 480 or lower, they don't typically support playback of videos larger than their native resolution.
transcode is a versatile tool when it comes to video conversion, and [Hack #63] provides examples of conversions between video codecs using transcode. This hack takes that process a step further and uses transcode's video-resiz-ing options. Because this hack uses transcode exclusively, you will definitely need to install it on your system. [Hack #63] explains transcode installation.
There are three primary arguments that transcode uses to resize video: -B, -X, and -Z. The -B and -X options are complementarythe -B option shrinks video resolution while -X increases video resolution. Both options perform a fast resize on the video, but have some rather particular requirements to use. The main requirement is that the resolution of the input and output files be a multiple of eight for transcode's fast-resizing algorithm. Although the algorithm is a bit less precise than the one used with -Z by default, it is substantially faster.
Both -B and -X arguments have the same three options; you can pass them separated by commas. The first option is the amount to resize the height of the image in rows, the second option is the amount to resize the width in columns, and the third option is 8, 16, or 32 (use whichever number works for your resolution). The rows and column values are calculated by multiplying the number you specify with the third option, so if you passed transcode the following command, it would increase the height by 96 (12 * 8) and the width by 128 (16 * 8):
It seems a bit tricky at first, but once you calculate a few times, you get the hang of it. So, if I had a 512 x 384 video that I wanted resized to 640 x 480, I would type:
$ transcode -i input.avi -o output.avi -y xvid -X 12,16,8
Even with fast encoding, transcode will take some time to resize a file. transcode will output its progress so you can at least keep track of where it is in the encoding process. Note that both the input and output file resolutions are multiples of eight. Also note the -y argument. This option tells transcode what format to use for the output file (in this case XviD) and is required. Without this option transcode will use the null output format, which writes nothing. What argument you pass -y depends on the output format you want to use, and [Hack #63] covers the video format options at your disposal.
Now that I have a 640 x 480 output.avi, I can also resize it back to 512 x 384 with the -B option. Since the relative sizes haven't changed, all I have to do is switch -X with -B:
$ transcode -i output.avi -o output2.avi -y xvid -B 12,16,8
Of course, having to perform all those calculations whenever you want to resize isn't too much fun, but transcode has that covered as well. The -Z option allows you to simply specify the output resolution to use. transcode will then perform all the necessary calculations for you. You can even leave out one component of the resolution and transcode will calculate the appropriate value using the aspect ratio it imports from the video file. An added benefit is that you can choose resolutions that aren't divisible by eight, but the downside is that transcode no longer uses its fast-resizing algorithm, so the process will take longer.
To perform the same image resize as the previous example, only with -Z, I would type:
$ transcode -i input.avi -o output.avi -y xvid -Z 640x480
I could also say -Z 640x (x after the value for width) or -Z x480 (x before the value for height) and transcode will figure out the rest. The -Z argument also provides a fast option. This option actually will calculate the -B or -X arguments for you automatically and then perform the resizing operation with that algorithm. Since it uses the fast resizing algorithm, you still need to make sure that your input and output resolutions are divisible by eight. So to resize the video from 512 x 384 to 640 x 480 with fast resizing, I can just type:
x$ transcode -i input.avi -o output.avi -y xvid \ -Z 640x480,fast transcode v0.6.14 (C) 2001-2003 Thomas Oestreich, 2003-2004 T. Bitterberg [transcode] (probe) suggested AV correction -D 0 (0 ms) | AV 0 ms | 0 ms [transcode] auto-probing source input.avi (ok) [transcode] V: import format | XviD RIFF data, AVI (V=ffmpeg|A=mp3) [transcode] V: import frame | 512x384 1.33:1 [transcode] V: fast resize | Using -B 0,0,8 -X 12,16,8 [transcode] V: new aspect ratio | 640x480 1.33:1 (-X) [transcode] V: bits/pixel | 0.244 [transcode] V: decoding fps,frc | 23.976,1 [transcode] V: Y'CbCr | YV12/I420 [transcode] A: import format | 0x55 MPEG layer-3 [48000,16,2] 132 kbps [transcode] A: export format | 0x55 MPEG layer-3 [48000,16,2] 128 kbps [transcode] V: encoding fps,frc | 23.976,1 [transcode] A: bytes per frame | 8008 (8008.000000) [transcode] A: adjustment | 0@1000 [transcode] V: IA32 accel mode | sse2 (sse2 sse mmxext mmx asm C) tc_memcpy: using mmxext for memcpy [transcode] V: video buffer | 10 @ 640x480 [import_mp3.so] v0.1.4 (2003-08-04) (audio) MPEG [import_ffmpeg.so] v0.1.11 (2004-02-29) (video) FFmpegcvsb4753: MS MPEG4v1- 3/MPEG4/MJPEG [export_xvid4.so] v0.0.5 (2003-12-05) (video) XviD 1.0.x series (aka API 4. 0) | (audio) MPEG/AC3/PCM [import_mp3.so] MP3->PCM [import_mp3.so] tcextract -a 0 -i "input.avi" -x mp3 -d 0 | tcdecode -x mp3 -d 0 -z 48000 [export_xvid4.so] Neither './xvid4.cfg' nor '~/.transcode/xvid4.cfg' [export_xvid4.so] found. Default settings will be used instead. [mpeg4 @ 0xb5b20008]frame skip 8 [mpeg4 @ 0xb5b20008]frame skip 8 tc_memcpy: using mmxext for memcpy Audio: using new version Audio: using lame-3.96.1 [encoder.c] Delaying audio (0) encoding frames [000000-030396], 16.37 fps, EMT: 0:21:07, ( 0| 0| 0) clean up | frame threads | unload modules | cancel signal | internal threads | done [transcode] encoded 30397 frames (0 dropped, 0 cloned), clip length 1267.81 s $
Notice, near the top of the output, the line that says:
[transcode] V: fast resize | Using -B 0,0,8 -X 12,16,8
Here you see the actual -B or -X arguments transcode calculated for youwhich is handy for helping you understand how the numbers are calculated.