适用于Web页面的网易云加密格式NCM解密工具,直接在前端转换,无需后端交互。
由taurusxin/ncmdump移植而来。
改进了传参方式,大幅提高了转换效率。
这是一个简单的示例页面,可以直接使用。
安装WASM工具链(如果没有的话)
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
# 这条指令每次启动都需要执行,为了使它永久生效,可将其添加到~/.bashrc
source ./emsdk_env.sh
下载源码并编译
git clone https://github.com/AthBe1337/ncmdump-web.git
cd ncmdump-web
mkdir build && cd build
emcmake cmake .. -DCMAKE_BUILD_TYPE=Release
emmake make -j$(nproc)
此时你将得到ncmdump.js
和ncmdump.wasm
,你可以将它集成到你的web页面中。
传入参数为缓冲区指针和长度,返回typed_memory_view(Uint8Array)。
index.html
和decrypt.worker.js
提供了一个简易的使用示例。以下是decrypt.worker.js
。
import createModule from './wasm/ncmdump.js';
let wasmModule = null;
let isWasmReady = false;
createModule({
locateFile: (path) => path.endsWith('.wasm') ? './wasm/ncmdump.wasm' : path
}).then((instance) => {
wasmModule = instance;
isWasmReady = true;
self.postMessage({ type: 'wasm-ready' });
}).catch((err) => {
self.postMessage({
type: 'error',
error: `WASM加载失败: ${err.message}`
});
});
self.onmessage = async (e) => {
const { type, payload } = e.data;
if (type === 'decrypt') {
try {
if (!isWasmReady) {
throw new Error("WASM模块尚未初始化完成");
}
const fileData = new Uint8Array(payload.fileData);
const baseName = payload.baseNameWithoutExtension || "output";
const inputDataPtr = wasmModule._malloc(fileData.length);
if (!inputDataPtr) {
throw new Error("无法为输入文件数据分配WASM内存");
}
wasmModule.HEAPU8.set(fileData, inputDataPtr);
const resultView = wasmModule.decryptNCM(inputDataPtr, fileData.length);
const result = new Uint8Array(resultView.length);
result.set(resultView);
self.postMessage({
type: 'decrypted',
payload: {
index: payload.index,
result: result.buffer
}
}, [result.buffer]);
} catch (error) {
self.postMessage({
type: 'error',
payload: {
index: payload.index,
error: error.message
}
});
} finally {
if (inputDataPtr) {
wasmModule._free(inputDataPtr);
}
}
}
};