diff --git a/package-lock.json b/package-lock.json index 48d7266..6041f43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "unlock-music", - "version": "1.10.6", + "version": "1.10.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "unlock-music", - "version": "1.10.6", + "version": "1.10.7", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 7e9d9f6..5c6ecc5 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,8 @@ { "name": "unlock-music", - "version": "1.10.6", + "version": "1.10.7", "ext_build": 0, - "updateInfo": "修正文件过小的情况下酷狗 / QQ解密错误问题", + "updateInfo": "修正文件未加密时出现错误的问题", "license": "MIT", "description": "Unlock encrypted music file in browser.", "repository": { diff --git a/src/decrypt/index.ts b/src/decrypt/index.ts index e7c464b..96ef623 100644 --- a/src/decrypt/index.ts +++ b/src/decrypt/index.ts @@ -1,3 +1,4 @@ +import { AudioMimeType, GetArrayBuffer, SniffAudioExt } from '@/decrypt/utils'; import { Decrypt as Mg3dDecrypt } from '@/decrypt/mg3d'; import { Decrypt as NcmDecrypt } from '@/decrypt/ncm'; import { Decrypt as NcmCacheDecrypt } from '@/decrypt/ncmcache'; @@ -23,32 +24,38 @@ export async function Decrypt(file: FileInfo, config: Record): Prom const raw = SplitFilename(file.name); let rt_data: DecryptResult; - switch (raw.ext) { + let raw_file: Blob; + raw_file = file.raw; + let ext = raw.ext; + const buffer = new Uint8Array(await GetArrayBuffer(raw_file)); + ext = SniffAudioExt(buffer, raw.ext); + if (ext !== raw.ext) raw_file = new Blob([buffer], { type: AudioMimeType[ext] }); + switch (ext) { case 'mg3d': // Migu Wav - rt_data = await Mg3dDecrypt(file.raw, raw.name); + rt_data = await Mg3dDecrypt(raw_file, raw.name); break; case 'ncm': // Netease Mp3/Flac - rt_data = await NcmDecrypt(file.raw, raw.name, raw.ext); + rt_data = await NcmDecrypt(raw_file, raw.name, raw.ext); break; case 'uc': // Netease Cache - rt_data = await NcmCacheDecrypt(file.raw, raw.name, raw.ext); + rt_data = await NcmCacheDecrypt(raw_file, raw.name, raw.ext); break; case 'kwm': // Kuwo Mp3/Flac - rt_data = await KwmDecrypt(file.raw, raw.name, raw.ext); + rt_data = await KwmDecrypt(raw_file, raw.name, raw.ext); break; case 'xm': // Xiami Wav/M4a/Mp3/Flac case 'wav': // Xiami/Raw Wav case 'mp3': // Xiami/Raw Mp3 case 'flac': // Xiami/Raw Flac case 'm4a': // Xiami/Raw M4a - rt_data = await XmDecrypt(file.raw, raw.name, raw.ext); + rt_data = await XmDecrypt(raw_file, raw.name, raw.ext); break; case 'ogg': // Raw Ogg - rt_data = await RawDecrypt(file.raw, raw.name, raw.ext); + rt_data = await RawDecrypt(raw_file, raw.name, raw.ext, false); break; case 'tm0': // QQ Music IOS Mp3 case 'tm3': // QQ Music IOS Mp3 - rt_data = await RawDecrypt(file.raw, raw.name, 'mp3'); + rt_data = await RawDecrypt(raw_file, raw.name, 'mp3', false); break; case 'qmc0': //QQ Music Android Mp3 case 'qmc3': //QQ Music Android Mp3 @@ -81,26 +88,26 @@ export async function Decrypt(file: FileInfo, config: Record): Prom case '6f6767': //QQ Music Weiyun Ogg case '6d3461': //QQ Music Weiyun M4a case '776176': //QQ Music Weiyun Wav - rt_data = await QmcDecrypt(file.raw, raw.name, raw.ext); + rt_data = await QmcDecrypt(raw_file, raw.name, raw.ext); break; case 'tm2': // QQ Music IOS M4a case 'tm6': // QQ Music IOS M4a - rt_data = await TmDecrypt(file.raw, raw.name); + rt_data = await TmDecrypt(raw_file, raw.name); break; case 'cache': //QQ Music Cache - rt_data = await QmcCacheDecrypt(file.raw, raw.name, raw.ext); + rt_data = await QmcCacheDecrypt(raw_file, raw.name, raw.ext); break; case 'vpr': case 'kgm': case 'kgma': - rt_data = await KgmDecrypt(file.raw, raw.name, raw.ext); + rt_data = await KgmDecrypt(raw_file, raw.name, raw.ext); break; case 'ofl_en': - rt_data = await JooxDecrypt(file.raw, raw.name, raw.ext); + rt_data = await JooxDecrypt(raw_file, raw.name, raw.ext); break; case 'x2m': case 'x3m': - rt_data = await XimalayaDecrypt(file.raw, raw.name, raw.ext); + rt_data = await XimalayaDecrypt(raw_file, raw.name, raw.ext); break; case 'mflach': //QQ Music New Flac throw '网页版无法解锁,请使用CLI版本' diff --git a/src/decrypt/kgm.ts b/src/decrypt/kgm.ts index 34edb92..c4de9db 100644 --- a/src/decrypt/kgm.ts +++ b/src/decrypt/kgm.ts @@ -21,7 +21,7 @@ const KgmHeader = [ 0xA8, 0xAF, 0xA6, 0x8E, 0x0F, 0xFF, 0x99, 0x14 ] -export async function Decrypt(file: File, raw_filename: string, raw_ext: string): Promise { +export async function Decrypt(file: Blob, raw_filename: string, raw_ext: string): Promise { const oriData = await GetArrayBuffer(file); if (raw_ext === 'vpr') { if (!BytesHasPrefix(new Uint8Array(oriData), VprHeader)) throw Error('Not a valid vpr file!'); diff --git a/src/decrypt/kwm.ts b/src/decrypt/kwm.ts index 587fd2f..9143c5c 100644 --- a/src/decrypt/kwm.ts +++ b/src/decrypt/kwm.ts @@ -22,7 +22,7 @@ const MagicHeader2 = [ ]; const PreDefinedKey = 'MoOtOiTvINGwd2E6n0E1i7L5t2IoOoNk'; -export async function Decrypt(file: File, raw_filename: string, _: string): Promise { +export async function Decrypt(file: Blob, raw_filename: string, _: string): Promise { const oriData = new Uint8Array(await GetArrayBuffer(file)); if (!BytesHasPrefix(oriData, MagicHeader) && !BytesHasPrefix(oriData, MagicHeader2)) { if (SniffAudioExt(oriData) === 'aac') { diff --git a/src/decrypt/mg3d.ts b/src/decrypt/mg3d.ts index 8ddc845..5bdb253 100644 --- a/src/decrypt/mg3d.ts +++ b/src/decrypt/mg3d.ts @@ -25,7 +25,7 @@ function decryptSegment(data: Uint8Array, key: Uint8Array) { return Buffer.from(data); } -export async function Decrypt(file: File, raw_filename: string): Promise { +export async function Decrypt(file: Blob, raw_filename: string): Promise { const buf = new Uint8Array(await GetArrayBuffer(file)); // 咪咕编码的 WAV 文件有很多“空洞”内容,尝试密钥。 diff --git a/src/decrypt/ncm.ts b/src/decrypt/ncm.ts index dfc8fd3..95c2bde 100644 --- a/src/decrypt/ncm.ts +++ b/src/decrypt/ncm.ts @@ -26,7 +26,7 @@ const CORE_KEY = EncHex.parse('687a4852416d736f356b496e62617857'); const META_KEY = EncHex.parse('2331346C6A6B5F215C5D2630553C2728'); const MagicHeader = [0x43, 0x54, 0x45, 0x4e, 0x46, 0x44, 0x41, 0x4d]; -export async function Decrypt(file: File, raw_filename: string, _: string): Promise { +export async function Decrypt(file: Blob, raw_filename: string, _: string): Promise { return new NcmDecrypt(await GetArrayBuffer(file), raw_filename).decrypt(); } diff --git a/src/decrypt/tm.ts b/src/decrypt/tm.ts index 7aa717d..29baceb 100644 --- a/src/decrypt/tm.ts +++ b/src/decrypt/tm.ts @@ -4,7 +4,7 @@ import { DecryptResult } from '@/decrypt/entity'; const TM_HEADER = [0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70]; -export async function Decrypt(file: File, raw_filename: string): Promise { +export async function Decrypt(file: Blob, raw_filename: string): Promise { const audioData = new Uint8Array(await GetArrayBuffer(file)); for (let cur = 0; cur < 8; ++cur) { audioData[cur] = TM_HEADER[cur]; diff --git a/src/decrypt/ximalaya.ts b/src/decrypt/ximalaya.ts index e20214a..971b1db 100644 --- a/src/decrypt/ximalaya.ts +++ b/src/decrypt/ximalaya.ts @@ -7,7 +7,7 @@ const HandlerMap: Map Uint8Array> = new Map([ ['x3m', ProcessX3M], ]); -export async function Decrypt(file: File, raw_filename: string, raw_ext: string): Promise { +export async function Decrypt(file: Blob, raw_filename: string, raw_ext: string): Promise { const buffer = new Uint8Array(await GetArrayBuffer(file)); const handler = HandlerMap.get(raw_ext); if (!handler) throw 'File type is incorrect!'; diff --git a/src/decrypt/xm.ts b/src/decrypt/xm.ts index d33dd98..66474f0 100644 --- a/src/decrypt/xm.ts +++ b/src/decrypt/xm.ts @@ -13,7 +13,7 @@ const FileTypeMap: { [key: string]: string } = { ' A4M': '.m4a', }; -export async function Decrypt(file: File, raw_filename: string, raw_ext: string): Promise { +export async function Decrypt(file: Blob, raw_filename: string, raw_ext: string): Promise { const oriData = new Uint8Array(await GetArrayBuffer(file)); if (!BytesHasPrefix(oriData, MagicHeader) || !BytesHasPrefix(oriData.slice(8, 12), MagicHeader2)) { if (raw_ext === 'xm') {