Kategorien

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.

GnuCash, AqBanking und HBCI bei der Commerzbank einrichten

Leider ist es nicht ganz einfach, HBCI mit GnuCash so einzurichten, dass es ohne Probleme läuft. Mit HBCI 3.0 funktioniert die Abfrage der Kontoumsätze nicht, da man die folgende Fehlermeldung bekommt:

Warte auf Antwort
Antwort erhalten
HBCI: 9050 - Teilweise fehlerhaft (M)
HBCI: 9210 - Keine gültige Kontoverbindung des Kunden (S)
Beende Dialog mit dem Server

Laut einer Diskussion in der GnuCash-Mailingliste liegt dies daran, dass AqBanking/GnuCash keine Unterkonten unterstützt mit HBCI 3.0. Mit HBCI 2.01 soll es dagegen funktionieren. Nur leider kann man die Schlüsseldatei nicht übermitteln, wenn man HBCI 2.01 beim Einrichten in AqBanking auswählt. In der Logdatei sieht der zugehörige Fehler so aus:

HBCI: 9010 - Auftrag abgelehnt
HBCI: 9130 - Inhalt syntaktisch ungültig, Segment/Auftrag wird abgelehnt
HBCI: 9050 - Teilweise fehlerhaft

Was also tun? Ich habe es schließlich doch noch geschafft, HBCI bei der Commerzbank zum Laufen zu bekommen. Man muss zunächst die Schlüsseldatei erstellen und dabei folgende Erweiterte Optionen einstellen:

Wichtig ist insbesondere, RDH-Version 1 einzustellen (nur diese Art Schlüssel ist kompatibel mit HBCI 2.x) . Nun funktioniert die Schlüsselübermittlung und wir können den Schlüssel anschließend entweder per INI-Brief in der Filiale oder online auf http://www.comerzbanking.de freischalten. Wenn das erfolgt ist, schalten wir den Schlüssel aktiv, d.h. wir setzen den Benutzer-Status auf aktiv:Wenn wir das gemacht haben, schließen wir AqBanking erstmal wieder und nehmen manuell Änderungen in der Konfiguration vor. Da der Abruf der Kontoumsätze nur mit HBCI 2.01 funktioniert, stellen wir die für die Schlüsselübermittlung verwendete Version 3.00 auf 2.01 um. Dazu editieren wir die entsprechende Konfigurationsdatei im Verzeichnis ~/aqbanking/settings/users/xxx.conf (xxx.conf auf eure Gegebenheiten anpassen) und ändern die Zeile

int  hbciVersion="300"

wie folgt ab

int  hbciVersion="201"

Im nächsten Schritt starten wir wieder den AqBanking-Einrichtungsassistenten, rufen den Benutzer für die Commerzbank-Konten auf und führen unter dem Reiter HBCI folgende Aktionen durch:

  1. Server-Schlüssel abrufen
  2. Systemkennung abrufen
  3. Kontenliste abrufen

Nun können wir den Einrichtungsassisten von AqBanking schließen und die Konten in GnuCash zuweisen. Und voilà, der Abruf der Kontoumsätze funktioniert!

E-Mails erneut zustellen aus Exims frozen queue

Bei der Aktualisierung meiner Programme aufgrund der zuletzt bekannt gewordenen Sicherheitslücken in dovecot, openssl usw. war bei mir kurzzeitig die Mailkonfiguration zerschossen. In der Folge konnten einige E-Mails nicht zugestellt werden und deshalb hat exim versucht, die Ursprungsnachricht mit einer Fehlermeldung an den Absender zu schicken. Da das auch nicht funktioniert hat, wurden diese als Nachrichten als frozen im Mailqueue markiert. Diese E-Mails wollte ich nun an den ursprünglichen Empfänger zustellen. Da es glücklicherweise nicht so viele waren, habe ich das kurz folgendermaßen per Hand bewerkstelligt:
Die IDs der frozen messages in Exims Queue auflisten mit

exiqgrep -z -i

Dann die Nachricht der entsprechenden ID anzeigen mit

exim -Mvb ID

Falls es sich um eine Spamnachricht handelt, diese direkt löschen mit

exim -Mrm ID

ansonsten die Ausgabe in eine Datei umleiten mit

exim -Mvb ID > mailcontent

Dann die Datei mailcontent editieren und die oberen Zeilen bis zum Beginn der ursprünglichen Mail löschen. Der „To:“-header darf nur die Mailaddresse des Empfängers enthalten, an den Exim die Mail eigentlich hätte zustellen sollen. Beispielsweise wird aus

1REOlj-0006ED-VH-D
This message was created automatically by mail delivery software.
 
A message that you sent could not be delivered to one or more of its
recipients. This is a permanent error. The following address(es) failed:
 
  xxx@mydomain
    local delivery failed
 
------ This is a copy of the message, including all the headers. ------
 
Return-path: <someone@senderdomain>
Received: from abc.com ([aaa.bbb.ccc.ddd])
        by mymailserver with esmtp (Exim 4.76)
        (envelope-from <someone@senderdomain>)
To: someone@somedomain; anotherone@anotherdomain; xxx@mydomain
...

dann

Return-path: <someone@senderdomain>
Received: from xxx.de ([129.187.xxx.yyy])
        by mymailserver with esmtp (Exim 4.76)
        (envelope-from <someone@senderdomain>)
