dimabagow

Video Editing in Linux Console

This is an archive of MPlayer/MEncoder and FFmpeg recipes from the period described. Several package names, codecs, download hosts and build options are obsolete. The examples document the original workflow; check the installed tool's documentation before adapting them. Stream-copy cuts are normally constrained by keyframes, and copying streams together requires compatible codecs and container parameters.

Video Editing in Linux Console

Linux is an excellent platform for working with video. Entire audio and video processing centres run on it, as do many professional studios. The post-production of Madagascar is one familiar example. The list of films made with Linux is long, but here I want to discuss what it offers for processing home video.

There is a good selection of programs for this. If you are new to Linux, you will have some learning to do. It is worth the effort, though it need not cost anything: much of the software is free.

MEncoder is one of the well-known tools for video processing on Linux. It runs in a terminal, which is an advantage when you want to automate processing with scripts. Video servers can use it for unattended conversion. If you have just switched to Linux and the command line terrifies you, there are graphical front-ends too; they simply do not come with MEncoder by default. I list some later, but first we need to understand the command line.

MEncoder belongs to the MPlayer project, whose tools cover playback, capture, recording, streaming and conversion. As the encyclopedia description puts it, MEncoder converts audio and video formats, supports many codecs and containers, and uses libavcodec.

MPlayer is usually presented as a media player, with conversion and the other functions provided by related tools. The packaging can be confusing, but the tools share the same project. This article introduces several of them. The project's website is mplayerhq.hu.

First install the tools we will use. Check whether your distribution already includes MPlayer and MEncoder. On Debian-based systems, the installation command is:

apt-get install mencoder mplayer

These examples come from the period of MEncoder, FLV video and PocketPC devices. Package names, download servers and build options below refer to those versions.

Common commands

Convert MPG to AVI

mencoder slobodnasrbija1912.mpg -o slobodna.avi -ovc lavc -oac lavc

Split an AVI file

avisplit -s 37 -i bagow-001.avi

Convert AVI to FLV

mencoder INPUT.avi -ofps 25 -o OUTPUT.flv -of lavf -oac mp3lame -lameopts abr:br=64 -srate 22050 -ovc lavc -lavcopts vcodec=flv:keyint=50:vbitrate=300:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -vf scale=320:240

Split an FLV file

ffmpeg -i input_file.flv -ss 00:00:00 -t 00:30:00 -vcodec copy -acodec copy output_file_1.flv

ffmpeg -i input_file.flv -ss 00:30:00 -vcodec copy -acodec copy output_file_2.flv

Extract a section of an AVI file

mencoder -oac copy -ovc copy -ss 00:00:00 -endpos 00:00:02 video.avi -o kusok.avi

Convert MTS or M2TS to AVI

mencoder 00001.mts -o 1.avi -oac copy -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=10000 -fps 60 -vf scale=1140:1080

Play video as ASCII

mplayer -vo aa [name_of_videofile]

A daemon for converting video to FLV

I found a useful article on Habr and kept the following daemon example. It watches an upload directory, moves new videos to an intermediate directory, starts conversion in the background, creates a thumbnail and places the resulting files in the user's directory.

The script is written in Bash, so use nohup or screen to keep it running. The original design does not limit concurrent conversions: a busy upload directory can overload the server. That was not a problem for the original author's workload. If it is for yours, a queue using flock is one possible approach.

The important settings can be passed on the command line; -h lists the options. In particular, -u sets the root directory of user folders. The directory layout is fixed in the script: converted videos go into USER_FOLDER/USER_ID/video. Changing that layout requires editing the script.

The -s and -t options specify the source and intermediate directories. Uploads in the source directory, /var/videoinput by default, must be named USER_ID_VIDEO_ID.ext. The first number is the user's folder ID; the second identifies the video, for example its database record.

The thumbnail goes next to the video, with the same basename and a .png extension. It is taken from the sixteenth second. Ideally, the script should check the duration because a clip may be shorter; that remains an exercise for the reader. The example keeps the source when conversion fails and uses a separate working directory for each thumbnail.

The required programs are:

