Dvb wiki script/Programmieranleitung: Unterschied zwischen den Versionen

Aus Linupedia.org
Wechseln zu: Navigation, Suche
(Korrekturlesen und Layout)
(Korrekturlesen bis 7.10.4)
Zeile 183: Zeile 183:
 
  exit
 
  exit
 
Wenn im Dialogfenster auf den Button Abbrechen gedrückt wurde, wird das Script beendet.
 
Wenn im Dialogfenster auf den Button Abbrechen gedrückt wurde, wird das Script beendet.
 
<font color="red"> Bearbeitungsmarkierung </font>
 
  
 
===<font color="olive"> verzeichnisauswahl() </font>===
 
===<font color="olive"> verzeichnisauswahl() </font>===
 
+
verzeichnis=`kdialog --caption "Verzeichnisauswahl" --geometry 500x500-0+0 --getexistingdirectory ${sicherungs_pfad}`
Hier gilt das bei der Funktion "filmauswahl ()" gesagte. Der Unterschied besteht darin, daß nicht eine Liste von Dateien, sondern eine Liste von Ordnern zur
+
*'''kdialog''': Das KDE-Dialog-Programm
Auswahl gestellt wird. Diese Ordner befinden sich im Verzeichnis $sicherungs_pfad.
+
*'''--caption "Verzeichnisauswahl"''': öffnet ein Fenster, das den Namen "Verzeichnisauswahl" trägt
 +
*'''--geometry 500x500-0+0''': und diese Größe und Position hat
 +
*'''--getexistingdirectory''': Es wird ein KDE-Fenster geöffnet, in dem aus einer Liste von Verzeichnissen ausgewählt werden kann
 +
*'''${sicherungs_pfad}''': Es werden die Verzeichnisse in diesem Pfad zur Auswahl angeboten.
 +
*'''verzeichnis=`...`''': Die ausgewählte Datei wird in die Variable $verzeichnis geschrieben.
 +
if [ $? != 0 ]
 +
then
 +
exit
 +
Wenn im Dialogfenster auf den Button Abbrechen gedrückt wurde, wird das Script beendet.
  
 
===<font color="olive"> pjx_demux_gui () </font>===
 
===<font color="olive"> pjx_demux_gui () </font>===
 
+
java -jar ${pjx} -demux -gui  -ini ${default_pfad}/X.ini.film -out ${tmp_pfad} -name film "$quelldatei" 1>/dev/null
Das Programm ProjectX wird aufgerufen mit folgenden Einstellungen:
+
*'''java -jar''': Es wird ein Java-Programm gestartet
 
+
*'''${pjx}''': und zwar das Programm ProjectX (z.B.: ~/ProjectX/ProjectX.jar)
 
*'''-demux''': Der mpeg-Stream wird demultiplext
 
*'''-demux''': Der mpeg-Stream wird demultiplext
 
*'''-gui''': PJX startet mit graphischer oberfläche (notwendig nur, wenn mit PJX geschnitten werden soll)
 
*'''-gui''': PJX startet mit graphischer oberfläche (notwendig nur, wenn mit PJX geschnitten werden soll)
Zeile 204: Zeile 210:
  
 
===<font color="olive"> pjx_ts_gui () </font>===
 
===<font color="olive"> pjx_ts_gui () </font>===
 
+
java -jar ${pjx} -tots -gui -split 4300 -ini ${default_pfad}/X.ini.film -out ${tmp_pfad} -name film "$quelldatei" 1>/dev/null
Es gilt das oben Gesagte mit folgenden Änderungen:
+
*'''java -jar''': Es wird ein Java-Programm gestartet
 
+
*'''${pjx}''': und zwar das Programm ProjectX (z.B.: ~/ProjectX/ProjectX.jar)
*'''-tots''': Der Film wird nicht demultiplext, sondern als TS-File gewandelt
+
*'''-tots''': Der Film wird zum TS-File gewandelt
 +
*'''-gui''': PJX startet mit graphischer oberfläche (notwendig nur, wenn mit PJX geschnitten werden soll)
 
*'''-split 4300''': Bei 4300 Mbyte wird die Aufnahme gesplittet (mehr passt nicht auf eine DVD drauf)
 
*'''-split 4300''': Bei 4300 Mbyte wird die Aufnahme gesplittet (mehr passt nicht auf eine DVD drauf)
 +
*'''-ini ${default_pfad]/X.ini.film''': mit dieser Initialisierungsdatei wird PJX gestartet.
 +
*'''-out $tmp_pfad''': Hierhin wird das Bearbeitungsergebnis geschrieben
 +
*'''-name film''': Die Ausgabedatei erhält den Basisnamen "film"
 +
*'''$quelldatei''':Dieser Stream wird verarbeitet
 +
*'''1>/dev/null''': Alles, was ich an Ausgeben auf dem Bildschirm nicht sehen will, wird ins Leere geschickt.
  
 
===<font color="olive"> pjx_clip () </font>===
 
===<font color="olive"> pjx_clip () </font>===
 
+
java -jar ${pjx} -demux -gui  -ini ${default_pfad}/X.ini.clip -out ${tmp_pfad} -name film "$quelldatei" 1>/dev/null
*'''-ini''': Als Initialisierungsdatei wird X.ini.clip verwendet, in der festgelegt wird, daß das mpg-audio zu einer wav-Datei decodiert wird.
+
*'''-ini ${default_pfad]/X.ini.clip''': mit dieser Initialisierungsdatei wird PJX gestartet. In ihr festgelegt wird, daß das mpg-audio zu einer wav-Datei decodiert wird.
 +
Alle anderen Optionen wie bei "pjx_demux_gui ()"
  
 
===<font color="olive"> mpeg1_input () </font>===
 
===<font color="olive"> mpeg1_input () </font>===
 
