抽象化ID3标签、M4A标签和FLAC标签之间的转换

14

我正在寻找一个 Python 或 Bash 的工具,可以轻松地将示例文件 X 的 mp3 标签和文件 Y 的 m4a 标签进行复制。

Python 的 "mutagen" 模块适用于一般标签的操作,但它没有跨不同类型标签的“艺术家字段”的抽象概念;我想要一个库,可以处理所有繁琐的细节并知道字段名称的等价性。对于不是所有标签系统都能表达的内容,我可以接受信息的丢失或最佳猜测。

(使用案例:我将无损文件编码为 mp3,然后使用这些 mp3 进行听歌。每个月左右,我希望能够根据我对 mp3 进行的任何标签更改更新“主”无损文件。我已经厌倦了在格式之间实现差异上遇到困难。)


你可以随时使用已经轻松完成此类操作的播放器,例如foobar2000。它的“复制标签”功能完全可以胜任,无论格式如何。 - tzot
7个回答

9
我需要这个确切的东西,但很快意识到mutagen并不足够抽象以执行这种操作。幸运的是,mutagen的作者们需要它来制作他们的媒体播放器QuodLibet
我不得不查看QuodLibet源代码才能了解如何使用它,但一旦我理解了它,我就编写了一个名为sequitur的实用程序,旨在成为ExFalso(QuodLibet的标记组件)的命令行等效工具。它使用这种抽象机制并提供了一些额外的抽象和功能。
如果您想查看源代码,这里有最新tarball的链接。该软件包实际上是三个命令行脚本和一个用于与QL交互的模块。如果您想安装整个软件包,可以使用:
easy_install QLCLI

需要记住的一件事情是 exfalso/quodlibet (以及因此而来的 sequitur) 实际上正确实现了音频元数据,这意味着所有标签都支持多个值(除非文件类型禁止,但这种类型很少)。因此,可以执行以下操作:
print qllib.AudioFile('foo.mp3')['artist']

不会输出单个字符串,而是会输出像列表一样的字符串:
[u'The First Artist', u'The Second Artist']

你可以这样使用它来复制标签:
import os.path
import qllib  # this is the module that comes with QLCLI

def update_tags(mp3_fn, flac_fn):
    mp3 = qllib.AudioFile(mp3_fn)
    flac = qllib.AudioFile(flac_fn)
    # you can iterate over the tag names
    # they will be the same for all file types
    for tag_name in mp3:
        flac[tag_name] = mp3[tag_name]
    flac.write()

mp3_filenames = ['foo.mp3', 'bar.mp3', 'baz.mp3']

for mp3_fn in mp3_filenames:
    flac_fn = os.path.splitext(mp3_fn)[0] + '.flac'
    if os.path.getmtime(mp3_fn) != os.path.getmtime(flac_fn):
        update_tags(mp3_fn, flac_fn)

1
由于时间的不可阻挡流逝,Quod Libet现在配备了一个名为operon的命令行工具,可以执行此操作及更多其他操作。例如:operon copy song.flac song.mp3 - smammy

2

我有一个bash脚本可以实现这个功能,atwat-tagger。它支持flac、mp3、ogg和mp4文件。

usage: `atwat-tagger.sh inputfile.mp3 outputfile.ogg`

我知道你的项目已经完成了,但是通过搜索引擎找到这个页面的人可能会发现它很有用。

2
这是我编写的一个脚本示例,使用Quod Libet的音乐格式类(而不是mutagen的)在文件之间复制标签。要运行它,只需执行“copytags.py src1 dest1 src2 dest2 src3 dest3”,它将复制sec1中的标签到dest1(在删除dest1上的任何现有标签之后!),以此类推。请注意黑名单,您应该根据自己的喜好进行调整。黑名单不仅会阻止复制某些标签,还会防止它们在目标文件中被覆盖。
清楚地说,Quod Libet的格式无关标记不是mutagen的功能;它是在mutagen之上实现的。因此,如果您想要格式无关标记,请使用“quodlibet.formats.MusicFile”来打开您的文件,而不是“mutagen.File”。
代码现在可以在这里找到:https://github.com/DarwinAwardWinner/copytags 如果您同时想要进行转码,请使用此代码:https://github.com/DarwinAwardWinner/transfercoder 对我来说,一个关键细节是Quod Libet的音乐格式类期望加载QL的配置,因此我的脚本中有“config.init”行。如果没有这个,当加载或保存文件时,我会遇到各种错误。
我已经测试了这个脚本,可以在flac、ogg和mp3之间复制,“标准”标签以及任意标签。到目前为止,它一直完美地工作着。
至于我为什么没有使用QLLib的原因,那是因为它对我没用。我怀疑它遇到了与配置相关的错误,但是默默地忽略它们,并简单地未能写入标签。

而且,正如墨菲定律所预测的那样,当我完成这个脚本的编写时,QLLib立刻完美地运行起来了。 - Ryan C. Thompson
这个解决方案在我尝试了很多方案后终于奏效了。谢谢! - e40
由于时间的不可阻挡流逝,Quod Libet现在配备了一个名为operon的命令行工具,可以执行此操作及更多其他操作。例如:operon copy song.flac song.mp3 - smammy

0

由于其他解决方案大多已经从网络上消失,这里是我基于Python媒体文件库(Debian GNU/Linux中的python3-mediafile)所想出的解决方案。

#!/usr/bin/python3

import sys
from mediafile import MediaFile

src = MediaFile (sys.argv [1])
dst = MediaFile (sys.argv [2])

for field in src.fields ():
   try:
      setattr (dst, field, getattr (src, field))
   except:
      pass

dst.save ()

用法:mediafile-mergetags 源文件 目标文件

它将从源文件中复制(合并)所有标签到目标文件中,并且似乎可以正常处理 flac、opus、mp3 等格式,包括复制专辑封面。


0
你只需要编写一个简单的应用程序,将每个格式中的标记名称映射到“抽象标记”类型,然后很容易从一个格式转换为另一个格式。你甚至不必知道所有可用的类型 - 只需了解你感兴趣的类型即可。
对我来说,这似乎是一个周末项目级别的时间投资,可能更短。玩得开心,如果你不介意发布,我很乐意查看你的实现并使用它 :-)。

0

还有tagpy,它似乎工作得很好。


0

自 2013 年以来,Quod Libet 自带一个命令行工具 operon ,可以执行此操作及更多操作:

operon copy song.flac song.mp3

由于Quod Libet基于Mutagen构建,它了解许多晦涩的标签以及如何在各种标记格式之间进行转换,这对某些工作流程非常重要。我注意到的唯一怪癖是它不会复制空值标签,但这并不困扰我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接