To: xxx@mydomain
...

Sobald die Änderungen erfolgt sind, kann die Mail mit einem

cat mailcontent | exim -t

an die Empfänger gemäß dem Mail-Header verschickt werden oder mit einem

cat mailcontent | exim someone@somedomain.com

direkt an den/die definierten Empfänger geschickt werden. Durch ein

exim -Mrm ID

wird die entsprechende frozen E-Mail aus dem Queue gelöscht. Diese Schritte müssen für alle Mails durchgeführt werden.

Epson Aculaser C1100 unter Arch Linux

Mit der Installation des Epson Aculaser C1100 unter Arch Linux habe ich mich etwas abgemüht, aber schließlich hat sich die Mühe gelohnt und der Drucker läuft. So habe ich es hinbekommen:

  1. Die entsprechenden RPM-Dateien von Avasys herunterladen
  2. Pakete und Abhängigkeiten installieren
    pacman -S cups ghostscript gsfonts rpmextract foomatic-filters bc libstdc++5

    Die Pakete cups, ghostscript und gsfonts sind die Standardpakete, welche für CUPS erforderlich sind. Mit  rpmextract können wir die Dateien aus den heruntergeladenen rpm-Pakten entpacken. Die Pakete foomatic-filters und libstdc++5 sind Abhängigkeiten des Druckertreibers (siehe dazu auch das Gentoo-Wiki).

  3. Das usblp Modul in rc.conf blacklisten, wie auch imWiki-Artikel zu CUPS empfohlen
    MODULES=(.. !usblp ..)
  4. Den Rechner neu starten
  5. Folgende Befehle als root ausführen, um die Dateien zu entpacken und mit den richtigen Berechtigungen zu erstellen:
    cd /
    rpmextract.sh /path/to/Epson-ALC1100-filter-1.2-0.i586.rpm
    rpmextract.sh /path/to/Epson-ALC1100-filter-cups-1.2-0.i586.rpm
  6. Drucker anschalten und über das CUPS-Webinterface den Drucker hinzufügen.
  7. Testseite drucken und freuen!

Mit strace prüfen, was ein Programm so treibt

Manchmal kommt man mit Fehlermeldungen von Programmen einfach nicht weiter. Bevor man jedoch im Trial- und Errorverfahren Konfigurationsparameter ausprobiert, um dem Fehler auf die Spur zu kommen oder gleich ein alternatives Programm wählt, kann man strace bemühen. Dieses kleine Programm erlaubt es Systemaufrufe eines Programmes zu protokollieren.

Die wichtigsten Parameter von strace

  • -o filename schreibt die Ausgabe in die Datei filename
  • -f mit diesem Parameter protokolliert das Programm auch forks (d.h. neue Prozesse, die durch das zu protokollierende Programm gestartet werden)
  • -tt mit diesem Parameter wird vor jedem Aufruf zunächst die Zeit protokolliert (auf Basis von Mikrosekunden)
  • -e schränkt die Events ein, die strace protokolliert (siehe Beispiele weiter unten)
  • -p PID strace protokolliert die Systemaufrufe des Prozesses mit der Prozess-ID PID

Ein beispielhafter Aufruf sieht dann so aus

strace -o logfile.log -f ./mycommand -mycommandparameter

Im Folgenden sind einige nützliche Beispiele für spezielle Programmaufrufe aufgeführt.

Auf welche Dateien greift ein Programm zu?

strace -e trace=open -o logfile.log ./mycommand -mycommandparameter

Das habe ich mir von NetAdminTools abgeschaut.

Welche Programme startet/pausiert/beendet das Programm?

strace -e trace=process -o logfile.log ./mycommand -mycommandparameter

Wie protokolliere ich die Systemaufrufe eine Programms, das schon gestartet ist?

Hierfür gibt es den Parameter -p von strace, mit dem man die entsprechende Prozess-ID des Programms an strace übergibt. Um diese ID herauszufinden bemüht man zunächst ps, welches mit dem folgenden Befehl die IDs aller laufenden Prozesse mit dem Namen mycommand auflistet.

ps aux | grep mycommand | grep -v grep mycommand

Wer es kürzer haben möchte, sollte sich meine bashrc anschauen, in der eine Funktion pg definiert ist, die mit dem Aufruf

pg mycommand

dasselbe Resultat erzielt. Angenommen die Ausgabe in der Spalte PID lautet 123, dann würde man strace folgendermaßen aufrufen.

strace -o logfile.log -p 123

Falls es mit Sicherhheit nur ein Programm namens mycommand läuft, geht das auch schneller mit einem

strace -o logfile.log -p `pidof mycommand`
<strong><strong>strace -e trace=open</strong></strong>

Wie versteht man die Ausgabe von strace?

Am Beispiel der folgenden Ausgabe wollen wir mal grob nachvollziehen, was ein Programm gerade macht

execve("/bin/cat", ["cat", "/var/log/messages"], [/* 37 vars */]) = 0

Was macht der Befehl execve? Dazu rufen wir mit

man execve

die entsprechende Hilfedatei auf und erfahren dort, dass das Programm cat mit dem Parameter /var/log/messages gestartet wird.

Welche Tips und Kniffe fallen euch noch im Zusammenhang mit strace ein?