Массовый экспорт/встраивание обложек альбомов в Banshee

Массовый экспорт/встраивание обложек альбомов в Banshee

У меня хорошо структурированная музыкальная библиотека в Banshee. Я годами просто пользовался папками, поэтому всегда был хорош в поддержании строгой системы хранения. Я говорю это не для того, чтобы похвастаться (в конце концов, это отняло у меня много времени), а чтобы объяснить, что моя конечная цель должна быть достижима.

До Banshee я никогда не пользовался обложками альбомов, поэтому, когда я начал им пользоваться, я использовал его Album Art Finder, чтобы (кропотливо) просмотреть все 8000 с лишним альбомов. Насколько я понимаю, Banshee хранит эти файлы в кэш-каталоге где-то с бессмысленным именем, прикрепленным к ним.

Недавно я перешел в мир Squeezebox. Он потрясающий, но у меня возникли проблемы с тем, чтобы он увидел существующую обложку альбома, потому что Banshee запер ее в своих собственных каталогах, а не поместил в «правильное» место.

Поэтому я ищу одно из двух решений, оба из которых анализируют базу данных Banshee для:

  1. Предпочтительный:Скопируйте файл с изображением как /artist/album/cover.jpg(сервер Squeezebox это поймет).
  2. Встраивайте обложку в каждый файл MP3/FLAC/OGG и т. д. (для этого требуется, чтобы все форматы поддерживали метаданные blob)

Редактировать: Только что нашел все произведения искусства ~/.cache/media-artс именами, album-f952aa94b80de0b31b8979d70d5605e2.jpgкак я и предполагал.

Если есть хороший способ соотнести « f952aa94b80de0b31b8979d70d5605e2» с художником, то это именно то, что мне нужно.

решение1

На основе поиска MD5 в скрипте Оли (спасибо!) я написал скрипт на Python, который используетглазD3модуль для поиска MP3, поиска обложек альбомов в кэше Banshee и встраивания обложек в MP3. Он пропускает любые файлы, в которые уже встроены обложки.

Он не идеален, но он сработал примерно на 90% моих MP3, и вы можете вручную обработать любые исключения с помощью EasyTag. В его нынешнем виде скрипт ожидает, что MP3 будут на два уровня глубже целевого каталога (корневая папка музыки/исполнитель/альбом). После завершения скрипт печатает отчет, выделяя все файлы, которые он не смог обработать или для которых не смог найти обложку.

Очевидно, вам нужно установить Python имодуль eyeD3чтобы использовать его:

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

решение2

Я написал этот небольшой сценарий, который следует нижечто делает Банши(что немного отличается отнадлежащие характеристики).

Короче говоря, это зацикливает мои музыкальные каталоги и формирует хэш на основе исполнителя и альбома (из названий каталогов), ищет файл с этим хешем и, если он существует, копирует его в каталог альбома. Просто.

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

Команда echo to ~/coverlogнужна только для того, чтобы отследить, куда были скопированы файлы (на случай, если что-то пойдет не так и вам понадобится удалить все записанные файлы обложек).

решение3

Чтобы убедиться, что я нашел все альбомы, мне нужно было нормализовать строку до NFKD перед хешированием. Я решил это в python следующим образом:

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

Весь мой скрипт основан на решении alphaloop, но я переключился на mutagen, чтобы также работать с flac и 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

решение4

Я использовал скрипт alphaloop, и он отлично работал, но он работает только с MP3, а моя музыкальная библиотека в основном состоит из FLAC и OGG, поэтому я написал небольшой инструмент командной строки Java для переноса всех обложек независимо от типа файла.

Вы можете найти это здесь:BansheeArtworkПисатель

Это заняло около 11 минут в моей музыкальной библиотеке из 2,7 тыс. файлов, и программа перенесла все обложки. Следуйте инструкциям в файле readme на GitHub, и любой сможет легко запустить ее.

Надеюсь, это поможет кому-то ещё.

Связанный контент