python修改mp3信息_Python3.根据ID3v2批量修改mp3文件名

这篇博客介绍了如何使用Python读取mp3文件中的ID3v2标签信息,批量将文件名重命名为"歌曲名-歌手"的格式。作者通过解析标签头和标签帧获取标题和艺术家信息,并提供了相应的读取函数。最终,该脚本实现了对一个文件夹下所有使用ID3v2标签的音乐文件进行重命名。
摘要由CSDN通过智能技术生成

我听歌并不专业,没有特定的口味,没有特定的播放软件,于是,随着换手机、换电脑、重装系统、朋友分享等等,我有了一堆mp3文件,而且越聚越多。

由于这些文件来源就乱七八糟的,文件名的格式有的是“歌曲名-歌手”,有的是“歌手-歌曲名”,甚至有些乱码的文件名。曾经几度想要整理一下,于是这些mp3文件被分为了“未整理”、“已整理”的文件夹,“未整理”文件夹下还有“手机1”、“手机2”等等文件夹,几次下来都没成功整理完。

网上一定有用来整理音乐收藏的软件,但懒得找了,我来写代码干它。

ID3v2

作为听歌听个响的非专业用户,之前播放这些音乐文件时发现一些现象: - 有的歌播放的时候会显示一张封面,甚至有歌词 - 有的歌文件名被改错,但播放时依然能正确显示歌名 - 查看大多数mp3文件的文件属性时有比较详细的“标题”、“参与创作的艺术家”等等信息

所以可以判断,mp3文件本身就有歌名、歌手的信息,不受文件名的影响。那么如果用程序直接读取mp3文件里面的歌名、歌手的信息,就可以实现批量重命名了。

大概查了一下,应该就是ID3v2这个东西了,根据定义,它位于音乐文件的文件头部,分为标签头和标签帧。

标签头为文件头10个字节,标记了是否使用了ID3v2标签,以及标签帧总共有多大,读取函数如下,输入为头10个字节,输出为标签帧总字节数,假如不是ID3v2标签则输出None:

def parse_ID3V2_head(head_bin):

if head_bin[:3] != b'ID3':

return None

frames_bin_size = (head_bin[6] << 21 | head_bin[7] << 14 |

head_bin[8] << 7 | head_bin[9])

return frames_bin_size

需要说明的是,描述整个ID3v2标签字节数的那4个字节最高位不使用,即这4个字节剩下的7位拼到一起所表示的二进制数才是字节数,真是诡异。

标签帧里面就是各种信息,读取函数如下,输入为标签帧的字节流,输出标签字典,其中TIT2表示标题,TPE1表示歌手,已经decode为字符串:

import struct

encondings = ['GBK', 'UTF-16', 'UTF-16BE', 'UTF-8']

def parse_ID3V2_frames(frames_bin):

pointer = 0

frames_bin_size = len(frames_bin)

frames = {}

while pointer < frames_bin_size - 10:

frame_header_bin = frames_bin[pointer : pointer+10]

# frame_header = (ID, Size, Flags)

frame_header = struct.unpack('>4sI2s', frame_header_bin)

frame_body_size = frame_header[1]

if frame_body_size == 0:

break

pointer += 10

frames[frame_header[0]] = frames_bin[pointer : pointer+frame_body_size]

pointer += frame_body_size

TIT2_bin = frames.get(b'TIT2', None)

TPE1_bin = frames.get(b'TPE1', None)

if TIT2_bin:

enconding = encondings[TIT2_bin[0]]

frames[b'TIT2'] = TIT2_bin[1:].decode(enconding)

if TPE1_bin:

enconding = encondings[TPE1_bin[0]]

frames[b'TPE1'] = TPE1_bin[1:].decode(enconding)

return frames

需要说明的是,很多中文歌曲的信息编码为GBK,但标记为ISO-8859-1,好在ISO-8859-1似乎是GBK的子集,于是所有ISO-8859-1编码的字节我都用GBK来解码了,我可真是个小机灵鬼。

批量修改文件名

那么通过如下脚本,就可以实现将一个文件夹下所有使用ID3v2标签的音乐文件按想要的格式重命名了,我想统一整理为“歌曲名-歌手”的格式。

import os

src_dir = r'E:\Music\test'

dst_dir = r'E:\Music\test_result'

file_names = os.listdir(src_dir)

for file_name in file_names:

file_old_path = rf'{src_dir}\{file_name}'

f = open(file_old_path, 'rb')

frames_bin_size = parse_ID3V2_head(f.read(10))

if frames_bin_size is None:

f.close()

continue

frames_bin = f.read(frames_bin_size - 10)

f.close()

frames = parse_ID3V2_frames(frames_bin)

TIT2 = frames[b'TIT2']

TPE1 = frames[b'TPE1']

file_new_path = rf'{dst_dir}\{TIT2}_{TPE1}.{file_name.split(".")[-1]}'

if os.path.exists(file_new_path):

continue

else:

os.rename(file_old_path, file_new_path)

在整理前是这样的

整理后是这样的

可以看到,所有文件名都按照“歌曲名-歌手”的格式重命名了,而且不限于mp3文件,有些其他类型文件如flac只要使用了ID3v2标签就可以一起整理。

结论与展望

基本实现了读取ID3v2标签,并可以用于实现文件名的重命名。

ID3v2标签中其他信息如封面、歌词等处理方式有待进一步研究。部分音乐文件并没有使用ID3v2标签而是其它标签,不在本文讨论范围内,有待进一步研究。可能需要制作可视化界面进一步管理音乐文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值