Album-Covers von Banshee in die Metadaten übernehmen

Veröffentlicht am

Wenn ihr Banshee für eure Musiksammlung benutzt, wisst ihr sicher, dass dabei alle Alben-Covers in einem separaten Verzeichnis abgelegt werden. Ein recht eigennütziges Verhalten, wie ich finde, denn an eine Weiterverwendung der Covers in anderen Programmen ist so nicht zu denken.

Auch, wenn Banshee sonst alle Informationen (je nach Konfiguration) in den Musikdateien selbst speichert – Covers werden ausnahmslos im besagten Verzeichnis verwaltet.

Mein konkreter Problemfall war die zusätzliche Nutzung meiner Musiksammlung in der Squeezebox-Umgebung. Natürlich wollte ich die Covers dabei haben. Lasst euch aber von dem Stichwort Squeezebox nicht abschrecken. Der Artikel sollte recht allgemein gültige Informationen bieten, und euch auch nützlich sein, wenn ihr keine Squeezebox habt.

Der Artikel soll also die Frage beantworten:

Welche Möglichkeiten gibt es, die „BansheeCovers“ weiterzuverarbeiten? …

Vergleich der Systeme

Lasst mich das Problem erst einmal noch etwas genauer beschreiben, indem ich im Speziellen die beiden Systeme, Banshee und Squeezebox, hinsichtlich der AlbumCovers vergleiche:

Ausgangsbasis: Banshee

Banshee’s Speicherort für die Cover-Dateien findet sich unterhalb des Home-Verzeichnisses (genau gesagt unter ~/.cache/media-art). Als Dateinamen werden Hashcodes verwendet, so dass man von den Namen der Dateien leider nicht einfach auf das jeweilige Album schließen kann. Außerdem liegen die Covers teils in unterschiedlichen Größen vor.

Ziel: Squeezebox-Server

Der Squeezebox-Server (früher auch SqueezeCenter genannt) bietet insgesamt drei Möglichkeiten, wie zu einem Album das passende Cover ermittelt werden kann:

  1. Der Server findet die (z.B.) als cover.jpg (weitere Namen sind möglich…) gespeicherten Covers, wenn sie im Album-Verzeichnis, direkt bei den Musikdateien, liegen.
  2. Es kann auch ein separates Cover-Verzeichnis angegeben werden, in dem die Covers zu allen Alben zu finden sind.
  3. Die in den Metadaten der Musikdateien enthaltenen Cover werden ausgelesen.

Pro/Contra

Zu den drei genannten Varianten, wie SqueezeCenter die Alben ermitteln kann, sehe ich die folgenden Pros und Contras hinsichtlich Banshee:

  1. Die erste Variante gefällt mir überhaupt nicht. Das ist zwar recht gängig, aber hat in Verbindung mit Banshee einen entscheidenden Nachteil: wenn ich in Banshee den Künstler- oder Bandnamen ändere (korrigiere), dann verschiebt Banshee die Musikdateien automatisch in einen neuen Ordner – der alte bleibt aber mit der Cover-Bilddatei bestehen. An diesem Verhalten ist schön zu erkennen, dass Banshee diese Cover-Datei nur genau einmal interessiert: zum Zeitpunkt des Imports in die Datenbank – dann nie wieder.
  2. Bei der zweiten Variante müssen natürlich die Bilddateien umbenannt werden, denn der Squeezebox-Server kann mit dem Hashcode im Namen selbstverständlich nichts anfangen. Im ersten Anlauf habe ich es mit dieser Variante versucht. Ich habe alle Bilddateien so umbenannt, dass der Dateiname sich jeweils aus Künstler- und Album-Namen zusammensetzt. Aber: nicht herausbekommen habe ich, wie ich beispielsweise den Künstlernamen AC/DC im Dateinamen angeben muss (der Slash bringt naturgemäß natürlich Probleme mit sich – und alle meine Kodierungs- und Maskierungsversuche schlugen leider fehl…).
  3. Die dritte Variante schien mir also die beste zu sein. Ich denke auch, dass sich die Musiksammlung auch in Zukunft am einfachsten in andere Umgebungen umziehen lässt, wenn die Covers direkt in den Musikdateien enthalten sind.

Covers aus Banshee „herausbekommen“

Zunächst hat sich ohnehin die Frage gestellt, wie die Covers aus dem Banshee-Verzeichnis weiterverarbeitet werden können. Dazu ist natürlich notwendig, zu wissen, wie der Dateiname genau gebildet wird. Ein Blick in den Banshee-Quellcode (speziell hier; siehe CreateArtistAlbumId (string, string)) hat mir aber verraten, wie der Hashcode im Dateinamen gebildet wird:
  1. Zunächst wird ein String aus Album-Künstler + Tabzeichen + Albumname zusammengesetzt.
  2. Dieser String wird dann normalisiert; Unicode/NFKD (siehe Normalization-FAQ).
  3. Für den Ergebnis-String wird dann ein MD5-Code erzeugt.

Dieser Part könnte in Python beispielsweise so aussehen:

#!/usr/bin/python
import unicodedata, md5
artist = u'Overseer'
album = u'Wreckage'
digestable = u'{0}\t{1}'.format(artist, album)
tmp = unicodedata.normalize('NFKD', unicode(digestable))
tmp = md5.new(tmp.encode('utf-8')).hexdigest()
print 'album-{0}.jpg'.format(tmp)

Fehlt noch das Auslesen der Alben aus Banshee. Dazu kann man mit Python einfach auf die Sqlite-Datenbank von Banshee zugreifen. Die Datenbankdatei ist unter ~/.config/banshee-1/banshee.db zu finden.

