PDA

View Full Version : script / program to convert videos to mp4 / aac / x264 (avc)


ewaguespack
2nd December 2006, 22:45
is there a script of program that will allow me to run to convert all videos in a directory structure (in linux) to mp4?

thanks.

btw, I am doing them one at a time with avidemux2, but it would be nice to automate.

alec_robertson
3rd December 2006, 01:43
Hi, this will convert all files in the current directory to quicktime compatible mp4/h264/aac.

Possible filter strings are (from mencoder man page):
* m0="dvd:// -ofps 23.976" for soft-telecined ntsc dvd's
* m0="dvd:// -vf pullup,softskip -ofps 23.976" for hard-telecined ntsc dvd's,
* m0="-vf yadif=2" to deinterlace (or -vf kerndeint, -vf pp=lb...)

for i in *.mpg; do
v=`basename "$i" .mpg`
b=2000;
r=29.97; # framerate: ntsc=29.97, pal=25, film=23.976
m0=""; # filters
x0="-ovc x264 -x264encopts bitrate=$b:bframes=2";
x1="$x0:turbo=2:pass=1 -of rawaudio -oac faac -faacopts br=128";
x2="$x0:pass=2 -of rawvideo -nosound";

mencoder $i $m0 $x1 -o $v.aac
mencoder $i $m0 $x2 -o $v.264
mp4box -add $v.264 -fps $r -add $v.aac -new $v.mp4
done

ewaguespack
3rd December 2006, 02:07
did you leave some stuff out? it barfed on $b not being defined and no $v provided on the mencoder lines, anyway this seems to be working, but a bitrate of 1000 was just a guess, not sure what that should be.

for v in *
do
b=1000
r=29.97; # ntsc, use 25 for pal
m0=""; # filters
x0="-passlogfile $v.log -ovc x264 -x264encopts bitrate=$b:bframes=2";
x1="$x0:turbo=2:pass=1 -of rawaudio -oac faac -faacopts br=128";
x2="$x0:pass=2 -of rawvideo -nosound";

mencoder $m0 $x1 -o $v.aac $v
mencoder $m0 $x2 -o $v.264 $v
MP4Box -add $v.264 -fps $r -add $v.aac -new $v.mp4
done

alec_robertson
3rd December 2006, 16:02
Good point, code changed accordingly :) As for the bitrate, I tend to use b=2000 but you can play around with anything from b=500 on up. There's a good program in the mplayer source called calcbpp.pl, which, combined with the description on the mailing list: http://article.gmane.org/gmane.comp.video.mplayer.user/8476 gives a pretty good metric for encoding bitrates.

nm
4th December 2006, 03:09
I'd recommend CRF encoding with x264 instead of bpp calculations because the latter won't take source complexity into account. And you won't even need a second pass with CRF. Just experiment with values between 18 and 26 and choose the highest value that still produces acceptable quality. Personally I'm usually satisfied with 21-23. You can use the same value for most sources.

As for x264 encoding options, something like this would give you a lot better quality, or actually smaller filesize when talking about crf/cq encoding, than the default parameters (with the cost of encoding time):
-x264opts crf=22:frameref=5:bframes=3:b_adapt:b_pyramid:weight_b:8x8dct:me=umh:subq=7:chroma_me:mixed_refs:trellis=2:brdo:bime:nofast_pskip:direct_pred=auto
If that's too slow, try using frameref=4, subq=6, me=hex and trellis=1.

alec_robertson
4th December 2006, 03:50
Interesting, I'll give the CRF thing a shot and see how it compares. Sadly Quicktime doesn't support b-pyramid, 8x8dct or bframes>2 (http://forum.doom9.org/showthread.php?t=102609) so I'm stuck with most of the lower quality defaults...

alec_robertson
5th December 2006, 04:25
OK, so it seems that there's some audio de-sync for soft-telecined ntsc dvd's with my original approach. Here's another script that uses one pass mencoder as suggested, then avi2raw to extract the audio and video and finally mp4box to stick it all back together again:
dvd2mp4 () {
v=$1; t=$2; cr=$3; sc=$4; b=$5; a=$6; id=$7;
m0="dvd://$t -dvd-device $v.iso -aid $a";
r30="29.97003"; r24="23.97602"; r25="25"; r60="59.94006";
case $id in # n43f n43i n43n n169f n169i n169n p43f p169f
p43f | p169f) ri=$r25; r=$r25;; # pal
n43f | n169f) ri=$r30; r=$r24;; # soft-telecined ntsc
n43n | n169n) ri=$r60; r=$r60; m1="-vf-add yadif=3,mcdeint";; # ntsc 59.94 fields/s
n43i | n169i) ri=$r30; r=$r24; m1="-vf-add filmdint";; # hard telecined ntsc 29.97
esac

