- Abraxas - https://www.effinger.org -

Monkey’s Audio (APE) und Cue Sheets mit Logitech Media Server

Meine Musiksammlung steuere ich über einen Logitech Media Server an und habe einige CDs so gerippt, dass für die komplette CD eine Monkey’s Audio Datei in Verbindung mit einem Cue Sheet vorliegt. Der Logitech Media Server unterstützt zwar prinzipiell Dateien im Monkey’s Audio Format, kann in diesen aber nicht an eine bestimmte Stelle springen, was natürlich für die Kombination mit Cue Sheets unbedingt erforderlich ist, denn schließlich möchte man nicht immer die ganze CD von Anfang an hören, wenn man eigentlich das 4. Lied darauf hören möchte. Deshalb habe ich mich daran gemacht, eine Lösung zu finden, so dass der Logitech Media Server mit der Kombination aus APE/Cue Sheets umgehen kann.

Basis meiner Lösung ist das Programm ffmpeg, welches im Gegensatz zu dem Standard-Logitech Decoder mac (Monkey’s Audio Console Front End) das Springen an eine Start-Position ermöglicht. Allerdings ist ffmpeg etwas speziell, was die Angabe der Sprungpositionen anbelangt, da es genau das Format hh:mm:ss.xxx erwartet und statt einer Endstelle in der Datei nur einen Parameter für die Abspieldauer akzeptiert. Deshalb habe ich ein kleines Übersetzungsprogramm geschrieben. Dieses muss als ffmpeg_wrapper im Verzeichnis /path_to_logitechmediaserver/Bin/i386-linux gespeichert werden und ausführbar gemacht werden (chmod +x):

#!/bin/sh

USAGE="Usage: `basename $0` [-s start_offset_in_sec] [-t end_offset_in_sec] [-i inputfile] any_other_args_for_ffmpeg"
# Example: ffmpeg_wrapper -s 514.733333333333 -t 764.133333333333 -i /path/to/file.ape -loglevel quiet -ac 2 -f wav pipe:1

# convert seconds.milliseconds to hh:mm:ss.xxx (maximum 3 digits for milliseconds)
function hms()
{
 local S=${1}
 ms=$(echo "scale=3;$S/1" | bc | cut -d '.' -f 2 | cut -c1,2,3)
 S=$(echo $S | cut -d '.' -f 1)
 ((h=S/3600))
 ((m=S%3600/60))
 ((s=S%60))
 printf "%02d:%02d:%02d.%d" "$h" "$m" "$s" "$ms"
}

# Parse command line options.
# we need to parse -i as an indicator that parsing of options is finished (keep in mind for convert.conf)
while getopts :s:t:i OPT;  do
    case "$OPT" in
        s)
            START=$OPTARG
            START_NEW="-ss $(hms $START)"
            ;;
        t)
            END=$OPTARG
            DURATION=$(echo "scale=3;$END-$START" | bc)
            DURATION="-t $(hms $DURATION)"
            ;;
        i)  ADDARG="-i"
            ;;
    esac
done

# Remove the switches we parsed above.
shift `expr $OPTIND - 1`

# We want at least one non-option argument = filename
if [ $# -eq 0 ]; then
    echo $USAGE >&2
    exit 1
fi

# Start ffmpeg with adjusted parameters
$(dirname "$0")/ffmpeg ${START_NEW} ${DURATION} ${ADDARG} "$@"

Außerdem muss natürlich ffmpeg auf dem Rechner installiert sein (bei mir funkioniert es wunderbar mit Version 0.11.1), so dass wir im Verzeichnis /path_to_logitechmediaserver/Bin/i386-linux einen symbolischen Link auf das Programm erzeugen können mit einem

ln -s /usr/bin/ffmpeg ffmpeg

Darüber hinaus ergänzen wir noch folgende Zeilen in /path_to_logitechmediaserver/convert.conf bzw. ändern diese ab:

ape mp3 * *
        # FB:{BITRATE=-B %B}D:{RESAMPLE=--resample %D}T:{START=-s %s}U:{END=-t %u}
        [ffmpeg_wrapper] $START$ $END$ -i $FILE$ -loglevel quiet -ac 2 -f wav pipe:1 | [lame] --silent -q $QUALITY$ $RESAMPLE$ -v $BITRATE$ - -

ape flc * *
        # FT:{START=-s %s}U:{END=-t %u}
        [ffmpeg_wrapper] $START$ $END$ -i $FILE$ -loglevel quiet -ac 2 -f wav pipe:1 | [flac] -cs --totally-silent --compression-level-0 --ignore-chunk-sizes -

ape ape * *
        -

Zusätzlich habe ich im Quellcode unter /path_to_logitechmediaserver/Slim/Formats/APE.pm noch eine Zeile ergänzt. Aus

        return $s->{tags}->{'COVER ART (FRONT)'};
}

1;

wird

        return $s->{tags}->{'COVER ART (FRONT)'};
}

sub canSeek { 1 }

1;

So, nun muss man den Logitech Media Server nur noch neu starten und man kann die Musik mit Monkey’s Audio/Cue Sheets genießen 🙂

Prinzipiell sollte die Lösung auch unter Windows mit einem entsprechenden Binary für ffmpeg auch funktionieren, allerdings muss man dann natürlich das Shell-Skript umschreiben.