+
${ffmpeg} -i "${quelldatei}" ${tmp_pfad}/film.mp2.wav -vcodec copy ${tmp_pfad}/film.m1v
Ein mpeg1-Video wird mit Hilfe von "ffmpeg" demultiplext. Dabei wird der Ton zu .wav decodiert. Die Optionen des Befehls im einzelnen:
+
*'''${ffmpeg}''': Aufruf von ffmpeg (z.B.: /usr/bin/ffmpeg),
 
+
*'''-i ${quelldatei}''': um diesen Video-Clip zu verarbeiten
*'''-i ${quelldatei}''': Dieser mpeg1-Viedeo-Clip wird verarbeitet
+
*'''${tmp_pfad}/film.mp2.wav''': Der Ton des Clips wird decodiert zu einem wav-file.
*'''${tmp_pfad}/film.mp2.wav''': In diese Datei wird der Ton decodiert (als .wav-File)
+
*'''-vcodec copy''': Das Videofile wird nicht verändert, sondern nur demultiplext
*'''-vcodec copy''': Das Videofile wird nicht verändert.
+
*'''${tmp_pfad}/film.m1v''': und ist dann hier zu finden
*'''${tmp_pfad}/film.m1v''': Hier ist dann das demultiplexte Videofile zu finden
 
  
 
===<font color="olive"> requantisieren () </font>===
 
===<font color="olive"> requantisieren () </font>===
Zeile 230: Zeile 242:
  
 
Der Sinn dessen, was wir hier tun, ist es, einen Film so zu stauchen, daß er auf eine einzelne DVD passt. Dieses Stauchen wollen wir, etwas eleganter,
 
Der Sinn dessen, was wir hier tun, ist es, einen Film so zu stauchen, daß er auf eine einzelne DVD passt. Dieses Stauchen wollen wir, etwas eleganter,
Requantisieren nennen. Und den "Stauchfaktor", also um wieviel mal das Ausgangsmaterial kleiner gemacht werden soll, bekommt von uns den Namen
+
Requantisieren nennen. Und der "Stauchfaktor", also um wieviel mal das Ausgangsmaterial kleiner gemacht werden soll, bekommt von uns den Namen
 
"Requantisierungsfaktor".
 
"Requantisierungsfaktor".
  
Es macht natürlich wenig Sinn, ein Audiofile verkleinern zu wollen. Das Viedofile mit seinen etlichen GByte's Größe bietet hier mehr Aussicht auf Erfolg. Also
+
Es macht wenig Sinn, ein Audiofile verkleinern zu wollen. Ein Videofile mit seinen etlichen GByte Größe bietet hier mehr Aussicht auf Erfolg.
werden wir nur das Videofile requantisieren.
 
  
 
Die Formel, nach der wir den Requantisierungsfaktor berechnen, lautet so:
 
Die Formel, nach der wir den Requantisierungsfaktor berechnen, lautet so:
Zeile 250: Zeile 261:
 
*'''-c''': Erzeugen einer Gesamtsumme (-b und -c sind zusammen gefasst nach -bc. dieses bc ist allerdings nicht identisch mit dem oben angepriesenen gleichnamigen Tachenrechner. Der kommt nachher noch)
 
*'''-c''': Erzeugen einer Gesamtsumme (-b und -c sind zusammen gefasst nach -bc. dieses bc ist allerdings nicht identisch mit dem oben angepriesenen gleichnamigen Tachenrechner. Der kommt nachher noch)
 
*'''${tmp_pfad}/*.m2v''': Alle Dateien im tmp_pfad, deren Name auf .m2v endet, gehen in die Größenermittlung ein.
 
*'''${tmp_pfad}/*.m2v''': Alle Dateien im tmp_pfad, deren Name auf .m2v endet, gehen in die Größenermittlung ein.
 
 
*'''tail -n 1''': Nur die letzte Zeile dessen, was "du" ausgeben will, wird auch tatsächlich ausgegeben (nämlich unsere Gesamtgrösse)
 
*'''tail -n 1''': Nur die letzte Zeile dessen, was "du" ausgeben will, wird auch tatsächlich ausgegeben (nämlich unsere Gesamtgrösse)
 
*'''cut -f1''': Von dieser letzten Zeile wird nur das erste Feld ausgegeben, also die reine Zahl
 
*'''cut -f1''': Von dieser letzten Zeile wird nur das erste Feld ausgegeben, also die reine Zahl
 +
*'''videogroesse=`....`''': Diese Groesse wird in die Variable $videogroesse geschrieben
  
 
====audiosumme====
 
====audiosumme====
 
  audio_summe=`du -bc ${tmp_pfad}/*.ac3 ${tmp_pfad}/*.mp2 | cut -f1 | tail -n 1`
 
  audio_summe=`du -bc ${tmp_pfad}/*.ac3 ${tmp_pfad}/*.mp2 | cut -f1 | tail -n 1`
Im Prinzip das gleiche wie oben, nur daß nun von allen Audiofiles die Grösse bestimmt wird (*.ac3 *.mp2). Das Ergebnis ist die Gesamtsumme der Audiofiles, wieder als bloße Zahl.
+
*'''du''': Bashprogramm, welches den Platzverbrauch von Dateien schätzt
 +
*'''-b''': Ausgabe der Größe in Bytes
 +
*'''-c''': Erzeugen einer Gesamtsumme (-b und -c sind zusammen gefasst nach -bc. dieses bc ist allerdings nicht identisch mit dem oben angepriesenen gleichnamigen Tachenrechner. Der kommt nachher noch)
 +
*'''${tmp_pfad}/*.ac3 ${tmp_pfad}/*.mp2''': Alle Dateien im tmp_pfad, deren Name auf .ac3 oder .mp2 endet, gehen in die Größenermittlung ein.
 +
*'''tail -n 1''': Nur die letzte Zeile dessen, was "du" ausgeben will, wird auch tatsächlich ausgegeben (nämlich unsere Gesamtgrösse)
 +
*'''cut -f1''': Von dieser letzten Zeile wird nur das erste Feld ausgegeben, also die reine Zahl
 +
*'''audio_summe=`....`''': Diese Groesse wird in die Variable $audio_summe geschrieben
  
 
====audio_video_summe====
 