#!/bin/bash
# folder_monitor.sh
SRC_DIR=/var/videoinput
TRG_DIR=/var/videooutput
PARAMS='-ovc lavc -lavcopts vcodec=flv:keyint=50:vbitrate=300:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -vf scale=480:360 -of lavf -oac mp3lame -lameopts abr:br=64 -srate 22050'
OUTPUT_FORMAT=flv
USER_FOLDER=/usr/local/jboss/server/default/resources/files/user_folders
THUMBNAIL_WIDTH=175
THUMBNAIL_HEIGHT=110
while getopts ':s:t:hp:u:H:W:' optname; do
    case "$optname" in
        u) USER_FOLDER=$OPTARG ;;
        p) PARAMS=$OPTARG ;;
        s) SRC_DIR=$OPTARG ;;
        t) TRG_DIR=$OPTARG ;;
        W) THUMBNAIL_WIDTH=$OPTARG ;;
        H) THUMBNAIL_HEIGHT=$OPTARG ;;
        h)
            printf '%s\n' '-h: help' '-W: thumbnail width' \
                '-H: thumbnail height' '-p: mencoder options' \
                '-u: user folders' '-s: source directory' \
                '-t: intermediate directory'
            exit 0 ;;
        *) printf 'Invalid option: %s\n' "$OPTARG" >&2; exit 1 ;;
    esac
