Archiv nach Kategorien: Snippets

Conky und die Fußball EM 2012

Ich bin neulich zufällig auf OpenLigaDB gestoßen, ein Community-Projekt, das zeitnah Sport-Ergebnisse als Webservice zur Verfügung stellen will. Über die SOAP-Schnitstelle lassen sich die Daten unkompliziert und ohne Registrierung abrufen.

Ich habe dazu ein kleines Python-Skript gebaut, das jeweils ausgibt, welche Spiele an einem Tag stattfinden und wie es ggf. gerade steht. Die Ausgabe eignet sich gut für die Einbindung in Conky.

Für das Skript gibt es eine Github-Projektseite. Es sollte genügen, die Datei csi.py im Ordner ~/.conky abzulegen und in der Datei ~/.conkyrc einen Eintrag wie diesen anzufügen:

${font size=11:italic}${color slate grey}Fußball EM 2012 ${hr}${color }${font }
${execi 120 python ~/.conky/csi.py}

Das Skript benötigt das Modul “suds”, das bei vielen Distributionen als “python-suds” oder “python2-suds” zur Verfügung stehen sollte. Unter Umständen (beispielsweise unter Arch) muss der Aufruf python durch python2 ersetzt werden, weil das Skript nur unter Python2 lauffähig ist. Wenn Python2 in eurer Distribution ohnehin noch der Standard ist, funktioniert der Aufruf python ~/.conky/csi.py aber auch.

Wirkliche “Echtzeitergebnisse” sind übrigens mit diesem Skript letztlich nicht möglich: Zum Einen werden die Ergebnisse bei OpenLigaDB händisch eingetragen, so dass es dort schon zu Verzögerungen von etwa einer Minute  kommen kann, zum Anderen empfiehlt es sich auch, Conky das Skript in größeren Intervallen ausführen zu lassen, um OpenLigaDB und den eigenen Rechner nicht unnötig zu belasten.

/edit: SUDS-Abhängigkeit ergänzt

Yet another tiling extension

Vor einiger Zeit habe ich ja bereits auf Shellshape hingewiesen. Die Kombination aus Gnome-Shell Extension und Mutter-Ersatz bringt echtes Tiling auf den Gnome-Desktop. Zum alltäglichen Einsatz konnte ich mich dann aber doch nicht durchringen: Die starke Unterscheidung der beiden Modi “Tiling” und “Floating” sprach mich nicht sonderlich an und die vielen Tastenkürzel um die jeweiligen Tiles zu vergrößern, zu verkleinern, zu verschieben und zu tauschen fand ich auch nicht übermäßig intuitiv.

Tiling mit gTile

Tiling mit gTile

gTile
Auf der neuen Gnome3-Extension-Seite bin ich dann noch auf gTile gestoßen. Diese Erweiterung erlaubt ebenfalls das überlappungsfreie Anordnen der Fenster – allerdings wird hier das jeweils aktive Fenster durch eine kleine Dialog-Box auf dem Bildschirm angeordnet. Auch ein sehr schöner Ansatz, der etwas einsteigerfreundlicher wirkt, als die Shellshape-Variante.

Mir war aber eher nach einem Ansatz, wie ich ihn unter Ubuntu einmal mit Compiz umgesetzt hatte: Durch Tastenkombinationen wollte ich die Fenster schnell und flexibel beliebigen Ecken des Bildschirms zuweisen können. Durch mehrmaliges Tasten-Drücken – so die Überlegung – würden die Fenster dann in ihrer Ecke verschiedene Größen annehmen. Eine gute Gelegenheit, sich einmal näher mit den Gnome-Shell-Extensions zu befassen.

Ein mit KeyTiling erstelltes Layout

Die verschiedenen Fenster wurden hier bequem mit “KeyTiling” angeordnet.

