是否可以使用诱变剂将ID3标签添加到m4a文件中?

问题描述:

我写了一个脚本,用诱变剂标记我的音乐库时遇到了问题。 以下代码在处理mp3文件时工作正常,但破坏了m4a文件。是否可以使用诱变剂将ID3标签添加到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) 

处理M4A文件后,标签可以读回用诱变剂,但未被任何其他球员检测,音频不会播放。

我试图在调用这个函数之前从文件中删除MP4标签,但它没有帮助。

我在做什么错?

+0

MP3!= MP4,你为什么试图在你的M4A文件上使用ID3?是不是很难输入Google:'mutagen m4a tags'并转到[第一个链接](http://mutagen.readthedocs.io/en/latest/api/mp4.html),弹出并解释了什么用于编辑MP4文件上的标签? – zwer

+0

哪个版本的python和OS? –

+0

@anony Kong python3.6 on windows10 – dobrovv

正如我在评论中所说的,MP4和MP3是不同的容器,它们使用完全不同的结构来存储元数据。从技术上讲,你可以在MP4元数据中编码ID3字段,这样的用法很大程度上取决于你的标签/播放器,因为有很多方法可以做到这一点,每个人都认为他们有最好的方式,因此推动他们自己的结构。

什么是MP3容器的ID3,XMP是用于MP4/M4A容器(以及许多其他容器,如JPEG,PDF甚至MP3,如果你想的话) - 除了XMP是一个实际的标准,而ID3是一个事后考虑(它实际上只是MP3文件末尾附加的尾部结构),每个人都随之而来,其功能主要由像WinAmp,foobar2000等大众流行播放器支配。相比之下,XMP本质上是一个类似于原子结构的结构(这就是为什么你会听到mp4标签被称为“原子”,即使他们不是指同一个东西),它与元数据一起还携带了什么信息元数据表现出来,即使是第一次遇到它的玩家在理论上也可以从不相关的元数据中识别出相关的元数据。

当然,实际上这也变成了玩家/标签战争,所以他们中的很多人都使用自己的自定义“扩展”进行标记 - 目前iTunes在应用字段和方式方面拥有巨大的影响力,其他球员类球 - 这是mutagen。 iTunes并不是一个单一的XMP结构,而是将这些标签作为非视频/音频帧(MP4中的实际'原子')传播,并且一些'标签'必须被怪异地命名(二进制名称等)不会干扰格式本身。虽然这种方法有一些优势(改变流媒体的元数据,对于现场活动非常有用),但这使得标记不必要地变得复杂,并且也是非标准的。

无论如何,您的问题发生是因为您试图将一个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) 

注:我只用在get_description()功能按“标签”的多个条目的最后desc条目被支撑着现有的标记作为回报名单。你显然不会在生产环境中使用上述内容。

你可以测试一下:

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. 

对于全套您可以检查mutagen.mp4.MP4Tag文档“支持”(或相当的iTunes,嗯,鼓励)键。当然,您可以使用*形式的结构(即----:foo:bar)创建自己的密钥,但不要指望其他玩家识别它们。