Tag Archive: icon

Minidlna/ReadyMedia mit eigenem Symbol kompilieren

DLNA

Ich habe nie verstanden, warum ReadyMedia (früher Minidlna) bei der Einbindung des Icons einen so umständlichen Weg eingeschlagen hat.

ReadyMedia – aus dem offiziellen Quell-Code – verwendet je nach System unterschiedliche Symbole. So sehen Linux-Benutzer etwa den Tux-Pinguin, BSD-Benutzer hingegen Beastie, den kleinen Teufel. Zudem existiert für spezielle Konfigurationen ein Logo Netgears.
Um jedoch ein eigenes Symbol zu verwenden, reicht es nicht aus, die ein oder andere Grafik auszutauschen. Die Grafiken liegen als „dumps“ in der Datei „icons.c“.
Das macht einen Eingriff in den Quell-Code unumgänglich.

Beispiel ReadyMedia Symbol
Beispiel für ReadyMedia Symbol
Zur Vereinfachung habe ich ein Script geschrieben, das eine Datei „icons.c“ im Verzeichnis des Scripts anlegt. Die Daten in dieser Datei gelten für alle Systeme.
Die Grafiken werden – wie ReadyMedia es verlangt – einmal in das JPEG- sowie PNG-Format umgewandelt. Im gleichen Schritt werden beiden Dateien auf die Größe 120×120 bzw. 40×40 Pixel skaliert.

Getestet habe ich alles Folgende unter Ubuntu Server 13.10. Es sollte jedoch problemlos auf nahen Derivaten läuffähig sein.

Zu Beginn installiere ich diverse Abhängigkeiten, wovon „imagemagick“ und „xd“ für das Script notwendig sind:

sudo apt-get install autoconf gettext autopoint build-essential libvorbis-dev libsqlite3-dev libogg-dev libjpeg-dev libid3tag0-dev libflac-dev libexif-dev libavutil-dev libavformat-dev libavcodec-dev debhelper imagemagick xd

Als nächstes die aktuellste Version herunterladen und entpacken. Gearbeitet wird im Verzeichnis „~/build“:

mkdir ~/build
cd ~/build
wget --content-disposition -O - http://sourceforge.net/projects/minidlna/files/latest/download | tar xfvz -

Nun in das neue Verzeichnis wechseln und das Script erstellen:

cd ~/build/minidlna*
nano minidlna_icon_patch.sh

Dort folgenden Inhalt einfügen:

#!/bin/bash
PATH=/usr/bin:/usr/local/bin:$PATH
command -v convert >/dev/null 2>&1 || { echo >&2 "Please install imagemagick"; exit 1; }
command -v xxd >/dev/null 2>&1 || { echo >&2 "Please install xd"; exit 1; }
if [ -z "$1" ]; then
        echo "Usage: $0 imagefile"
        exit 1
fi
if [ ! -f $1 ]; then
        echo "Image does not exist"
        exit 1
fi
if [ -f icons.c ]; then
        mv icons.c icons.c_bak
fi
convert $1 -resize 40x40\! tmp_png_sm.png
convert $1 -flatten -resize 40x40\! tmp_jpeg_sm.jpeg
convert $1 -resize 120x120\! tmp_png_lrg.png
convert $1 -flatten  -resize 120x120\! tmp_jpeg_lrg.jpeg
xxd -p -c 24 tmp_png_sm.png | sed -e '    s/../\\x&/g' \
        -e '1   s/^/unsigned char png_sm\[\] =  "/' \
        -e '1 ! s/^/             "/' \
        -e '    s/$/"/' \
        -e '$   s/$/;/' >> icons.c
xxd -p -c 24 tmp_jpeg_sm.jpeg | sed -e '    s/../\\x&/g' \
        -e '1   s/^/unsigned char jpeg_sm\[\] =  "/' \
        -e '1 ! s/^/             "/' \
        -e '    s/$/"/' \
        -e '$   s/$/;/' >> icons.c
xxd -p -c 24 tmp_png_lrg.png | sed -e '    s/../\\x&/g' \
        -e '1   s/^/unsigned char png_lrg\[\] =  "/' \
        -e '1 ! s/^/             "/' \
        -e '    s/$/"/' \
        -e '$   s/$/;/' >> icons.c
xxd -p -c 24 tmp_jpeg_lrg.jpeg | sed -e '    s/../\\x&/g' \
        -e '1   s/^/unsigned char jpeg_lrg\[\] =  "/' \
        -e '1 ! s/^/             "/' \
        -e '    s/$/"/' \
        -e '$   s/$/;/' >> icons.c