KeyTiling
Herausgekommen ist dabei “KeyTiling“, eine einfache Gnome-Shell-Erweiterung, die das Arrangieren der Fenster mittels Tastenkombinationen erlaubt. Natürlich sind die damit erreichbaren Layouts letztlich begrenzt; für die meisten Anwendungsfälle sollte es aber genügen. Außerdem unterstützt KeyTiling mehrere Monitore und erlaubt es beispielsweise, ein Fenster schnell auf den nächsten Monitor zu packen und dort nach Wunsch auszurichten.

Die Erweiterung läuft stabil, hat aber noch einen kleinen Pferdefuß: Ich habe bisher nur die Funktion “Main.wm.setKeybindingHandler” gefunden, um globale Tastenkombinationen aus der Erweiterung heraus zu registrieren. Diese Funktion scheint aber auf bestimmte vordefinierte Kombinationen in “/apps/metacity/global_keybindings” beschränkt zu sein. Daher ist es mir bisher nicht gelungen, neue Kombinationen zu registrieren – ich musste bestehende Schlüssel überschreiben, namentlich die Schlüssel “run_command_[1-11]“. Das sollte in der Regel nicht schmerzen, weil benutzerdefinierte Tastenkürzel in Gnome3 diese Schlüssel gar nicht mehr berühren. Dennoch: Bei der Aktivierung der Erweiterung werden die fraglichen Tastenkürzel kurzer Hand überschrieben und auf “KeyTiling” umgebogen.

Außerdem könnten die Fenstergrößen Anlass zur Kritik geben. Momentan nehmen die Fenster in den Ecken wahlweise 1/3, 1/2 oder 2/3 der Bildschirms ein. Eine strikte Aufteilung in Vierteln wäre sicher sinnvoller bezüglich der Kombinationsmöglichkeiten – die resultierende Fenstergröße fand ich aber nicht sonderlich günstig für meinen Bildschirm. Eine Aufteilung in Sechstel würde noch mehr Freiheiten bei der Anordnung der Fenster ermöglichen – dazu müsste der Nutzer aber bis zu 30 Mal eine bestimmte Tastenkombination drücken – nicht gerade erstrebenswert.

Schließlich scheint es in bestimmten Fällen Probleme mit der Positionierung der Fenster zu geben – eventuell ist dies auf Sekundärbildschirme beschränkt, die keine obere Leiste haben, ganz sicher bin ich mir da noch nicht.

Wie auch immer: Dieses kurze und nicht sonderlich unterhaltsame Video zeigt, wie verschiedene Fenster auf dem Desktop angeordnet werden und mittels mehrfacher Tastendrücke unterschiedliche Größen annehmen.

Von echtem Tiling kann, wie ihr seht, keine Rede sein – “KeyTiling” ist eher eine Hilfe, um Fenster nebeneinander anzuordnen.

Die Tastenkombinationen
Zur Zeit sind alle Tastenkombinationen fest im Script eingebaut. Sie können dort aber relativ leicht angepasst werden. Die Belegung stellt sich dabei wie folgt dar:

  • <Control><Alt>KP_1: Fenster unten links anordnen.
  • <Control><Alt>KP_2: Fenster unten anordnen.
  • <Control><Alt>KP_3: Fenster unten rechts anordnen.
  • <Control><Alt>KP_4: Fenster links anordnen.
  • <Control><Alt>KP_5: Fenster auf anfängliche Position und Größe zurück setzen.
  • <Control><Alt>KP_6: Fenster rechts anordnen.
  • <Control><Alt>KP_7: Fenster oben links anordnen.
  • <Control><Alt>KP_8: Fenster oben anordnen.
  • <Control><Alt>KP_9: Fenster oben rechts anordnen.
  • <Control><Alt>KP_0: Zwischen Vollbild- und Normalmodus hin- und herschalten.
  • <Control><Alt>KP_Enter: Fenster auf den nächsten Monitor verschieben.

Wer KeyTiling einmal testen möchte, kann es über Github beziehen. Für Rückmeldungen und Tipps – besonders bzgl. einer besseren Hotkey-Schnittstelle – bedanke ich mich schonmal.

Kleiner Ersatz für nautilus-open-terminal

