使用Python访问MP3元数据

151

有没有一个我可以使用的维护好的 Python 包来检索和设置 MP3 ID3 元数据?


https://eyed3.readthedocs.io/en/latest/ - Freddy Mcloughlan
这是我试图解密元数据的尝试... https://github.com/JayRizzo/MP3Player/blob/master/mp3TagEditor.py - JayRizzo
16个回答

131
我前几天使用了eyeD3并且取得了很大的成功。我发现它可以添加艺术作品到ID3标签中,而其他我查看过的模块则不能。您需要使用pip来安装或从源文件夹下载tar并执行python setup.py install
以下是网站上相关的示例。
读取包含v1或v2标签信息的mp3文件内容:
 import eyeD3
 tag = eyeD3.Tag()
 tag.link("/some/file.mp3")
 print tag.getArtist()
 print tag.getAlbum()
 print tag.getTitle()

读取 MP3 文件(轨道长度、比特率等参数)并访问其标签:

if eyeD3.isMp3File(f):
     audioFile = eyeD3.Mp3AudioFile(f)
     tag = audioFile.getTag()

可以选择特定的标签版本:

 tag.link("/some/file.mp3", eyeD3.ID3_V2)
 tag.link("/some/file.mp3", eyeD3.ID3_V1)
 tag.link("/some/file.mp3", eyeD3.ID3_ANY_VERSION)  # The default.

或者您可以遍历原始帧:

 tag = eyeD3.Tag()
 tag.link("/some/file.mp3")
 for frame in tag.frames:
    print frame

一旦标签与文件关联,就可以修改和保存:

 tag.setArtist(u"Cro-Mags")
 tag.setAlbum(u"Age of Quarrel")
 tag.update()
如果链接的标签是v2,而你想将其保存为v1:
 tag.update(eyeD3.ID3_V1_1)

读取标签并将其从文件中移除:

 tag.link("/some/file.mp3")
 tag.remove()
 tag.update()

添加一个新标签:

 tag = eyeD3.Tag()
 tag.link('/some/file.mp3')    # no tag in this file, link returned False
 tag.header.setVersion(eyeD3.ID3_V2_3)
 tag.setArtist('Fugazi')
 tag.update()

23
eyeD3也是GPL许可证,如果像我一样你计划在你的程序中使用它,那么你必须将你的程序作为自由软件发布...这些人真让人头疼,为什么不能使用LGPL许可证发布呢? - Ciantic
13
@Ciantic:ID3标签非常简单,为什么不自己制作一个库并在BSD下发布呢?此外,这些人首先并没有对你做任何事情。请看这里http://diveintopython.org/object%5Foriented%5Fframework/index.html - Esteban Küber
10
在更新的版本中,请使用 import eyed3(小写字母d)。 - Jake Z
6
请注意,这些笔记适用于较旧版本的eyed3,现在已不再适用。例如,link()函数已经消失了,属性现在是通过声明式设置而不是使用setter设置。 - mlissner
3
不幸的是,现在大多数这些命令都已经过时了,即使是更新的 eyed3 对于常见的 MP3 文件也会抛出错误。最好使用 mutagen 类中的 EasyID3,如 此答案 所示。 - Chris Redford
显示剩余5条评论

39

我以前使用过mutagen来编辑媒体文件的标签。mutagen的好处是它可以处理其他格式,如mp4、FLAC等。 我使用这个API编写了几个脚本,并且取得了很大的成功。


3
请注意,Mutagen采用GPL协议,这对大多数项目来说是不允许的。 - Ciantic
4
突变原理是不错的,但我想要一种统一的方式来获取艺术家、标题、流派等信息。你最终需要知道不同格式所使用的各种键,如MP3的"TIT2"、OGG的"title"、MP4的"\xa9nam"、WMA的"Title"等等。这很糟糕。 - Has QUIT--Anony-Mousse

34

eyed3存在的一个问题是对于普通的MP3文件,它会抛出NotImplementedError("Unable to write ID3 v2.2")

根据我的经验,mutagen类中的EasyID3更加可靠。例如:

from mutagen.easyid3 import EasyID3

audio = EasyID3("example.mp3")
audio['title'] = u"Example Title"
audio['artist'] = u"Me"
audio['album'] = u"My album"
audio['composer'] = u"" # clear
audio.save()

通过这种方式可以访问和保存所有其他标签,这将满足大多数需求。更多信息可以在Mutagen教程中找到。


https://github.com/tooxie/shiva-server/issues/14 说:“eyeD3库已被Mutagen替换”。 - Qiulang
你提到的 eyeD3 错误有一个解决方法。在执行任何属性赋值之前,只需调用标签的 clear() 方法(如果需要保留任何原始标签值,请在清除它之前复制音频的标签对象)。clear() 会重置所有标签数据并创建一个新的标签,使用与 eyeD3 兼容的默认 ID3 标签版本。 - triplethreatguy

13
你需要的是ID3模块。它非常简单,可以给你所需的一切。只需将ID3.py文件复制到您的site-packages目录中,您就能够执行以下操作:
from ID3 import *
try:
  id3info = ID3('file.mp3')
  print id3info
  # Change the tags
  id3info['TITLE'] = "Green Eggs and Ham"
  id3info['ARTIST'] = "Dr. Seuss"
  for k, v in id3info.items():
    print k, ":", v
