web-dev-qa-db-fra.com

Exportation en vrac / pochettes d'album à Banshee

J'ai une bibliothèque musicale bien structurée à Banshee. Je n'utilisais que des dossiers pendant des années, j'ai donc toujours su maintenir un système de classement strict. Je ne dis pas cela pour me vanter (après tout, cela m'a fait perdre beaucoup de temps), mais pour expliquer que mon jeu final devrait être possible.

Jusqu'à Banshee, je n'avais jamais vraiment utilisé les pochettes d'album. Lorsque j'ai commencé à les utiliser, j'utilisais alors Album Art Finder pour parcourir (minutieusement) les quelque 8 000 albums. D'après ce que j'ai compris, Banshee a ces fichiers supprimés dans un répertoire de cache quelque part avec un nom dépourvu de sens.

J'ai récemment déménagé dans le monde de la Squeezebox. C’est génial, mais j’ai du mal à voir les pochettes d’album existantes, car Banshee les garde dans leurs propres répertoires au lieu de les placer "au bon" endroit.

Je recherche donc l'une des deux solutions, analysant la base de données de Banshee pour:

  1. préféré: Copiez le fichier d'art en tant que /artist/album/cover.jpg (le serveur Squeezebox le comprendra).
  2. Intégrez l'art dans chaque fichier MP3/FLAC/OGG/etc (cela nécessite que tous les formats prennent en charge les métadonnées de blob)

Edit: Je viens de trouver tout l’art dans ~/.cache/media-art avec des noms comme album-f952aa94b80de0b31b8979d70d5605e2.jpg comme je le suspectais.

S'il existe un bon moyen de corroder "f952aa94b80de0b31b8979d70d5605e2" à un artiste, c'est ce que je recherche vraiment.

6
Oli

Basé sur la recherche MD5 dans le script d'Oli (merci!), J'ai écrit un script Python qui utilise le module eyeD pour rechercher des fichiers MP3, recherchez les pochettes d'album dans la mémoire cache de Banshee. et incorporer l’œuvre dans les fichiers MP3. Il ignore tous les fichiers contenant déjà des illustrations.

Ce n'est pas parfait, mais cela a fonctionné sur environ 90% de mes MP3 et vous pouvez gérer manuellement les exceptions à l'aide d'EasyTag. Dans l'état actuel des choses, le script s'attend à ce que les fichiers MP3 soient situés à deux niveaux de répertoire différents du répertoire cible (répertoire racine/artiste/album). Le script imprime un rapport une fois terminé, en mettant en évidence les fichiers qu'il n'a pas pu traiter ou pour lesquels il n'a pas trouvé d'illustration.

Vous devez évidemment installer Python et le module eyeD pour l'utiliser:

#! /usr/bin/env python

import os, sys, glob, eyeD3, hashlib

CACHE_FILE_PREFIX = os.getenv("HOME") + "/.cache/media-art/album-"

def embedAlbumArt(dir = "."):
    artworkNotFoundFiles = []
    errorEmbeddingFiles = []
    noMetadataFiles = []
    mp3s = findMP3Files(dir)

    for mp3 in mp3s:
        print "Processing %s" % mp3

        tag = eyeD3.Tag()
        hasMetadata = tag.link(mp3)

        if not hasMetadata:
            print "No Metadata - skipping."
            noMetadataFiles.append(mp3)
            continue

        if hasEmbeddedArtwork(tag):
            print "Artwork already embedded - skipping."
            continue

        artworkFilename = findAlbumArtworkFile(tag)

        if not artworkFilename:
            print "Couldn't find artwork file - skipping."
            artworkNotFoundFiles.append(mp3)
            continue

        print "Found artwork file: %s" % (artworkFilename)

        wasEmbedded = embedArtwork(tag, artworkFilename)

        if wasEmbedded:
            print "Done.\n"
        else:
            print "Failed to embed.\n"
            errorEmbeddingFiles.append(mp3)

    if artworkNotFoundFiles:
        print "\nArtwork not found for:\n"
        print "\n".join(artworkNotFoundFiles)

    if errorEmbeddingFiles:
        print "\nError embedding artwork in:\n"
        print "\n".join(errorEmbeddingFiles)

    if noMetadataFiles:
        print "\nNo Metadata found for files:\n"
        print "\n".join(noMetadataFiles)

