在 Banshee 中批量導出/嵌入專輯封面

在 Banshee 中批量導出/嵌入專輯封面

我在 Banshee 有一個結構良好的音樂庫。多年來我一直只使用資料夾,所以我一直很擅長維護嚴格的檔案系統。我這麼說並不是為了吹牛(畢竟這確實浪費了我很多時間),而是為了解釋我的最終遊戲應該是可能的。

在 Banshee 之前,我從來沒有真正使用過專輯封面,所以當我開始使用它時,我使用它的專輯封面查找器(煞費苦心地)瀏覽了所有 8000 多張專輯。我的理解是,Banshee 將這些檔案記錄在某個快取目錄中,並附加了一個無意義的名稱。

我最近進入了 Squeezebox 的世界。這太棒了,但我在讓它看到現有的專輯封面時遇到了問題,因為 Banshee 將它鎖在自己的目錄中,而不是將其放在「正確」的位置。

所以我正在尋找兩種解決方案之一,都將 Banshee 的資料庫解析為:

  1. 首選:將藝術檔案複製為/artist/album/cover.jpg(Squeezebox 伺服器會理解這一點)。
  2. 將藝術作品嵌入到每個 MP3/FLAC/OGG/等(這需要所有格式都支援 blob 元資料)

編輯:剛剛發現所有的藝術作品的~/.cache/media-art名字都像album-f952aa94b80de0b31b8979d70d5605e2.jpg我懷疑的那樣。

如果有一種好方法將「f952aa94b80de0b31b8979d70d5605e2」與藝術家聯繫起來,那就是我真正追求的。

答案1

基於 Oli 腳本中的 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 命令列工具來遷移所有封面,無論檔案類型如何。

你可以在這裡找到它:Banshee藝術作家

在我的 2.7k 檔案音樂庫中大約花了 11 分鐘,它遷移了所有封面,按照 GitHub 自述文件中的說明進行操作,任何人都應該很容易運行它。

希望它對其他人有幫助。

相關內容