You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Mutagen提取MP3多艺人信息时的分隔符问题求助

解决Mutagen提取MP3艺人信息的分隔符问题

问题根源

你的问题来自两方面:

  1. 标签不规范:部分MP3未遵循ID3标准,将多位艺人用/拼接成单个字符串存入TPE1标签,而非用标准多值格式存储。
  2. 代码逻辑局限:当前代码直接取extractKey返回列表的第一个元素,即便遇到规范的多值标签,也会丢失其他艺人信息。

解决方案

1. 优先处理规范标签

ID3v2.4标准中,多艺人是作为独立元素存储的,Mutagen会直接返回包含所有艺人的列表。修改代码中提取艺人的逻辑,保留完整列表:

# 原代码:仅取第一个元素
self.artist = self.extractKey(file, 'TPE1')[0]

# 修改为:保留完整艺人列表
self.artists = self.extractKey(file, 'TPE1')  # 变量名改为artists更贴合语义

如果是规范的ID3v2.4文件,self.artists会直接得到类似['Ministry', 'AC/DC']的结果,无需额外拆分。

2. 处理不规范的/分隔标签

对于用/拼接艺人的不规范标签,需要区分艺人名自带的/(如AC/DC)和分隔用的/。可以通过以下逻辑处理:

  • 定义常见带/的艺人名列表
  • 临时替换这些艺人名里的/为特殊符号,避免误拆分
  • 按/拆分后再恢复原符号

修改你的MusicData类,添加解析函数:

import re
import mutagen

class MusicData:
    # 可根据音乐库扩展这个列表,覆盖更多带/的艺人
    COMMON_SLASH_ARTISTS = {'AC/DC', 'Broken Social Scene/Feist', 'The Prodigy/The Chemical Brothers'}

    def __init__(self, root, filepath):
        self.fullpath = root + '\\' + filepath
        
        self.prepath = re.sub(r'\\[^\\]*$', '', self.fullpath) + '\\'
        self.filename = self.fullpath.replace(self.prepath, '')

        file = mutagen.File(self.fullpath)
        self.duration = file.info.length
        
        self.title = self.extractKey(file, 'TIT2')[0]
        # 处理艺人信息
        raw_artists = self.extractKey(file, 'TPE1')
        self.artists = self._parse_artists(raw_artists)
        self.album = self.extractKey(file, 'TALB')[0]
        self.year = self.extractKey(file, 'TDRC')[0]
        self.genre = self.extractKey(file, 'TCON')[0]
        self.publisher = self.extractKey(file, 'TPUB')[0]
        self.key = self.extractKey(file, 'TKEY')[0]
        self.bpm = self.extractKey(file, 'TBPM')[0]
    
    def extractKey(self, file, key):
        if(key in file):
            if(type(file.tags[key].text[0]) == mutagen.id3._specs.ID3TimeStamp):
                return [str(file.tags[key].text[0])]
            else:
                return file.tags[key].text
        else:
            return [""]
    
    def _parse_artists(self, raw_artists):
        parsed = []
        for item in raw_artists:
            if '/' not in item:
                parsed.append(item)
                continue
            # 临时替换艺人名内的/为|,避免被拆分
            temp_str = item
            for artist in self.COMMON_SLASH_ARTISTS:
                temp_str = temp_str.replace(artist, artist.replace('/', '|'))
            # 按/拆分分隔符
            parts = temp_str.split('/')
            # 恢复原符号并去除冗余空格
            parsed.extend([part.replace('|', '/').strip() for part in parts])
        return parsed

3. 兼容ID3v2.3的分号分隔

如果遇到ID3v2.3用;分隔的多艺人标签,可在_parse_artists函数中添加类似/的处理逻辑(艺人名含;的情况极少)。

补充说明

  • 可根据自己的音乐库持续扩展COMMON_SLASH_ARTISTS列表,提升拆分准确性。
  • 若标签存在混用/和;的情况,可在拆分逻辑中同时处理两种分隔符。

内容的提问来源于stack exchange,提问作者Anteino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 22:45:59