У меня хорошо структурированная музыкальная библиотека в Банши. Я годами просто использовал папки, поэтому я всегда был достаточно хорош в поддержании строгой системы регистрации. Я говорю это не для того, чтобы похвастаться (в конце концов, это потратило много времени), а чтобы объяснить, что моя финальная игра должна быть возможной.
До Banshee я никогда не пользовался обложками альбомов, поэтому, когда я начал его использовать, я использовал его Album Art Finder, чтобы (кропотливо) просмотреть все 8000 с лишним альбомов. Насколько я понимаю, Banshee хранит эти файлы в каком-то каталоге кеша с бессмысленным именем.
Я недавно переехал в мир Squeezebox. Это потрясающе, но у меня возникают проблемы с тем, чтобы увидеть существующее оформление альбома, потому что Банши заперла его в своих собственных каталогах, а не поместила в «правильном» месте.
Итак, я ищу одно из двух решений, оба из которых анализируют базу данных Banshee:
Если есть хороший способ соотнести «f952aa94b80de0b31b8979d70d5605e2
» с художником, это то, чего я действительно хочу.
На основе поиска MD5 в сценарии Oli (Спасибо!), я записал сценарий Python, который использует eyeD3 модуль, чтобы найти MP3s, искать иллюстрации альбома от кэша Банши и встроить иллюстрации в MP3s. Это пропускает любые файлы, которым уже встроили иллюстрации.
Это не прекрасно, но это продолжило работать приблизительно 90% моего MP3s, и можно вручную обработать любое использование исключений EasyTag.как есть Сценарий ожидает, что MP3s будет двумя уровнями каталога, глубокими из целевого каталога (музыкальный корень/художник/альбом). Сценарий печатает отчет, после того как он сделал выделение любых файлов, которые он не мог обработать или для которого он не мог найти иллюстрации.
Очевидно, необходимо установить 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])
Я написал этот небольшой сценарий, который следует тому, что делает Банши (что немного отличается от соответствующих спецификаций ).
Короче говоря, это зацикливает мои музыкальные каталоги и, формируя хеш на основе исполнителя и альбома (из имен каталогов), ищет файл с таким хешем и, если он существует, копирует его в каталог альбома. Простой.
#!/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
как раз для того, чтобы отследить, куда были скопированы файлы (в случае, если что-то пойдет не так, и вам нужно удалить все файлы обложки, которые это записывает.
Для проверки я нашел все альбомы, я должен был нормализовать строку к NFKD перед хешированием. Я решил его в Python:
def strip_accents(s):
return unicodedata.normalize('NFKD', s)
Мой целый сценарий основан на решении alphaloop, все же я переключился на мутаген, чтобы также иметь дело с 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
Я использовал скрипт alphaloop, и он отлично работал, но он работает только для MP3, а моя музыкальная библиотека в основном FLAC и OGG, поэтому я написал небольшой инструмент командной строки Java для переноса всех обложек независимо от типа файла. [ 111]
Вы можете найти его здесь: BansheeArtworkWriter
Это заняло примерно 11 минут в моей музыкальной библиотеке файлов 2.7k, и она перенесла все обложки, следуйте инструкциям в readme GitHub и любой должен легко его запустить.
Надеюсь, это поможет кому-то еще.