音频ncm格式转mp3格式

2023-12-16 12:36
文章标签 音频 格式 mp3 ncm

本文主要是介绍音频ncm格式转mp3格式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

做个笔记,ncm格式转mp3格式
参考:传送门

import os
import json
import base64
import struct
import logging
import binascii
from glob import glob
from tqdm.auto import tqdm
from textwrap import dedent
from Crypto.Cipher import AES
from multiprocessing import Poolclass TqdmLoggingHandler(logging.StreamHandler):"""Avoid tqdm progress bar interruption by logger's output to console"""# see logging.StreamHandler.eval method:# https://github.com/python/cpython/blob/d2e2534751fd675c4d5d3adc208bf4fc984da7bf/Lib/logging/__init__.py#L1082-L1091# and tqdm.write method:# https://github.com/tqdm/tqdm/blob/f86104a1f30c38e6f80bfd8fb16d5fcde1e7749f/tqdm/std.py#L614-L620def emit(self, record):try:msg = self.format(record)tqdm.write(msg, end=self.terminator)except RecursionError:raiseexcept Exception:self.handleError(record)log = logging.getLogger(__name__)
log.setLevel(logging.INFO)
handler = TqdmLoggingHandler()
fmt = '%(levelname)7s [%(asctime)s] %(message)s'
datefmt = '%Y-%m-%d %H:%M:%S'
handler.setFormatter(logging.Formatter(fmt, datefmt))
log.addHandler(handler)def dump_single_file(filepath):try:filename = filepath.split('/')[-1]if not filename.endswith('.ncm'): returnfilename = filename[:-4]for ftype in ['mp3', 'flac']:fname = f'{filename}.{ftype}'if os.path.isfile(fname):log.warning(f'Skipping "{filepath}" due to existing file "{fname}"')returnlog.info(f'Converting "{filepath}"')# hex to strcore_key = binascii.a2b_hex('687A4852416D736F356B496E62617857')meta_key = binascii.a2b_hex('2331346C6A6B5F215C5D2630553C2728')unpad = lambda s: s[0:-(s[-1] if isinstance(s[-1], int) else ord(s[-1]))]with open(filepath, 'rb') as f:header = f.read(8)# str to hexassert binascii.b2a_hex(header) == b'4354454e4644414d'f.seek(2, 1)key_length = f.read(4)key_length = struct.unpack('<I', bytes(key_length))[0]key_data = f.read(key_length)key_data_array = bytearray(key_data)for i in range(0, len(key_data_array)):key_data_array[i] ^= 0x64key_data = bytes(key_data_array)cryptor = AES.new(core_key, AES.MODE_ECB)key_data = unpad(cryptor.decrypt(key_data))[17:]key_length = len(key_data)key_data = bytearray(key_data)key_box = bytearray(range(256))c = 0last_byte = 0key_offset = 0for i in range(256):swap = key_box[i]c = (swap + last_byte + key_data[key_offset]) & 0xffkey_offset += 1if key_offset >= key_length:key_offset = 0key_box[i] = key_box[c]key_box[c] = swaplast_byte = cmeta_length = f.read(4)meta_length = struct.unpack('<I', bytes(meta_length))[0]meta_data = f.read(meta_length)meta_data_array = bytearray(meta_data)for i in range(0, len(meta_data_array)):meta_data_array[i] ^= 0x63meta_data = bytes(meta_data_array)meta_data = base64.b64decode(meta_data[22:])cryptor = AES.new(meta_key, AES.MODE_ECB)meta_data = unpad(cryptor.decrypt(meta_data)).decode('utf-8')[6:]meta_data = json.loads(meta_data)crc32 = f.read(4)crc32 = struct.unpack('<I', bytes(crc32))[0]f.seek(5, 1)image_size = f.read(4)image_size = struct.unpack('<I', bytes(image_size))[0]image_data = f.read(image_size)target_filename = filename + '.' + meta_data['format']with open(target_filename, 'wb') as m:chunk = bytearray()while True:chunk = bytearray(f.read(0x8000))chunk_length = len(chunk)if not chunk:breakfor i in range(1, chunk_length + 1):j = i & 0xffchunk[i - 1] ^= key_box[(key_box[j] + key_box[(key_box[j] + j) & 0xff]) & 0xff]m.write(chunk)log.info(f'Converted file saved at "{target_filename}"')return target_filenameexcept KeyboardInterrupt:log.warning('Aborted')quit()def list_filepaths(path):if os.path.isfile(path):return [path]elif os.path.isdir(path):return [fp for p in glob(f'{path}/*') for fp in list_filepaths(p)]else:raise ValueError(f'path not recognized: {path}')def dump(*paths, n_workers=None):header = dedent(r'''_  _  ___ __  __ ___  _   _ __  __ ____ __ _  _| \| |/ __|  \/  |   \| | | |  \/  | _ \| '_ \ || | .` | (__| |\/| | |) | |_| | |\/| |  _/| .__/\_, |_|\_|\___|_|  |_|___/ \___/|_|  |_|_|  |_|   |__/                                        pyNCMDUMP                     https://github.com/allenfrostline/pyNCMDUMP  ''')for line in header.split('\n'):log.info(line)all_filepaths = [fp for p in paths for fp in list_filepaths(p)]if n_workers > 1:log.info(f'Running pyNCMDUMP with up to {n_workers} parallel workers')with Pool(processes=n_workers) as p:list(p.map(dump_single_file, all_filepaths))else:log.info('Running pyNCMDUMP on single-worker mode')for fp in tqdm(all_filepaths, leave=False): dump_single_file(fp)log.info('All finished')if __name__ == '__main__':from argparse import ArgumentParserparser = ArgumentParser(description='pyNCMDUMP command-line interface')parser.add_argument('paths',metavar='paths',type=str,nargs='+',help='one or more paths to source files')parser.add_argument('-w', '--workers',metavar='',type=int,help=f'parallel convertion when set to more than 1 workers (default: 1)',default=1)args = parser.parse_args()dump(*args.paths, n_workers=args.workers)