====audio_video_summe====
 
  audio_video_summe=`du -bc ${tmp_pfad}/*.ac3 ${tmp_pfad}/*.mp2 ${tmp_pfad}/*.m2v | cut -f1 | tail -n 1`
 
  audio_video_summe=`du -bc ${tmp_pfad}/*.ac3 ${tmp_pfad}/*.mp2 ${tmp_pfad}/*.m2v | cut -f1 | tail -n 1`
Das Prinzip sollte nun bekannt sein. Das Ergebnis ist die Summe aller Video- und Audiofiles.
+
Das Prinzip sollte nun bekannt sein. Das Ergebnis ist die Groesse der Summe aller Video- und Audiofiles und findet sich in der Variablen $audio_video_summe wieder
  
 
====requantisierungsfaktor====
 
====requantisierungsfaktor====
Zeile 267: Zeile 284:
 
*'''${videogroesse}/$((maxgroesse-audio_summe))*1.04''': Diese Formel wird ausgerechnet
 
*'''${videogroesse}/$((maxgroesse-audio_summe))*1.04''': Diese Formel wird ausgerechnet
 
*'''scale=8''': auf 8 Nachkommastellen genau
 
*'''scale=8''': auf 8 Nachkommastellen genau
*'''echo''': und der Nachwelt zu Verfügung gestellt
+
*'''echo''': und der Nachwelt zu Verfügung gestellt,
Diese Nachwelt ist die Variabele $requantisierungsfaktor, der das Ergebnis der Berechnung mit Hilfe er sogenannten Substitution (`....`) übergeben wird.
+
*'''requantisierungsfaktor=`....`''': indem es in diese Variable geschrieben wird
 +
 
 +
<font color="red"> Bearbeitungsmarkierung </font>
  
 
====Muß requantisiert werden?====
 
====Muß requantisiert werden?====

Version vom 19. Juni 2008, 22:44 Uhr

Vom DVB zur DVD, ein Wikibuch: Übersicht - Der Weg - Die Helferprogramme - Das Script - Installation - Bedienungsanleitung - Programmieranleitung


In diesem Artikel wird näher darauf eingegangen, wie das Script aufgebaut ist und warum es so funktioniert, wie es funktioniert.

Dazu habe ich einen Ausdruck der Version 0.5.5 gemacht und dabei festgestellt, daß es ganz schön umfangreich geworden ist, das was ich da programmiert habe. Es ist also an Zeit, zu Papier (bzw. auf den Bildschirm) zu bringen, was im Script im Einzelnen vor sich geht.

Dafür gibt es zwei Gründe. Zum einen soll der interessierte Nutzer in die Lage versetzt werden, das Script für sich selber zu erweitern bzw. zu ändern. Und zum anderen möchte ich selbst nachschauen können, warum ich Schritt x so programmiert habe und nicht anders (Purer Eigennutz also).

Greifen wir es also an und schauen uns zusammen den Aufbau des Scriptes an:

Beschreibung

In diesem Abschnitt stehen ein paar allgemeine Daten über das Script.

Evt. vom Benutzer anzupassen

Folgende Variablen können, wenn es sein muß, an die eigenen Gegebenheiten anpepasst werden

  • $basisverzeichnis: Diese Variable enthält den Pfad zum sogenannten Basiverzeichnis. In diesem Verzeichnis werden vom Script weitere Arbeitsverzeichnisse angelegt.

Um eine wilde Jongliererei mit Rechten zu umgehen, muß das Basisverzeichis im Heimatverzeichnis des Benutzers liegen. Existiert der Default-Pfad bereits und/oder wird er von anderen Anwendungen benutzt, muß in die Variable ein anderer Pfadname eingetragen werden.

Aber, wie gesagt, im Heimatverzeichnis bleiben!

  • $maxgroesse: Diese Variable enthält die Anzahl der Bytes, die maximal auf eine DVD passen. Ist der Film größer, wird requantisiert.
  • $brenngeschwindigkeit: In dieser Variablen steht die maximale Geschwindigkeit, mit der die DVD vom growisofs gebrannt wird.
  • $suchpfade: In den hier enthaltenen Pfaden wird während der Installationsroutine nach den Helferprogrammen gesucht.

Fehlermeldungen abschalten

  • exec 2>/dev/null: Damit werden Meldungen auf dem Standard-Fehlerkanal ins Nirwana geschickt (Für Inbetriebnahme und Fehlersuche evt. auskommentieren).

Das Script ist so programmiert, daß Betriebs- und Fortschrittsmeldungen der einzelnen Funktionen in einem Konsolenfenster auf dem Bildschirm erscheinen (echo "..."). Die Fehlermeldungen wurden mit obigem Befehl bewußt ausgeklammert, da die Ausgaben im Betrieb sonst schnell unübersichtlich werden.

Es gibt einige Programme, die auch Betriebsmeldungen über den Standard-Fehlerkanal senden. Um diese Meldungen trotzdem auf dem Bildschirm zu sehen, wurde für diese Programme der Fehlerkanal auf die Standardausgabe umgeleitet. Das erfolgt durch Anhängen von 2>&1 ans Ende des jeweiligen Programmaufrufs.

Installationsroutine

Programmnamen

Dies sind die Namen der Helferprogramme, die in einer indizierten Variablen abgelegt werden.

Anlegen der notwendigen Verzeichnisse

Das Basisverzeichnis wird angelegt. Und im Basiverzeichnis werden folgende Arbeitsordner angelegt:

  • dvd_aufnahme: Hier wird zuerst nach den zu bearbeitenden Filmen gesucht.
  • dvd_tmp: Hier legen die Helferprogramme Zwischenergebnisse ab ab und suchen nach den Ergebnissen anderen Helferprogramme
  • dvd_struktur: In diesem Ordner wird die fertige DVD-Struktur zwischengespeichert.
  • dvd-sicherung: Hierhin werden fertige Arbeitsergebnisse gesichert, wenn das vom User so gewünscht wird.
  • default: Hier stehen die Pfadnamen der Helferprogramme und die Initialisierungsdateien für ProjectX.
  • screenshot: Mit mplayer erstellte Screenshots der Filme / Clips, die ich dann zum Bedrucken der DVD verwende.