done
mkdir -p "$SRC_DIR" "$TRG_DIR" "$USER_FOLDER" || exit 1
SRC_DIR=$(cd "$SRC_DIR" && pwd) || exit 1
TRG_DIR=$(cd "$TRG_DIR" && pwd) || exit 1
USER_FOLDER=$(cd "$USER_FOLDER" && pwd) || exit 1
read -r -a ENCODER_OPTIONS <<< "$PARAMS"
while :; do
    printf 'Looking in %s...\n' "$SRC_DIR"
    while IFS= read -r -d '' INPUT; do
        FILE=${INPUT##*/}
        [[ $FILE =~ ^([0-9]+)_([0-9]+)\.[A-Za-z0-9]+$ ]] || continue
        USER_ID=${BASH_REMATCH[1]}
        VIDEO_ID=${BASH_REMATCH[2]}
        JOB_DIR=$(mktemp -d "$TRG_DIR/job.XXXXXX") || continue
        if ! mv -- "$INPUT" "$JOB_DIR/$FILE"; then
            rmdir "$JOB_DIR"
            continue
        fi
        (
            cd "$JOB_DIR" || exit 1
            printf 'Converting %s...\n' "$FILE"
            DEST="$USER_FOLDER/$USER_ID/video"
            mkdir -p "$DEST" || exit 1
            if ! mencoder "$FILE" -o "$FILE.$OUTPUT_FORMAT" "${ENCODER_OPTIONS[@]}"; then
                printf 'Conversion failed; source retained in %s\n' "$JOB_DIR" >&2
                exit 1
            fi
            flvtool2 -UP "$FILE.$OUTPUT_FORMAT" || exit 1
            if mplayer -ss 16 -frames 1 -vo png -nosound "$FILE" && [ -f 00000001.png ]; then
                convert 00000001.png -resize "$THUMBNAIL_WIDTH" \
                    -gravity center -crop "${THUMBNAIL_WIDTH}x${THUMBNAIL_HEIGHT}+0+0" \
                    -quality 75 "$DEST/$VIDEO_ID.png"
            fi
            mv -- "$FILE.$OUTPUT_FORMAT" "$DEST/$VIDEO_ID.$OUTPUT_FORMAT" || exit 1
            rm -- "$FILE"
            rm -f -- 00000001.png
            cd "$TRG_DIR" || exit 1
            rmdir "$JOB_DIR"
        ) &
    done < <(find "$SRC_DIR" -maxdepth 1 -type f -print0)
    sleep 10
done

Installing on the server

The following build sequence preserves the original versions and the RPM-based server setup, including LAME, Ogg/Vorbis, MPlayer, FFmpeg, FLVTool2 and the PHP extension. Its old download locations are historical examples.

cd /usr/local/src/

# DOWNLOAD MODULES

wget www3.mplayerhq.hu/MPlayer/releases/codecs/essential-20061022.tar.bz2
wget -O flvtool2_1.0.5_rc6.tgz http://rubyforge.org/frs/download.php/9225/flvtool2_1.0.5_rc6.tgz
wget easynews.dl.sourceforge.net/sourceforge/lame/lame-3.97.tar.gz
wget superb-west.dl.sourceforge.net/sourceforge/ffmpeg-php/ffmpeg-php-0.5.1.tbz2
wget downloads.xiph.org/releases/ogg/libogg-1.1.3.tar.gz
wget downloads.xiph.org/releases/vorbis/libvorbis-1.1.2.tar.gz

# EXTRACT MODULES

tar zxvf lame-3.97.tar.gz
tar zxvf libogg-1.1.3.tar.gz
tar zxvf libvorbis-1.1.2.tar.gz
tar zxvf flvtool2_1.0.5_rc6.tgz
tar jxvf essential-20061022.tar.bz2
tar jxvf ffmpeg-php-0.5.1.tbz2

mkdir /usr/local/lib/codecs/

yum install gcc gmake make libcpp libgcc libstdc++ gcc4 gcc4-c++ gcc4-gfortran subversion ruby ncurses-devel -y

DOWNLOAD FFMPEG and MPLAYER

svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
svn checkout svn://svn.mplayerhq.hu/mplayer/trunk mplayer
cd /usr/local/src/mplayer

svn update

cd /usr/local/src/
mv /usr/local/src/essential-20061022/* /usr/local/lib/codecs/
chmod -R 755 /usr/local/lib/codecs/

# LAME:

cd /usr/local/src/lame-3.97
./configure
make && make install

# LIBOGG

cd /usr/local/src/
cd /usr/local/src/libogg-1.1.3
./configure --enable-shared && make && make install
PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
export PKG_CONFIG_PATH

# LIBVORBIS

cd /usr/local/src/
cd /usr/local/src/libvorbis-1.1.2
./configure && make && make install

# FLVTOOL2

cd /usr/local/src/
cd /usr/local/src/flvtool2_1.0.5_rc6/
ruby setup.rb config
ruby setup.rb setup
ruby setup.rb install

# MPLAYER

cd /usr/local/src/
cd /usr/local/src/mplayer
./configure && make && make install

cd /usr/local/src/

# FFMPEG:

cd /usr/local/src/ffmpeg/
./configure --enable-libmp3lame --enable-libvorbis --disable-mmx --enable-shared
make
make install

export LD_LIBRARY_PATH=/usr/local/lib/

ln -s /usr/local/lib/libavformat.so.50 /usr/lib/libavformat.so.50
ln -s /usr/local/lib/libavcodec.so.51 /usr/lib/libavcodec.so.51
ln -s /usr/local/lib/libavutil.so.49 /usr/lib/libavutil.so.49
ln -s /usr/local/lib/libmp3lame.so.0 /usr/lib/libmp3lame.so.0
ln -s /usr/local/lib/libavformat.so.51 /usr/lib/libavformat.so.51

# FFMPEG-PHP:

cd /usr/local/src/
cd /usr/local/src/ffmpeg-php-0.5.1/
phpize
./configure
make
make install

NOTICE: Make sure this is the correct php.ini for the box!!

echo 'extension=ffmpeg.so' >> /usr/local/Zend/etc/php.ini

NOTICE: Make sure this is the correct php.ini for the box!!

# RESTART APACHE

service httpd restart

Another article on MEncoder

Source: boombick.org/blog/posts/19.

MEncoder is the conversion utility distributed with MPlayer. MPlayer plays audio and video, while MEncoder processes them and converts between formats. There are many graphical front-ends, but the following examples show how much you can do directly from the command line.

Mencoder supports many file types, here are some of them: MPEG/VOB, AVI, ASF/WMA/WMV, RM, QT/MOV/MP4, Ogg/OGM, MKV, VIVO, FLI, FLV. Command syntax is fairly simple despite a large number of options. Despite its "modest" interface, mencoder can do amazing things with multimedia files.

A simple command to convert an MPG file to AVI format:

mencoder file.mpg -o file.avi -ovc lavc -oac lavc

Options -oac and -ovc indicate the desired audio and video codecs. You can view the list of available codecs using the commands mencoder -ovc help and mencoder -oac help

Suppose you need an uncompressed audio stream and decided to use PCM. You can specify the desired audio format using the acodec option:

mencoder file.mpg -o file.avi -ovc lavc -oac pcm

If you use mp3 compression, you can also specify the bitrate:

mencoder file.mpg -o file.avi -ovc lavc -oac lavc -lavcopts acodec=libmp3lame:abitrate=128

You can use lameopts if libmp3lame is installed on your system and you want to expand the list of options available during audio encoding. Also with lameopts you can create files with variable bitrate:

mencoder file -o file.avi -ovc lavc -oac mp3lame -lameopts vbr=2:q=3

where q is any number in the range from 0 to 9.
Also you can work with audio tracks from video files:

mencoder file.mpg -o file.avi -ovc lavc -oac lavc -lavcopts acodec=libmp3lame:abitrate=128:vcodec=mpeg4

If you don't want to use video compression, use -ovc copy. With this option, the video stream will simply be copied byte for byte from the source file.

You can use DivX and xvid directly without the lavc option:

mencoder -ovc xvid -oac mp3lame -o destination.avi source.avi

To specify more detailed parameters, you can use xvid options:

mencoder -ovc xvid -oac mp3lame -xvidencopts bitrate=878 -o destination.avi source.avi

Increasing the bitrate improves image quality, but along with quality, the file size also grows. Keep this in mind.

The next step, or rather two, will be describing the process of transcoding DVD to XviD. First mencoder analyzes the file, then, based on the data obtained, transcodes the DVD stream. Using two passes is not much longer, but on output you get a higher quality file. Be prepared that during the encoding process CPU load will be around 90%:

mencoder dvd:// -oac mp3lame -ovc xvid -xvidencopts pass=1 -o /dev/null
mencoder dvd:// -oac mp3lame -ovc xvid -xvidencopts pass=2:bitrate=800 -o xvidfile.avi

You can specify bitrate to get the required quality. For example, to fit a DVD into a 700-megabyte xvid file, use the following options:

mencoder dvd:// -ovc xvid -oac mp3lame -xvidencopts bitrate=-700000 -o file.avi

Use nice to lower encoding priority and let other tasks take precedence. It does not impose a CPU usage limit:

nice -n 19 mencoder dvd:// -ovc xvid -oac mp3lame -xvidencopts bitrate=-700000 -o file.avi

If you have many small video files and want to make one big one out of them, mencoder can help you... Rename the source files so that they sort in the required order. Then use:

mencoder *.avi -ovc copy -oac copy -o output.avi

If you want to add an audio track to a video file, use:

mencoder source.avi -o destination.avi -ovc copy -oac mp3lame -audiofile file.wav
mencoder source.avi -o destination.avi -ovc copy -oac copy -audiofile file.mp3

To get video suitable for playback on iPodLinux, use:

mencoder -ovc raw -ofps 15 -oac pcm -vf scale=176:-2,expand=176:132,format=bgr16 input.file -o output.avi

This command will create a RAW AVI file with uncompressed audio stream and scale it to the Nano screen size.

I have a PocketPC, which often accompanies me on business trips. I use mencoder to get movies that fit on a 512 MB SD-Card and play on my Pocket:

mencoder -oac mp3lame -lameopts mode=3:preset=24 -ovc lavc -lavcopts vcodec=mpeg4:vhq:vbitrate=384:keyint=250 -vf expand="320:240" -o outputfile.avi inputfile.avi

or

mencoder input.avi -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=200:abitrate=48 -vf scale=320:240 -oac copy -o output.avi

The difference is that the second command scales the movie to the PocketPC screen size - 320x240 pixels.

If you have a webcam and want to record video from it, use:

mencoder tv:// -tv driver=v4l:device=/dev/video0:width=640:height=480:forceaudio -ovc lavc -oac lavc -lavcopts vcodec=mpeg4:acodec=mp3 -ffourcc divx -o test.avi

The command records all /dev/video0 output into a file with 640x480 resolution and mp3 audio.

As you can see, with mencoder you can work with a large number of formats, a huge number of options are available, it is small, lightweight, and works very fast. And I won't trade it for any utility with a more "friendly" interface.

Specially for those interested, a list of front-ends for mencoder:

Kmencoder http://sf.net/projects/kmencoder/
Konverter http://www.libsdl.de/projects/konverter/
Kmenc 15 http://kmenc15.sf.net/
GMencoder http://gmencoder.sf.net/
AcidRIP http://untrepid.com/acidrip/
MenGUI http://jahjah.free.fr/morphos/