Da die Erweiterung nautilus-open-terminal schon seit einiger Zeit für Probleme sorgt und Nautilus abstürzen lässt (Fehlermeldung,Bericht bei Chris) und ich mir ohnehin mal die Python-Schnittstelle von Nautilus ansehen wollte, habe ich eine kleine Erweiterung geschrieben, die nautilus-open-terminal ersetzen soll, bis das Original wieder einwandfrei arbeitet.

Die von Chris angesprochenen Probleme mit “Nautilus-Python” scheinen insgesamt darauf zurückzuführen zu sein, dass für Nautilus-Erweiterungen die GTK3-Anbindung jetzt zwingend erforderlich sind. Durch die Ableitung von GObject ließen sich in meinem Fall also die Probleme beseitigen.

Wer sich meine “open-terminal”-Variante einmal ansehen möchte, kann dies bei GitHub tun. Abgelegt wird das Skript im Verzeichnis ~/.local/share/nautilus-python/extensions/, wobei ich das Verzeichnis in meinem Fall erst noch erstellen musste.

Nvidia, Twinview und das Youtube-Vollbild

Bei der Verwendung des proprietären Nvidia-Treibers in Kombination mit Twinview kommt es bei einigen Flash-Video-Seiten zu einem hässlichen Fehler: Videos werden im Vollbild nicht korrekt dargestellt, das Bild füllt nur einen kleinen Teil des Bildschirms aus.

Ich hatte bisher noch keine zufriedenstellende Lösung gefunden. Einige Nutzer lassen durch zusätzliche Skripte den Flashplayer auf Youtube durch VLC ersetzen. Andere Nutzer lassen durch diesen Trick das Flash-Video das gesamte Browser-Fenster einnehmen und versetzen dann den Browser in den Vollbild-Modus. Wirklich befriedigend ist das alles nicht.

Alistair Buxton hat sich auf seiner Homepage einmal näher mit dem Problem beschäftigt und rausgefunden, warum der Flashplayer auf Youtube so skaliert, wie er skaliert. Letztendlich ermittelt das Flash-Plugin durch einen bestimmten API-Aufruf (XGetGeometry) die Größe der Anzeigefläche. Diese wird an den Flash-Player weitergereicht, der daraus seine Schlüsse zieht. Der Youtube-Player scheint zunächst das Flash-Video auf den gesamten Anzeigebereich zu skalieren, um dieses Bild dann (inklusive schwarzer Balken) wieder auf die Größe der primären Anzeige runterzuskalieren oder entsprechend zu beschneiden. Auf der Seite von Alistair Buxton ist das anhand verschiedener Bilder gut nachzuvollziehen.

Alistair hat nun einen kleinen Hack veröffentlicht, der den Aufruf der Methode “XGetGeometry” durch dynamisches Linken mittels LD_PRELOAD überschreibt. Wenn das Flash-Plugin nun nach der Anzeigegröße fragt, werden ihm Breite und Höhe des primären Bildschirms zurückgegeben. Der kleine Hack findet sich hier und ist leicht zu verwenden, in der Readme-Datei finden sich alle wichtigen Informationen.

Einen Nachteil hat auch diese Methode natürlich: Bei jedem Aufruf des Browsers muss die Umgebungsvariable LD_PRELOAD explizit gesetzt werden, damit die modifizierte XGetGeometry-Funktion zum Tragen kommt. Es empfiehlt sich daher, die .desktop-Datei des Lieblingsbrowsers entsprechend anzupassen. Alternativ könnte auch ein kleines Skript erstellt werden, das statt des Browsers aufgerufen wird:

#!/bin/bash
LD_PRELOAD=/usr/lib/libfullscreenhack.so chromium-browser $@

Letztlich ist natürlich auch diese Lösung keine Dauerlösung. Durch den kleinen Trick von Alistair kann man das Problem aber erstmal umschiffen. Endlich.

 

Fenstertitel ändern