rm tmp_*jpeg tmp_*png

Nun das Script als ausführbar markieren:

chmod +x minidlna_icon_patch.sh

Das neue Symbol sollte eine Aspect Ratio von 1:1 haben, also genauso breit wie hoch sein. Am besten wird ein Bild >= 120×120 Pixel ausgewählt. Das Format spielt keine Rolle.
Diese Bild-Datei, angenommen „image.png“, lege ich in diesem Beispiel im Verzeichnis des Scripts ab. Die Syntax lautet „./minidlna_icon_patch.sh grafik.ext“:

./minidlna_icon_patch.sh image.png

Es wurde ein Backup der originalen Datei „icon.c“ unter dem Namen „icon.c_bak“ angelegt.
Die Installation konfiguriere ich ohne besondere Parameter (etwa „prefix“ etc.):

./configure
make -j2
sudo make install

Die ausführbare Datei befindet sich so unter „/usr/local/sbin/minidlnad“.
Nun zur ReadyMedia-Konfiguration, welche ich sehr simpel halte. Hierzu bitte einfach in die man-page schauen. Ausgeführt wird ReadyMedia als Benutzer „nobody“.

sudo nano /etc/minidlna.conf

Inhalt:

user=nobody
media_dir=/opt/files
friendly_name=ReadyMedia
inotify=yes
log_dir=/var/log
log_level=warn
root_container=B

Diverse Verzeichnisse wird ReadyMedia nicht selbstständig anlegen, da der Benutzer „nobody“ dies nicht darf. Das erledige ich manuell:

sudo mkdir /var/{run,cache}/minidlna
sudo touch /var/log/minidlna.log
sudo chown -R nobody:nogroup /var/{run,cache}/minidlna /var/log/minidlna.log

Das Verzeichnis „/opt/files“, welches die Medien-Dateien (Urlaubsbilder ;) ) enthält, muss natürlich für den Benutzer „nobody“ lesbar sein.
Für den automatischen Start, wird ein Init-Script angelegt:

sudo nano /etc/init.d/minidlna

Der Inhalt:

#!/bin/sh

# chkconfig: 345 99 10
# description: Startup/shutdown script for MiniDLNA daemon
#
# Based on the MiniUPnPd script by Thomas Bernard
# Modified for MiniDLNA by Justin Maggard 
# Status function added by Igor Drobot
#
### BEGIN INIT INFO
# Provides:          minidlna
# Required-Start:    $network $local_fs $remote_fs
# Required-Stop::    $network $local_fs $remote_fs
# Should-Start:      $all
# Should-Stop:       $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: DLNA/UPnP-AV media server
### END INIT INFO

MINIDLNA=/usr/local/sbin/minidlnad
PIDFILE=/var/run/minidlna/minidlna.pid
CONF=/etc/minidlna.conf
ARGS="-f $CONF"

test -f $MINIDLNA || exit 0

. /lib/lsb/init-functions

case "$1" in
start)  log_daemon_msg "Starting minidlna" "minidlna"
        start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $MINIDLNA -- $ARGS $LSBNAMES
        log_end_msg $?
        ;;
stop)   log_daemon_msg "Stopping minidlna" "minidlna"
        start-stop-daemon --stop --quiet --pidfile $PIDFILE
        log_end_msg $?
        ;;
restart|reload|force-reload)
        log_daemon_msg "Restarting minidlna" "minidlna"
        start-stop-daemon --stop --retry 5 --quiet --pidfile $PIDFILE
        start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $MINIDLNA -- $ARGS $LSBNAMES
        log_end_msg $?
        ;;
status)
        status_of_proc -p $PIDFILE $MINIDLNA minidlna && exit 0 || exit $?
        ;;
*)      log_action_msg "Usage: /etc/init.d/minidlna {start|stop|restart|reload|force-reload|status}"
        exit 2
        ;;
esac
exit 0

Das Script als ausführbar markieren und den Dienst installieren:

sudo chmod +x /etc/init.d/minidlna
sudo update-rc.d minidlna defaults

Bevor der Dienst gestartet wird, erhöhe ich die „max_user_watches“ für „inotify“, damit ReadyMedia vernünftig arbeiten kann. Dies dient zur Erkennung neuer Medien-Dateien:

sudo bash -c "echo fs.inotify.max_user_watches=1048576 >> /etc/sysctl.conf" && sudo sysctl -p

Nun den Dienst starten:

sudo service minidlna start