在 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 脚本,使用eyeD3模块用于查找 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

我写了下面的这个小脚本Banshee 的作用(与适当的规格)。

简而言之,这会循环我的音乐目录,并根据艺术家和专辑(来自目录名称)形成哈希,查找包含该哈希的文件,如果存在,则将其复制到专辑的目录中。很简单。

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

回显~/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作家

它在我的 2.7k 文件音乐库中花费了大约 11 分钟并迁移了所有封面,按照 GitHub 自述文件中的说明进行操作,任何人都可以轻松运行它。

希望它能帮助别人。

相关内容