Programmerkennung

In dieser Routine wird nachgesehen, ob die notwendigen Helferprogramme installiert sind. Und das funktioniert so:

Hauptschleife

for ((i=0 ; i<9 ; i++))

Diese Schleife wird neunmal durchlaufen, so oft also, wie Helferprogramme vorhanden sind.

Alles folgende spielt sich in der Schleife ab.

Default-Pfade lesen

pfad[i]=`cat $basisverzeichnis/default/pfad[$i].txt`
  • $basisverzeichnis/default/pfad[$i].txt: Der Inhalt dieser Datei (das ist der Pfad, wo das zugehöige Programm gefunden werden kann)
  • cat: wird gesendet (über die Standartausgabe)
  • pfad[i]=`...`: an die Variable ${pfad[i]}

Das i steht immer für die Nummer des Schleifendurchlaufs und damit dafür, welches Programm gerade gesucht wird.

Helferprogramm vorhanden?

if [ ! -e ${pfad[i]}/${name[i]} ]

Wenn das Programm nicht existiert,dann

Programmsuche

gefundene_pfade=`find ${suchpfade} -type f -name ${name[i]} -printf "%h "`
  • find ${suchpfade}: In den Suchpfaden suchen
  • -type f: nach einer normalen Datei
  • -name ${name[i]}: mit dem Namen, der in der Variablen ${name[i]} steht.
  • -printf "%h ": Von den gefundenen Dateien werden die Verzeichnisnamen ausgegeben
  • gefundene_pfade=: und in diese Variable geschrieben

Wieviele Versionen des Helferprogramms gefunden?

pfadanzahl=`echo "$gefundene_pfade" | wc -w`
  • echo "$gefundene_pfade": Von dem, was in der Variablen $gefundene_pfade steht
  • wc -w werden die Worte gezählt (und damit die Anzahl der gefundenen Pfade).
  • pfadanzahl=: diese Anzahl wird in die Variable $pfadanzahl geschrieben.

Was wird damit gemacht?

case "$pfadanzahl" in

In Abhängigkeit der Anzahl der gefundenen Pfade passier folgendes:

  • 0): Anzahl 0, das Programm wurde nicht gefunden.

Nach einem Hinweis wird das Script beendet . Das Hfehlende Helferprogramm muß installiert werden..

  • 1): Anzahl 1, das Programm existiert genau einmal.

Der dazugehörige Pfad wird in das Default-Verzeichnis geschrieben.

  • *): Das Programm existiert mehr als einmal.

Es wird nachgefragt (kdialog --combobox), welcher der Pfade verwendet werden soll. Dieser Pfad wird dann ins Default-Verzeichnis geschrieben.

Nachdem diese Routine neunmal erfolgreich durchlaufen ist, kann mit der eigentlichen Videobearbeitung begonnen werden.

Variablenzuweisungen

Diese Zuweisungen haben den Sinn, das Script besser lesbar zu machen. Im Script selbst wird dann ausschließlich mit diesen Variablen gearbeitet bzw. mit in Variablen gespeicherten Pfaden. Durch diese Strategie kann das Script einfach an neue Gegebenheiten anpepasst werden. Es muß nicht lange im Code gesucht werden, an welchen Stellen was geändert werden muß. Es braucht nur der Inhalt der entsprechenden Variablen ausgetauscht werden.

Konfiguration PJX

Hier werden die Initialisierungsdateien festgelegt, in denen Einstellungen stehen, mit denen ProjectX startet:

X.ini für Filmbearbeitung

Die X.ini.film enthält folgende Einstellungen:

  • Application.Agreement=1: Ja zur Lizenz
  • Application.Language=de: PJX startet auf deutsch
  • WindowPosition.Main.Heigh/Width: Größe des PJX-Fensters
  • WindowPosition.Main.X/Y: Position des Fensters (hier rechts oben)
  • optionPanel.NormalLog=0: Es wird keine Log-Datei geschrieben (die würde bloß stören)
  • OptionPanel.CloseOnEnd=1: Nachdem PJX fertig ist, beendet es sich selber

X.ini für Videoclips

