Exportar/incrustar carátulas de álbumes en masa en Banshee

Exportar/incrustar carátulas de álbumes en masa en Banshee

Tengo una biblioteca de música bien estructurada en Banshee. Solía ​​​​usar carpetas durante años, así que siempre he sido bastante bueno manteniendo un sistema de archivo estricto. Digo esto no para alardear (después de todo, me hizo perder mucho tiempo), sino para explicar que mi final debería ser posible.

Hasta Banshee, nunca tuve ningún uso para la carátula del álbum, así que cuando comencé a usarla, usé su Buscador de carátulas para revisar (minuciosamente) los más de 8000 álbumes. Según tengo entendido, Banshee tiene estos archivos guardados en un directorio de caché en algún lugar con un nombre sin sentido adjunto.

Recientemente me mudé al mundo de Squeezebox. Es increíble, pero tengo problemas para que vea la carátula del álbum existente porque Banshee la tiene guardada en sus propios directorios en lugar de colocarla en el lugar "correcto".

Así que estoy buscando una de dos soluciones, ambas analizando la base de datos de Banshee para:

  1. Privilegiado:Copie el archivo artístico como /artist/album/cover.jpg(el servidor de Squeezebox lo entenderá).
  2. Incrustar el arte en cada MP3/FLAC/OGG/etc (esto requiere que todos los formatos admitan metadatos de blobs)

Editar: Acabo de encontrar todo el arte ~/.cache/media-artcon nombres como album-f952aa94b80de0b31b8979d70d5605e2.jpgel que sospechaba.

Si hay una buena manera de correlacionar " f952aa94b80de0b31b8979d70d5605e2" con un artista, eso es lo que realmente busco.

Respuesta1

Basado en la búsqueda de MD5 en el script de Oli (¡gracias!), escribí un script de Python que usa elojoD3módulo para buscar MP3, buscar la carátula del álbum en el caché de Banshee e incrustar la carátula dentro de los MP3. Omite cualquier archivo que ya tenga ilustraciones incrustadas.

No es perfecto, pero funcionó en aproximadamente el 90% de mis MP3 y puedes manejar manualmente cualquier excepción usando EasyTag. Tal como está, el script espera que los MP3 estén a dos niveles de directorio del directorio de destino (raíz de música/artista/álbum). El script imprime un informe una vez que termina resaltando los archivos que no pudo procesar o para los cuales no pudo encontrar ilustraciones.

Obviamente necesitas instalar Python y elmódulo eyeD3para usarlo:

#! /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 __name__ == "__main__":
    if len(sys.argv) == 1:
        print "Usage: %s path" % (sys.argv[0])
    else:
        embedAlbumArt(sys.argv[1])

Respuesta2

Escribí este pequeño guión que sigue.lo que hace banshee(que es ligeramente diferente alas especificaciones adecuadas).

En resumen, esto repite mis directorios de música y forma un hash basado en el artista y el álbum (a partir de los nombres de los directorios), busca un archivo con ese hash y, si existe, lo copia en el directorio del álbum. Simple.

#!/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

El eco to ~/coverlogestá ahí solo para detectar dónde se han copiado los archivos (en caso de que algo salga mal y necesite eliminar todos los archivos de portada que escribe).

Respuesta3

Para asegurarme de encontrar todos los álbumes, necesitaba normalizar la cadena a NFKD antes del hash. Lo resolví en Python por:

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

Todo mi script se basa en la solución de alphaloop, pero cambié a mutágeno para tratar también con flac y 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

Respuesta4

Utilicé el script de alphaloop y funcionó bien, pero funciona solo para MP3 y mi biblioteca de música es principalmente FLAC y OGG, así que escribí una pequeña herramienta de línea de comandos Java para migrar todas las carátulas sin importar el tipo de archivo.

Lo puedes encontrar aquí:BansheeObra De ArteEscritor

Me tomó aproximadamente 11 minutos en mi biblioteca de música de 2.7k archivos y migró todas las portadas, siga las instrucciones en el archivo Léame de GitHub y debería ser fácil para cualquiera ejecutarlo.

Espero que ayude a alguien más.

información relacionada