Programme wie “Titlebar Time 2” zeigen unter Windows die Zeit in der Titelleiste des Fensters an. Bei Ubuntuusers kam die Frage auf, wie sich das auch unter Ubuntu umsetzen ließe. Nach einigen Versuchen mit “wmctrl” bin ich bald auf die nützliche Bibliothek libwnck gestoßen, für die es auch eine Python-Anbindung gibt.

Ich habe das Ganze in ein Skript gegossen, das es ermöglicht, die Fenstertitel um beliebige Informationen zu erweitern – etwa die aktuelle IP-Adresse oder die Uhrzeit.

Parameter

Wird das Skript ohne weitere Parameter gestartet, zeigt es die Zeit im aktiven Fenster an. Weiterhin kennt es noch folgende Optionen:

  • -s / –seperator: Es wird eine eindeutige Zeichenkette benötigt, mit der die zusätzliche Information im Fenstertitel vom ursprünglichen Fenstertitel getrennt wird. Mit diesem Schalter kann man die entsprechende Zeichenkette verändern.
  • -a / –all-windows: Normalerweise wird nur der Fenstertitel des aktiven Fenster verändert. Wer die Fenstertitel *aller* Fenster verändern möchte, muss diese Option setzen.
  • -r / –run: Wer statt der Zeit andere Angaben im Fenstertitel zeigen möchte, kann hier entsprechende Befehle ausführen lassen – etwa “date”.
  • -t / –timeout: Dauer zwischen zwei Aktualisierungen in ms. Standard: 10.000 ms.
  • -c / –cache: Wenn eigene Befehle mit “-r” ausgeführt werden, können die Ergebnisse gecacht werden. Standard: 30.000 ms).

Um beispielsweise die aktuelle IP im Fenstertitel anzeigen zu lassen, wäre folgender Aufruf denkbar:

 ./titlechanger.py -r 'curl -s http://www.wieistmeineip.de/|egrep -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+"'

Nachteile

(Achtung: Siehe Abschnit “Update”)

Da jeder Zeit Fenster geöffnet und geschlossen werden können, muss das Skript recht häufig nach Veränderungen Ausschau halten. Standard sind hier 250ms.  Das ist kein großes Problem, so lange nur die Zeit angezeigt wird. Sobald aber der Parameter “-r” ins Spiel kommt, sollte man sich vor Augen halten, dass der entsprechende Shell-Befehl alle 250ms ausgeführt wird. Mag das bei “date” noch akzeptabel sein, würde man damit beim Ermitteln der IP mittels einer externen Webseite den Anbieter 4 Mal in der Sekunde mit Anfragen belästigen. Entsprechend wurde im obigen Beispiel der Timeout auf 5 Sekunden erhöht – mit dem hässlichen Effekt, dass neue Fenster im schlimmsten Fall erst nach 5 Sekunden mit der gewünschten Angabe versehen werden.

Etwas mehr Logik im Skript könnte das Problem sicher eingrenzen. Zum Herumspielen und Experimentieren eignet sich das Skript allemal. Darüber hinaus muss jeder selbst abwägen, ob ihm modifizierte Fenstertitel die zusätzlichen Ressourcen wert sind.

Update

In der aktuellen Version des Skript (0.2) wurden viele der o.g. Probleme behoben: Das Skript erkennt, wenn das aktive Fenster gewechselt oder ein neues Fenster geöffnet wurde. Auch vom Programm veränderte Titelleisten werden jetzt erkannt. Deshalb wurde der Standard-Timeout auf 10 Sekunden angehoben.

Weiterhin wurde mit der Option “-c” ein Cache implementiert, der die Ergebnisse von Shell-Kommandos 30 Sekunden vorhält. Damit sollten dann auch Abfragen von Internetseiten kein Problem mehr darstellen.

Abhängigkeiten

Bei einer normalen Ubuntu-Installation sollte die Installation des Paketes

  • python-wnck

ausreichen.

Download

titlechangerV02.py.tar (aktuell)

titlechanger.py.tar (veraltet)

