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:
/artist/album/cover.jpg
(le serveur Squeezebox le comprendra).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.
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])
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.
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
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.