如何用Python读取MP3非标准Date标签并实现批量标签替换?
问题解决方案
一、专业音乐软件如何写入任意格式的Date字段
foobar2000、Mp3tag这类软件并没有严格遵守ID3标准对Date字段的格式建议,它们的核心逻辑是直接将字符串原样写入ID3标签的对应文本帧:
- ID3v2标准里的日期相关帧(如
TDRC录制时间、TDRL发行时间等)本质是文本存储容器,标准仅推荐使用YYYY-MM-DD格式,但并未强制限制输入内容。 - 专业软件会直接操作这些帧的原始文本内容,无论字符串是否符合日期格式规范,只要是合法的文本就能写入。
二、用Python提取非标准Date字符串的方法
eyeD3、mutagen默认会尝试将Date字段解析为日期对象,导致非标准格式无法被正常读取。解决办法是绕过库的日期解析逻辑,直接读取对应ID3帧的原始文本:
1. 使用mutagen库
from mutagen.id3 import ID3 audio = ID3("your_file.mp3") # 直接读取TDRC帧的原始文本(若为其他日期帧如TDRL,替换对应帧ID即可) if 'TDRC' in audio: raw_date_str = audio['TDRC'].text[0] print(raw_date_str) # 输出原始非标准日期字符串,如"01/02/1934"
2. 使用eyeD3库
import eyed3 audio = eyed3.load("your_file.mp3") if audio.tag and 'TDRC' in audio.tag.frame_set: raw_date_str = audio.tag.frame_set['TDRC'][0].text print(raw_date_str)
注:如果目标文件使用的是ID3v1标签,Date字段仅支持4位年份,你的场景显然是ID3v2标签,无需考虑这种情况。
三、批量替换标签的实现思路
- 读取源文件标签:遍历源MP3文件夹,逐个提取需要的标签(包括原始Date字符串),以文件名作为键存储到字典中(需确保源文件与目标文件文件名一一对应)。
- 写入目标文件标签:遍历目标MP3文件夹,匹配源标签后,直接将原始字符串写入对应ID3帧,不做日期解析。
示例代码(基于mutagen):
import os from mutagen.id3 import ID3, TDRC, TIT2, TPE1 # 配置路径 source_dir = "path/to/source_mp3s" target_dir = "path/to/target_mp3s" # 读取所有源文件标签 source_tag_map = {} for filename in os.listdir(source_dir): if not filename.endswith(".mp3"): continue file_path = os.path.join(source_dir, filename) try: audio = ID3(file_path) source_tag_map[filename] = { "title": audio["TIT2"].text[0] if "TIT2" in audio else None, "artist": audio["TPE1"].text[0] if "TPE1" in audio else None, "date": audio["TDRC"].text[0] if "TDRC" in audio else None } except Exception as e: print(f"读取源文件 {filename} 失败: {str(e)}") # 批量写入目标文件标签 for filename in os.listdir(target_dir): if not filename.endswith(".mp3") or filename not in source_tag_map: continue file_path = os.path.join(target_dir, filename) try: audio = ID3(file_path) tag_data = source_tag_map[filename] # 写入标签(encoding=3对应UTF-8编码) if tag_data["title"]: audio["TIT2"] = TIT2(encoding=3, text=tag_data["title"]) if tag_data["artist"]: audio["TPE1"] = TPE1(encoding=3, text=tag_data["artist"]) if tag_data["date"]: audio["TDRC"] = TDRC(encoding=3, text=tag_data["date"]) audio.save() print(f"已更新目标文件 {filename}") except Exception as e: print(f"写入目标文件 {filename} 失败: {str(e)}")
内容的提问来源于stack exchange,提问作者Myusico
相关产品推荐
相关产品推荐