Upload aus dem Kontext-Menü

Dieses Skript lädt die ausgewählten Dateien auf einen FTP Server. Angepasst werden müssen:
FTP-Server: Der zu nutzende FTP-Server
Server: Der gleiche Server – über HTTP
sowie
BENUTZERNAME (selbsterklärend).
Das Passwort wird jeweils vorher abgefragt. Wie zuvor wird das Paket zenity benötigt, ebenso das Paket wput.

#!/bin/sh
 
paths=$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
selected=$NAUTILUS_SCRIPT_SELECTED_URIS
cur=$NAUTILUS_SCRIPT_CURRENT_URI
 
if ! PASS=$(zenity --entry --hide-text --text "Bitte geben Sie das Passwort ein:" --title "Und das Passwort?"); then
  exit;
fi
 
for x in $selected
do
	name=$(echo $x|sed 's/file:\/\///')
	timestamp=$(date +%s.%N)
	#lastchar=$(echo $name|tail -c 5)
	nn=$(echo $name|awk -F/ '{print $NF}')
	output="$timestamp-$nn"
	wput "$name" ftp://BENUTZERNAME:$PASS@FTP-SERVER/bilder/$output
	error=$?
	uri=http://SERVER/bilder/$output
	if [ $error != 0 ]
	then	
		zenity --info --text "Fehler beim Hochladen der Datei $name" --title "Fehler"
	else
		zenity --info --text "Datei $name erfolgreich hochgeladen\nUrl:\t $uri" --title "Abgeschlossen"
	fi
 
done

Wie schon zuvor gilt: Abzulegen ist das Ganze in einer ausführbaren Datei im Verzeichnis ~/.gnome2/nautilus-scripts.

FourCC mit Nautilus-Skript ändern

#!/bin/sh
 
paths=$NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
selected=$NAUTILUS_SCRIPT_SELECTED_URIS
cur=$NAUTILUS_SCRIPT_CURRENT_URI
 
fourcc=$(zenity --entry --text "Geben sie den neuen FOURCC ein")
 
for x in $selected
do
    name=$(echo $x|sed 's/file:\/\///')
    cfourcc -u $fourcc $name
done

Abzulegen ist das Ganze in einer ausführbaren Datei im Verzeichnis ~/.gnome2/nautilus-scripts. Benötigt werden die Pakete cfourcc und zenity

pyConnect

Da ich in letzter Zeit doch öfter mal meinen Router neu starten musste, habe ich mich nach Möglichkeiten umgesehen, dies automatisiert zu tun. Auf dieser Seite finden sich dazu sehr einfache Skripte für dutzende von Routern.

Mit etwas Python drumherum erhält man auch direkt Rückmeldung darüber, in welchem Zustand sich die Verbindung gerade befindet:

#!/usr/bin/env python
# coding:utf-8
 
import subprocess
from pynotify import init, Notification
import sys
 
IP="192.168.2.123"
pwd="PASSWORD"
user="USERNAME"
 
# For information how to restart your router,
# visit:
#
# http://www.paehl.de/reconnect
 
init("PyConnect")
 
class main(object):
    def __init__(self):
        self.notification = None
 
    def go(self):
        self.notify(message="Loging in")
        subprocess.Popen('curl -sS "http://%s/cgi-bin/login.exe" -d "user=%s&pws=%s" 1>/dev/null' % (IP, user, pwd), shell=True).wait()
 
        self.notify(message="Disconnecting")
        subprocess.Popen('curl -sS "http://%s/cgi-bin/statusprocess.exe" -d "pvc=0&cur_if=11&disconnect.x=102&disconnect.y=5&disconnect=Reconnect" 1>/dev/null' %IP , shell=True).wait()
 
        self.notify(message="Connecting")
        subprocess.Popen('curl -sS "http://%s/cgi-bin/statusprocess.exe" -d "pvc=0&cur_if=3&connect.x=47&connect.y=10&connect=+Verbinden+" 1>/dev/null' % (IP), shell=True).wait()
 
        self.notify(message="Done")        
 
    def notify(self, title="pyConnect", message=""):
        if not self.notification:
            self.notification = Notification(title, message)
        else:
            self.notification.update(title, message)
        self.notification.show()
 
