优化: KGM解密并行化,多线程处理block,提升服务器卡顿时转码速度

This commit is contained in:
ypshidifu
2026-09-17 21:32:45 +08:00
parent c6a0125ec2
commit ca8c8aa490
+16 -5
View File
@@ -9,6 +9,7 @@ from mutagen.flac import FLAC
from mutagen.oggvorbis import OggVorbis
from mutagen.id3 import ID3, TIT2, TPE1, TALB, APIC
from pydub import AudioSegment
from concurrent.futures import ThreadPoolExecutor
NCM_MAGIC = b"CTENFDAM"
CORE_KEY = b"hzHRAmso5kInbaxW"
@@ -262,16 +263,26 @@ class KgmDecoder:
pub_len = len(self.pub_key)
out = bytearray(len(audio))
block_count = (len(audio) + BLOCK - 1) // BLOCK
for block_idx in range(block_count):
if block_idx >= pub_len:
raise ValueError("Key file mismatch")
if block_count > pub_len:
raise ValueError("Key file mismatch")
# Pre-compute all 17 phase tables; workers only read from cache
for phase in range(17):
self._phase_tables(phase, own_key, self.pub_key)
# Parallel block decryption: each block is independent
def _decrypt_block(block_idx):
phase = block_idx % 17
tables = self._phase_tables(phase, own_key, self.pub_key)
pub_value = self.pub_key[block_idx]
start = block_idx * BLOCK
end = min(start + BLOCK, len(audio))
for col, offset in enumerate(range(start, end)):
out[offset] = tables[col][pub_value][audio[offset]]
blk = bytearray(end - start)
for col in range(end - start):
blk[col] = tables[col][pub_value][audio[start + col]]
return start, bytes(blk)
max_workers = min(16, max(1, block_count))
with ThreadPoolExecutor(max_workers=max_workers) as executor:
for start, blk in executor.map(_decrypt_block, range(block_count)):
out[start:start + len(blk)] = blk
payload = bytes(out)
container = _sniff_container(payload[:64])
return payload, container, {}, None