PDA

View Full Version : Trying a script to convert files from avi to mp4


DrEaMeR86
22nd February 2007, 10:28
Just trying to simplify some daily actions (converting anime :P).

#!/bin/bash
# Doom9's solutions :P
# DrEaMeR... Just Copy, Paste, and Use it
# DrEaMuX v0.3

SRCFILE="$1"
RESX=`mplayer -identify -frames 0 -vo null -ao null "${SRCFILE}" | grep ID_VIDEO_WIDTH | cut -f 2 -d "="`
RESY=`mplayer -identify -frames 0 -vo null -ao null "${SRCFILE}" | grep ID_VIDEO_HEIGHT | cut -f 2 -d "="`
FPS=`mplayer -identify -frames 0 -vo null -ao null "${SRCFILE}" | grep ID_VIDEO_FPS | cut -f 2 -d "="`
STREAMV=streamvideo$(printf '%05d' ${RANDOM})
STREAMA=streamaudio$(printf '%05d' ${RANDOM})
DSTVFILE="`basename "${SRCFILE}" .avi`.mp4"
DSTAFILE="`basename "${SRCFILE}" .avi`.aac"
LOGFILE=/tmp/"`basename "${SRCFILE}" .avi`.log"
ENCSTATS=/tmp/"`basename "${SRCFILE}" .avi`.stats"

echo -en "Encoding \e[1;31m$1\e[0m from \e[1;32m`mplayer -identify -frames 0 -vo null -ao null "${SRCFILE}" | grep ID_AUDIO_CODEC | cut -f 2 -d "="`\e[0m to \e[1;32mAAC\e[0m"
echo
mkfifo /tmp/"${STREAMA}"
echo -en "Working with pipe \e[1;34m/tmp/${STREAMA}\e[0m..."
echo
echo -en "Writing to a temporary \e[1;32mAAC\e[0m \e[1;34m/tmp/${DSTAFILE}\e[0m..."
echo
mplayer -ao pcm:file="/tmp/"${STREAMA}"" "${SRCFILE}" -vc dummy -vo null | faac -o lc -c 18000 -b 64 -o /tmp/"${DSTAFILE}" /tmp/"${STREAMA}"
echo -en "Deleting pipe created before \e[1;34m/tmp/${STREAMA}\e[0m..";echo
rm /tmp/"${STREAMA}";
echo "Done."
echo -en "Encoding \e[1;31m$1\e[0m from \e[1;32m`mplayer -identify -frames 0 -vo null -ao null "${SRCFILE}" | grep ID_VIDEO_FORMAT | cut -f 2 -d "="`\e[0m to \e[1;32mMP4\e[0m. "${RESX}"x"${RESY}" @ "${FPS}""
echo
mkfifo /tmp/"${STREAMV}"
echo -en "Working with pipe \e[1;34m/tmp/${STREAMV}\e[0m..."
echo
echo "First Pass...";
mencoder "${SRCFILE}" -nosound -ovc raw -sws 9 -vf format=i420 -of rawvideo -o /tmp/"${STREAMV}" 2&>1 "${LOGFILE}.v1" & x264 --threads 2 --bitrate 800 --partitions all --direct spatial --direct-8x8 -1 --subme 7 --b-rdo --mixed-refs --8x8dct --trellis 2 --no-dct-decimate --nr 0 --weightb --me hex --merange 16 --scenecut 40 --bframes 3 --b-bias 0 --b-pyramid --ref 9 --no-fast-pskip --deblock 1:1 --qpmin 10 --qpmax 51 --qpstep 4 --keyint 250 --min-keyint 25 --ipratio 1.40 --pbratio 1.60 --pass 1 --stats "${ENCSTATS}" --sar 1:1 --no-psnr --fps "${FPS}" -o "${DSTVFILE}" /tmp/"${STREAMV}" "${RESX}"x"${RESY}" --progress &> "${LOGFILE}.v1b"
echo "First Pass done.";
echo "Second Pass...";
mencoder "${SRCFILE}" -nosound -ovc raw -sws 9 -vf format=i420 -of rawvideo -o /tmp/"${STREAMV}" 2&>1 "${LOGFILE}.v2" & x264 --threads 2 --bitrate 800 --partitions all --direct spatial --direct-8x8 -1 --subme 7 --b-rdo --mixed-refs --8x8dct --trellis 2 --no-dct-decimate --nr 0 --weightb --me hex --merange 16 --scenecut 40 --bframes 3 --b-bias 0 --b-pyramid --ref 9 --no-fast-pskip --deblock 1:1 --qpmin 10 --qpmax 51 --qpstep 4 --keyint 250 --min-keyint 25 --ipratio 1.40 --pbratio 1.60 --pass 2 --stats "${ENCSTATS}" --sar 1:1 --no-psnr --fps "${FPS}" -o "${DSTVFILE}" /tmp/"${STREAMV}" "${RESX}"x"${RESY}" --progress &> "${LOGFILE}.v2b"
echo "Second Pass done";
echo -en "Deleting pipe created before \e[1;34m/tmp/${STREAMV}\e[0m..";echo
rm /tmp/"${STREAMV}";
echo -en "Muxing \e[1;32mAAC\e[0m and \e[1;32mMP4\e[0m."
mp4creator -create=/tmp/"${DSTAFILE}" "${DSTVFILE}"
echo "Done."
echo
echo -en "Deleting temprary \e[1;32mAAC\e[0m"
rm /tmp/"${DSTAFILE}"
echo
echo -en "\e[1;31m$1\e[0m conversion completed."
echo