prog = main()
prog.go()

TV-Karte trifft auf GStreamer

Im dritten Teil dieser kleinen Serie schauen wir uns mal das Zusammenspiel von GStreamer und einer TV-Karte oder Webcam an.
GStreamer ist ein Multimedia-Framework, das in vielen Programmen Anwendung findet – etwa in Totem, Exaile, Banshee, OGG Convert oder Ubuntus zukünftigem Standard-Videoeditor PiTiVi. Sogar in meinem Pyjama ;). Gerade unter GNOME ist GStreamer das Media-Framework schlechthin.

Entsprechend sollte es eigentlich nicht wundern, dass GStreamer ohne Probleme auf die V4L2-Schnittstelle zugreifen kann. Im Rahmen dieses Eintrages werde ich auch  versuchen, ein paar Grundlegende Fähigkeiten von GStreamer zu beschreiben – es ist anfangs gar nicht so leicht, sich in dieses Gebiet einzuarbeiten.

Videowiedergabe

Grundsätzlich kann man bei GStreamer  3 Arten von Elementen unterscheiden: Source-Elemente kümmen sich um die Eingabe und lesen beispielsweise eine Datei. Filter-Elemente verarbeiten diese Daten, indem sie diese etwa kodieren. Die sogenannten Sink-Elemente kümmern sich schließlich um die Ausgabe und schreiben die Daten beispielsweise in eine Datei. Schauen wir uns einfach mal diesen Befehl zur Videowiedergabe an:

gst-launch-0.10 v4l2src device=/dev/video0 ! video/x-raw-rgb,width=640,height=480 ! ffmpegcolorspace ! xvimagesink

Hier wird schon deutlich, dass GStreamer in Pipes organisiert ist. Das Programm gst-launch-0.10 erlaubt es dabei, selbst komplexe GStreamer-Pipes zu testen, ohne tatsächlich irgendwelchen Code schreiben zu müssen. Hier werden die einzelnen Elemente mit Rufzeichen miteinander verbunden. Eigentlich ist dieser Befehl aber nur zum Testen gedacht: Für richtige Programme bietet GStreamer andere Schnittstellen, so dass auch Laufzeit-Interaktion möglich ist.

Im obigen Beispiel liest das Plugin v4l2src Daten aus der angegebenen Quelle. Diese werden dann an das nachfolgende Element weitergegeben – und in diesem Fall auf 640×480 Pixel skaliert. Das nächste Element ffmpegcolorspace konvertiert die Videodaten in den richtigen Farbraum und xvimagesink gibt schließlich das Bild aus.

Das Ganze mit Ton

Bisher haben wir leider nur Video und keinen Ton. Mit folgendem Befehl lässt sich das ändern:

gst-launch-0.10 v4l2src device=/dev/video0 ! video/x-raw-rgb,width=640,height=480 ! ffmpegcolorspace ! xvimagesink osssrc device=/dev/dsp ! osssink

Hier wird eine zweite Pipe eingerichtet, die sich um die Audioausgabe kümmert. Das Element osssrc liest nun Audiodaten vom Geät /dev/dsp. In diesem Fall haben wir keine Filter-Elemente zwischengeschaltet – die Daten werden sofort an den osssink weiter- und damit ausgegeben. Die beiden Abschnitte dieses Befehls sind dabei voneinander völlig unabhängig. Sowohl die Pipe

v4l2src device=/dev/video0 ! video/x-raw-rgb,width=640,height=480 ! ffmpegcolorspace ! xvimagesink

als auch die Pipe

osssrc device=/dev/dsp ! osssink

sind vollständig lauffähig. Nicht unterschlagen werden soll, dass es sei bei dem “video/x-raw-rgb…”-Element nicht im strengen Sinne um ein Element handelt: Intern wird es erst zu einem Capsfilter-Element umgewandelt. Für uns ist das hier aber zunächst nicht weiter wichtig.

