dob*_*ovv 1 python mutagen python-3.6
我在编写脚本时遇到问题,用mutagen标记我的音乐库.以下代码在处理mp3文件时工作正常,但会破坏m4a文件.
def set_video_tags(video, filepath):
try:
tags = ID3(filepath, v2_version=3)
except ID3NoHeaderError:
tags = ID3()
tags.add(TXXX(3, desc='desc:custom_tag',text= video.custom_text))
tags.save(filepath, v2_version=3)
Run Code Online (Sandbox Code Playgroud)
处理完m4a文件后,可以使用mutagen回读标签,但任何其他播放器都不会检测到标签,并且音频不会播放.
我试图在调用此函数之前从文件中删除MP4标签,但它没有帮助.
我究竟做错了什么?
正如我在评论中所说,MP4和MP3是不同的容器,它们使用完全不同的结构来存储元数据.虽然从技术上讲,你可以在MP4元数据中对ID3字段进行编码,但这种情况的使用在很大程度上取决于你的标记器/播放器,因为有很多方法可以做到这一点,而且每个人都认为他们有最好的方式来推动他们自己的结构.
什么是MP3容器的ID3,XMP适用于MP4/M4A容器(如果你想的话,还有许多其他容器,如JPEG,PDF甚至MP3) - 除了XMP是一个实际的标准,而ID3是事后的想法(它实际上是只是在MP3文件末尾增加了一个尾随结构,每个人都参与其中,其功能主要由当时大受欢迎的玩家决定,如WinAmp,foobar2000等.相比之下,XMP本质上是一个类似原子的结构(这就是为什么你会听到mp4标签被称为'原子',即使它们不是指同一个东西),它与元数据一起也带有什么信息.元数据表示,即使是第一次遇到它的玩家,理论上也可以从不相关的元数据中辨别相关信息.
当然,在实践中,这也变成了一个玩家/标记器战争,因此他们中的许多人使用他们自己的自定义"扩展"进行标记 - 目前iTunes对于应该使用哪些字段以及如何以及其他玩家如何使用 - 打球 - 所以mutagen.iTunes将标签扩展为MP4结构本身的非视频/音频帧(实际的"原子")而不是单个XMP结构,并且一些"标签"必须奇怪地命名(二进制名称等),因此它们不会t干扰格式本身.虽然这种方法有一些优势(使用流式传输更改元数据,对实时事件非常有用),但它会使标记变得不必要地复杂化,而且非标准化.
无论如何,你的问题出现是因为你正在尝试将ID3结构写入MP4容器 - 当写入ID3标签时mutagen不会解析整个文件以辨别基础文件是否支持ID3以及在何处/如何编写它,而是假设它已被送入一个普通的MP3文件,并以错误的格式写下错误的地方,最好只是在文件的末尾添加一些垃圾(早期的,不可流传输的ID3版本),或者最坏的情况是,破坏你的M4A容器因此.当你读回文件时也是如此 - 它可以读取它之前在可预测位置写入的ID3结构,它不关心其余数据是什么.
因此,正如我所说,并且正如文档中所示,在处理MP4/M4A容器时使用mutagen.mp4.MP4(或者更确切地说是底层mutagen.mp4.MP4Tags),因为这些容器是为了使用MP4容器而创建的.例如,要desc在尝试时更改标记:
from mutagen.mp4 import MP4
def get_description(filename):
return MP4(filename).tags.get("desc", [None])[-1]
def set_description(filename, description):
tags = MP4(filename).tags
tags["desc"] = description
tags.save(filename)
Run Code Online (Sandbox Code Playgroud)
注意:我只使用函数中的最后一个desc条目,get_description()因为每个'tag'支持多个条目,因此现有标记将作为列表返回.你显然不会在生产环境中使用上述内容.
你可以测试它:
print("Current description: {}".format(get_description("test.m4a")))
# Current description: None
set_description("test.m4a", "Test description") # let's add some description
print("Current description: {}".format(get_description("test.m4a")))
# Current description: Test description
# You can also modify the description once set:
set_description("test.m4a", get_description("test.m4a") + " update")
print("Current description: {}".format(get_description("test.m4a")))
# Current description: Test description update
# etc.
Run Code Online (Sandbox Code Playgroud)
对于一整套"支持"(或更确切地说是iTunes,嗯,鼓励)键,您可以查看mutagen.mp4.MP4Tag文档.当然,您可以使用自由形式结构(即----:foo:bar)创建自己的密钥,但不要指望任何其他玩家识别它们.
| 归档时间: |
|
| 查看次数: |
2459 次 |
| 最近记录: |