m2="-vfm libmpeg2 -fps $ri -ofps $r -sws 9 -oac faac
-faacopts br=128 -vf-add crop=$cr,dsize=$sc,scale=$sc,harddup
-ovc x264 -passlogfile $v.log -x264encopts crf=$b:bframes=2";

mencoder $m0 $m1 $m2 -o $v.avi; # single pass encode
avi2raw --video $v.avi $v.264; # extract video
avi2raw --audio $v.avi $v.aac; # extract audio
mp4box -add $v.264 -fps $r -add $v.aac -new $v.mp4 # remux into mp4
rm -f $v.{264,aac,avi,log} # cleanup
}

dvd2mp4 moofie 1 688:462:16:8 480:272 18 128 n169f;

alec_robertson
6th December 2006, 00:30
OK, my third reply :) Seems that mencoder's -faac output is not quicktime compatible, so use lavc instead. Also, after reading some of the x264 threads out there, 2-pass seems better than crf. I'm still not 100% confident about the audio sync using the -of rawaudio for pass #1 and -of rawvideo for pass #2 but it seems ok...
dvd2mp4 () {
v=$1; a=$2; cr=$3; sc=$4; b=$5; id=$6;
r30="29.97003"; r24="23.97602"; r25="25"; r60="59.94006";
case $id in # n43f n43i n43n n169f n169i n169n p43f p169f
p43f | p169f) ri=$r25; r=$r25;; # pal
n43f | n169f) ri=$r30; r=$r24;; # soft-telecined ntsc
n43n | n169n) ri=$r60; r=$r60; vf="-vf-add yadif=3,mcdeint";; # ntsc 59.94 fields/s
n43i | n169i) ri=$r30; r=$r24; vf="-vf-add filmdint";; # hard telecined ntsc 29.97 frames/sec
esac

m0="$v.mpg -aid $a -vfm libmpeg2 -fps $ri -ofps $r -sws 9 -oac copy
$vf -vf-add crop=$cr,dsize=$sc,scale=$sc,harddup
-oac lavc -lavcopts acodec=aac:abitrate=128
-ovc x264 -passlogfile $v.log -x264encopts bitrate=$b:bframes=2";
x1="$m0:turbo=2:pass=1"; x2="$m0:pass=2";

mencoder $x1 -of rawaudio -o $v.aac; # first pass -> aac audio
mencoder $x2 -of rawvideo -o $v.264; # second pass -> h264 video
mp4box -add $v.264 -fps $r -add $v.aac -new $v$e.mp4 # mux into mp4
}

dvd2mp4 moofie 128 688:462:16:8 480:272 1000 n169f;

nm
6th December 2006, 20:07
Also, after reading some of the x264 threads out there, 2-pass seems better than crf.
Yes, but only slightly. The difference is probably not visible in normal cases, and figuring out a suitable bitrate for 2-pass encoding is harder than letting the encoder do that on the fly with CRF.

m0="$m0 -vfm libmpeg2 -fps $ri -ofps $r -sws 9 -oac copy
-vf-add crop=$cr,dsize=$sc,scale=$sc,harddup
-ovc x264 -passlogfile $v.log -x264encopts crf=$b:bframes=2";
x1="$m0:turbo=2:pass=1"; x2="$m0:pass=2";
I don't think this will work properly. You can do a CRF encode with pass=1, but for the second pass, you'll need to specify a bitrate and no CRF option. You could parse the average bitrate from the console output that x264/MEncoder returns after the CRF pass and then give that to the second pass, if you wan't to use a 2-pass CRF hybrid encoding scheme. However, the turbo=2 will inflate the bitrate so that it will be much higher that what you would get with normal CRF encoding. So, I'd suggest doing either CRF or normal 2-pass, or a CRF encoding with pass=1, but no turbo and then a second pass with the bitrate that the first pass CRF gave you.

