MediaTomb unter MacOS X

Auf der Suche nach einem funktionierenden UPnP AV Mediaserver für meinen Macintosh habe ich verschiedene Produkte evaluiert. Der MediaTomb machte dabei einen ganz guten Eindruck (alleine schon wegen der Skriptingfähigkeit), allerdings störte es mich ein wenig, dass es keine fertige Distribution für OSX gab.

Man kann die Software zwar bequem von den MacPorts oder von Fink aus installieren, aber nicht jeder hat diese Tools installiert (die dann auch noch eine Installation von XCode vorraussetzen).

Ich nahm dies zum Anlass, ein fertiges Binary für OSX Leopard INTeL zu generieren (wenn ich mal Zeit habe, baue ich ein ordentliches Universal Binary, was dann auf allen Macs ab 10.4 laufen wird), das man durch simples Drag&Drop aus dem DMG zum Laufen bekommt.

Download der fertigen Anwendung

Hier gibt es die ZIP Datei mit dem MediaTomb zum einfachen Herunterladen. Die Anwendung muss ausgepackt und dann unbedingt in den Programm/Applications Ordner kopiert werden, da der Pfad zum internen Document-Root des Webservers noch hartkodiert ist (eventuell ändere ich das mal).

Falls die Anwendung nicht laufen sollte, dann zunächst weiter unten die Probleme Sektion durchlesen - andernfalls einfach mir mailen. :-)

Anleitung zum Selberbauen

Ich bin zunächst einen sehr bequemen Weg gegangen und habe mir aus den MacPorts das Binary inklusive aller Dependancies erstellen lassen.

Da der MacPort jedoch nicht alle Option so setze, wie ich es wollte (Support für Playstation3) und einige interne Suchpfade nicht stimmten, habe ich mich entschlossen, das Binary nochmals selber aus den Sourcen zu bauen (die notwendigen Libraries waren zu dem Zeitpunkt schon installiert).

Patchen

Ich lud mir die Sourcedistribution von MediaTomb von deren Homepage und führte nach dem Auspacken den Patch aus, der auch in der MacPorts Distribution angewendet wird:

--- src/url.cc    2008/03/01 17:33:21    1714
+++ src/url.cc    2008/04/09 10:32:57    1775
@@ -75,7 +75,7 @@

     if (only_header)
     {
-        curl_easy_setopt(curl_handle, CURLOPT_NOBODY);
+        curl_easy_setopt(curl_handle, CURLOPT_NOBODY, 1);
         curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, URL::dl);
         curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA,
                          (void *)buffer.getPtr());

Der Patch sollte sauber auf die Quellen abgebildet werden (obiges Fragment in eine Datei blubb.diff kopieren und innerhalb des ausgepackten Ordner der MediaTomb Sourcen abspeichern; danach das Kommando patch -p0 < blubb.diff ausführen).

Compilieren

Nun sind die Quellen bereit zum konfigurieren und zum Übersetzen:

$ ./configure \
  --datarootdir=/Applications/MediaTomb.app/Contents/Resources \
  --enable-protocolinfo-extension --enable-db-autocreate \
  --enable-libjs --with-js-h=/opt/local/include/js/ \
  --enable-curl --with-curl-cfg=/opt/local/bin/curl-config \
  --enable-taglib --with-taglib-cfg=/opt/local/bin/taglib-config \
  --enable-libexif --enable-sqlite3 --enable-ffmpeg \
  --disable-id3lib --disable-mysql --disable-libextractor
[.. einige Zeilen configure Output gelöscht ..]
$ make

Suchpfade fixen

Das nächste Problem wäre dann der Umstand, dass im fertigen Binary die Suchpfade zu den dynamisch nachgeladenen Programmbibliotheken auf dem zukünftigen Zielsystem vermutlich nicht vorhanden sind.