def findMP3Files(dir = "."):    
    pattern = "/".join([dir, "*/*", "*.mp3"])   
    mp3s = glob.glob(pattern)
    mp3s.sort()
    return mp3s

def hasEmbeddedArtwork(tag):
    return len(tag.getImages())

def findAlbumArtworkFile(tag):
    key = "%s\t%s" % (tag.getArtist(), tag.getAlbum())
    md5 = getMD5Hash(key)
    filename = CACHE_FILE_PREFIX + md5 + ".jpg"
    if os.path.exists(filename):
        return filename
    else:
        return 0

def getMD5Hash(string):
    string = string.encode("utf-8")
    md5 = hashlib.md5()
    md5.update(string)
    return md5.hexdigest()

def embedArtwork(tag, artworkFilename):
    tag.addImage(eyeD3.ImageFrame.FRONT_COVER, artworkFilename)
    success = 0
    try:
        success = tag.update()
    except:
        success = 0
    return success

if __== "__main__":
    if len(sys.argv) == 1:
        print "Usage: %s path" % (sys.argv[0])
    else:
        embedAlbumArt(sys.argv[1])
5
alphaloop

J'ai écrit ce petit script qui suit ce que fait Banshee (qui est légèrement différent de les spécifications appropriées ).

En bref, cela boucle mes répertoires de musique et forme un hachage basé sur l'artiste et l'album (à partir des noms de répertoires), recherche un fichier contenant ce hachage et, s'il existe, le copie dans le répertoire de l'album. Facile.

#!/bin/bash

TPATH="/home/oli/.cache/media-art/"

cd /media/ned/music/

for f in *; do 
        cd "$f"
        for al in *; do
                THUMB="${TPATH}album-$(echo -ne "$f\t$al" | md5sum | cut -b1-32).jpg"
                if [ -e $THUMB ]; then
                        cp $THUMB ./cover.jpg
                        echo "/media/ned/music/$f/$al/cover.jpg" >> ~/coverlog
                fi
        done
        cd ..        
done

L'écho vers ~/coverlog est juste là pour repérer les endroits où les fichiers ont été copiés (en cas de problème et que vous deviez supprimer tous les fichiers de garde écrits.

2
Oli

Pour être sûr d'avoir trouvé tous les albums, j'avais besoin de normaliser la chaîne en NFKD avant le hachage. Je l'ai résolu en python par:

def strip_accents(s):
    return unicodedata.normalize('NFKD', s)

Tout mon script est basé sur la solution d'alphaloop, mais je suis passé à mutagen pour traiter également flac et m4a:

def getArtistAlbum(musicfile):
     """ return artist and album strings of a music file """
     import mutagen

     # key of stored information per file extension
     keys={'flac': ('artist','album'),
           'mp3': ('TPE2','TALB'),
           'm4a': ('\xa9ART','\xa9alb')}

     # read the tag
     tag = mutagen.File(musicfile)
     # get extension of musicfile
     ext = os.path.splitext(musicfile)[1][1:]

    try:
        return tag[keys[ext][0]][0], tag[keys[ext][1]][0]
    except KeyError:
        return None,None
1
mark

J'ai utilisé le script alphaloop et cela a bien fonctionné, mais cela fonctionne uniquement pour les MP3 et ma bibliothèque musicale est principalement composée de FLAC et OGG. J'ai donc écrit un petit outil de ligne de commande Java pour migrer tous les pochettes, quel que soit le fichier. type.

Vous pouvez le trouver ici: BansheeArtworkWriter

Il a fallu environ 11 minutes dans ma bibliothèque musicale de fichiers 2.7k et la migration de toutes les couvertures a été effectuée, suivez les instructions du fichier readme de GitHub et il devrait être facile à utiliser pour tout le monde.

J'espère que ça aide quelqu'un d'autre.

0
Federico Schmidt