alec_robertson
6th December 2006, 22:12
Yes, that last script with the two passes should not use CRF (a typo on my part, now fixed :)).

Does anyone know if there's likely to be any difference in terms of audio sync between the following two encodes:

mencoder $x1 -of rawaudio -o $v.aac;
mencoder $x2 -of rawvideo -o $v.264;


mencoder $x1 -o /dev/null;
mencoder $x2 -o $v.avi;
avi2raw --video $v.avi $v.264
avi2raw --audio $v.avi $v.aac

The rest of the script remains unchanged...

nm
7th December 2006, 00:15
The first one works for me. Haven't tried with avi2raw but I think it should be fine too, like you seem to have experienced.

ewaguespack
3rd March 2007, 08:27
can you guys post any recent findings... I would really like to have some kind of consensus on what are some good encoding settings for re-encoding general videos to h.264/aac/mp4.

I do not need compatibility with either quicktime or ipods.

I also do not mind having long encode times, but I don't really like 2 pass encoding, because I have no idea what the target size of the file is, I just want it recompressed using the codecs above and with high quality settings.

thanks.

Amnon82
4th March 2007, 01:56
I found this script in the german doom9 forum:

(C) by marcdevil (27. February 2007)

#!/bin/bash

if [[ $# -ne 2 ]] ; then
echo usage: $0 source crop
echo example: $0 file.foo 704:416:8:80
echo ""
echo 'possible VARs: '
echo 'AID=129 - change language stream, (128 is default)'
echo 'QP=22 - change x264 Quality Mode (24 = default, 0 = lossless)'
echo 'AQ=95 - change vbr quality (100=128kbps, 90=80kbps, 95 is default)'
echo ""
echo example: AID=130 QP=20 AQ=93 $0 Film 560:432:12:72

exit 1
fi

if [[ $2 == none ]] ; then
crop="720:576:0:0"
else
crop="$2"
fi

if [[ $AID == "" ]] ; then AID=128 ; fi
if [[ $QP == "" ]] ; then QP=24 ; fi
if [[ $AQ == "" ]] ; then AQ=95 ; fi

if [[ -f "$1".264 ]] ; then rm -i "$1".264 ; fi
if [[ -f "$1".log ]] ; then rm -i "$1".log ; fi
if [[ -f "$1".wav ]] ; then rm -i "$1".wav ; fi
if [[ -f "$1".m4a ]] ; then rm -i "$1".m4a ; fi
if [[ -f "$1".mp4 ]] ; then rm -i "$1".mp4 ; fi

if [[ ! -f "$1" ]] ; then
echo -e '\E[48;33m'"\033[1m### FILE NOT FOUND, TRYING TO RIP THE DVD ###\033[0m"
mplayer -really-quiet dvd:// -dumpstream -dumpfile "$1"
fi

echo ""
echo ""
echo "ok, mencode $1 mit "
echo CROP=$crop
echo AID=$AID
echo QP=$QP
echo AQ=$AQ
echo ""
echo ""

if [[ ! -f "$1".wav ]] ; then
echo ""
echo -e '\E[48;32m'"\033[1m### DUMP AUDIO STREAM ###\033[0m"
mplayer -really-quiet -aid $AID -vo null -ao wav -ao pcm:fast:file="$1".wav "$1" || exit 1
echo ""
echo -e '\E[48;32m'"\033[1m### NORMALIZE AUDIO STREAM ###\033[0m"
normalize-audio "$1".wav || exit 1
else
echo ""
echo -e '\E[48;33m'"\033[1m### AUDIO STREAM ALREADY DUMPED ###\033[0m"
fi

if [[ ! -f "$1".m4a ]] ; then
echo ""
echo -e '\E[48;32m'"\033[1m### ENCODE AUDIO STREAM TO AAC ###\033[0m"
faac -w -q $AQ "$1".wav -o "$1".m4a || exit 1
else
echo ""
echo -e '\E[48;33m'"\033[1m### AUDIO STREAM ALREADY ENCODED ###\033[0m"
fi


if [[ ! -f "$1".log ]] ; then
echo ""
echo -e '\E[48;32m'"\033[1m### ENCODE VIDEO STREAM TO X264 1ST PASS ###\033[0m"
nice -n 5 mencoder "$1" \
-o "$1".264 \
-of rawvideo \
-nosound \
-vf crop=$crop \
-passlogfile "$1".log \
-ovc x264 -x264encopts qp="$QP":subq=6:partitions=all:8x8dct:me=umh:frameref=5:bframes=3:b_pyramid:weight_b:pass=1:turbo=1:threads=1 || exit 1
rm "$1".264
else
echo ""
echo -e '\E[48;33m'"\033[1m### 1ST PASS ALREADY ENCODED ###\033[0m"
fi

if [[ ! -f "$1".264 ]] ; then
echo ""
echo -e '\E[48;32m'"\033[1m### ENCODE VIDEO STREAM TO X264 2ND PASS ###\033[0m"
nice -n 5 mencoder "$1" \
-o "$1".264 \
-of rawvideo \
-nosound \
-vf crop=$crop \
-passlogfile "$1".log \
-ovc x264 -x264encopts qp="$QP":subq=6:partitions=all:8x8dct:me=umh:frameref=5:bframes=3:b_pyramid:weight_b:pass=2:threads=1 || exit 1
else
echo ""
echo -e '\E[48;33m'"\033[1m### 2ND PASS ALREADY ENCODED ###\033[0m"
fi

if [[ ! -f "$1".mp4 ]] ; then
echo ""
echo -e '\E[48;32m'"\033[1m### MUX VIDEO AND AUDIO STREAM TO MP4 ###\033[0m"
MP4Box -fps 25 -add "$1".264 -add "$1".m4a:lang=de "$1".mp4 || exit 1
else
echo ""
echo -e '\E[48;33m'"\033[1m### ALREADY MUXED ###\033[0m"
fi

echo ""
echo -e '\E[48;32m'"\033[1m### DONE ###\033[0m"

weaver4
7th March 2007, 14:36
I have been doing encoding in the Windows world, just now changing to Linux.

How do I get from a DVD to a *.mpg file to start this whole process; in Linux.

~L~
7th March 2007, 19:54
something like this?
mplayer dvd://N -dumpstream -v -dumpfile movie.vob

This will have all the audio tracks also. In my script, which monitors a directory structure for appearance of
.vob files in and code them to x264+ogg+vobsubs in mkv or x264+ac3 in avi, I define which audio track to copy.

xxxyzzzz
19th March 2007, 23:40
I found a cool bash script on the KDE-apps page:

http://www.kde-apps.org/content/show.php?content=51872

It is on sourceforge. He has one for xvid too:

http://www.kde-apps.org/content/show.php?content=51873

Z

hobart_george
21st March 2007, 09:42
I'd recommend CRF encoding with x264 instead of bpp calculations because the latter won't take source complexity into account. And you won't even need a second pass with CRF. Just experiment with values between 18 and 26 and choose the highest value that still produces acceptable quality. Personally I'm usually satisfied with 21-23. You can use the same value for most sources.

As for x264 encoding options, something like this would give you a lot better quality, or actually smaller filesize when talking about crf/cq encoding, than the default parameters (with the cost of encoding time):
-x264opts crf=22:frameref=5:bframes=3:b_adapt:b_pyramid:weight_b:8x8dct:me=umh:subq=7:chroma_me:mixed_refs:trellis=2:brdo:bime:nofast_pskip:direct_pred=auto
If that's too slow, try using frameref=4, subq=6, me=hex and trellis=1.

NM would you do that for one pass or two? Same options on both?

How could i make that a little more quicktime compatible?

nm
22nd March 2007, 13:39
I would do either a one-pass CRF or two-pass with the average bitrate specified. You could also do a CRF first pass, parse the resulting average bitrate from the MEncoder/x264 output and do a second pass with that bitrate and same options, but IMO that is waste of time since the CRF-encoded first pass output is already very good.

I don't know much about Quicktime's restrictions, but I'd suggest you to take a look at the MeGUI Quicktime profile (if there was one, or perhaps it was just for Ipod...).