shellscripts:encode

Encodieren mit mplayer

Das Shellscript bietet eine menugeführte Auswahl der Zielcodes an (divx-kompatibel+mp3 bzw. ogg theora und ogg audio) und schreibt dann die (neu)kodierte Datei an den gewünschten Zielort.

Als Vorraussetzung wird bc bzw. xdialog benötigt sowie die entsprechenden Codecs. Die Lizensierung ist unter der GPL.

Die Theorakompression funktioniert nicht aus allen Formaten heraus (mpeg2 funzt z.B. nicht).

#!/bin/bash
 
#part of the Mutils by Paul Hänsch
#to be ditributed under the terms of the GPL v.2 and any later version
 
frontend=Xdialog
terminal="xterm -e "
 
mb=2		#makroblock decision algorythm
keys=30		#keyframe interval
thresh=0	#scenechange threshold (-1000000=every frame is a keyframe; 1000000=no keyframes out of interval)
 
#if more than one file is opened at once in konqueror, one instance of the script 
#will be opened for every file - this if-else stuff passes all files to the first
#instance of the script (using the fifo "/tmp/encode.list")
if [ -e /tmp/encode.list ]; then
 echo \#$1 >>/tmp/encode.list
 exit 0
else
 mkfifo /tmp/encode.list
 echo \#$1 >>/tmp/encode.list &
 sleep 3
 files=`cat /tmp/encode.list`
 rm /tmp/encode.list
 
 #I cannot control in which order the files are given, that's why I sort them
 files=`echo $files |sed '/#/s//\n#/g'|sort`
 #The filenames must be translated into a format which mplayer understands
 #I also try to translate the damn kde-media:-protocol path but that's very
 #simple yet and may not work on your system
 files=`echo $files |sed '/media:\/hdc/s//\/mnt\/cdrom/g;/-/s//\\-/g;/ #/s//#/g;/ /s//\\ /g'`
 
 #now we are going to ask some questiones
 #the file /tmp/querrys catches the output of dialog
 $frontend --radiolist "Ausgabeformat:" 0 0 0 "avi" "Video: DivX5-kompatibel; Audio: mp3" on "OGM" "Video: Ogg Theora      ; Audio: Ogg Vorbis" off 2>/tmp/querrys
 if [ $? == 1 ];then
  rm /tmp/querrys
  exit 0
 fi
 format=`cat /tmp/querrys`
 
 $frontend --inputbox "Videobitrate:" 0 0 800 2>/tmp/querrys
 if [ $? == 1 ];then
  rm /tmp/querrys
  exit 0
 fi
 vrate=`cat /tmp/querrys`
 
 $frontend --inputbox "Audiobitrate:" 0 0 128 2>/tmp/querrys
 if [ $? == 1 ];then
  rm /tmp/querrys
  exit 0
 fi
 arate=`cat /tmp/querrys`
 
 text="Ich kann das Videobild an den Rändern zurecht schneiden um z.B.\n
schwarze Streifen los zu werden. Geben Sie hier die Schnitt-\n
koordinaten in der Form\n\n
breite:höhe:x:y\n\n
an, wobei x und y die Abstände zu den Rändern sind. Sie können\n
x und y auch weglassen um den Bildausschnitt zu zentrieren."
 stat=3
 crop="breite:höhe:x:y"
 while [ $stat == 3 ]; do
  if [ $frontend == dialog ]; then
   $frontend --extra-button --extra-label "Testen" --inputbox "$text" 0 0 "$crop" 2>/tmp/querrys
   stat=$?
  else
   $frontend --check "erst testen" on --inputbox "$text" 0 0 "$crop" 2>/tmp/querrys
   stat=$?
   grep "unchecked" /tmp/querrys || stat=3
  fi
  crop=`grep ":" /tmp/querrys`
  if [ $stat == 3 ]; then
   mplayer "`echo $files |cut -d "#" -f2`" -vf rectangle=$crop
  fi
  if [ $stat == 1 ];then
   rm /tmp/querrys
   exit 0
  fi
 done
 #refomatting crop-data for use with ffmpeg2theora
  #get data
  mplayer "`echo $files |cut -d "#" -f2`" -vo null -ao null -frames 1 -identify 2>/tmp/querrys
  vw=`cat /tmp/querrys |grep "ID_VIDEO_WIDTH=" |cut -d "=" -f2`
  vh=`cat /tmp/querrys |grep "ID_VIDEO_HEIGHT=" |cut -d "=" -f2`
  cw=`echo $crop |cut -d ":" -f1`
  if [ -z $cw ]; then 
   cw=$vw
  fi
  ch=`echo $crop |cut -d ":" -f2`
  if [ -z $ch ]; then
   ch=$vh
  fi
  cx=`echo $crop |cut -d ":" -f3`
  cy=`echo $crop |cut -d ":" -f4`
  #calculate params
  if [ -z $cx ]; then
   cl=`expr \( $vw - $cw \) / 2`
   cr=$cl
  else
   cl=$cx
   cr=`$vw - \( $cx + $cw \)`
  fi
  if [ -z $cy ]; then
   ct=`expr \( $vh - $ch \) / 2`
   cb=$ct
  else
   ct=$cy
   cb=`$vh - \( $cy + $ch \)`
  fi
  cropTH=`echo "--croptop $ct --cropleft $cl --cropbottom $cb --cropright $cr"`
 
 #calculate scale of image
 width=`echo $crop |cut -d ":" -f1`
 height=`echo $crop |cut -d ":" -f2`
 echo "scale=6" >/tmp/querrys
 echo "sqrt( 128000 / ( $width * $height ) )" >>/tmp/querrys
 echo "quit" >>/tmp/querrys
 scale=`bc -q /tmp/querrys`
 width=`echo "$scale * $width" |bc |cut -d "." -f1`
 height=`echo "$scale * $height" |bc |cut -d "." -f1`
 scale=`echo "$width:$height"`
 
 text="Üblicherweise wird das Video für die Kompression auf ein\n
