运行 遇到使用 Python 和 Mutagen 为 MP4 文件设置封面的问题
Running into problems setting cover art for MP4 files using Python and Mutagen
根据其他 Whosebug 问题和 mutagen 文档的多项建议,我能够想出代码来获取和设置 MP3 和 MP4 文件中的每个 ID3 标签。我遇到的问题是为 M4B 文件设置封面。
我已经按照这个答案中的布局完全复制了代码:
但是当我尝试 运行 代码时,我仍然收到错误消息。如果我 运行 具有 'albumart' 值的代码本身我收到错误:
MP4file.tags['covr'] = albumart
Exception has occurred: TypeError
can't concat int to bytes
但是,如果我像上述 Whosebug 问题中所示用方括号括起 albumart 变量,我会得到以下输出:
MP4file.tags['covr'] = [albumart]
Exception has occurred: struct.error
required argument is not an integer
这是完整的功能。 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]
这两天我一直在想我做错了什么。如果有人能帮助我发现问题,我会感激你的。
谢谢!
在 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
是封面标签的名称,value
是从图像中读取的数据,包装到 MP4Cover
对象中。好吧,事实证明,如果您像上面的代码一样迭代一个 MP4Cover
对象,那么迭代会在每次迭代中产生一个图像字节 int
。
此外,在 Python 版本 3+ 中,struct.pack
returns 类型为 bytes
的对象。我认为 cover
参数是从封面图像中提取的字节集合。
在你上面给出的代码中,封面图像的字节被包裹在一个类型为 MP4Cover
的对象中,不能像 [= 的第二个参数那样添加到 bytes
23=]。
为了避免必须编辑或修补 mutagen
库源代码,诀窍是将 'MP4Cover' 对象转换为 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)
我还添加了 MP4file.save(filename)
作为代码的最后一行,以保留对文件所做的更改。
根据其他 Whosebug 问题和 mutagen 文档的多项建议,我能够想出代码来获取和设置 MP3 和 MP4 文件中的每个 ID3 标签。我遇到的问题是为 M4B 文件设置封面。
我已经按照这个答案中的布局完全复制了代码:
但是当我尝试 运行 代码时,我仍然收到错误消息。如果我 运行 具有 'albumart' 值的代码本身我收到错误:
MP4file.tags['covr'] = albumart
Exception has occurred: TypeError can't concat int to bytes
但是,如果我像上述 Whosebug 问题中所示用方括号括起 albumart 变量,我会得到以下输出:
MP4file.tags['covr'] = [albumart]
Exception has occurred: struct.error required argument is not an integer
这是完整的功能。 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]
这两天我一直在想我做错了什么。如果有人能帮助我发现问题,我会感激你的。
谢谢!
在 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
是封面标签的名称,value
是从图像中读取的数据,包装到 MP4Cover
对象中。好吧,事实证明,如果您像上面的代码一样迭代一个 MP4Cover
对象,那么迭代会在每次迭代中产生一个图像字节 int
。
此外,在 Python 版本 3+ 中,struct.pack
returns 类型为 bytes
的对象。我认为 cover
参数是从封面图像中提取的字节集合。
在你上面给出的代码中,封面图像的字节被包裹在一个类型为 MP4Cover
的对象中,不能像 [= 的第二个参数那样添加到 bytes
23=]。
为了避免必须编辑或修补 mutagen
库源代码,诀窍是将 'MP4Cover' 对象转换为 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)
我还添加了 MP4file.save(filename)
作为代码的最后一行,以保留对文件所做的更改。