I've recently been getting into making
Video CDs from Linux. There are quite a few nice command-line utilities, but it was kind of a headache to get all the right flags and options for VCD-compliant output. Anyhow, I've been working on a small script to do VCD encoding of videos. It's far from perfect, but it has worked pretty well for several videos I've tried it on - it'll even do some PAL to NTSC conversion! Anyhow, here it is in case anyone's interested in using it.
Code:
#!/bin/bash
# Convert any video/audio stream that mplayer can play
# into a VCD-compatible Mpeg output file.
# Arguments: $1 - name of input
# $2 - name of output
if [ $# -ne 2 ]; then
echo "Usage:"
echo " tovcd <input file> <output prefix>"
exit 1
fi
# Probe for width, height, and frame rate
tcprobe -i "$1" > fileinfo
WIDTH=`grep 'import frame size' fileinfo | \
perl -e ' $line=<STDIN> ; $line =~ /import frame size: -g (\d+?)x\d+ / ; print $1' `
HEIGHT=`grep 'import frame size' fileinfo | \
perl -e ' $line=<STDIN> ; $line =~ /import frame size: -g \d+?x(\d+) / ; print $1' `
FPS=`grep 'frame rate' fileinfo | \
perl -e ' $line=<STDIN> ; $line =~ /frame rate: -f (.+?) \[/ ; print $1' `
echo "Input file is $WIDTH x $HEIGHT at $FPS fps."
# If FPS is already 29.97 (NTSC) or 23.976 (NTSC film), leave it alone
if [[ $FPS == "29.970" ]];
then
echo "Source is 29.970 fps (NTSC). Encoding as NTSC video."
ADJUSTFPS=""
ENCFPS="-F 4"
elif [[ $FPS == "23.976" ]];
then
echo "Source is 23.976 fps (NTSC film). Encoding as NTSC film."
ADJUSTFPS=""
ENCFPS="-F 1"
else
echo "Source is not at an NTSC frame rate. Adjusting FPS."
ADJUSTFPS="yuvfps -r 30000:1001 -v 0 |"
ENCFPS="-F 4"
fi
# If resolution is already 352x240, do not rescale
if [[ $WIDTH == "352" && $HEIGHT == "240" ]];
then
echo "Source appears to be VCD resolution (352x240). No rescaling will be applied."
ADJUSTSIZE=""
# See if source is VCD PAL (352x288) or (320x240)
# If so, just rescale; aspect ratio should be fine
elif [[ $WIDTH == "352" && $HEIGHT == "288" ]] || [[ $WIDTH == "320" && $HEIGHT == "240" ]];
then
echo "Assuming a VCD PAL (352x288) or (320x240) correct 4:3 aspect ratio. Rescaling."
ADJUSTSIZE="yuvscaler -O VCD -v 0 -n n |"
# Otherwise, assume a widescreen (16:9) aspect, and pad with black bars
else
echo "Assuming source is widescreen (16:9) aspect ratio. Padding with black bars."
ADJUSTSIZE="yuvscaler -O VCD -v 0 -n n -M WIDE2VCD |"
fi
echo "Creating and encoding video stream..."
mkfifo stream.yuv
mplayer -nosound -noframedrop -vo yuv4mpeg -vf pp=hb/vb/dr,hqdn3d "$1" &
eval `echo "cat stream.yuv | $ADJUSTFPS $ADJUSTSIZE nice -n 16 mpeg2enc -a 2 -f 1 $ENCFPS -v 0 -n n -H -o $2.m1v"`
echo "Creating WAV of audio stream..."
mplayer -vc dummy -vo null -ao pcm -aofile stream.wav "$1"
echo "Normalizing WAV audio..."
normalize --amplitude=-10dBFS stream.wav
echo "Encoding WAV..."
cat stream.wav | mp2enc -V -o "$2.mpa"
echo "Multiplexing audio and video together..."
tcmplex -i "$2.m1v" -p "$2.mpa" -o "$2.mpg" -m v
echo "Cleaning up..."
rm stream.yuv
rm stream.wav
rm "$2.m1v"
rm "$2.mpa"
rm fileinfo
echo "Done"
It requires mpeg2enc and mp2enc (from the
MJpegtools package) and
Mplayer, as well as tcprobe (from the
transcode package). Perl required also (though it could probably be rewritten to eliminate some of these dependencies).
The resulting output mpeg can be burned straight to a VCD using
K3B or any other software that can create the VCD filesystem.
No clue if it works with longer videos. Will probably distort the picture if the source material is widescreen. Might cause audio/video sync problems (though I think I got most of those ironed out).
I take absolutely no responsibility if this script does not work, crashes your computer, eats all your twinkies, etc. If you make improvements to it, please send them to me.
Have fun!
Edit: Script has been improved slightly to (I hope) correct for video/audio desync with film framerate (23.976fps). Also, PAL-resolution VCD (352x288) is detected and scaled correctly; other resolutions are presumed to be widescreen, and padded with black bars.
Edit again: Added another feature to normalize the audio output. I was getting some videos that were too quiet; the normalize feature tries to bump all output to a consistent level. Requires the
normalize package. If it's not installed, it should still work (your audio just won't be normalized).