Man muss also im MediaTomb Binary diese Pfade austauschen (sichtbar mit otool -L mediatomb); hilfreich ist dazu das Tool install_name_tool unter OS X, welches exakt das macht. Da eine Vielzahl von Bibliotheken angepasst werden muss, habe ich mir ein kleines Shellskript geschrieben, was das übernimmt:

#!/bin/sh
# Fixes searchpath for dynamic libraries inside the mediatomb binary
 
for lib in liba52.0.dylib libavcodec.dylib libavformat.dylib libavutil.dylib \
           libbz2.1.0.dylib libcurl.4.dylib libexif.12.dylib libexpat.1.dylib \
           libiconv.2.dylib libintl.8.dylib libjs.dylib libmagic.1.dylib \
           libnspr4.dylib libplc4.dylib libplds4.dylib libsqlite3.0.dylib \
           libtag.1.dylib libz.1.dylib ; do
  install_name_tool -change /opt/local/lib/$lib @executable_path/../Libraries/$lib mediatomb.bin
done

Natürlich muss man dann noch alle notwendigen Bibliotheken aus den MacPorts mit in das zukünftige MediaTomb Application Bundle kopieren und auch hier überprüfen ob irgendwelche Abhängigkeiten bestehen und falls ja, diese Auflösen und zu guter Letzt alles mit dem install_name_tool behandeln. :-D

Auch dazu gibt es ein Skript, welches ich innerhalb der Libraries Ordner im Application Bundle ausführte, nachdem ich alle notwendigen Bibliotheken aus den MacPorts rüberkopiert hatte:

#!/bin/sh
# Fixes searchpath for dynamic libraries inside dynamic libraries
 
for bin in *.dylib ; do
  for lib in liba52.0.dylib libavcodec.dylib libavformat.dylib libavutil.dylib \
           libbz2.1.0.dylib libcurl.4.dylib libexif.12.dylib libexpat.1.dylib \
           libiconv.2.dylib libintl.8.dylib libjs.dylib libmagic.1.dylib \
           libnspr4.dylib libplc4.dylib libplds4.dylib libsqlite3.0.dylib \
           libtag.1.dylib libz.1.dylib libavdevice.dylib ; do
    install_name_tool -change /opt/local/lib/$lib @executable_path/../Libraries/$lib $bin
  done
done

Wrapper Skript

Damit man einige Einstellungen dem Programm übergeben kann, habe ich noch ein kleines Wrapper Skript geschrieben, welches beim Anklicken des Programmicons ausgeführt wird und welches dann das eigentliche Binary ausführt (und ein Browserfenster zur MediaTomb Instanz öffnet).

#!/bin/sh
#
# Shellskript wrapper for MediaTomb
#
 
# Points to SQLite database for libmagic - overrides builtin value
export MAGIC=/Applications/MediaTomb.app/Contents/Resources/file/magic
 
# MediaTomb server port (the SDK only permits values => 49152)
SERVER_PORT=50123
 
# Fire up application then wait 4 seconds and open up webbrowser
/Applications/MediaTomb.app/Contents/MacOS/MediaTomb.bin --port $SERVER_PORT & \
  ( sleep 4; open http://localhost:$SERVER_PORT & )

Dies und das...

Neben dem Anpassen der Suchpfade und dem Wrapperskript muss man im Application Bundle noch die notwendigen Resource-Files anlegen, also das Icon und das Info.plist. Das Icon habe ich mir mit Gimp schnell selber gebastelt. Wer ein besseres hat, soll es mir doch bitte mailen. :-)

Unterhalb vom Resources-Verzeichnis habe ich dann noch das Webserver Root-Verzeichnis angelegt, sowie die Datenbank für die libmagic abgelegt.

Probleme

Falls nach dem Starten der Anwendung nur ein leeres Browserfenster erscheint, kann dies verschiedene Ursachen haben. Recht häufig wird jedoch bereits eine Anwendung im Hintergrund laufen, die auf die gleiche Technologie zurückgreift und entsprechende Netzwerk-Ports bereits belegt. Das kann eine andere Mediaserver Software sein1), aber auch jedes beliebige andere Programm, welches von UPnP Gebrauch2) macht (bzw. der verwendeten miniupnp-Bibliothek).

