一个计算机技术爱好者与学习者

0%

修改 MP3 的 ID3Tags

1. ID3Tags是啥?

ID3Tags,简称 ID3 ,表示MP3文件曲目标签。
ID3位于一个mp3文件的开头或末尾的若干字节内,附加了关于该mp3的歌手,标题,专辑名称,年代,风格等信息,该信息就被称为ID3信息,ID3信息分为两个版本,v1和v2版。
其中v1版的ID3在mp3文件的末尾128字节,以TAG三个字符开头,后面跟上歌曲信息。v2版一般位于mp3的开头,可以存储歌词,该专辑的图片等大容量的信息。

ID3全称是啥?没有找到,懂得的小伙伴感谢留言告知。

2. 思路

使用python第三方库,查看mp3当前id3tags,修改id3tags并保存。
找到了两个不错的python第三方库:

这里选择eyeD3,因为使用更简单。
使用到的参数和方法,参考eyed3.id3

3. 安装使用eyeD3

3.1. 安装eyeD3

1
python3 -m pip install eyed3 -i https://pypi.tuna.tsinghua.edu.cn/simple/

3.2. 查看mp3的id3

1
2
eyeD3 -h
eyeD3 song.mp3

可能输出:No audio files found.
这是因为,有些音频文件虽然以.mp3结尾,也可以使用音频播放器播放,但是不一定是mp3文件。
查看真实文件类型的方法:

1
2
file song.mp3
file *

如果发现了非mp3文件,请先转成mp3文件,再进行id3修改,因为只有mp3文件才具有mp3文件曲目标签。

4. 编码实现修改ID3Tags

4.1. 查看id3

查看所有mp3的id3信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/env python3
# coding: utf-8

import os

import eyed3
from pydub.utils import mediainfo
from pydub import AudioSegment

def get_audio_paths(dir_path):
audio_paths = []
for dirs, dirnames, files in os.walk(dir_path):
for file in files:
if file.endswith('.mp3'):
audio_paths.append(dirs+'/'+file)
return audio_paths

def show_id3(audio_path):
# load 和 save 时会打印出 Invalid date: ???????:36903863 ,可忽略
audio = eyed3.load(audio_path)
audio_name = audio_path.split('/')[-1]
if audio is None:
info = mediainfo(audio_path)
print('------ ' + audio_name + ' ------')
print(audio_name + '不是mp3格式')
print('音频编码: ' + info['codec_name'])
print('文件类型: ' + info['codec_tag_string'])
print('------ ' + '------' + ' ------')
elif audio.tag is None:
print('------ ' + audio_name + ' ------')
print('不存在id3')
print('------ ' + '------' + ' ------')
else:
print('------ ' + audio_name + ' ------')
if audio.tag.title:
print('title: ' + audio.tag.title)
if audio.tag.artist:
print('artist: ' + audio.tag.artist)
print('------ ' + '------' + ' ------')

if __name__ == '__main__':
audio_paths = get_audio_paths('./mp3')

# 显示id3信息
for audio_path in audio_paths:
show_id3(audio_path)

4.2. m4a转换为mp3

m4a(mp4a)格式的文件,转换为mp3格式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def m4a_to_mp3(audio_path):
audio = eyed3.load(audio_path)
audio_name = audio_path.split('/')[-1]
if audio is None:
info = mediainfo(audio_path)
print('------ ' + audio_name + ' ------')
print('codec_name: ' + info['codec_name'])
print('codec_tag_string: ' + info['codec_tag_string'])
print('------ ' + '------' + ' ------')

if info['codec_tag_string'] == 'mp4a':
# 加载m4a文件
audio = AudioSegment.from_file(audio_path, format="m4a")
# 导出为mp3文件
audio.export(audio_path + '.mp3', format="mp3")
print(audio_name + ' converted to ' + audio_path + '.mp3')

4.3. 脚本修改id3

需求:已有200个mp3文件,id3信息都是广告。现在想要批量清除mp3文件现有的id3,然后根据文件名修改title,根据真实作者修改artist,根据真实封面修改封面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def modify_id3(audio_path, title, artist ,img_path):
audio = eyed3.load(audio_path)
if not audio.tag:
audio.initTag()
else:
audio.tag.clear()
audio.tag.title = title
audio.tag.artist = artist
audio.tag.images.set(3, open(img_path,'rb').read(), 'image/jpeg')
audio.tag.save()


if __name__ == '__main__':
audio_paths = get_audio_paths('./mp3')

# 修改id3信息
for audio_path in audio_paths:
title = audio_path.split('/')[-1]
artist = '钱文忠'
img_path = './img.png' # 200x200
modify_id3(audio_path, title, artist ,img_path)