...making Linux just a little more fun!

Video editing from the command line

By Silas Brown

This is an article about basic video production in MPlayer. MPlayer has its own "edit decision list" facility, but that is limited to deleting scenes from an already-made movie; it cannot be used to take scenes from more than one source file and to sequence them in a different order, as is often needed in production. However, by running several MPlayer commands in succession you can do this on the command line, and you don't need particularly high-spec equipment or dexterous mouse skills or even eyesight to do it (some eyesight is a plus but you don't need much).

Previewing in MPlayer

Firstly, make sure you can play each of your source-material videos with the mplayer command (use mplayer -framedrop if you have a slow computer). Installing mplayer from your package manager may be enough, but in some cases a newer version of mplayer and/or support for additional types of video codecs is needed; in this case the exact setup procedure can vary, depending on your distribution and its version, so you may have to do some web searching to find out.

Once mplayer is set up correctly to play the video format you have, in the video window you should be able to press Space to pause and use the left and right arrow keys to seek, and in the console window you should get a continuously-updated one-line status report which includes the field V: followed by the video's time counter in seconds. When the video is paused, you will be able to read off the exact V: value, and you can use these values to decide where you want to start and end your clips. (You can fine-tune the values later by trial and error.)

Taking the clips

After you've decided on the order of your clips and have made a note of their start and stop timestamp values (for example in a text editor), you can extract each clip to a separate file by running mencoder once for each clip, like this:

mencoder video3.avi -ofps 25 -o clip1.avi -oac lavc -ovc lavc -vf scale=320:240 -ss 59 -endpos 15
mencoder video1.avi -ofps 25 -o clip2.avi -oac lavc -ovc lavc -vf scale=320:240 -ss 14 -endpos 3

In the above example, clip1.avi is taken from video3.avi, starting at 59 seconds in (the -ss 59) and lasting 15 seconds (the -endpos 15). clip2.avi is taken from video1.avi, starting at 14 seconds and lasting 3 seconds. We specified a value for the output frames per second (-ofps 25) and the pixel size of the output video (-vf scale=320:240) to make sure that all our clips will have the same pixel size and frame rate, which is necessary to make sure they can be put together properly.

After running mencoder for each clip, it is advisable to use mplayer to view the resulting clip and check that its start and stop points were just right. If not, you may have to re-run the mencoder command with adjusted values (add a half-second here, subtract a half-second there) until you're happy with the result.

Check the framerates

In some cases, in addition to -ofps, you may also have to specify an -fps value (best put near the beginning of the mencoder command) to make sure that the input frames per second is read correctly; for example some FLV videos need -fps 24. If the input frames per second is not read correctly, after a while the picture will run ahead of the sound if the FPS is too high, or will lag behind the sound if the FPS is too low. Even if the clip is very short, a wrong FPS could result in the next clip starting the picture before the sound or vice versa. So when playing each clip, check that the sound finishes at exactly the same time as the picture finishes. Thankfully mplayer usually gets the input FPS value right by itself, but it's worth knowing about this for when it doesn't.

You may also want to check that the output frames per second (-ofps) value you provide is actually being obeyed by mencoder. Sometimes mencoder has to adjust it to cope with the constraints of whatever output format you're using. If you look at mencoder's textual output, toward the end there will be a line beginning Video: which will include the number of seconds and the number of frames in the output video; divide the frames by the seconds to get the frame rate. Synchronization might work slightly better if you then choose an approximation of this new value as your preferred -ofps value. (Don't pay any attention to the "fps" values that are incrementally printed by mencoder; these are merely telling you how fast mencoder is doing the conversion, not the actual running speed of the film.)

Putting the clips together

When you are happy with all the component clips, you need to combine them into the final video in order. This is done with a final mencoder command, for example:

./mencoder clip1.avi clip2.avi clip3.avi -o result.avi -oac lavc -ovc lavc

Then check that the result.avi file plays using mplayer and that you are happy with it. Sometimes (perhaps due to floating point rounding errors in mencoder) the video will run ahead of the sound in the final result even if all the individual clips are in step; if the final mencoder frequently reports Skipping frame! then this may happen. If it does, you can experiment with the -fps option on mplayer to find the framerate that synchronizes sound and video, and then run an additional ffmpeg command to adjust the framerate to that speed, for example:

ffmpeg -r 23 -i result.avi -sameq -ab 224k corrected-result.avi

where 23 is the framerate you found that best synchronizes to the audio, and 224k is the audio bitrate in use (you can change this at this stage if you like). ffmpeg seems to be better at making this adjustment than mencoder. Don't be tempted just to add the new -fps to the above final mencoder command instead, because in some cases doing that can result in the inclusion of extra audio from outside your original clipping points. Re-check the adjusted result with mplayer, and if necessary try repeating the ffmpeg command with a slightly different framerate.


Talkback: Discuss this article with The Answer Gang

[BIO] Silas Brown is a legally blind computer scientist based in Cambridge UK. He has been using heavily-customised versions of Debian Linux since 1999.

Copyright © 2010, Silas Brown. Released under the Open Publication License unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 178 of Linux Gazette, September 2010