geignetes Größenverhältnis skaliert. Erfahrungsgemäß ist,\n
unabhängig vom Seitenverhältnis des Videos, eine Fläche von\n
etwa 128.000 Pixeln empfehlenswert. Ich habe die entsprechenden\n
Abmessungen unter Beibehaltung des Seitenverhältnisses\n
errechnet. Sie können jedoch eigene Abmessungen in der Form\n\n
breite:höhe\n\n
eingeben."
 $frontend --inputbox "$text" 0 0 "$scale" 2>/tmp/querrys
 if [ $? == 1 ];then
  rm /tmp/querrys
  exit 0
 fi
 scale=`cat /tmp/querrys`
 vf=`echo "crop=$crop,scale=$scale"`
 
 #reformatting sclae params for ffmpeg2theora
 width=`echo $scale |cut -d ":" -f1`
 height=`echo $scale |cut -d ":" -f2`
 
 text="Geben Sie im folgenden Dialog den Zielpfad mit dem Präfix des\n
Dateinamens ein. Da Ich die Zieldateien durchnummeriere,\n
wird nur der Anfang des Dateinamens benötigt.\n
Das Benennungsschema ist:\n\n
[Pfad][Präfix]-{nummer}.$format\n\n
Geben sie nur den Teil an, der oben in eckigen Klammern steht."
 $frontend --msgbox "$text" 0 0
 
 prefix=~/
 while [ -d $prefix ]; do
  $frontend --fselect "$prefix" 15 70 2>/tmp/querrys
  if [ $? == 1 ];then
   rm /tmp/querrys
   exit 0
  fi
  prefix=`cat /tmp/querrys`
 done
 
 text="Die Folgenden Dateien werden Komprimiert:`echo $files |sed '/#/s//\n/g' |cat`\n\n
Die Zieldateien sind:
$prefix-{nummer}.$format\n\n
Videobitrate: $vrate kbps
Audiobitrate: $arate kbps\n\n
Skalierungsoptionen:
$vf\n\n
Es wird empfohlen die Kompression mit gesenkter Priorität
auszuführen um das System nicht gänzlich zu blockieren\n\n
Priorität       (0=normal, 20=geringste,
negative Prioritäten nur für Superuser):"
 
 $frontend --cr-wrap --ok-label " Hey, ho, let's go! " --inputbox "$text" 0 0 "5" 2>/tmp/querrys
 if [ $? == 1 ];then
  rm /tmp/querrys
  exit 0
 fi
 prio=`cat /tmp/querrys`
 
 
 result=0
 n=2
 while [ ! -z "`echo $files |cut -d "#" -f$n`" ]; do
  infile=`echo $files |cut -d "#" -f$n`
  outfile="$prefix-`expr $n - 1`.$format"
  if [ $format == "avi" ]; then
   $terminal nice -n $prio mencoder "$infile" -o $outfile -vf $vf -ffourcc dx50 -oac mp3lame -lameopts mode=1:vbr=0:aq=0:br=$arate -ovc lavc -lavcopts vcodec=mpeg4:vme=5:mbd=$mb:vbitrate=$vrate:keyint=$keys:sc_threshold=$thresh:v4mv:vb_strategy=1:autoaspect:preme=2:dia=2
   result=`expr $result + $?`
  else
   $terminal nice -n $prio ffmpeg2theora -o '$outfile' -V $vrate -v 10 $cropTH -x $width -y $height --optimize -S 1 -K 30 -A $arate "$infile"
   result=`expr $result + $?`
  fi
  n=`expr $n + 1`
 done
 
 if [ $result == 0 ]; then
  $frontend --ok-label " Dankeschön " --msgbox "    Kompression(en) erfolgreich abgeschlossen.  " 6 53
 else
  $frontend --ok-label " Tja! " --msgbox "Irgendwas ging schief.\n - sorry -" 0 0
 fi
fi