Banshee でアルバムアートを一括エクスポート/埋め込み

Banshee でアルバムアートを一括エクスポート/埋め込み

私は Banshee に、よく構造化された音楽ライブラリを持っています。何年もの間、フォルダーだけを使用していたので、厳格なファイリング システムを維持するのが得意でした。これは自慢するためではなく (結局、かなりの時間を無駄にしました)、私の最終目標は実現可能であることを説明するためです。

Banshee を使うまでは、アルバム アートをまったく使わなかったので、使い始めたときは、アルバム アート ファインダーを使って (苦労して) 8000 枚ほどのアルバムをすべて調べました。私の理解では、Banshee はこれらのファイルを意味のない名前でどこかのキャッシュ ディレクトリに隠しているようです。

最近、Squeezebox の世界に入りました。これは素晴らしいのですが、Banshee がアルバム アートを「正しい」場所に配置するのではなく、独自のディレクトリにロックしているため、既存のアルバム アートを表示させるのに問題があります。

そこで私は、Banshee のデータベースを解析して次のことを実行する 2 つのソリューションのいずれかを探しています。

  1. 推奨:アート ファイルを次のようにコピーします/artist/album/cover.jpg(Squeezebox サーバーはこれを認識します)。
  2. 各 MP3/FLAC/OGG などにアートを埋め込みます (すべてのフォーマットが BLOB メタデータをサポートしている必要があります)

編集:予想通りの~/.cache/media-art名前の付いたアートをすべて見つけました。album-f952aa94b80de0b31b8979d70d5605e2.jpg

f952aa94b80de0b31b8979d70d5605e2「 」をアーティストに関連付ける良い方法があれば、それが私が本当に求めていることです。

答え1

OliのスクリプトのMD5ルックアップに基づいて(ありがとう!)、私はPythonスクリプトを書きました。目D3MP3 を検索し、Banshee のキャッシュからアルバム アートワークを検索し、アートワークを MP3 内に埋め込むモジュールです。アートワークがすでに埋め込まれているファイルはスキップされます。

完璧ではありませんが、私の MP3 の約 90% で動作しました。例外は EasyTag を使用して手動で処理できます。現状では、スクリプトは MP3 がターゲット ディレクトリ (音楽ルート/アーティスト/アルバム) から 2 ディレクトリ レベル深いことを想定しています。スクリプトは、処理できなかったファイルやアートワークが見つからなかったファイルをハイライト表示し、完了するとレポートを出力します。

もちろん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 のソリューションに基づいていますが、flac と m4a も処理できるように mutagen に切り替えました。

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 コマンドライン ツールを作成しました。

こちらからご覧いただけます:Bansheeアートワークライター

私の 2.7k ファイルの音楽ライブラリでは約 11 分かかりましたが、すべてのカバーが移行されました。GitHub の readme の指示に従えば、誰でも簡単に実行できるはずです。

他の誰かの役に立つことを願います。

関連情報