根据其他StackOverflow问题和诱变剂文档的多项建议,我能够拿出代码来获取和设置MP3和MP4文件中的每个ID3标签。我遇到的问题是设置M4B文件的封面。
我已完全按照此答案中的布局复制了代码:
Embedding album cover in MP4 file using Mutagen
但是,当我尝试运行代码时,我仍然收到错误。如果我自己使用“ albumart”值运行代码,则会收到错误:
MP4file.tags['covr'] = albumart
发生异常:TypeError 无法将int转换为字节
但是,如果我用上面提到的StackOverflow问题中的方括号将albumart变量括起来,则会得到以下输出:
MP4file.tags['covr'] = [albumart]
发生异常:struct.error 必填参数不是整数
这是全部功能。 MP3部分可以正常工作。
from mutagen.mp3 import MP3
from mutagen.mp4 import MP4, MP4Cover
def set_cover(filename, cover):
r = requests.get(cover)
with open('C:/temp/cover.jpg', 'wb') as q:
q.write(r.content)
if(filename.endswith(".mp3")):
MP3file = MP3(filename, ID3=ID3)
if cover.endswith('.jpg') or cover.endswith('.jpeg'):
mime = 'image/jpg'
else:
mime = 'image/png'
with open('C:/temp/cover.jpg', 'rb') as albumart:
MP3file.tags.add(APIC(encoding=3, mime=mime, type=3, desc=u'Cover', data=albumart.read()))
MP3file.save(filename)
else:
MP4file = MP4(filename)
if cover.endswith('.jpg') or cover.endswith('.jpeg'):
cover_format = 'MP4Cover.FORMAT_JPEG'
else:
cover_format = 'MP4Cover.FORMAT_PNG'
with open('C:/temp/cover.jpg', 'rb') as f:
albumart = MP4Cover(f.read(), imageformat=cover_format)
MP4file.tags['covr'] = [albumart]
两天以来,我一直在努力弄清楚我做错了什么。如果有人可以帮助我找出问题所在,我将在您的债务中。
谢谢!
答案 0 :(得分:1)
在mutagen
的源代码中,在引发异常的位置,我发现了以下几行:
def __render_cover(self, key, value):
...
for cover in value:
try:
imageformat = cover.imageformat
except AttributeError:
imageformat = MP4Cover.FORMAT_JPEG
...
Atom.render(b"data", struct.pack(">2I", imageformat, 0) + cover))
...
其中key
是Cover标签的名称,value
是从图像读取的数据,包装在MP4Cover
对象中。好吧,事实证明,如果您像上面的代码那样遍历MP4Cover
对象,则每次迭代将为int
生成一个图像字节。
此外,在Python 3+版本中,struct.pack
返回类型为bytes
的对象。我认为cover
参数是从封面图像中提取字节的集合。
在您上面给出的代码中,封面图像的字节被包装在MP4Cover
类型的对象内,该对象无法像{{1}的第二个参数那样添加到bytes
}。
为避免不得不编辑或修补Atom.render
库源代码,诀窍是将“ MP4Cover”对象转换为mutagen
并将结果包装在集合中,如下所示。
bytes
我还添加了import requests
from mutagen.mp3 import MP3
from mutagen.mp4 import MP4, MP4Cover
def set_cover(filename, cover):
r = requests.get(cover)
with open('C:/temp/cover.jpg', 'wb') as q:
q.write(r.content)
if(filename.endswith(".mp3")):
MP3file = MP3(filename, ID3=ID3)
if cover.endswith('.jpg') or cover.endswith('.jpeg'):
mime = 'image/jpg'
else:
mime = 'image/png'
with open('C:/temp/cover.jpg', 'rb') as albumart:
MP3file.tags.add(APIC(encoding=3, mime=mime, type=3, desc=u'Cover', data=albumart.read()))
MP3file.save(filename)
else:
MP4file = MP4(filename)
if cover.endswith('.jpg') or cover.endswith('.jpeg'):
cover_format = 'MP4Cover.FORMAT_JPEG'
else:
cover_format = 'MP4Cover.FORMAT_PNG'
with open('C:/temp/cover.jpg', 'rb') as f:
albumart = MP4Cover(f.read(), imageformat=cover_format)
MP4file.tags['covr'] = [bytes(albumart)]
MP4file.save(filename)
作为代码的最后一行,以保留对文件所做的更改。