:stupid:
Audio/Video desync fixed
FPS and RES parameters fixed

Usage: DrEaMuX.sh VIDEO.AVI

TODO:
Add language tag
Silence faac and x264.

for batch encode:
#!/bin/bash
# Doom9's solutions :P
# DrEaMeR... Just Copy, Paste, and Use it
# DrEaMuX-dir v0.1

current_directory="$1"

for i in *.avi; do DrEaMuX.sh "$i"; done

Usage: DrEaMuX-dir.sh /avifiles/

DrEaMeR86
22nd February 2007, 12:35
arf.. I realised that it has audio/video desync, maybe framerate.
Trying to fix it..

EDIT: One solution, Use MP4Box..
MP4Box -add videoin.264 -add audioin.aac -fps fps out.mp4
We would need a new parameter, fps :S

Any idea?

nm
22nd February 2007, 12:54
Also I would like to get the resolution from somewhere. Actually, I should run the script with that "./enc-x264 FILE.avi 640 480" and I would like to get automatically the "640 480" from mplayer or whatever. Any idea?
Parse the output of mplayer -identify -frames 0 -vo null -ao null FILE (and even more information with the -v parameter). This will also give you the framerate.

But if you wan't to keep the source resolution, there is no need to read it. Just don't scale.

nm
22nd February 2007, 13:01
EDIT: One solution, Use MP4Box..
MP4Box -add videoin.264 -add audioin.aac -fps fps out.mp4
We would need a new parameter, fps :S
mp4creator should work as well (actually it works better for me with large files). Use parameter -rate=fps.

DrEaMeR86
22nd February 2007, 19:06
I forgot the "-rate=fps" :P, but I know it works too. I realised that it is not necessary because you can put it on the x264 command and finally add the aac to the video.mp4 created by x264.

DrEaMeR86
22nd February 2007, 20:04
Any idea how to silence when faac runs? I've tried > file, > /dev/null, `faac ....` > /dev/null. Theres is no way to do it :S.
x264 the same.:confused:

nm
22nd February 2007, 21:36
Try &> /dev/null, which redirects both stdout and stderr.

More redirection tips here: http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-3.html

hobart_george
20th March 2007, 10:05
Hi Dreamer86,

I was wondering if you had any new versions of this script you might be able to offer?

I'm looking to write a script to do almost exactly the same thing but in batch for all the files in a folder.

Other than the obvious for loop i would need i was looking to change 2 other key points in your script.
1. Use x264's quantizer (-crt or something i think) so i don't have to specify a bit rate (as all the files are different resolutions/quality to start with).
2. Maybe use ffmpeg so i don't have to demux then mux them back together...

Would really appreciate any base you've got to offer!:thanks:

DrEaMeR86
20th March 2007, 13:11
arf, I added the script to encide in batch. You should have both scripts in the same folder. I have them in /usr/local/bin/, and I do: cd $HOME/avifile/; DrEaMuX-dir ./; Each script I run, I do it in background, you know (with &) or, Ctrl + z; bg;
Your first point souns interesting. I will look for that option.
If you don't want to demux an mux them back, maybe, if you just need video compressed in x264, you could try mencoder with its builtin x264 encoder. You will get an avi. ffmpeg could be a good idea, this afternoon I will do some tests. Any suggestions, post, please.

hobart_george
21st March 2007, 02:06
So far as i've read, it's not ideal to do two passes both using quantization, only the first. but what was suggested was using one pass as -crf then finding the average bitrate from that pass and using it as the set bitrate for the second pass if you know what i mean...?

DrEaMeR86
22nd March 2007, 13:47
Yes, I understand what you say but I'm not an expert :P.
Im trying to get a bitrate from a mp4 and it's not possible,
"ID_VIDEO_BITRATE=0". I can't help you in that. If you have some news, posts here :)