Use native single-call decrypt mux from downloaders

This commit is contained in:
glomatico
2026-07-08 13:03:02 -03:00
parent 3131aca0fd
commit f58fd4b631
3 changed files with 72 additions and 22 deletions
+53
View File
@@ -1492,6 +1492,31 @@ async def decrypt_file_hex(
)
async def decrypt_and_mux_hex(
decryption_key_audio: str,
input_audio_path: str,
output_path: str,
decryption_key_video: str | None = None,
input_video_path: str | None = None,
*,
use_cenc: bool = False,
use_single_content_key: bool = False,
m4v_brand: bool = False,
) -> None:
"""Decrypt and mux in one Rust call, streaming payloads through temp files."""
await asyncio.to_thread(
_amdecrypt.decrypt_and_mux_hex_native,
decryption_key_audio,
input_audio_path,
output_path,
decryption_key_video,
input_video_path,
use_cenc,
use_single_content_key,
m4v_brand,
)
async def write_decrypted_media(
decrypted_media: DecryptedMedia,
output_path: str,
@@ -3103,6 +3128,34 @@ async def decrypt_wrapper(
)
async def decrypt_and_mux_wrapper(
wrapper_api: WrapperApi,
track_id: str,
input_audio_path: str,
output_path: str,
fairplay_key_audio: str,
*,
input_video_path: str | None = None,
fairplay_key_video: str | None = None,
use_single_content_key: bool = False,
m4v_brand: bool = False,
) -> None:
"""Decrypt through wrapper-v2 and mux in one Rust call."""
await asyncio.to_thread(
_amdecrypt.decrypt_and_mux_wrapper_native,
wrapper_api.decrypt_host,
wrapper_api.decrypt_port,
track_id,
input_audio_path,
output_path,
fairplay_key_audio,
input_video_path,
fairplay_key_video,
use_single_content_key,
m4v_brand,
)
decrypt_file = decrypt_wrapper
+3 -6
View File
@@ -2,7 +2,7 @@ from pathlib import Path
from ..interface.enums import CoverFormat
from ..interface.types import AppleMusicMedia, DecryptionKeyAv
from .amdecrypt import decrypt_file_hex, write_decrypted_media
from .amdecrypt import decrypt_and_mux_hex
from .base import AppleMusicBaseDownloader
from .enums import RemuxFormatMusicVideo, RemuxMode
from .types import DownloadItem
@@ -25,15 +25,12 @@ class AppleMusicMusicVideoDownloader:
decryption_key: DecryptionKeyAv,
is_m4v: bool = False,
):
decrypted_media = await decrypt_file_hex(
await decrypt_and_mux_hex(
decryption_key.audio_track.key,
encrypted_path_audio,
staged_path,
decryption_key.video_track.key,
encrypted_path_video,
)
await write_decrypted_media(
decrypted_media,
staged_path,
m4v_brand=is_m4v,
)
+16 -16
View File
@@ -4,7 +4,7 @@ import structlog
from ..interface.enums import CoverFormat
from ..interface.types import AppleMusicMedia, DecryptionKeyAv
from .amdecrypt import decrypt_file_hex, decrypt_wrapper, write_decrypted_media
from .amdecrypt import decrypt_and_mux_hex, decrypt_and_mux_wrapper
from .base import AppleMusicBaseDownloader
from .types import DownloadItem
@@ -63,14 +63,14 @@ class AppleMusicSongDownloader:
if wrapper_api is None:
raise ValueError("wrapper_api is required for FairPlay decrypt")
decrypted_media = await decrypt_wrapper(
wrapper_api,
media_id,
input_path,
fairplay_key_audio=fairplay_key,
use_single_content_key=use_single_content_key,
)
await write_decrypted_media(decrypted_media, output_path)
await decrypt_and_mux_wrapper(
wrapper_api,
media_id,
input_path,
output_path,
fairplay_key_audio=fairplay_key,
use_single_content_key=use_single_content_key,
)
async def _decrypt_amdecrypt_hex(
self,
@@ -81,13 +81,13 @@ class AppleMusicSongDownloader:
use_cenc: bool = False,
use_single_content_key: bool = False,
) -> None:
decrypted_media = await decrypt_file_hex(
decryption_key,
input_path,
use_cenc=use_cenc,
use_single_content_key=use_single_content_key,
)
await write_decrypted_media(decrypted_media, output_path)
await decrypt_and_mux_hex(
decryption_key,
input_path,
output_path,
use_cenc=use_cenc,
use_single_content_key=use_single_content_key,
)
async def stage(
self,