Einmal speichern bitte!

Wer die Audio- und Videodaten nun speichern möchte, sollte sich folgenden Befehl einmal näher ansehen:

gst-launch-0.10 v4l2src device=/dev/video0 !  queue ! video/x-raw-rgb,width=640,height=480 ! ffmpegcolorspace ! theoraenc ! queue !  oggmux name=mux osssrc device=/dev/dsp ! queue ! audioconvert ! vorbisenc ! queue ! mux. mux. ! queue ! filesink location=video.ogg

Wie gehabt werden hier zunächst Videodaten ausgelesen, skaliert und farbkonvertiert. Das neue Element theoraenc kodiert die Daten. Wie wir später noch sehen werden, kann hier genauer spezifiziert werden, in welcher Qualität die Kodierung erfolgen soll. Das Element oggmux packt die kodierten Daten schließlich in einen OGG-Datenstrom, der den Namen “mux” erhält.
Der zweite Abschnitt dieser Pipeline wird durch das Source-Element osssrc eingeleitet. audioconvert wandelt die Raw-Audiodaten zur Weiterverarbeitung um, vorbisenc komprimiert das Ganze mit dem OGG-Vorbis-Encoder. Die Daten aus diesem Vorgang fließen über ein Queue-Element in den OGG-Muxer, den wir zuvor ja “mux” getauft haben. Das war der zweite Abschnitt unserer Pipeline.
Im letzten Teil werden nun die Daten aus “mux” – wieder über einen Queue – an filesink übergeben. Wie der Name schon andeutet, kümmert sich dieser Sink darum, die Daten in eine Datei zu gießen. Das etwas irritierende Element “! mux. mux. !” besteht also tatsächlich aus zwei Elementen: Das erste “mux” fungiert als Ziel für die komprimierten Audiodaten. Da “mux” ja der Name des OGG-Muxers ist, werden diese Audiodaten hier also mit den Videodaten “gemultiplext” – sprich: Zusammen in einen Datenstrom gepackt. Das zweite “mux” leitet einen neuen Abschnitt unserer Pipeline ein: Es fungiert hier also als Source-Element und gibt die Daten an das filesink weiter.

Die  Queues sind übrigens immer da gefordert, wo ein nachfolgendes Element potenziell “langsamer” ist, das aktuelle: Um Aussetzer in Ton und Bild zu vermeiden, wird so schlicht ein Puffer zwischengeschaltet. Besonders, wenn ihr feststellt, dass eine GStreamer-Pipeline in eurer Programm-Implementierung stuckt und springt, fehlen sehr wahrscheinlich Queues an der richtigen Stelle.

Sehen, hören und speichern

Jetzt wollen wir die ganzen Einzelschritte einmal zusammenbringen. Folgender Aufruf sieht schon wirklich mächtig aus:

gst-launch-0.10 v4l2src device=/dev/video0 ! tee name=videoout ! queue ! video/x-raw-yuv,width=640,height=480 ! queue  ! theoraenc quality=30 ! muxout.

osssrc device=/dev/dsp ! tee name=audioout ! queue ! audio/x-raw-int,rate=44000 ! queue ! audioconvert ! vorbisenc !  muxout.

oggmux name=muxout ! filesink location=media2.ogg

videoout. ! queue ! ffmpegcolorspace ! xvimagesink

audioout. ! queue ! osssink

Zur besseren Übersicht habe ich die jeweiligen Abschnitte einmal voneinander getrennt. Eigentlich ist das aber eine zusammenhängende Befehlszeile!

