NCM 转 MP3 工具 ncm_to_mp3

NCM 转 MP3 工具

用法:

  转换单个文件: python ncm_to_mp3.py <ncm文件路径>

  批量转换目录: python ncm_to_mp3.py <目录路径>

  指定输出目录: python ncm_to_mp3.py <输入路径> <输出目录>      


示例:

  python ncm_to_mp3.py abc.ncm

  python ncm_to_mp3.py ./input_folder ./output_folder


code:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
NCM 文件转换为 MP3 文件工具
用于将网易云音乐的 .ncm 加密音频文件转换为标准的 .mp3 文件
"""

import os
import sys
from pathlib import Path
from ncmdump import NeteaseCloudMusicFile


def convert_ncm_to_mp3(ncm_file_path, output_dir=None):
    """
    将单个 NCM 文件转换为 MP3 文件
    
    Args:
        ncm_file_path (str): NCM 文件的路径
        output_dir (str, optional): 输出目录,默认为 NCM 文件所在目录
    
    Returns:
        str: 转换成功后的 MP3 文件路径,失败返回 None
    """
    try:
        # 检查输入文件是否存在
        if not os.path.exists(ncm_file_path):
            print(f"错误:文件 {ncm_file_path} 不存在")
            return None
       
        # 确定输出目录
        if output_dir is None:
            output_dir = os.path.dirname(ncm_file_path)
       
        # 确保输出目录存在
        os.makedirs(output_dir, exist_ok=True)
       
        print(f"正在转换: {ncm_file_path}")
       
        # 创建 NCM 文件对象
        ncm_file = NeteaseCloudMusicFile(ncm_file_path)
       
        # 解密文件
        ncm_file.decrypt()
       
        # 获取音乐元数据
        metadata = ncm_file.music_metadata
        if hasattr(metadata, 'get'):
            music_name = metadata.get('musicName', '未知')
            artist = metadata.get('artist', '未知')
        else:
            music_name = getattr(metadata, 'get', lambda x, default: default)('musicName', '未知')
            artist = getattr(metadata, 'get', lambda x, default: default)('artist', '未知')
       
        print(f"音乐信息: {music_name} - {artist}")
       
        # 保持原文件名,只改扩展名
        original_filename = os.path.basename(ncm_file_path)
        name_without_ext = os.path.splitext(original_filename)[0]
        output_filename = f"{name_without_ext}.mp3"
        output_path = os.path.join(output_dir, output_filename)
       
        # 转储音乐文件
        ncm_file.dump_music(output_path)
       
        print(f"转换完成: {output_path}")
        return output_path
       
    except Exception as e:
        print(f"转换失败 {ncm_file_path}: {str(e)}")
        return None


def batch_convert_ncm_to_mp3(input_dir, output_dir=None):
    """
    批量转换目录中的所有 NCM 文件为 MP3
    
    Args:
        input_dir (str): 输入目录路径
        output_dir (str, optional): 输出目录路径,默认为输入目录
    """
    if output_dir is None:
        output_dir = input_dir
   
    # 确保输出目录存在
    os.makedirs(output_dir, exist_ok=True)
   
    # 查找所有 .ncm 文件
    ncm_files = list(Path(input_dir).glob("*.ncm"))
   
    if not ncm_files:
        print(f"在目录 {input_dir} 中未找到 .ncm 文件")
        return
   
    print(f"找到 {len(ncm_files)} 个 NCM 文件,开始批量转换...")
   
    success_count = 0
    for ncm_file in ncm_files:
        if convert_ncm_to_mp3(str(ncm_file), output_dir):
            success_count += 1
   
    print(f"转换完成!成功转换 {success_count}/{len(ncm_files)} 个文件")


def main():
    """主函数:提供命令行界面"""
    if len(sys.argv) == 1:
        print("NCM 转 MP3 工具")
        print("用法:")
        print("  转换单个文件: python ncm_to_mp3.py <ncm文件路径>")
        print("  批量转换目录: python ncm_to_mp3.py <目录路径>")
        print("  指定输出目录: python ncm_to_mp3.py <输入路径> <输出目录>")
        print()
        print("示例:")
        print("  python ncm_to_mp3.py abc.ncm")
        print("  python ncm_to_mp3.py ./input_folder ./output_folder")
        return
   
    input_path = sys.argv[1]
    output_path = sys.argv[2] if len(sys.argv) > 2 else None
   
    if os.path.isfile(input_path) and input_path.lower().endswith('.ncm'):
        # 单个文件转换
        convert_ncm_to_mp3(input_path, output_path)
    elif os.path.isdir(input_path):
        # 批量转换
        batch_convert_ncm_to_mp3(input_path, output_path)
    else:
        print(f"错误:无效的输入路径 {input_path}")
        print("请提供有效的 .ncm 文件路径或包含 .ncm 文件的目录路径")


if __name__ == "__main__":
    main()