mikeym
6th August 2006, 16:35
Hi,
To begin with I will just explain that I am not verry experienced with this type of video conversion so I am mostly interested I getting good results that work. :)
I am trying to write a linux bash script for mencoder to convert files into x264 video and OGG audio and put them into a MKV container. This file format just happens to be the way I have tried from a forum post and I was pleased with the result. Here is the post (http://lists.mplayerhq.hu/pipermail/mencoder-users/2006-May/003316.html).
I am working on a linux only system so I have choosen mencoder - the only choise as far as I can tell.
With your knowledge of audio / video / containers is this a scensible way to be encoding x264 video?
Do you have any better suggestions?
The encoding options I have given it are a bit on the slow side 72+ hours. (my machine is fairly low spec) is there somewhere I can find out about good parameters options to pass to mencoder for different quality / speed combinations.
In the post it gives the frame rate to mp4box as 23.976025 but 24000 / 1001 is 23.976024 rounded to the nearest and 23.976023 truncated to 6 places - do you know why the slightly higher figgure was given and would it cause any problems using the "correct" figgure as the film went on? (I have used the "correct" figgure truncated to 9 decimal places in my script.)
Also as it stands when I encode and select to rip subtitles the .sub files are comming out at 0 bytes. They would be ripped OK normally this way that is happening with x264?
Here is the script: (as I said it's more about getting something that works than being pretty)
#!/bin/sh
echo "PASS THIS AS A PARAMETER FOR TESTING \"-dvd-device /media/dvdimage -frames 1000\""
echo "***********************************************************"
echo " TITLE SELECT "
echo "***********************************************************"
echo "* Pick DVD Title number"
read TITLE
echo
echo "***********************************************************"
echo " TESTING VIDEO SOURCE (will take a few seconds) "
echo "***********************************************************"
DVDSOURCE="dvd://$TITLE $1"
# Play DVD for 1000 frames and capture the output so we can get the
# settings for it.
mplayer $DVDSOURCE -frames 1000 -nosound -vo null -vf cropdetect -benchmark -identify > Out.log 2>> /dev/null
# Do it by frames rather than time.
# mplayercommand &
# MPPID=$!
# echo "Process $MPPID"
# sleep 30s
# kill -9 $MPPID >> /dev/null 2>> /dev/null
echo "***********************************************************"
echo " ENCODING OPTIONS "
echo "***********************************************************"
echo "* Enter base filename"
read FILENAME
echo
echo "* Pick Number of files"
read NUMFILES
echo
echo "* Pick the size of each file in MB"
read FILESIZE
echo
# Convert into KB from MB
FILESIZE=$(( FILESIZE*1024 ))
echo "* Choose Audio language"
cat Out.log | awk ' BEGIN { FS = "=" } /^ID_AID_/ { print $2 } ' | nl
echo
read AIDLINE
AID=`cat Out.log | grep "^ID_AID_" | sed -n -e "${AIDLINE}p" | cut -c 8-10`
echo "* Choose Subtitle language"
# cat Out.log | grep "\(^ID_AID_\)\([[:digit:]]\+\)\(_LANG=\)\([[:alpha:]]\+\)" | sed "s/\(^ID_AID_\)\([[:digit:]]\+\)\(_LANG=\)\([[:alpha:]]\+\)/\2/"
cat Out.log | awk ' BEGIN { FS = "=" } /^ID_SID_/ { print $2 } ' | nl
echo
read SIDLINE
SID=`cat Out.log | grep "^ID_SUBTITLE_ID=" | sed -n -e "${SIDLINE}p" | cut -c 16`
# CALCULATE GENERAL OPTIONS
TOTALLENGTH=`cat Out.log | sed "s/\.[[:digit:]]\+$//" | awk ' BEGIN { FS = "=" } /^ID_DVD_TITLE_'$TITLE'_LENGTH/ { print $2 } '`
LENGTH=$((TOTALLENGTH/NUMFILES))
TOTALCHAPTERS=`cat Out.log | awk ' BEGIN { FS = "=" } /^ID_DVD_TITLE_'$TITLE'_CHAPTERS/ { print $2 } '`
CROPPING=`cat Out.log | awk ' BEGIN { FS = "=" } /-vf crop=/ { print $2 } ' | sed "s/)\.$//" | tail -n 1`
FRAMERATE=`cat Out.log | grep "demux_mpg: " | sed -e "s/[[:alpha:]]*//g" -e "s/,*//g" -e "s/\.*//g" -e "s/:*//g" -e "s/_*//g" -e "s/ *//g"`
FS=""
if [ `echo -e "$FRAMERATE" | wc -l` -gt 1 ]; then
echo "May be mixed progressive / teleclined or interlaced"
fi
FS="
"
FPFRAMERATE=`echo "scale=9; $FRAMERATE" | bc`
FILECOUNT=0
LASTCHAPTER=0
CHAPTERS=0
while [ $FILECOUNT -lt $NUMFILES ]
do
FILECOUNT=$(($FILECOUNT+1))
LASTCHAPTER=$((CHAPTERS+1))
echo "***********************************************************"
echo " FILE $FILECOUNT"
echo "***********************************************************"
MODIFIER=$(( TOTALCHAPTERS % NUMFILES ))
if [ $FILECOUNT -eq $NUMFILES ]; then
MODIFIER=$(( -1 * MODIFIER ))
fi
CHAPTERS=$(( (TOTALCHAPTERS + MODIFIER)/NUMFILES ))
VIDEOSOURCE="$DVDSOURCE -chapter $LASTCHAPTER-$((LASTCHAPTER+CHAPTERS-1))"
DEST=$FILENAME-$FILECOUNT
echo $VIDEOSOURCE
echo "* Encoding audio"
# DUMP AUDIO TO WAV
mplayer $VIDEOSOURCE -vo null -aid $AID -ao pcm:file="audio.wav" >> /dev/null 2>> /dev/null
# ENCODE WAV TO OGG
oggenc -q8 audio.wav >> /dev/null 2>> /dev/null
# CALCULATE BITRATE
AUDIOBYTES=`ls -l audio.ogg | awk ' BEGIN { FS = " " } { print $5 } '`
AUDIOKB=$(($AUDIOBYTES/1024))
RATE=$(( (FILESIZE - AUDIOKB)/LENGTH * 8 ))
echo "*******************************"
echo " RESULTS "
echo
echo "Bit Rate: ${RATE}Kbps"
echo "Audio Size: ${AUDIOKB}KB"
echo "Chapters: ${CHAPTERS} / ${TOTALCHAPTERS}"
echo "Length: ${LENGTH}s / ${TOTALLENGTH}s"
echo "File Size: ${FILESIZE}KB"
echo "Number Of Files: ${NUMFILES}"
echo "Audio ID: ${AID}"
echo "Subtitle ID: ${SID}"
echo "Frame Rate: ${FRAMERATE} fps"
echo "Floating Point Frame Rate: ${FPFRAMERATE} fps"
echo "Cropping: ${CROPPING}"
if [ $FILECOUNT -eq 1 ]; then
echo "***Press the enter key to begin encoding"
read RUBBISH
fi
# PASS 1
echo "* Encoding pass 1"
MENC="mencoder $VIDEOSOURCE -sid $SID -vobsubout \"$DEST\" -vf pullup,softskip,crop=$CROPPING -nosound -ovc x264 -x264encopts bitrate=$RATE:subq=4:bframes=3:b_pyramid:weight_b:turbo=1:pass=1 -ofps $FRAMERATE -of rawvideo -o video.264"
echo "$MENC"
$MENC
# PASS 2
echo "* Encoding pass 2"
MENC="mencoder $VIDEOSOURCE -sid $SID -vobsubout \"$DEST\" -vf pullup,softskip,crop=$CROPPING -nosound -ovc x264 -x264encopts bitrate=$RATE:subq=6:frameref=6:4x4mv:8x8dct:me=3:bframes=3:b_pyramid:weight_b:pass=2 -ofps $FRAMERATE -of rawvideo -o video.264"
echo "$MENC"
$MENC
# VIDEO TO MP4 FORMAT -fps 23.976025
MP4B="mp4box -fps $FPFRAMERATE -add video.264 rip.mp4"
echo "$MP4B"
$MP4B
# STICK TOGETHER IN MATROSKA FILE
MKVM="mkvmerge -o \"$DEST.mkv\" audio.ogg rip.mp4"
echo "$MKVM"
$MKVM
# CLEANUP
# unlink video.264
# unlink audio.wav
# unlink audio.ogg
# unlink rip.mp4
# Keep these just now for testing
done
# THE END
To begin with I will just explain that I am not verry experienced with this type of video conversion so I am mostly interested I getting good results that work. :)
I am trying to write a linux bash script for mencoder to convert files into x264 video and OGG audio and put them into a MKV container. This file format just happens to be the way I have tried from a forum post and I was pleased with the result. Here is the post (http://lists.mplayerhq.hu/pipermail/mencoder-users/2006-May/003316.html).
I am working on a linux only system so I have choosen mencoder - the only choise as far as I can tell.
With your knowledge of audio / video / containers is this a scensible way to be encoding x264 video?
Do you have any better suggestions?
The encoding options I have given it are a bit on the slow side 72+ hours. (my machine is fairly low spec) is there somewhere I can find out about good parameters options to pass to mencoder for different quality / speed combinations.
In the post it gives the frame rate to mp4box as 23.976025 but 24000 / 1001 is 23.976024 rounded to the nearest and 23.976023 truncated to 6 places - do you know why the slightly higher figgure was given and would it cause any problems using the "correct" figgure as the film went on? (I have used the "correct" figgure truncated to 9 decimal places in my script.)
Also as it stands when I encode and select to rip subtitles the .sub files are comming out at 0 bytes. They would be ripped OK normally this way that is happening with x264?
Here is the script: (as I said it's more about getting something that works than being pretty)
#!/bin/sh
echo "PASS THIS AS A PARAMETER FOR TESTING \"-dvd-device /media/dvdimage -frames 1000\""
echo "***********************************************************"
echo " TITLE SELECT "
echo "***********************************************************"
echo "* Pick DVD Title number"
read TITLE
echo
echo "***********************************************************"
echo " TESTING VIDEO SOURCE (will take a few seconds) "
echo "***********************************************************"
DVDSOURCE="dvd://$TITLE $1"
# Play DVD for 1000 frames and capture the output so we can get the
# settings for it.
mplayer $DVDSOURCE -frames 1000 -nosound -vo null -vf cropdetect -benchmark -identify > Out.log 2>> /dev/null
# Do it by frames rather than time.
# mplayercommand &
# MPPID=$!
# echo "Process $MPPID"
# sleep 30s
# kill -9 $MPPID >> /dev/null 2>> /dev/null
echo "***********************************************************"
echo " ENCODING OPTIONS "
echo "***********************************************************"
echo "* Enter base filename"
read FILENAME
echo
echo "* Pick Number of files"
read NUMFILES
echo
echo "* Pick the size of each file in MB"
read FILESIZE
echo
# Convert into KB from MB
FILESIZE=$(( FILESIZE*1024 ))
echo "* Choose Audio language"
cat Out.log | awk ' BEGIN { FS = "=" } /^ID_AID_/ { print $2 } ' | nl
echo
read AIDLINE
AID=`cat Out.log | grep "^ID_AID_" | sed -n -e "${AIDLINE}p" | cut -c 8-10`
echo "* Choose Subtitle language"
# cat Out.log | grep "\(^ID_AID_\)\([[:digit:]]\+\)\(_LANG=\)\([[:alpha:]]\+\)" | sed "s/\(^ID_AID_\)\([[:digit:]]\+\)\(_LANG=\)\([[:alpha:]]\+\)/\2/"
cat Out.log | awk ' BEGIN { FS = "=" } /^ID_SID_/ { print $2 } ' | nl
echo
read SIDLINE
SID=`cat Out.log | grep "^ID_SUBTITLE_ID=" | sed -n -e "${SIDLINE}p" | cut -c 16`
# CALCULATE GENERAL OPTIONS
TOTALLENGTH=`cat Out.log | sed "s/\.[[:digit:]]\+$//" | awk ' BEGIN { FS = "=" } /^ID_DVD_TITLE_'$TITLE'_LENGTH/ { print $2 } '`
LENGTH=$((TOTALLENGTH/NUMFILES))
TOTALCHAPTERS=`cat Out.log | awk ' BEGIN { FS = "=" } /^ID_DVD_TITLE_'$TITLE'_CHAPTERS/ { print $2 } '`
CROPPING=`cat Out.log | awk ' BEGIN { FS = "=" } /-vf crop=/ { print $2 } ' | sed "s/)\.$//" | tail -n 1`
FRAMERATE=`cat Out.log | grep "demux_mpg: " | sed -e "s/[[:alpha:]]*//g" -e "s/,*//g" -e "s/\.*//g" -e "s/:*//g" -e "s/_*//g" -e "s/ *//g"`
FS=""
if [ `echo -e "$FRAMERATE" | wc -l` -gt 1 ]; then
echo "May be mixed progressive / teleclined or interlaced"
fi
FS="
"
FPFRAMERATE=`echo "scale=9; $FRAMERATE" | bc`
FILECOUNT=0
LASTCHAPTER=0
CHAPTERS=0
while [ $FILECOUNT -lt $NUMFILES ]
do
FILECOUNT=$(($FILECOUNT+1))
LASTCHAPTER=$((CHAPTERS+1))
echo "***********************************************************"
echo " FILE $FILECOUNT"
echo "***********************************************************"
MODIFIER=$(( TOTALCHAPTERS % NUMFILES ))
if [ $FILECOUNT -eq $NUMFILES ]; then
MODIFIER=$(( -1 * MODIFIER ))
fi
CHAPTERS=$(( (TOTALCHAPTERS + MODIFIER)/NUMFILES ))
VIDEOSOURCE="$DVDSOURCE -chapter $LASTCHAPTER-$((LASTCHAPTER+CHAPTERS-1))"
DEST=$FILENAME-$FILECOUNT
echo $VIDEOSOURCE
echo "* Encoding audio"
# DUMP AUDIO TO WAV
mplayer $VIDEOSOURCE -vo null -aid $AID -ao pcm:file="audio.wav" >> /dev/null 2>> /dev/null
# ENCODE WAV TO OGG
oggenc -q8 audio.wav >> /dev/null 2>> /dev/null
# CALCULATE BITRATE
AUDIOBYTES=`ls -l audio.ogg | awk ' BEGIN { FS = " " } { print $5 } '`
AUDIOKB=$(($AUDIOBYTES/1024))
RATE=$(( (FILESIZE - AUDIOKB)/LENGTH * 8 ))
echo "*******************************"
echo " RESULTS "
echo
echo "Bit Rate: ${RATE}Kbps"
echo "Audio Size: ${AUDIOKB}KB"
echo "Chapters: ${CHAPTERS} / ${TOTALCHAPTERS}"
echo "Length: ${LENGTH}s / ${TOTALLENGTH}s"
echo "File Size: ${FILESIZE}KB"
echo "Number Of Files: ${NUMFILES}"
echo "Audio ID: ${AID}"
echo "Subtitle ID: ${SID}"
echo "Frame Rate: ${FRAMERATE} fps"
echo "Floating Point Frame Rate: ${FPFRAMERATE} fps"
echo "Cropping: ${CROPPING}"
if [ $FILECOUNT -eq 1 ]; then
echo "***Press the enter key to begin encoding"
read RUBBISH
fi
# PASS 1
echo "* Encoding pass 1"
MENC="mencoder $VIDEOSOURCE -sid $SID -vobsubout \"$DEST\" -vf pullup,softskip,crop=$CROPPING -nosound -ovc x264 -x264encopts bitrate=$RATE:subq=4:bframes=3:b_pyramid:weight_b:turbo=1:pass=1 -ofps $FRAMERATE -of rawvideo -o video.264"
echo "$MENC"
$MENC
# PASS 2
echo "* Encoding pass 2"
MENC="mencoder $VIDEOSOURCE -sid $SID -vobsubout \"$DEST\" -vf pullup,softskip,crop=$CROPPING -nosound -ovc x264 -x264encopts bitrate=$RATE:subq=6:frameref=6:4x4mv:8x8dct:me=3:bframes=3:b_pyramid:weight_b:pass=2 -ofps $FRAMERATE -of rawvideo -o video.264"
echo "$MENC"
$MENC
# VIDEO TO MP4 FORMAT -fps 23.976025
MP4B="mp4box -fps $FPFRAMERATE -add video.264 rip.mp4"
echo "$MP4B"
$MP4B
# STICK TOGETHER IN MATROSKA FILE
MKVM="mkvmerge -o \"$DEST.mkv\" audio.ogg rip.mp4"
echo "$MKVM"
$MKVM
# CLEANUP
# unlink video.264
# unlink audio.wav
# unlink audio.ogg
# unlink rip.mp4
# Keep these just now for testing
done
# THE END