except InvalidTagError, message:
  print "Invalid ID3 tag:", message

14
注意:该模块非常古老(2002年),不支持ID3标签的V2版本。 - Eli Bendersky

9

在尝试了这里推荐的简单的pip install方法后,我发现这第四个选项是唯一可行的。其余的都出现了C++中缺少依赖项的导入错误,或者是一些魔法或其他库,pip错过了它们。因此,为了基本的ID3标签读取(所有版本),请使用以下方法:

https://pypi.python.org/pypi/tinytag/0.18.0

from tinytag import TinyTag
tag = TinyTag.get('/some/music.mp3')

TinyTag可能获取的属性列表:

tag.album         # album as string
tag.albumartist   # album artist as string
tag.artist        # artist name as string
tag.audio_offset  # number of bytes before audio data begins
tag.bitrate       # bitrate in kBits/s
tag.disc          # disc number
tag.disc_total    # the total number of discs
tag.duration      # duration of the song in seconds
tag.filesize      # file size in bytes
tag.genre         # genre as string
tag.samplerate    # samples per second
tag.title         # title of the song
tag.track         # track number as string
tag.track_total   # total number of tracks as string
tag.year          # year or data as string

它真的很小巧,而且像广告宣传的一样自足。

1
Tinytag的新版本请见:https://pypi.org/project/tinytag/ - Daenys Targaryen
最佳解决方案!谢谢 - rafaoc
1
截至2022年,它仅支持读取属性,也没有BPM属性可供查询。 - laimison

8

看看这个:

https://github.com/Ciantic/songdetails

使用示例:

>>> import songdetails
>>> song = songdetails.scan("data/song.mp3")
>>> print song.duration
0:03:12

保存更改:

>>> import songdetails
>>> song = songdetails.scan("data/commit.mp3")
>>> song.artist = "Great artist"
>>> song.save()

7
最简单的方法是使用songdetails库来读取数据。
import songdetails
song = songdetails.scan("blah.mp3")
if song is not None:
    print song.artist

同样适用于编辑。
import songdetails
song = songdetails.scan("blah.mp3")
if song is not None:
    song.artist = u"The Great Blah"
    song.save()

在学会中文之前,请不要忘记在名字前添加u

您可以使用Python的glob模块进行批量阅读和编辑。

例如:

import glob
songs = glob.glob('*')   # script should be in directory of songs.
for song in songs:
    # do the above work.

7
我会尽力为您翻译中文,以下是需要翻译的内容:

我使用 tinytag 1.3.1 的原因是

  1. 它目前得到积极支持:
1.3.0 (2020-03-09):
added option to ignore encoding errors ignore_errors #73
Improved text decoding for many malformed files

它支持主要格式:
MP3 (ID3 v1, v1.1, v2.2, v2.3+)
Wave/RIFF
OGG
OPUS
FLAC
WMA
MP4/M4A/M4B
  • 这段代码在短短几分钟的开发中就运行成功了。
  • from tinytag import TinyTag
    
    fileNameL ='''0bd1ab5f-e42c-4e48-a9e6-b485664594c1.mp3
    0ea292c0-2c4b-42d4-a059-98192ac8f55c.mp3
    1c49f6b7-6f94-47e1-a0ea-dd0265eb516c.mp3
    5c706f3c-eea4-4882-887a-4ff71326d284.mp3
    '''.split()
    
    for fn in fileNameL:
        fpath = './data/'+fn
        tag = TinyTag.get(fpath)
        print()
        print('"artist": "%s",' % tag.artist)
        print('"album": "%s",' % tag.album)
        print('"title": "%s",' % tag.title)
        print('"duration(secs)": "%s",' % tag.duration)
    
    
    • 结果
    JoeTagPj>python joeTagTest.py
    
    "artist": "Conan O’Brien Needs A Friend",
    "album": "Conan O’Brien Needs A Friend",
    "title": "17. Thomas Middleditch and Ben Schwartz",
    "duration(secs)": "3565.1829583532785",
    
    "artist": "Conan O’Brien Needs A Friend",
    "album": "Conan O’Brien Needs A Friend",
    "title": "Are you ready to make friends?",
    "duration(secs)": "417.71840447045264",
    
    "artist": "Conan O’Brien Needs A Friend",
    "album": "Conan O’Brien Needs A Friend",
    "title": "Introducing Conan’s new podcast",
    "duration(secs)": "327.22187551899646",
    
    "artist": "Conan O’Brien Needs A Friend",
    "album": "Conan O’Brien Needs A Friend",
    "title": "19. Ray Romano",
    "duration(secs)": "3484.1986772305863",
    
    C:\1d\PodcastPjs\JoeTagPj>
    

    看起来是一个不错的库的开端。不幸的是,他们还不支持所有标签,特别是用于歌词的USLT和SYLT标签。 - SouthernYankee65

    7

    给大家提供一些额外的信息:

    PythonInMusic页面中,可以查看“MP3工具和元数据编辑器”部分。


    6
    我查看了以上答案,发现由于GPL许可证的问题,它们不适用于我的项目。
    而我找到了这个:PyID3Lib,虽然该特定的Python绑定发布日期较旧,但它使用的ID3Lib本身是最新的。
    值得一提的是,两者都是LGPL许可证,可以放心使用。

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