前言
迩来想换用当地其它播放器听音乐,但网易云音乐下载下来的文件格式是.ncm,不兼容其它播放器。网上找了下方案,参考网易云音乐ncm格式分析以及ncm与mp3格式转换实现了基本功能,在此基础上加了个多进程同时转换,以及通过下令行传一些参数,比如并发实行数、输入输出目次路径。
示例代码
此中有个非标准库依赖需要安装- python -m pip install pycryptodome
复制代码 基本逻辑是参考原文的,修改处是添加了多进程实行、路径操作改用pathlib、支持下令行传参
[code]import binasciiimport structimport base64import jsonimport osfrom Crypto.Cipher import AESfrom pathlib import Pathfrom concurrent.futures import ProcessPoolExecutorfrom time import timeimport argparsedef get_args(): parser = argparse.ArgumentParser(description="ncm file convertor") parser.add_argument("-j", type=int, default=None, help="Maximum number of concurrency, default is cpu cores count") parser.add_argument("-i", type=str, default=".", help="input dir path, default is current dir") parser.add_argument("-o", type=str, default=None, help="output dir path") return parser.parse_args()def get_savepath(output_dir: str, file_name: str) -> Path: base_dir = Path(output_dir) if not base_dir.exists(): base_dir.mkdir(parents=True, exist_ok=True) p = base_dir / file_name return pdef process(file_path: Path, output_dir: str): start = time() print(f"start convert {file_path}") core_key = binascii.a2b_hex("687A4852416D736F356B496E62617857") meta_key = binascii.a2b_hex("2331346C6A6B5F215C5D2630553C2728") unpad = lambda s: s[0 : -(s[-1] if type(s[-1]) == int else ord(s[-1]))] f = open(file_path, "rb") header = f.read(8) if binascii.b2a_hex(header) != b"4354454e4644414d": print("incorrect file header, skiped ...") return f.seek(2, 1) key_length = f.read(4) key_length = struct.unpack(" |