在这里插入图片描述

这篇关于音频ncm格式转mp3格式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500498

相关文章

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal

[数据集][目标检测]血细胞检测数据集VOC+YOLO格式2757张4类别

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2757 标注数量(xml文件个数):2757 标注数量(txt文件个数):2757 标注类别数:4 标注类别名称:["Platelets","RBC","WBC","sickle cell"] 每个类别标注的框数:

一步一步将PlantUML类图导出为自定义格式的XMI文件

一步一步将PlantUML类图导出为自定义格式的XMI文件 说明: 首次发表日期:2024-09-08PlantUML官网: https://plantuml.com/zh/PlantUML命令行文档: https://plantuml.com/zh/command-line#6a26f548831e6a8cPlantUML XMI文档: https://plantuml.com/zh/xmi

单精度浮点数按存储格式转为整数的程序

///#include<cstdio>//-----------------union int_char{unsigned char ch[4];float i;};void out_put(union int_char x)//x86是小端对其模式,即最数据的最低位存储在地址的最低位上。{printf("单精度浮点数值为:%f\n",x.i,x.i);printf("存储位置从左到右

[数据集][目标检测]智慧农业草莓叶子病虫害检测数据集VOC+YOLO格式4040张9类别

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):4040 标注数量(xml文件个数):4040 标注数量(txt文件个数):4040 标注类别数:9 标注类别名称:["acalcerosis","fertilizer","flower","fruit","grey

spring事务属性的xml格式配置

实际是使用代理做的事务优化 <!--配置事务的属性--><tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!--匹配所有以add开头的方法--><tx:method name="add*" propagation="REQUIRED" /> <tx:metho

ORA-01861:文字与格式字符串不匹配

select t.*, t.rowid from log_jk_dtl t; insert into log_jk_dtl (rq,zy,kssj,jssj,memo)  values (to_date(sysdate,'yyyy-mm-dd'),'插入供应商', to_char(sysdate,'hh24:mi:ss'),to_char(sysdate,'hh24:mi:ss'),'备注'

Matplotlib图像读取和输出及jpg、png格式对比,及透明通道alpha设置

图像像素值 图像像素值一般size为3,也就是通道数,分别代表R,G,B,如果只有单一 一个值则表示灰度值,也就是说一张二维图片,当长和宽都为1080时,那么若是灰度图像,图像尺寸为(1080,1080,1)若是RGB图像则为(1080,1080,3), jpg、png图像格式 jpg图像的灰度值范围和RGB范围为[0,255],数值类型为uint8,也就是无符号整数 png图像的灰度值范

Oracle之用TO_CHAR函数将日期格式转化为不带前导零的月份和日

要求: 1、日期格式转化成字符串格式,月和日前面的0需要去掉,如日期2024-09-06需要转化成2024-9-6; 2、如果用截取拼接函数写法就会复杂,最好用TO_CHAR函数格式化实现。 正确写法: SELECT TO_CHAR(SYSDATE,'YYYY-fmMM-dd') AS DATE1 , -- 执行结果为 2024-9-6TO_CHAR(SYSDATE,'fmYYYY-MM-d

Ural319(输出格式)

题目链接:点击打开链接 解题思路: 分别从右上角和左下角考虑,和姐姐跟我说的上一题差不多····· 完整代码: #include <algorithm>#include <iostream>#include <cstring>#include <climits>#include <cstdio>#include <string>#include <cmath>