Transcoding
Divx to VCD, SVCD, CVCD, etc. under Linux
by paranouei
LinuxMalaga
News(02/12/2004): New script for encoding to KVCD, check
this thread,
the link to the script is at the bottom
News(06/09/2003): New script divx2cvcd available.
This new script doesn't use transcode anymore so now supports more codecs and its more
customizable.
News(20/01/2003): New forum available.
You can ask there your questions about this guide.
So you just came from shopping with your brand new DVD player, and
now you would like to transcode your Divx files to VCD to enjoy them in
your big TV at the living room...
This task can be done in linux, you can even automate it so you just have
to type i.e. divx2vcd <file.avi>, go for a walk, and when you
are back you have a fresh .bin and .cue files ready to burn.
Ok, let's see a few basic concepts before we begin:
Basic concepts:
-
VCD: Video CD. It's
an MPEG-1 stream, at 352x288 and 25 fps (PAL), or 352x240 and 29.976 fps
(NTSC). It has constat bitrate at 1150kbps and the audio is MPEG layer
2 at 224 kbps. You can fit as many minutes as the CD says (74 or 80).
-
SVCD: Super Video CD. It's
an MPEG-2 stream, at 480x576 and 25 fps (PAL), or 480x480 and 29.976 fps
(NTSC). The bitrate may be variable up to 2600kbps, and the audio can
be between 32 and 384 kbps. Depending on the bitrate you choose you can
fit more or less minutes, but you can usually fit between 40 and 55 minutes
per CD.
-
XVCD, CVCD..: These are modifications
of the standard, with different bitrates, etc., and they could not work
on all DVDs. But today's DVD players can play almost everything.
For instance, CVCD is just a VCD with variable
bitrate. This way, "easy" scenes take a lower bitrate
so you have more space left and you can fit more minutes. You can
fit this way more than 90 minutes in a CD.
Tools:
-
Mplayer.
This will be our input filter for transcode. This way, transcode will
be able to handle everthing mplayer can read (divx, realmedia, subtitles...)
-
Transcode.
This is the main tool. It's for transcoding between almost any imaginable
format.
-
MJPEG
Tools. This will be our output filter. Also, in includes tools for multiplexing
the mpg.
-
VCDImager.
This tool is for creating the .bin and .cue files from the mpg.
Also, my scripts use some basic utils like bc (calculator)
and perl.
Well, once you've got that, let's start ;)
Divx2VCD:
I wrote the following script "divx2vcd", it takes care of the calculations
to get an image with the same aspect ratio (adding black borders if needed).
It uses constant, so it's fully VCD standard. The maximum file size (to
make them fit in a CD), it's in CDSIZE variable. The script creates the
video and audio with transcode, then it multiplexes them with mplex, and
finally it creates de images. You can download it from here. I'm gonna paste it here so you can see it (sorry
comments are in spanish):
-- Inicio divx2vcd --
#!/bin/bash
# Este script pasa un Divx a VCD. Para los archivos temporales se # necesita al menos 4.5 Gigas (m1v y mpa, los .mpg y los .bin)
DIR=`pwd` TEMPFOLDER=/tmp/divx2vcd-$RANDOM TEMP_TEMPLATE=/tmp/tcmplex-template-$RANDOM
# CDSIZE Values. VCDs are write in Mode 2, so the filesizes are the # the following: # 74 Min/650Mb ---> CDSIZE=735 # 80 Min/700Mb ---> CDSIZE=795 CDSIZE=795 #VIDEORATE=1150 AUDIORATE=224
if [ $# -eq 0 ]; then echo "Usage:" echo " divx2vcd <divxfile>" exit 1 fi
FILE=$1 if [ "$1" == "`basename \"$1\"`" ]; then FILE="$DIR/$1" fi
mkdir $TEMPFOLDER cd $TEMPFOLDER
tcprobe -i "$FILE" > $TEMPFOLDER/info
WIDTH=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /width=(\d+)/ ; print $1' ` HEIGHT=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /height=(\d+)/ ; print $1' ` FPS=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /V: (.+?) fps/ ; print $1' ` FPS_1=`echo "scale=1 ; $FPS/1"| bc -l` FRAMES=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /frames=(\d+)/ ; print $1' ` SEGUNDOS_TOTAL=`echo "scale=0 ; ($FRAMES / $FPS)"| bc -l` HORAS=`echo "scale=0 ; ($SEGUNDOS_TOTAL / 3600)"| bc -l` MINUTOS=`echo "scale=0 ; (($SEGUNDOS_TOTAL - 3600 * $HORAS)/60)"| \ bc -l` SEGUNDOS=`echo "scale=0 ; ($SEGUNDOS_TOTAL % 60)"| bc -l`
echo "*************** FILE INFO ***************" echo "Frame Size: ${WIDTH}x${HEIGHT} - FPS: $FPS" echo "Length: $FRAMES - Seconds: $SEGUNDOS_TOTAL" echo "$HORAS hours, $MINUTOS minutes, $SEGUNDOS seconds"
if [ $FPS_1 == "29.9" -o $FPS_1 == "30" -o $FPS_1 == "23.9" ]; then WIDTH_OUT=352 HEIGHT_OUT=240 else WIDTH_OUT=352 HEIGHT_OUT=288 fi
echo "Video Output: ${WIDTH_OUT}x${HEIGHT_OUT}"
# Ahora calculamos los valores pa los bordes.
ANCHO_1_1_OUT=`echo "($HEIGHT_OUT * 4/3)"| bc -l` ALTO_OUT=`echo "$HEIGHT / ($WIDTH / $ANCHO_1_1_OUT)" | bc -l` # Redondeamos ALTO_OUT=`echo "scale=0 ; $ALTO_OUT/1"| bc -l` # Nos aseguramos de que sea par ALTO_OUT=`echo "scale=0 ; $ALTO_OUT+$ALTO_OUT%2" | bc -l`
BORDE=`echo "scale=0 ; ($HEIGHT_OUT-$ALTO_OUT)/2"| bc -l` echo "alto sin bordes: $ALTO_OUT, con borde: $BORDE"
# Borramos Pelicula.m1v y Pelicula.mpa rm -f Pelicula.m1v Pelicula.mpa
cd $TEMPFOLDER
echo "transcode -i \"$FILE\" -V -x mplayer -y mpeg2enc,mp2enc \ -F 1 -Z ${WIDTH_OUT}x$ALTO_OUT -Y -$BORDE,0,-$BORDE,0 \ --export_asr 2 -E 44100 -b $AUDIORATE -o $DIR/Pelicula" transcode -i "$FILE" -V -x mplayer -y mpeg2enc,mp2enc \ -F 1 -Z ${WIDTH_OUT}x$ALTO_OUT -Y -$BORDE,0,-$BORDE,0 \ --export_asr 2 -E 44100 -b $AUDIORATE -o $DIR/Pelicula
rm $TEMPFOLDER/* rmdir $TEMPFOLDER
cd $DIR
# Si no hay Pelicula.m1v y Pelicula.mpa salir [ -f Pelicula.m1v -a -f Pelicula.mpa ] || exit 1
rm -f Pelicula*.mpg
#Ahora multiplexamos el .mpg echo "maxFileSize = $CDSIZE" > $TEMP_TEMPLATE tcmplex -i Pelicula.m1v -p Pelicula.mpa -o Pelicula.mpg \ -m 1 -F $TEMP_TEMPLATE rm $TEMP_TEMPLATE
# Y creamos las imagenes... for i in `ls Pelicula*mpg` ; do vcdimager -t vcd2 -c $i.cue -b $i.bin $i done
-- Final divx2vcd --
Divx2CVCD:
New script Divx2CVCD (16/12/2002). This scripts gets all information
from the .avi file, and then calculates automatically the video bitrate to
make it fit in a CD in CVCD format (VCD with variable bitrate). You can change
the QUANTUM variable. It's the quality (like the CQ-Constant Quality
from TMPGenc), it must be between 2 and 31, the smaller it is, the biggest
quality. With a value under 8 you get good quality. You can change AUDIORATE
too. The script is available here, and I'm
pasting it here:
News(06/09/2003): New script divx2cvcd available.
This new script doesn't use transcode anymore so now supports more codecs and its more
customizable.
-- Inicio divx2cvcd --
#!/bin/bash
# Este script pasa un Divx a CVCD. Para los archivos temporales se # necesita al menos 4.5 Gigas (m1v y mpa, los .mpg y los .bin)
DIR=`pwd` TEMPFOLDER=/tmp/divx2vcd-$RANDOM TEMP_TEMPLATE=/tmp/tcmplex-template-$RANDOM
# CDSIZE Values. VCDs are write in Mode 2, so the filesizes are the # the following: # 74 Min/650Mb ---> CDSIZE=735 # 80 Min/700Mb ---> CDSIZE=795 CDSIZE=795 QUANTUM=5 # Maxrate ahora es automatico #MAXRATE=900 AUDIORATE=128
if [ $# -eq 0 ]; then echo "Usage:" echo " divx2cvcd <divxfile>" exit 1 fi
FILE=$1 if [ "$1" == "`basename \"$1\"`" ]; then FILE="$DIR/$1" fi
mkdir $TEMPFOLDER cd $TEMPFOLDER
tcprobe -i "$FILE" > $TEMPFOLDER/info
WIDTH=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /width=(\d+)/ ; print $1' ` HEIGHT=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /height=(\d+)/ ; print $1' ` FPS=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /V: (.+?) fps/ ; print $1' ` FPS_1=`echo "scale=1 ; $FPS/1"| bc -l` FRAMES=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /frames=(\d+)/ ; print $1' ` SEGUNDOS_TOTAL=`echo "scale=0 ; ($FRAMES / $FPS)"| bc -l` HORAS=`echo "scale=0 ; ($SEGUNDOS_TOTAL / 3600)"| bc -l` MINUTOS=`echo "scale=0 ; (($SEGUNDOS_TOTAL - \ 3600 * $HORAS)/60)"| bc -l` SEGUNDOS=`echo "scale=0 ; ($SEGUNDOS_TOTAL % 60)"| bc -l`
VIDEO_RATE=`echo "scale=0 ;(($CDSIZE * 1024 - \ ($AUDIORATE/8*$SEGUNDOS_TOTAL))*8 / $SEGUNDOS_TOTAL)"| bc -l` # +5% MAXRATE=`echo "scale=0 ; ($VIDEO_RATE * 105 / 100)" | bc -l`
echo "*************** FILE INFO ***************" echo "Frame Size: ${WIDTH}x${HEIGHT} - FPS: $FPS" echo "Length: $FRAMES - Seconds: $SEGUNDOS_TOTAL" echo "$HORAS hours, $MINUTOS minutes, $SEGUNDOS seconds" echo "Recommended averagge video bitrate: $VIDEO_RATE" echo "Using max video bitrate: $MAXRATE"
if [ $FPS_1 == "29.9" -o $FPS_1 == "30" -o $FPS_1 == "23.9" ]; then WIDTH_OUT=352 HEIGHT_OUT=240 else WIDTH_OUT=352 HEIGHT_OUT=288 fi
echo "Video Output: ${WIDTH_OUT}x${HEIGHT_OUT}"
# Ahora calculamos los valores pa los bordes.
ANCHO_1_1_OUT=`echo "($HEIGHT_OUT * 4/3)"| bc -l` ALTO_OUT=`echo "$HEIGHT / ($WIDTH / $ANCHO_1_1_OUT)" | bc -l` # Redondeamos ALTO_OUT=`echo "scale=0 ; $ALTO_OUT/1"| bc -l` # Nos aseguramos de que sea par ALTO_OUT=`echo "scale=0 ; $ALTO_OUT+$ALTO_OUT%2" | bc -l`
BORDE=`echo "scale=0 ; ($HEIGHT_OUT-$ALTO_OUT)/2"| bc -l`
echo "alto sin bordes: $ALTO_OUT, con borde: $BORDE"
# Borramos Pelicula.m1v y Pelicula.mpa rm -f Pelicula.m1v Pelicula.mpa
cd $TEMPFOLDER echo "transcode -i \"$FILE\" -V -x mplayer -y mpeg2enc,mp2enc \ -F 2,\"-q $QUANTUM\" -Z ${WIDTH_OUT}x$ALTO_OUT -Y -$BORDE,0,-$BORDE,0 \ --export_asr 2 -E 44100 -b $AUDIORATE -o $DIR/Pelicula -w $MAXRATE" transcode -i "$FILE" -V -x mplayer -y mpeg2enc,mp2enc \ -F 2,"-q $QUANTUM" -Z ${WIDTH_OUT}x$ALTO_OUT -Y -$BORDE,0,-$BORDE,0 \ --export_asr 2 -E 44100 -b $AUDIORATE -o $DIR/Pelicula -w $MAXRATE
rm $TEMPFOLDER/* rmdir $TEMPFOLDER
cd $DIR
# Si no hay Pelicula.m1v y Pelicula.mpa salir [ -f Pelicula.m1v -a -f Pelicula.mpa ] || exit 1
rm -f Pelicula*.mpg
#Ahora multiplexamos el mpg echo "maxFileSize = $CDSIZE" > $TEMP_TEMPLATE tcmplex -i Pelicula.m1v -p Pelicula.mpa -o Pelicula.mpg \ -m 1 -F $TEMP_TEMPLATE rm $TEMP_TEMPLATE
# Y creamos las imagenes... for i in `ls Pelicula*.mpg` ; do vcdimager -t vcd2 -c $i.cue -b $i.bin $i done
-- Final divx2cvcd --
Divx2SVCD:
For the SVCD creation is basically the same script, I only adjusted it
to create a SVCD. You can change CDSIZE, QUANTUM, MAXVIDEORATE and AUDIORATE.
You don't need to create an bbmpeg template because it creates it automatically..
Like before, you can download the script from here,
and I paste it here also:
-- Inicio divx2svcd --
#!/bin/bash
# Este script pasa un Divx a SVCD. Para los archivos temporales se # necesita al menos 4.5 Gigas (m2v y mpa, los .mpg y los .bin)
DIR=`pwd` TEMPFOLDER=/tmp/divx2svcd-$RANDOM TEMPLATE=$TEMPFOLDER/template
# CDSIZE Values. VCDs are write in Mode 2, so the filesizes are the # the following: # 74 Min/650Mb ---> CDSIZE=735 # 80 Min/700Mb ---> CDSIZE=795 CDSIZE=795 QUANTUM=7 MAXVIDEORATE=4000000 AUDIORATE=160
if [ $# -eq 0 ]; then echo "Usage:" echo " divx2svcd <divxfile>" exit 1 fi
FILE=$1 if [ "$1" == "`basename \"$1\"`" ]; then FILE="$DIR/$1" fi
mkdir $TEMPFOLDER cd $TEMPFOLDER
# Create a template for bbmpeg encoder echo "quant_value = $QUANTUM" > $TEMPLATE echo "max_bitrate = $MAXVIDEORATE" >> $TEMPLATE
echo "Dir: $DIR" echo "Temp: $TEMPFOLDER" tcprobe -i "$FILE" > $TEMPFOLDER/info
WIDTH=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /width=(\d+)/ ; print $1' ` HEIGHT=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /height=(\d+)/ ; print $1' ` FPS=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /V: (.+?) fps/ ; print $1' ` FPS=`echo "scale=1 ; $FPS/1"| bc -l` FRAMES=`grep '\[avilib\] V:' $TEMPFOLDER/info | \ perl -e ' $line=<STDIN> ; $line =~ /frames=(\d+)/ ; print $1' ` SEGUNDOS_TOTAL=`echo "scale=0 ; ($FRAMES / $FPS)"| bc -l` HORAS=`echo "scale=0 ; ($SEGUNDOS_TOTAL / 3600)"| bc -l` MINUTOS=`echo "scale=0 ; (($SEGUNDOS_TOTAL - 3600 * $HORAS)/60)"| \ bc -l` SEGUNDOS=`echo "scale=0 ; ($SEGUNDOS_TOTAL % 60)"| bc -l`
echo "*************** FILE INFO ***************" echo "Frame Size: ${WIDTH}x${HEIGHT} - FPS: $FPS" echo "Length: $FRAMES - Seconds: $SEGUNDOS_TOTAL" echo "$HORAS hours, $MINUTOS minutes, $SEGUNDOS seconds"
if [ $FPS == "29.9" -o $FPS == "30" -o $FPS == "23.9" ]; then WIDTH_OUT=480 HEIGHT_OUT=480 MPEG_OPTIONS=s,2,$TEMPLATE else WIDTH_OUT=480 HEIGHT_OUT=576 MPEG_OPTIONS=s,3,$TEMPLATE fi
echo "Salida: $WIDTH_OUT x $HEIGHT_OUT"
# Ahora calculamos los valores pa los bordes.
ANCHO_1_1_OUT=`echo "($HEIGHT_OUT * 4/3)"| bc -l` ALTO_OUT=`echo "$HEIGHT / ($WIDTH / $ANCHO_1_1_OUT)" | bc -l` # Redondeamos ALTO_OUT=`echo "scale=0 ; $ALTO_OUT/1"| bc -l` # Nos aseguramos de que sea par ALTO_OUT=`echo "scale=0 ; $ALTO_OUT+$ALTO_OUT%2" | bc -l`
BORDE=`echo "scale=0 ; ($HEIGHT_OUT-$ALTO_OUT)/2"| bc -l` echo "alto sin bordes: $ALTO_OUT, con borde: $BORDE"
# Borramos Pelicula.m1v y Pelicula.mpa rm -f Pelicula.m2v Pelicula.mpa
cd $TEMPFOLDER echo "transcode -i \"$FILE\" -V -x mplayer -y mpeg \ -F $MPEG_OPTIONS -Z ${WIDTH_OUT}x$ALTO_OUT -Y -$BORDE,0,-$BORDE,0 \ --export_asr 2 -E 44100 -b $AUDIORATE -o $DIR/Pelicula" transcode -i "$FILE" -V -x mplayer -y mpeg \ -F $MPEG_OPTIONS -Z ${WIDTH_OUT}x$ALTO_OUT -Y -$BORDE,0,-$BORDE,0 \ --export_asr 2 -E 44100 -b $AUDIORATE -o $DIR/Pelicula
cd $DIR
[ -f Pelicula.m2v -a -f Pelicula.mpa ] || exit 1
rm -f Pelicula*.mpg
# Plantilla pa multiplexar echo "maxFileSize = $CDSIZE" >> $TEMPLATE
#Ahora multiplexamos el .mpg tcmplex -i Pelicula.m2v -p Pelicula.mpa -o Pelicula.mpg \ -m s -F $TEMPLATE
rm $TEMPFOLDER/* rmdir $TEMPFOLDER
# Y creamos las imagenes... for i in `ls Pelicula*mpg` ; do vcdimager -t svcd -c $i.cue -b $i.bin $i done
-- Final divx2svcd --
Subtitles:
If we've got a divx file in a foreign language, and a subtitles file it
is also possible to transcode them when we create the *VCD. The subtitles
will be recorded as part of the movie (so you can't disable them when
watching the *VCD).
The method is quite simple, you just have to have a subtitles file supported
by mplayer (subrip, microdvd... mplayer supports almost everything),
and put the file in the same folder as the .avi, and rename the file
so it has exactly the same name as the .avi file
(except the extension of course). This way we make mplayer to autoload
the subtitles. You can try if it works before transcoding, just do mplayer
<file.avi> and see if the subtitles are autoloaded.
Well, I hope this little guide was helpful for you ;).
|