Exportar/incorporar arte do álbum em massa no Banshee

Exportar/incorporar arte do álbum em massa no Banshee

Tenho uma biblioteca de música bem estruturada no Banshee. Eu costumava usar pastas há anos, então sempre fui muito bom em manter um sistema de arquivamento rígido. Digo isso não para me gabar (afinal, perdi muito do meu tempo), mas para explicar que meu final de jogo deveria ser possível.

Até o Banshee, eu nunca tive nenhuma utilidade para a arte do álbum, então, quando comecei a usá-lo, usei o Album Art Finder para (meticulosamente) percorrer todos os mais de 8.000 álbuns. Meu entendimento é que o Banshee tem esses arquivos armazenados em um diretório de cache em algum lugar com um nome sem sentido anexado a eles.

Recentemente mudei para o mundo do Squeezebox. É incrível, mas estou tendo problemas para ver a arte do álbum existente porque o Banshee a trancou em seus próprios diretórios, em vez de colocá-la no lugar "certo".

Então, estou procurando uma de duas soluções, ambas analisando o banco de dados do Banshee para:

  1. Preferido:Copie o arquivo de arte como /artist/album/cover.jpg(o servidor Squeezebox entenderá isso).
  2. Incorpore a arte em cada MP3/FLAC/OGG/etc (isso requer que todos os formatos suportem metadados de blob)

Editar: acabei de encontrar toda a arte ~/.cache/media-artcom nomes album-f952aa94b80de0b31b8979d70d5605e2.jpgcomo eu suspeitava.

Se existe uma boa maneira de correlacionar " f952aa94b80de0b31b8979d70d5605e2" com um artista, é isso que eu realmente procuro.

Responder1

Com base na pesquisa MD5 no script de Oli (obrigado!), escrevi um script Python que usa oolhoD3módulo para encontrar MP3s, procurar a capa do álbum no cache do Banshee e incorporar a capa dentro dos MP3s. Ele ignora todos os arquivos que já possuem arte incorporada.

Não é perfeito, mas funcionou em cerca de 90% dos meus MP3s, e você pode lidar manualmente com quaisquer exceções usando o EasyTag. Da forma como está, o script espera que os MP3s estejam a dois níveis de diretório do diretório de destino (raiz da música/artista/álbum). O script imprime um relatório assim que terminar, destacando todos os arquivos que não conseguiu processar ou para os quais não conseguiu encontrar a arte.

Obviamente você precisa instalar o Python e omódulo eyeD3para usá-lo:

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

Responder2

Eu escrevi este pequeno script que segueo que Banshee faz(que é um pouco diferente deas especificações adequadas).

Resumindo, isso faz um loop em meus diretórios musicais e, forma um hash baseado no artista e no álbum (a partir dos nomes dos diretórios), procura um arquivo com esse hash e, se existir, copia-o para o diretório do álbum. Simples.

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

O echo to ~/coverlogestá lá apenas para capturar onde os arquivos foram copiados (caso algo dê errado e você precise excluir todos os arquivos de capa que isso grava.

Responder3

Para ter certeza de que encontrei todos os álbuns, precisei normalizar a string para NFKD antes de fazer o hash. Eu resolvi isso em python por:

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

Todo o meu script é baseado na solução do alphaloop, mas mudei para o mutagen para lidar também com flac e 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

Responder4

Usei o script do alphaloop e funcionou bem, mas funciona apenas para MP3 e minha biblioteca de música é principalmente FLAC e OGG, então escrevi uma pequena ferramenta de linha de comando Java para migrar todas as capas, independentemente do tipo de arquivo.

Você pode encontrá-lo aqui:BansheeArtworkWriter

Demorou aproximadamente 11 minutos na minha biblioteca de música de 2,7 mil arquivos e migrou todas as capas, siga as instruções no leia-me do GitHub e deve ser fácil para qualquer pessoa executá-lo.

Espero que isso ajude mais alguém.

informação relacionada