Der erste Abschnitt ähnelt den bisher besprochenen Abschnitten. Neu ist das Element tee: Es dupliziert den Stream – wie das tee in der Linux-Konsole. So können wir später über den Namen “videoout” auf eine Kopie des Videostreams zurückgreifen. Nach einem tee-Element ist immer ein Queue-Element erforderlich. Es folgen weitere bekannte Elemente und schließlich wird der Stream an ein Element mit dem Namen “muxout” übergeben. Das es sich dabei nur um den Namen eines anderen Elementes handelt, erkennt man an dem nachgestellten Punkt. Für uns ist hier erstmal nur wichtig, dass wir den Stream gewissermaßen “zwischengeparkt” haben.

Im zweiten Abschnitt wird parallel für den Audiostream verfahren. Die meisten Elemente sind bekannt, auch hier wird eine “Kopie” mit tee erstellt und auch dieser Stream wird in “muxout” zwischengeparkt.

Der dritte Abschnitt bringt Licht ins Dunkel: “muxout” ist der OGG-Mixer. Er multiplexiert Audio- und Videodaten und gibt das Resultat an den filesink weiter, der das Ganze speichert. Bis hierher ähnelt das Beispiel sehr dem vorherigen Beispiel in “Einmal speichern bitte!”. Neu ist lediglich das Element tee und die Verwendung des Multiplexers. Wann und wo man den Multiplexer “definiert”, ist hier aber eigentlich egal: Man kann auch – wie hier – zunächst einen Stream an einen  Element-Namen leiten und diesen erst später einem Element zuweisen.

In Abschnitt 4 wird der Video-Stream wie gewohnt ausgegeben. Neu ist lediglich, dass hier nicht eine Datei oder ein Gerät als Source dient, sondern eben das Element “videout.“, das wir zuvor mit tee definiert als Kopie des Streams definiert haben.

Im Abschnitt 5 wird mit “audioout.” parallel verfahren.

Fazit

GStreamer stellt Einsteiger meines Erachtens zunächst vor große Hürden. Das einfache Wiedergeben eines schnöden Videos kann dabei durchaus schon einige Kopfschmerzen bereiten. Was aber wirklich begeistert, ist die Vielzahl an Möglichkeiten, die man mit GStreamer hat. So ist es sogar ohne große Probleme möglich, Bluebox-Effekte mit GStreamer zu erzeugen – und das finde ich schon recht imposant. Weiterhin profitiert man als Programmierer von der Vielzahl der unterstützten Codecs. So ist es sicher nicht verwunderlich, dass unter GNOME so viele Programme auf GStreamer zurückgreifen.

Munin Uptime Plugin

Dieses Plugin erweitert Munin (ein Monitoring-Tool für Rechnernetzwerke) um einen Graphen für die Laufzeit der beobachteten Rechner. Erfasst wird jeweils die Laufzeit in Stunden (leicht abzuändern in Tage) und die Leerlaufzeit So kann man schön beobachten, wie lange ein Rechner jeweils läuft und wie viel Zeit davon er sich im Leerlauf befindet.

Derartige Plugins gibt es sicher schon für Munin – aber ich fand es doch reitzvoll, eine eigene Variante einzusetzen.

Viel Spaß damit!

#!/bin/bash
 
if [ "$1" = "config" ]; then
        echo 'graph_title Uptime'
        echo 'graph_args --base 1000 -l 0'
        echo 'graph_vlabel hours'
        echo 'graph_scale no'
        echo 'graph_category system'
        echo 'graph_info How long is your system running?'
        echo 'uptime.label uptime'
        echo 'uptime.info Your PCs uptime'
        echo 'uptime.draw AREA'
        echo 'idle.label idle'
        echo 'idle.info Your PCs idle time'
        echo 'idle.draw AREA'
        exit 0
fi
 
t=$(cut -d " " -f 1 /proc/uptime|cut -d . -f 1)
i=$(cut -d " " -f 2 /proc/uptime|cut -d . -f 1)
 
uptime=$(($t/60/60))
idle=$(($i/60/60))
 
 
echo "uptime.value " $uptime
echo "idle.value " $idle

Obiger Code sollte als ausführbare Datei in dem Verzeichnis “/etc/munin/plugins/” abgelegt werden. Also etwa “/etc/munin/plugins/uptime”.