Die X.ini.clip enthält zusäthlich:

  • AudioPanel.decodeMPGAudio=1: Die mpeg-audio-Dateien werden zu .wav decodiert (Für's spätere Normalisieren des Tons notwendig)

Diese beiden X.ini's werden im Default-Verzeichnis abgelegt, von wo sie bei Bedarf geladen werden.

Werden im PJX-Fenster irgendwelche Einstellungen verändert, so werden diese Änderungen nicht in die jeweilige X.ini übernommen. Das wurde absichtlich so programmiert, damit man immer einen definierten Ausgangszustand hat.
Wird hier eine Speicherung gewünscht, kann dies durch einen zusätzlichen Eintrag in die X.ini's erfolgen. Dann steht man allerdings vor dem Problem, oft nicht zu wissen, mit welchen Einstellungen PJX denn nun tatsächlich startet. Da es mir immer wieder so ging, kann ich nur raten, die Speicherung ausgeschalten zu lassen.

Funktionen

Diese Funktionen werden vom Hauptprogrmm nach Bedarf aufgerufen und bilden das eigentliche Gerüst des Scriptes. Wird von einer Funktion erwartet, daß sie einen Wert an das Hauptprogramm übergeben soll, dann wird das durch den Befehl "echo Variable" am Ende der Funktion realisiert.

del_ordner ()

  • rm: Die Inhalte des Ordners $tmp_pfad werden gelöscht. Ebenso die Inhalte der im dvd_strukturpfad enthaltenen Ordner AUDIO_TS und VIDEO_TS.
  • rmdir: Die Ordner AUDIO_TS und VIDEO_TS selbst werden gelöscht

Damit ist ein definierter Ausgangszustand hergestellt.

fehler ()

if [ ! -e ${tmp_pfad}/film.mpg ]

Wenn keine Datei film.mpg im Ordner ${tmp_pfad} existiert, wurde auch nichts multiplext. Es muß also irgendwo ein Fehler passiert sein.

nach einem Hinweis auf diesen Fehler (mit kdialog) wird das Script beendet.

aktionenauswahl ()

was_tun=`kdialog --caption "Videobearbeitung" --geometry 500x300-0+0 --radiolist "Was soll also getan werden?"
  • kdialog: Das KDE-Dialog-Programm
  • --caption "Videobearbeitung": öffnet ein Fenster, das den Namen "Videobearbeitung" trägt
  • --geometry 500x300-0+0: und diese Größe und Position hat
  • --radiolist als Liste mit Radio-Buttons
  • "Was soll also getan werden?": Das wird gefragt.
  • was_tun=`...`: In diese Variable wird die Nummer der Antwort geschrieben.

Diese Nummer wird dann später vom Hauptprogramm ausgewertet werden.

filmauswahl ()

quelldatei=`kdialog --caption "Filmauswahl" --geometry 500x500-0+0 --getopenfilename ${aufnahme_pfad}`
  • kdialog: Das KDE-Dialog-Programm
  • --caption "Filmauswahl": öffnet ein Fenster, das den Namen "Filmauswahl" trägt
  • --geometry 500x300-0+0: und diese Größe und Position hat
  • --getopenfilename: Es wird ein KDE-Fenster geöffnet, in dem aus einer Liste von Dateien ausgewählt werden kann
  • ${aufnahme_pfad}: Es werden die Dateien in diesem Pfad zur Auswahl angeboten.
  • quelldatei=`...`: Die ausgewählte Datei wird in die Variable $quelldatei geschrieben.
if [ $? != 0 ]
then
exit

Wenn im Dialogfenster auf den Button Abbrechen gedrückt wurde, wird das Script beendet.

verzeichnisauswahl()

verzeichnis=`kdialog --caption "Verzeichnisauswahl" --geometry 500x500-0+0 --getexistingdirectory ${sicherungs_pfad}`
  • kdialog: Das KDE-Dialog-Programm
  • --caption "Verzeichnisauswahl": öffnet ein Fenster, das den Namen "Verzeichnisauswahl" trägt
  • --geometry 500x500-0+0: und diese Größe und Position hat
  • --getexistingdirectory: Es wird ein KDE-Fenster geöffnet, in dem aus einer Liste von Verzeichnissen ausgewählt werden kann
  • ${sicherungs_pfad}: Es werden die Verzeichnisse in diesem Pfad zur Auswahl angeboten.
  • verzeichnis=`...`: Die ausgewählte Datei wird in die Variable $verzeichnis geschrieben.
if [ $? != 0 ]
then
exit

Wenn im Dialogfenster auf den Button Abbrechen gedrückt wurde, wird das Script beendet.

pjx_demux_gui ()

java -jar ${pjx} -demux -gui  -ini ${default_pfad}/X.ini.film -out ${tmp_pfad} -name film "$quelldatei" 1>/dev/null
  • java -jar: Es wird ein Java-Programm gestartet
  • ${pjx}: und zwar das Programm ProjectX (z.B.: ~/ProjectX/ProjectX.jar)
  • -demux: Der mpeg-Stream wird demultiplext
  • -gui: PJX startet mit graphischer oberfläche (notwendig nur, wenn mit PJX geschnitten werden soll)
  • -ini ${default_pfad]/X.ini.film: mit dieser Initialisierungsdatei wird PJX gestartet.
  • -out $tmp_pfad: Hierhin wird das Bearbeitungsergebnis geschrieben
  • -name film: Die Ausgabedatei erhält den Basisnamen "film"
  • $quelldatei:Dieser Stream wird verarbeitet
  • 1>/dev/null: Alles, was ich an Ausgeben auf dem Bildschirm nicht sehen will, wird ins Leere geschickt.

pjx_ts_gui ()

java -jar ${pjx} -tots -gui -split 4300 -ini ${default_pfad}/X.ini.film -out ${tmp_pfad} -name film "$quelldatei" 1>/dev/null
  • java -jar: Es wird ein Java-Programm gestartet
  • ${pjx}: und zwar das Programm ProjectX (z.B.: ~/ProjectX/ProjectX.jar)
  • -tots: Der Film wird zum TS-File gewandelt
  • -gui: PJX startet mit graphischer oberfläche (notwendig nur, wenn mit PJX geschnitten werden soll)
  • -split 4300: Bei 4300 Mbyte wird die Aufnahme gesplittet (mehr passt nicht auf eine DVD drauf)
  • -ini ${default_pfad]/X.ini.film: mit dieser Initialisierungsdatei wird PJX gestartet.
  • -out $tmp_pfad: Hierhin wird das Bearbeitungsergebnis geschrieben
  • -name film: Die Ausgabedatei erhält den Basisnamen "film"
  • $quelldatei:Dieser Stream wird verarbeitet
  • 1>/dev/null: Alles, was ich an Ausgeben auf dem Bildschirm nicht sehen will, wird ins Leere geschickt.

pjx_clip ()

java -jar ${pjx} -demux -gui  -ini ${default_pfad}/X.ini.clip -out ${tmp_pfad} -name film "$quelldatei" 1>/dev/null
  • -ini ${default_pfad]/X.ini.clip: mit dieser Initialisierungsdatei wird PJX gestartet. In ihr festgelegt wird, daß das mpg-audio zu einer wav-Datei decodiert wird.

Alle anderen Optionen wie bei "pjx_demux_gui ()"

mpeg1_input ()

${ffmpeg} -i "${quelldatei}" ${tmp_pfad}/film.mp2.wav -vcodec copy ${tmp_pfad}/film.m1v
  • ${ffmpeg}: Aufruf von ffmpeg (z.B.: /usr/bin/ffmpeg),
  • -i ${quelldatei}: um diesen Video-Clip zu verarbeiten
  • ${tmp_pfad}/film.mp2.wav: Der Ton des Clips wird decodiert zu einem wav-file.
  • -vcodec copy: Das Videofile wird nicht verändert, sondern nur demultiplext
  • ${tmp_pfad}/film.m1v: und ist dann hier zu finden

requantisieren ()

Jetzt gibt es, oh Schreck, etwas Mathematik. Mathe ist nicht nur etwas, mit dem viele Normal-Sterbliche, egal welchen Alters, auf Kriegsfuß stehen. Mathe ist auch etwas, mit dem die Bash nicht so ohne weiteres umgehen kann, wäre da nicht ein kleines eingebautes Tool mit dem Namen "bc". Mit diesem Tool hat die Bash einen Taschenrechner.Und genau so einen Rechner brauchen wir in dieser Funktion.

Der Sinn dessen, was wir hier tun, ist es, einen Film so zu stauchen, daß er auf eine einzelne DVD passt. Dieses Stauchen wollen wir, etwas eleganter, Requantisieren nennen. Und der "Stauchfaktor", also um wieviel mal das Ausgangsmaterial kleiner gemacht werden soll, bekommt von uns den Namen "Requantisierungsfaktor".

Es macht wenig Sinn, ein Audiofile verkleinern zu wollen. Ein Videofile mit seinen etlichen GByte Größe bietet hier mehr Aussicht auf Erfolg.

Die Formel, nach der wir den Requantisierungsfaktor berechnen, lautet so:

Requantifizierungsfaktor = ("Größe des Videofiles" / ("Was auf die DVD maximal passt" - "Summe aller Audiofiles"))*1,04

Wieso diese Formel gerade so lautet, darf der geneigte Leser selber zu ergründen versuchen. Eine kleine Denksportaufgabe ist mit Sicherheit nicht die Schlechteste aller Freizeitbeschäftigungen. Ich verrate nur soviel, daß der Faktor 1,04 dafür da ist, die Verwaltung des Dateisystems auf der DVD zu berücksichtigen (Die einzelnen Ordner brauchen ja schließlich auch Platz).

Schauen wir uns also eine Umsetzung dieser Formel in der Bash an:

videogroesse

videogroesse=`du -bc ${tmp_pfad}/*.m2v | cut -f1 | tail -n 1`
  • du: Bashprogramm, welches den Platzverbrauch von Dateien schätzt
  • -b: Ausgabe der Größe in Bytes
  • -c: Erzeugen einer Gesamtsumme (-b und -c sind zusammen gefasst nach -bc. dieses bc ist allerdings nicht identisch mit dem oben angepriesenen gleichnamigen Tachenrechner. Der kommt nachher noch)
  • ${tmp_pfad}/*.m2v: Alle Dateien im tmp_pfad, deren Name auf .m2v endet, gehen in die Größenermittlung ein.
  • tail -n 1: Nur die letzte Zeile dessen, was "du" ausgeben will, wird auch tatsächlich ausgegeben (nämlich unsere Gesamtgrösse)
  • cut -f1: Von dieser letzten Zeile wird nur das erste Feld ausgegeben, also die reine Zahl
  • videogroesse=`....`: Diese Groesse wird in die Variable $videogroesse geschrieben

audiosumme

audio_summe=`du -bc ${tmp_pfad}/*.ac3 ${tmp_pfad}/*.mp2 | cut -f1 | tail -n 1`
  • du: Bashprogramm, welches den Platzverbrauch von Dateien schätzt
  • -b: Ausgabe der Größe in Bytes
  • -c: Erzeugen einer Gesamtsumme (-b und -c sind zusammen gefasst nach -bc. dieses bc ist allerdings nicht identisch mit dem oben angepriesenen gleichnamigen Tachenrechner. Der kommt nachher noch)
  • ${tmp_pfad}/*.ac3 ${tmp_pfad}/*.mp2: Alle Dateien im tmp_pfad, deren Name auf .ac3 oder .mp2 endet, gehen in die Größenermittlung ein.
  • tail -n 1: Nur die letzte Zeile dessen, was "du" ausgeben will, wird auch tatsächlich ausgegeben (nämlich unsere Gesamtgrösse)
  • cut -f1: Von dieser letzten Zeile wird nur das erste Feld ausgegeben, also die reine Zahl
  • audio_summe=`....`: Diese Groesse wird in die Variable $audio_summe geschrieben

audio_video_summe

audio_video_summe=`du -bc ${tmp_pfad}/*.ac3 ${tmp_pfad}/*.mp2 ${tmp_pfad}/*.m2v | cut -f1 | tail -n 1`

Das Prinzip sollte nun bekannt sein. Das Ergebnis ist die Groesse der Summe aller Video- und Audiofiles und findet sich in der Variablen $audio_video_summe wieder

requantisierungsfaktor

requantisierungsfaktor=`echo "scale=8 ; ${videogroesse}/$((maxgroesse-audio_summe))*1.04" | bc`
  • bc: Nun ist er endlich da, unser Taschenrechner
  • ${videogroesse}/$((maxgroesse-audio_summe))*1.04: Diese Formel wird ausgerechnet
  • scale=8: auf 8 Nachkommastellen genau
  • echo: und der Nachwelt zu Verfügung gestellt,
  • requantisierungsfaktor=`....`: indem es in diese Variable geschrieben wird

Bearbeitungsmarkierung

Muß requantisiert werden?

if [ $audio_video_summe -ge $maxgroesse ] ; then

Wenn die Summe der Audio- und Videofiles größer ist als das, was auf die DVD drauf passt, dann wird die Requantisierung übersprungen. Ist sie nicht größer, wird requantisiert.

Die Requantisierung

${tcrequant} -d2 -i ${tmp_pfad}/film.m2v -o ${tmp_pfad}/film.requant -f ${requantisierungsfaktor}
  • -d2: Den Bearbeitungsfortschritt anzeigen
  • -i ${tmp_pfad}/film.m2v: Dieses Videofile wird requantisiert
  • -o ${tmp_pfad}/film.requant: Das ist das Ergebnis der Requantisierung
  • -f ${requantisierungsfaktor}:Mit diesem Faktor wird requantisiert

Was noch folgt ist eine Namensänderung der Datei film.requant zu film.m2v (mv ...) und das Löschen von film.requant. Die Namensänderung ist übrigens notwendig, weil die Funktion "multiplex ()" das Videofile unter dem Namen film.m2v erwartet.

normalisieren ()

Meine schon etwas in die Jahre gekommene Stereoanlage zeichnet sich noch dadurch aus, daß ein großer Drehknopf zur Lautstärkeregelung vorhanden ist. Und den kann man aufdrehen, bis buchstäblich die Wände wackeln (4 x 70 W Sinus können ganz schön Dampf machen). Aber irgendwann ist Schluß. Nein, nicht daß die Nachbarn sich beschwert hätten. Der Regler ist vielmehr am Rechtanschlag angelangt und die Anlage liefert die maximal mögliche Lautstärke.

Auch die Audio-Files, mit denen wir hier im Script herumjonglieren, kennen einen maximal möglichen Pegel. Der ist nämlich denn erreicht, wenn die Bytes, welche die Lautstärke im Digitalsignal kennzeichnen ihre Maximalwerte erhalten (z.B.: FFFF bei 4 Byte, mehr geht einfach nicht, es sei denn, man macht ein fünftes Byte auf).

Fernsehsender beanspruchen für sich eine gewisse Individualität. Manchmal kommt es mir aber so vor, daß diese Individualität dadurch zum Ausdruck gebracht wird, das jeder Sender mit einer anderen Lautstärke sein Programm ausstrahlt. Das ist schon beim Zappen unangenehm. Noch unerfreulicher wird diese Tatsache jedoch, wenn die mühsam aufgenommenen Videoclips mit Hilfe einer Wiedergabeliste abgespielt werden. Denn bei jedem zweiten Stück ist ein Griff zum Lautstärkeregler notwendig. Beim einen Lied versteht man kaum, was aus den Lautsprechern kommt, beim nächsten Mal brüllt es einen geradezu aus dem Sessel heraus.

Ein PCM-Signal auf einen definierten Lautstärkepegel zu bringen, ohne die Dynamik selbst zu verändern, wird "normalisieren" genannt.

Mit dem in dieser Funktion verwendeten Befehl "normalize" wird die lauteste Stelle in dem Audio-File "film.mp2.wav" auf -12dBfs (also 12dB unter "full scale") gebracht. Der Rest wird entsprechend mitgezogen. Aber, wie gesagt, ohne Verlust an Dynamik.

Die normalisierte Datei überschreibt und ersetzt in diesem Fall die Ausgangsdatei. Die Option -v zaubert dabei etwas Bearbeitungsfortschritt auf den Bildschirm.

Das Normalisieren funktioniert nur mit PCM-Files. eine komprimierte Datei (mp2) muß erst zu PCM (wav) decodiert werden.

Beim mp3-Format wird übrigens eine andere Strategie zum Normalisieren angewandt, und zwar eine ohne Umcodierverluste. Hier bleibt das ursprünliche File erhalten. Lediglich in den Header wird die Information geschrieben, um wieviel die Lautstärke angepasst werden müsste. Der Player wertet diesen Header dann aus und regelt entsprechend die Lautstärke beim Abspielen des Files. Die Voraussetzung ist hier sebstvertändlich ein Player, der dies Auswertung auch verarbeiten kann. Dies nur zur Information, daß es noch eine Welt ausßerhalb von mp2 gibt.

Da der Ton von Fersehprogrammen aber im mp2 Verfahren codiert ist (AC3 lassen wir hier einmal außen vor), müssen wir den ober beschriebenen verlustbehafteten Weg mit normalize gehen. Aber keine Angst, die Verluste sind nicht so groß, daß sie stören würden. Der mit einem normal arbeitenden Gehör ausgestattete Mitteleuropäer wird also zufrieden sein mit der Qualität seines Bearbeitungsergebnisses.

encode2mp2 ()

${ffmpeg} -i ${tmp_pfad}/film.mp2.wav -acodec mp2 -ab 192k ${tmp_pfad}/film.mp2 2>&1
  • -i ${tmp_pfad}/film.mp2.wav: Dieses PCM-file
  • -acodec mp2: wird zu einem mp2-File encodiert,
  • -ab 192k: welches eine Audio-bitrate von 192k erhält (mp2-Standard)
  • ${tmp_pfad}/film.mp2: Das Ergebnis findet man dann hier
  • 2>&1: Damit kann man am Bildschirm verfolgen, was gerade passiert

multiplexen ()

Mit mplex wird aus den getrennten Bild- und Ton-Dateien ein mpg-File gemacht, welches für das spätere Authoring mit dvdauthor schon vorbereitet ist.

Vorbereiten der Dateien

  • mpeg1_video=: Es wird eine leere Variabe mpeg1_video erzeugt
  • mpeg1_video=`find ${tmp_pfad} | grep "m1v"`: In diese Variable werden die Namen der Dateien, die ein "m1v" im Namen enthalten, geschrieben

Dass gleiche geschieht mit den Variablen mpeg2_viedo, mp2_audio und ac3_audio. Ist im tmp_pfad zum Beispiel keine AC3-Datei vorhanden, so bleibt die entsprechende Variable leer.

Das eigentliche Multiplexen

${mplex} -v1 -f8 -o ${tmp_pfad}/film.mpg ${mpeg1_video} ${mpeg2_video} ${mp2_audio} ${ac3_audio}
  • ${mplex}: /usr/bin/mplex
  • -v1: Fortschrittsanzeige (beim Befehl mplex leider nicht so sehr fortschrittlich)
  • -f8: Format zur späteren Erzeugung einen DVD
  • -o ${tmp_pfad}/film.mpg: Das Ergebnis
  • ${mpeg1_video} ${mpeg2_video} ${mp2_audio} ${ac3_audio}: die Eingangsdateien, die multiplext werden, enthalten in den angegebenen Variablen. Eine leere Variable wird von mplex ignoriert.

Anschließend werden mit "rm" die nun nicht mehr benötigten Eingangsdateien gelöscht.

authoring_ohne_menue ()

Hier wird der einfachste Fall einer DVD-Struktur erzeugt (ohne DVD-Menue).

${dvdauthor} -o ${dvdstruktur_pfad} -t ${tmp_pfad}/film.mpg 2>&1
  • ${dvdauthor}: /usr/bin/dvdauthor (Programmaufruf)
  • -o ${dvdstruktur_pfad}: Das Ergebnis wird hier zu finden sein
  • -t: Es wird ein Titel erzeugt (Ordner AUDIO_TS: leer / Ordner VIDEO_TS: Inhalt ifo-files und vob-files)
  • ${tmp_pfad}/film.mpg: Diese mpg-Datei wird als Eingangsdatei verwendet
${dvdauthor} -o ${dvdstruktur_pfad} -T
  • -o ${dvdstruktur_pfad}: In diesem Ordner: ${dvdstruktur_pfad}/VIDEO_TS
  • -T: werden noch folgende Dateien erzeugt: VIDEO_TS.BUP und VIDEO_TS.IFO

brennen_video_dvd ()

Mit dieser Funktion wird die fertige DVD-Struktur auf DVD kopiert. Das Ergebnis ist eine Video-DVD

${growisofs} -speed=${brenngeschwindigkeit} -dvd-compat -Z /dev/dvd -dvd-video ${brenn_pfad} 2>&1
  • ${growisofs}: Programmaufruf (z.B. /usr/bin/growisofs)
  • -speed=${brenngeschwindigkeit}: maximale Brenngeschwindigkeit
  • -dvd-compat: Schließt nach dem Brennen die DVD ab, um maximale Kompatibilität zu gewährleisten
  • -Z /dev/dvd: Burn an initial session to the selected device (so stehts in der man-page). Was immer das auch bedeuten mag. auf jeden Fall funktioniert es prima mit dieser Option.
  • -dvd-video: udf-Filesystem für Video-DVD's
  • ${brenn_pfad}: Was hier drin steht, wird gebrannt
  • 2>&1: Damit kann man am Bildschirm verfolgen, was gerade passiert

brennen_ts ()

Brennen des TS-Files als Daten-DVD

Wieviele DVD's sind notwendig?

dvdzahl=`find ${brenn_pfad} -type f | wc -l`
  • find ${brenn_pfad}: Der Pfad mit den zu brennenden Files wird durchsucht
  • -type f: nach normalen Dateien
  • wc -l: und es wird gezählt, wieviele Dateien das sind
  • dvdzahl=`...`: Diese Anzahl wird mit Hilfe der Substitution in die Variable $dvdzahl geschrieben
for((i=1; i<=${dvdzahl}; i++))

In dieser If-Schleife wird so oft eine neue DVD angefordert, bis alle Dateien gebrannt sind.

Das Brennen

kdialog --msgbox "Bitte DVD Nr.: $i einlegen"

Aufforderung , eine neue DVD bzw. die nächste DVD zum Brennen einzulegen

${growisofs} -speed=${brenngeschwindigkeit} -Z /dev/dvd  -allow-limited-size -R -J ${brenn_pfad}/"film($((i-1)))"* 2>&1
  • ${growisofs}: Programmaufruf (z.B. /usr/bin/growisofs)
  • -speed=${brenngeschwindigkeit}: maximale Brenngeschwindigkeit
  • -Z /dev/dvd: siehe Funktion brennen_video_dvd ()
  • -allow-limited-size: Damit lassen sich Dateien bis zu 4,3GB brennen
  • -R: Rock Ridge Erweiterung benutzen
  • -J```: Joliet-Extention benutzen (macht es leichter, die DVD unter Windows abzuspielen)
  • ${brenn_pfad}/"film($((i-1))): Diese Datei auf DVD brennen
  • 2>&1: Damit kann man am Bildschirm verfolgen, was gerade passiert

sichern_struktur ()

Diese Funktion sichert die DVD-Struktur

sicherungsordner=$(date +%Y%m%d%H%M%S)

In diesen Sicherungsordner wird die DVD-Struktur geschrieben. Der Name des Ordner wird aus dem aktuellen Datum und der momentanen Uhrzeit generiert.

mkdir ${sicherungs_pfad}/${sicherungsordner}

Hiermit wird der Sicherungsordner angelegt

mv ${dvdstruktur_pfad}/* ${sicherungs_pfad}/${sicherungsordner}

mv verschiebt die DVD-Struktur in den Sicherungsordner

sichern_ts ()

Diese Funktion sichert die TS-files

sicherungsordner=$(date +%Y%m%d%H%M%S)

In diesen Sicherungsordner wird die DVD-Struktur geschrieben. Der Name des Ordner wird aus dem aktuellen Datum und der momentanen Uhrzeit generiert.

mkdir ${sicherungs_pfad}/${sicherungsordner}

Hiermit wird der Sicherungsordner angelegt

mv ${tmp_pfad}/*.ts ${sicherungs_pfad}/${sicherungsordner}

mv verschiebt die TS-files in den Sicherungsordner

clip_speichern ()

Diese Funktion speichert einen Videoclip

clipspeicher=`kdialog --title "$quelldatei" --getsavefilename /Videoclips/Archiv`
  • kdialog: Programmaufruf (z.B. /usr/bin/kdialog)
  • --title "$quelldatei": Überschrift für das KDE-Fenster
  • --getsavefilename: Generiert ein KDE-Fenster, in dem


will be continued





Vom DVB zur DVD, ein Wikibuch: Übersicht - Der Weg - Die Helferprogramme - Das Script - Installation - Bedienungsanleitung - Programmieranleitung



Zurück zur Multimedia-Übersicht