MP3批量更名工具

查看 88|回复 9
作者:hdxzd12   
MP3批量更名工具
背景:之前下载到了一堆像ap1014_us1846931430_mii0w1iw8z2ai2iphcu80ooo2ki81120_pi406_mx610400681_s1349348668.mp3这样的乱码文件名的MP3文件,看了一下,发现ID3标签包含作者和歌曲的元数据,所以就写了这个东西
介绍:这是一个用于批量重命名MP3文件的Python脚本,根据MP3文件的元数据(ID3标签)自动重命名文件为"作者 - 歌曲名.mp3"的格式。
功能特点
  • 自动读取MP3文件的ID3标签信息
  • 根据作者和歌曲名批量重命名文件
  • 自动清理文件名中的非法字符
  • 支持多种ID3标签格式
  • 重命名前预览和确认机制
  • 防止文件覆盖和重复重命名

    安装依赖
    mutagen
    使用方法
    [ol]
  • 将脚本放在包含MP3文件的目录中
  • 运行脚本:
  • 脚本会显示当前目录下的所有MP3文件
  • 输入 y 或 yes 确认开始重命名
  • 脚本会自动处理所有MP3文件并显示处理结果
    [/ol]
    文件命名规则
    重命名后的文件格式为:作者 - 歌曲名.mp3
    示例:
  • 原文件名:ap1014_us1846931430_mii0w1iw8z2ai2iphcu80ooo2ki81120_pi406_mx610400681_s1349348668.mp3
  • 重命名后:詹振威 - 小小世界.mp3

    注意事项
  • 脚本只会处理当前目录下的MP3文件,不会处理子目录
  • 如果MP3文件缺少作者或歌曲名信息,会被跳过
  • 如果目标文件名已存在,会跳过重命名以避免覆盖
  • 文件名中的非法字符(如 :"/\|?* 等)会被自动移除
  • 重命名操作不可逆,建议先备份重要文件

    错误处理
  • 如果无法读取MP3文件的元数据,会显示错误信息并跳过该文件
  • 如果重命名过程中出现错误(如权限问题),会显示错误信息并继续处理其他文件

    代码
    import os
    import glob
    from mutagen import File
    from mutagen.id3 import ID3, TPE1, TIT2
    import re
    def clean_filename(text):
        """清理文件名中的非法字符"""
        if text is None:
            return ""
        # 移除Windows文件名中不允许的字符
        illegal_chars = r'[:"/\\|?*\x00-\x1f]'
        cleaned = re.sub(illegal_chars, '', str(text))
        # 移除首尾空格
        return cleaned.strip()
    def get_mp3_metadata(file_path):
        """获取MP3文件的元数据(作者和歌曲名)"""
        try:
            audio = File(file_path, easy=True)
            if audio is None:
                audio = ID3(file_path)
            # 尝试获取作者信息
            artist = None
            if 'artist' in audio and audio['artist']:
                artist = audio['artist'][0]
            elif 'TPE1' in audio and audio['TPE1']:
                artist = str(audio['TPE1'])
            # 尝试获取歌曲名
            title = None
            if 'title' in audio and audio['title']:
                title = audio['title'][0]
            elif 'TIT2' in audio and audio['TIT2']:
                title = str(audio['TIT2'])
            return artist, title
        except Exception as e:
            print(f"读取文件 {file_path} 的元数据时出错: {e}")
            return None, None
    def rename_mp3_files():
        """批量重命名当前目录下的MP3文件"""
        # 获取当前目录下所有MP3文件
        mp3_files = glob.glob("*.mp3")
        if not mp3_files:
            print("当前目录下没有找到MP3文件。")
            return
        print(f"找到 {len(mp3_files)} 个MP3文件:")
        renamed_count = 0
        skipped_count = 0
        for mp3_file in mp3_files:
            print(f"\n处理文件: {mp3_file}")
            # 获取元数据
            artist, title = get_mp3_metadata(mp3_file)
            if artist and title:
                # 清理作者和歌曲名
                clean_artist = clean_filename(artist)
                clean_title = clean_filename(title)
                # 构建新文件名
                new_name = f"{clean_artist} - {clean_title}.mp3"
                # 如果新文件名与旧文件名相同,跳过
                if new_name == mp3_file:
                    print(f"  文件名已符合格式,跳过: {mp3_file}")
                    skipped_count += 1
                    continue
                # 检查新文件名是否已存在
                if os.path.exists(new_name):
                    print(f"  警告: 目标文件已存在,跳过重命名: {new_name}")
                    skipped_count += 1
                    continue
                try:
                    # 重命名文件
                    os.rename(mp3_file, new_name)
                    print(f"  成功重命名为: {new_name}")
                    renamed_count += 1
                except Exception as e:
                    print(f"  重命名失败: {e}")
                    skipped_count += 1
            else:
                missing_info = []
                if not artist:
                    missing_info.append("作者")
                if not title:
                    missing_info.append("歌曲名")
                print(f"  跳过 - 缺少元数据: {', '.join(missing_info)}")
                skipped_count += 1
        print(f"\n批量重命名完成!")
        print(f"成功重命名: {renamed_count} 个文件")
        print(f"跳过: {skipped_count} 个文件")
    def main():
        """主函数"""
        print("MP3批量更名工具")
        print("=" * 40)
        print("此工具将重命名当前目录下的MP3文件为格式: 《作者名》 - 《歌曲名》.mp3")
        print("\n当前目录:", os.getcwd())
        # 显示当前目录下的MP3文件
        mp3_files = glob.glob("*.mp3")
        if mp3_files:
            print(f"\n当前目录下的MP3文件 ({len(mp3_files)} 个):")
            for file in mp3_files:
                print(f"  - {file}")
        # 确认操作
        confirm = input("\n是否继续重命名? (y/N): ").strip().lower()
        if confirm in ['y', 'yes']:
            rename_mp3_files()
        else:
            print("操作已取消。")
    if __name__ == "__main__":
        main()

    文件, 重命名

  • hunanxiaom   

    一般喜欢用歌曲名-作者.mp3的格式
    ygt123   

    收藏看看
    zjl3480   


    hunanxiaom 发表于 2025-10-7 22:27
    一般喜欢用歌曲名-作者.mp3的格式

    我修改了下:
    1 当前目录无 MP3 文件时,允许用户手动输入目标文件夹路径
    2. 文件名格式调整为 “歌曲名 - 作者名.mp3”
    [Python] 纯文本查看 复制代码import os
    import glob
    from mutagen import File
    from mutagen.id3 import ID3, TPE1, TIT2
    import re
    def clean_filename(text):
        """清理文件名中的非法字符"""
        if text is None:
            return ""
        # 移除Windows文件名中不允许的字符
        illegal_chars = r'[:"/\\|?*\x00-\x1f]'
        cleaned = re.sub(illegal_chars, '', str(text))
        # 移除首尾空格
        return cleaned.strip()
    def get_mp3_metadata(file_path):
        """获取MP3文件的元数据(作者和歌曲名)"""
        try:
            audio = File(file_path, easy=True)
            if audio is None:
                audio = ID3(file_path)
            # 尝试获取作者信息
            artist = None
            if 'artist' in audio and audio['artist']:
                artist = audio['artist'][0]
            elif 'TPE1' in audio and audio['TPE1']:
                artist = str(audio['TPE1'])
            # 尝试获取歌曲名
            title = None
            if 'title' in audio and audio['title']:
                title = audio['title'][0]
            elif 'TIT2' in audio and audio['TIT2']:
                title = str(audio['TIT2'])
            return artist, title
        except Exception as e:
            print(f"读取文件 {os.path.basename(file_path)} 的元数据时出错: {e}")
            return None, None
    def get_valid_directory():
        """获取用户输入的有效目录(存在且包含MP3文件)"""
        while True:
            # 获取当前目录
            current_dir = os.getcwd()
            mp3_files = glob.glob(os.path.join(current_dir, "*.mp3"))
            
            if mp3_files:
                return current_dir, mp3_files
            
            # 当前目录无MP3文件,提示用户输入目录
            print("\n当前目录未找到MP3文件,请指定包含MP3的文件夹路径")
            dir_path = input("请输入文件夹路径(直接回车返回当前目录): ").strip()
            
            # 处理用户输入
            if not dir_path:  # 直接回车,返回当前目录(虽然里面没文件,但给用户再次确认的机会)
                return current_dir, []
            
            # 检查目录是否有效
            if not os.path.isdir(dir_path):
                print(f"错误:'{dir_path}' 不是有效的目录,请重新输入")
                continue
            
            # 检查目录中是否有MP3文件
            target_mp3 = glob.glob(os.path.join(dir_path, "*.mp3"))
            if not target_mp3:
                print(f"警告:'{dir_path}' 目录中未找到MP3文件")
                continue
            
            return dir_path, target_mp3
    def rename_mp3_files(target_dir, mp3_files):
        """批量重命名指定目录下的MP3文件"""
        if not mp3_files:
            print("目标目录下没有找到MP3文件,无法执行重命名")
            return
        print(f"\n在目录 '{target_dir}' 中找到 {len(mp3_files)} 个MP3文件:")
        renamed_count = 0
        skipped_count = 0
        for file_path in mp3_files:
            # 获取文件名(不含路径)用于显示
            file_name = os.path.basename(file_path)
            print(f"\n处理文件: {file_name}")
            # 获取元数据
            artist, title = get_mp3_metadata(file_path)
            if artist and title:
                # 清理作者和歌曲名
                clean_artist = clean_filename(artist)
                clean_title = clean_filename(title)
                # 构建新文件名(格式:歌曲名-作者名.mp3)
                new_name = f"{clean_title}-{clean_artist}.mp3"
                new_path = os.path.join(target_dir, new_name)
                # 如果新文件名与旧文件名相同,跳过
                if new_path == file_path:
                    print(f"  文件名已符合格式,跳过: {file_name}")
                    skipped_count += 1
                    continue
                # 检查新文件名是否已存在
                if os.path.exists(new_path):
                    print(f"  警告: 目标文件已存在,跳过重命名: {new_name}")
                    skipped_count += 1
                    continue
                try:
                    # 重命名文件
                    os.rename(file_path, new_path)
                    print(f"  成功重命名为: {new_name}")
                    renamed_count += 1
                except Exception as e:
                    print(f"  重命名失败: {e}")
                    skipped_count += 1
            else:
                missing_info = []
                if not artist:
                    missing_info.append("作者")
                if not title:
                    missing_info.append("歌曲名")
                print(f"  跳过 - 缺少元数据: {', '.join(missing_info)}")
                skipped_count += 1
        print(f"\n批量重命名完成!")
        print(f"成功重命名: {renamed_count} 个文件")
        print(f"跳过: {skipped_count} 个文件")
    def main():
        """主函数"""
        print("MP3批量更名工具")
        print("=" * 40)
        print("此工具将重命名MP3文件为格式: 歌曲名-作者名.mp3")
       
        # 获取有效目录和MP3文件列表
        target_dir, mp3_files = get_valid_directory()
        print("\n当前操作目录:", target_dir)
        # 显示目标目录下的MP3文件
        if mp3_files:
            print(f"\n目标目录下的MP3文件 ({len(mp3_files)} 个):")
            for file in mp3_files:
                print(f"  - {os.path.basename(file)}")
        else:
            print("\n目标目录下没有MP3文件")
            return
        # 确认操作
        confirm = input("\n是否继续重命名? (y/N): ").strip().lower()
        if confirm in ['y', 'yes']:
            rename_mp3_files(target_dir, mp3_files)
        else:
            print("操作已取消。")
    if __name__ == "__main__":
        main()
    bssqcdf   

    收藏备用
    jcc1988520   

    感谢,我是小白,怎么运行代码
    wu1357924680   

    这下不用一个一个的命名文件了
    aaa74124   

    感谢分享,非常好用
    tds220   

    感谢热心分享,受用学习一下
    wqwuaipjlt8848   

    看了自己不会用奈何
    您需要登录后才可以回帖 登录 | 立即注册

    返回顶部