Und so könnte das Auslesen aussehen (aus Sicherheitsgründen sollte vielleicht besser mit einer Sicherheitskopie der Datenbankdatei gearbeitet werden – obwohl hier ja nur lesend zugegriffen wird):

#!/usr/bin/python
import sqlite3
dbcon = sqlite3.connect('/home/ich/.config/banshee-1/banshee.db')
dbcur = dbcon.cursor()
dbcur.execute('SELECT AlbumID, ArtistName, Title FROM CoreAlbums WHERE ArtistName <> \'\' AND EXISTS (SELECT * FROM CoreTracks WHERE CoreTracks.AlbumID = CoreAlbums.AlbumID) ORDER BY ArtistName, Title;')
for (albumId, artist, album) in dbcur:
    print u'Artist: {0} / Album: {1}'.format(artist, album)

Falls Sqlite nicht installiert ist, kann man das übrigens folgendermaßen nachholen:

sudo apt-get install sqlite3

Wir wissen nun also, wie wir die Alben-Informationen aus der Banshee-Datenbank auslesen und den Dateinamen des Covers für jedes Album bilden können. Nun kommt noch eine Kleinigkeit hinzu: Banshee führt pro Album ggfs. mehrere Cover-Bilder in verschiedenen Größen. So wäre es also praktisch, wenn man das jeweils größte Bild im BansheeCover-Verzeichnis ausfindig machen könnte.

Ich habe das mit dieser Funktion gelöst:

from PIL import Image
import os
import fnmatch
def findBiggestCover(albumCode):
    cover = None; bH = 0; bW = 0
    for root, dirnames, filenames in os.walk('/home/ich/.cache/media-art'):
        for filename in fnmatch.filter(filenames, u'album-{0}.jpg'.format(albumCode)):
            filepath = os.path.join(root, filename)
            img = Image.open(filepath)
            w, h = img.size
            if (w > bW and h > bH) or (w == bW and h > bH) or (h == bH and w > bW):
                cover = filepath; bW = w; bH = h
    return cover

Im Argument albumCode bekommt sie den Hashcode des Albums übergeben. Von dort aus sucht sie dann das größte Cover und gibt den Dateipfad dieser zurück (oder None falls nichts gefunden).

Der Pfad zu den BansheeCovers muss an eure Umgebung angepasst werden (hier mit /home/ich/.cache/media-art angegeben).

Bilder in Audiodateien einbinden

Nun geht es noch darum, wie Bilder in Audiodateien eingebunden werden können. Zu diesem Thema, speziell um die Verwendung des Python-Moduls mutagen zu diesem Zweck, habe ich vor Kurzem schon einen Artikel geschrieben. An diesen möchte ich euch an dieser Stelle natürlich verweisen – auch, um diesen Artikel nicht zu lange werden zu lassen…


Dieser Artikel wurde in der/den Kategorie(n) Planet-U, Praxis, Programmierung und Skripting veröffentlicht und mit den Tags , , , , , , , versehen.

2 Kommentare zu Album-Covers von Banshee in die Metadaten übernehmen

  1. Kommentar von enolive
    19. September 2011, 23:26 Uhr.

    das klingt ja eigentlich ganz nett. So etwas Ähnliches gab es als Perl-Script für Amarok 1.x, seit dem Umstieg auf Banshee vermisse ich leider ein Pendant dazu.

    was ich nicht ganz verstehe ist deine Begründung gegen Variante 1. Bei meinen eigenen Versuchen blieb der Dateiname/Ordnername beim Ändern unbeanstandet. Vielleicht hängt es mit der Option in Banshee zum Aktualisieren der Dateinamen zusammen: http://efreedom.com/Question/6-39344/Way-Banshee-Rename-Song-File-According-Tags. Bei mir ist die Funktion deaktiviert.

    Beim Schreiben eines eigenen Python-Programms sind mir allerdings paar Tücken aufgefallen. Ich muss zugegeben, dass ich fast keine Python-Erfahrung habe:

    1. in der Funktion findBiggestCover kann es doch eigentlich nur ein einziges Cover mit dem Namen album-.jpg geben? Wozu der ganze Aufwand?

    2. kann das Albumcover aus Banshee ein anderer Typ als jpeg sein?

    3. hast du eine Idee, wie man Covers mit mutagen in ogg-Dateien einbettet? Offensichtlich nicht ganz so einfach: http://groups.google.com/group/quod-libet-development/browse_thread/thread/bc517c06181af1eb

    Übrigens scheint es einfacher zu sein, mit mutagen.File anstatt den speziellen Dateitypen zu arbeiten (auch im obigen Link)

    • Kommentar von Gerald
      20. September 2011, 08:23 Uhr.

      Hey, danke für deinen ausführlichen Kommentar!

      Ja, das Problem, das ich mit Variante 1 habe hängt an dieser Option in den Einstellungen. Die will ich aber schon gesetzt haben, damit alle Ordner und Dateien einheitlich benannt sind. Die Metadatenpflege mache ich (größtenteils) mit Banshee.

      Zu den Tücken:

      1. Banshee speichert ein Cover ggfs. mehrfach in unterschiedlichen Größen (pro Größe gibt es dann ein Unterverzeichnis). Zumindest habe ich das so bei mir vorgefunden. Daher die Suche nach dem größten Exemplar.

      2. Weiß ich nicht. Ich wollte es aber offen halten.

      3. Ogg-Files dürften eigentlich ähnlich zu handhaben sein, wie die Flacs. So weit ich weiß benutzen beide das Vorbis-Metadatenformat. Ich hab’s aber selber nie mit Ogg-Files ausprobiert (da ich keine führe).

      Wg. dem Hinweis auf File: ich werde mir das mal ansehen…

      Danke nochmal + Gruß,
      Gerald

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>