mirror of
https://github.com/glomatico/gamdl.git
synced 2025-01-22 11:18:39 +00:00
Playready
This commit is contained in:
parent
3d5742471c
commit
4eb227493e
@ -121,7 +121,7 @@ Config file values can be overridden using command line arguments.
|
||||
| `--codec-music-video` / `codec_music_video` | Music video codec. | `h264` |
|
||||
| `--quality-post` / `quality_post` | Post video quality. | `best` |
|
||||
| `--no-config-file`, `-n` / - | Do not use a config file. | `false` |
|
||||
|
||||
| `--playready`, `playready` / - | Use Playready DRM | `false` |
|
||||
|
||||
### Tags variables
|
||||
The following variables can be used in the template folders/files and/or in the `exclude_tags` list:
|
||||
@ -178,6 +178,7 @@ The following codecs are available:
|
||||
* `aac-legacy`
|
||||
* `aac-he-legacy`
|
||||
|
||||
|
||||
The following codecs are also available, **but are not guaranteed to work**, as currently most (or all) of the songs fails to be downloaded when using them:
|
||||
* `aac`
|
||||
* `aac-he`
|
||||
@ -190,6 +191,7 @@ The following codecs are also available, **but are not guaranteed to work**, as
|
||||
* `alac`
|
||||
* `ask`
|
||||
* When using this option, Gamdl will ask you which codec from this list to use that is available for the song.
|
||||
With PlayReady and the right CDM, binaural, atmos and aac should download.
|
||||
|
||||
### Music videos codecs
|
||||
The following codecs are available:
|
||||
|
@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import json
|
||||
import re
|
||||
import time
|
||||
import typing
|
||||
@ -41,7 +42,7 @@ class AppleMusicApi:
|
||||
self.storefront = self.session.cookies.get_dict()["itua"]
|
||||
self.session.headers.update(
|
||||
{
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.2903.86", #"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
|
||||
"User-Agent": "iTunes/12.11.3 (Windows; Microsoft Windows 10 x64 Professional Edition (Build 19041); x64) AppleWebKit/7611.1022.4001.1 (dt:2)", #"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.2903.86", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
|
||||
"Accept": "application/json",
|
||||
"Accept-Language": "en-US,en;q=0.5",
|
||||
"Accept-Encoding": "gzip, deflate, br",
|
||||
@ -273,7 +274,7 @@ class AppleMusicApi:
|
||||
"uri": track_uri,
|
||||
"adamId": track_id,
|
||||
"isLibrary": False,
|
||||
"user-initiated": True,
|
||||
"user-initiated": False,
|
||||
},
|
||||
)
|
||||
try:
|
||||
@ -286,7 +287,12 @@ class AppleMusicApi:
|
||||
requests.exceptions.JSONDecodeError,
|
||||
AssertionError,
|
||||
):
|
||||
if response_dict.get("status") == -1002:
|
||||
raise Exception("-1002: You do not own the title in the requested quality.")
|
||||
elif response_dict.get("status") == -1021:
|
||||
raise Exception("-1021: Device has insufficient security level or is blacklisted/revoked.")
|
||||
self._raise_response_exception(response)
|
||||
|
||||
return license
|
||||
|
||||
|
||||
|
@ -561,9 +561,10 @@ def main(
|
||||
logger.warning(
|
||||
f"({queue_progress}) Song is not downloadable or is not"
|
||||
" available in the chosen codec, skipping"
|
||||
f"\n{stream_info.pssh}, {stream_info.stream_url}"
|
||||
|
||||
)
|
||||
continue
|
||||
logger.debug(f"{stream_info.pssh}, {stream_info.stream_url}")
|
||||
logger.debug("Getting decryption key")
|
||||
decryption_key = downloader.get_decryption_key(
|
||||
stream_info.pssh, track_metadata["id"]
|
||||
|
@ -343,7 +343,7 @@ class Downloader:
|
||||
elif self.drm == DRM.Playready:
|
||||
from pyplayready import PSSH
|
||||
try:
|
||||
pssh_obj = PSSH(pssh.split(",")[-1]).get_wrm_headers(downgrade_to_v4=False)[0]
|
||||
pssh_obj = PSSH(pssh.split(",")[-1]).get_wrm_headers(downgrade_to_v4=True)[0] # Downgrade to v4 has to be set to True
|
||||
cdm_session = self.cdm.open()
|
||||
challenge = base64.b64encode(
|
||||
self.cdm.get_license_challenge(cdm_session, pssh_obj).encode("utf-8")
|
||||
@ -354,13 +354,15 @@ class Downloader:
|
||||
challenge,
|
||||
self.drm,
|
||||
)
|
||||
self.cdm.parse_license(cdm_session, license)
|
||||
decryption_key = next(
|
||||
i for i in self.cdm.get_keys(cdm_session) if i.key_type == "AES_128_CBC"
|
||||
).key.hex()
|
||||
self.cdm.parse_license(cdm_session, base64.b64decode(license.encode("utf-8")).decode("utf-8"))
|
||||
decryption_keys = [i.key.hex() for i in self.cdm.get_keys(cdm_session)]
|
||||
if len(decryption_keys) != 1:
|
||||
raise ValueError(f"Expecting only one key to be returned, but {len(decryption_keys)} keys were returned")
|
||||
elif len(decryption_keys) == 1 and "32b8ade1769e26b1ffb8986352793fc6" in decryption_keys:
|
||||
raise ValueError("Only default key returned for track.")
|
||||
finally:
|
||||
self.cdm.close(cdm_session)
|
||||
return decryption_key
|
||||
return decryption_keys[0]
|
||||
|
||||
def download(self, path: Path, stream_url: str):
|
||||
if self.download_mode == DownloadMode.YTDLP:
|
||||
|
Loading…
Reference in New Issue
Block a user