Die Fehlermeldung (an der Console) sieht in diesem Fall dann so aus:

  INFO: Loading configuration from: /Users/rhoenie/.mediatomb/config.xml
  INFO: Checking configuration...
  INFO: Setting filesystem import charset to ISO-8859-1
  INFO: Setting metadata import charset to ISO-8859-1
  INFO: Setting playlist charset to ISO-8859-1
  INFO: Configuration check succeeded.
 ERROR: main: upnp error -203
 ERROR: Could not bind to socket.
  INFO: Please check if another instance of MediaTomb or
  INFO: another application is running on the same port.
 ERROR: upnp_cleanup: UpnpUnRegisterRootDevice failed

Die Lösung ist natürlich entsprechend simpel: einfach die andere Anwendung beenden. :-)

Andere Problemlösungen sind in der FAQ-Sektion der MediaTomb Homepage beschrieben.

Anpassung der config.xml

Falls das lokale Setup vom Default abweicht, kann man bestimmte Pfade auch in der config.xml Datei anpassen, welche nach dem ersten Start der Anwendung im Heimatverzeichnis im versteckten Unterordner .mediatomb angelegt wird:

    <name>Mein Toller Server</name>
    <udn>uuid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</udn>
    <home>/pfad/nach/irgendwohin/.mediatomb</home>
    <webroot>/und/noch/ein/anderer/pfad/web</webroot>

Diese Datei muss sowieso in den Editor genommen werden, wenn man die Playstation 3 Erweiterungen aktivieren will:

<protocolInfo extend="yes"/><!-- For PS3 support change to "yes" -->

.. und:

        <!-- Uncomment the line below for PS3 divx support -->
        <map from="avi" to="video/divx"/>

Auf dem Macintosh ist auch dieses Setting wichtig, damit die UTF-8 Dateinamen korrekt wieder gegeben werden. Es kommt in die <import> Sektion der XML Datei:

    <filesystem-charset>UTF-8-MAC</filesystem-charset>
    <metadata-charset>UTF-8-MAC</metadata-charset>

Wer sich näher mit der Konfiguration befassen will und auch einen ersten Einstieg in die Programmierung von Skripten zur Transkodierung sucht, dem sei diese Webseite ans Herz gelegt.

Alternatives Wrapperskript

Hier noch eine andere Variante für das Wrapperskript. Es bindet den MediaTomb auf das Wireless Interface meines iMacs und hält die Anwendung im Vordergrund (angezeigt durch ein Bouncendes Icon im Dock), damit man sie leicht beenden kann.

Allerdings funktioniert das Streamen von Videos nicht in jedem Fall zufriedenstellend über WiFi. Hohe Bitraten bzw. schnelle Wechsel im Bildgeschehen führen zu starken Rucklern - einfache SD-aufgelöste Videodateien sollten jedoch sauber abspielen.

#!/bin/sh
#
# Shellskript wrapper for MediaTomb
#
 
# Extend PATH environment variable (for ffmpeg)
export PATH=/Applications/MediaTomb.app/Contents/MacOS:$PATH
 
# Points to SQLite database for libmagic - overrides builtin value
export MAGIC=/Applications/MediaTomb.app/Contents/Resources/file/magic
 
# MediaTomb server port (the SDK only permits values => 49152)
MT_PORT=50123
 
# MediaTomb notework interface
MT_INTERFACE=en1
 
# Open up webbrowser (you have to wait a little until the application fires up)
open http://localhost:$MT_PORT
 
# Fire up application and keep it in the foreground so user can kill it
/Applications/MediaTomb.app/Contents/MacOS/MediaTomb.bin --port $MT_PORT \
  --interface $MT_INTERFACE
1) TwonkyVision, FUPPES, XMBC
2) XTorrent
Print/export
QR Code
QR Code osx:mediatomb_unter_macos_x (generated for current page)