mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-12 12:05:07 +00:00
fix(remote): stop warning about missing keys for tracks that carry no DRM
The server names the clear tracks in the licence response and the client skips them instead of warning for every requested track without keys.
This commit is contained in:
@@ -1077,6 +1077,7 @@ Get the content keys for the DRM. The `mode` field selects one of two modes.
|
||||
| `pssh` | Base64 PSSH (server-CDM mode). |
|
||||
| `drm_type` | `widevine` (default) or `playready`. |
|
||||
| `mode` | `proxy` (default) or `server_cdm`. |
|
||||
| `clear_tracks` (response) | Requested track ids that carry no DRM, so they have no keys. Absent when every requested track is encrypted. |
|
||||
| `vault_keys` (response) | KIDs whose content key came from a server vault, not the CDM. The client proves such a content key with a decode before it trusts it; the field is absent when every content key came from the CDM. |
|
||||
|
||||
| Status | Error code | Meaning |
|
||||
|
||||
@@ -146,3 +146,25 @@ async def test_server_tells_a_remote_vault_only_when_it_served_the_pair(monkeypa
|
||||
assert local.flagged == [("SVC", KID, "v", "sqlite")]
|
||||
assert source.flagged == [("SVC", KID, "v", "sqlite")]
|
||||
assert bystander.flagged == []
|
||||
|
||||
|
||||
def test_resolve_server_keys_does_not_warn_for_clear_tracks(monkeypatch):
|
||||
"""A requested track the server lists in clear_tracks carries no DRM, so its
|
||||
missing keys are expected and draw no warning."""
|
||||
svc = remote_service()
|
||||
warnings: list = []
|
||||
svc.log = SimpleNamespace(warning=lambda msg, *a, **k: warnings.append(msg), debug=lambda *a, **k: None)
|
||||
svc._server_cdm = True
|
||||
svc.drain_server_logs = lambda: None
|
||||
svc.client = SimpleNamespace(post=lambda ep, data: {"keys": {}, "clear_tracks": ["a-1"]})
|
||||
|
||||
video_track = SimpleNamespace(id="v-1", drm=None)
|
||||
audio_track = SimpleNamespace(id="a-1", drm=None)
|
||||
|
||||
class Tracks(list):
|
||||
videos = [video_track]
|
||||
audio = [audio_track]
|
||||
|
||||
svc.resolve_server_keys(SimpleNamespace(tracks=Tracks([video_track, audio_track])))
|
||||
|
||||
assert warnings == ["Server CDM returned no content keys for track v-1"]
|
||||
|
||||
@@ -4177,6 +4177,7 @@ async def session_license_handler(
|
||||
|
||||
all_keys: Dict[str, Dict[str, str]] = {}
|
||||
vault_keys: list[str] = []
|
||||
clear_tracks: list[str] = []
|
||||
drm_types: Dict[str, str] = {}
|
||||
keys_by_pssh: Dict[tuple, Dict[str, str]] = {}
|
||||
sources_by_pssh: Dict[tuple, Dict[str, str]] = {}
|
||||
@@ -4250,7 +4251,8 @@ async def session_license_handler(
|
||||
init_data = fetch_init_segment(track, svc_session)
|
||||
ensure_track_drm(track, svc_session, init_data)
|
||||
if not track.drm:
|
||||
warn(f"Track {sanitize_log(tid[:12])} carries no DRM, so it has no keys to resolve")
|
||||
log.info(f"Track {sanitize_log(tid[:12])} carries no DRM, so it has no keys to resolve")
|
||||
clear_tracks.append(tid)
|
||||
continue
|
||||
|
||||
title = find_title_for_track(tid, session)
|
||||
@@ -4311,6 +4313,8 @@ async def session_license_handler(
|
||||
actual_drm_type = track_drm_type
|
||||
|
||||
response: Dict[str, Any] = {"keys": all_keys}
|
||||
if clear_tracks:
|
||||
response["clear_tracks"] = clear_tracks
|
||||
if vault_keys:
|
||||
response["vault_keys"] = vault_keys
|
||||
if actual_drm_type:
|
||||
|
||||
@@ -1833,7 +1833,8 @@ async def session_license(request: web.Request) -> web.Response:
|
||||
License response. In server_cdm mode `keys` maps KID to content key and `vault_keys`,
|
||||
an array of KID hex strings that may be absent and may repeat a KID shared by several
|
||||
tracks, lists the content keys a server vault supplied, which the client has to prove
|
||||
before it trusts them.
|
||||
before it trusts them. `clear_tracks`, absent when empty, lists the requested track ids
|
||||
that carry no DRM and so have no keys.
|
||||
'404':
|
||||
description: Remote session or track not found
|
||||
"""
|
||||
|
||||
@@ -1178,6 +1178,7 @@ class RemoteService:
|
||||
)
|
||||
self.drain_server_logs()
|
||||
keys_by_track = resp.get("keys", {})
|
||||
clear_tracks = set(resp.get("clear_tracks", []))
|
||||
vault_kids = set(resp.get("vault_keys", []))
|
||||
for track_keys in keys_by_track.values():
|
||||
self.note_vault_keys(track_keys, vault_kids)
|
||||
@@ -1189,7 +1190,7 @@ class RemoteService:
|
||||
for track in title.tracks:
|
||||
track_keys = keys_by_track.get(str(track.id), {})
|
||||
if not track_keys:
|
||||
if str(track.id) in track_ids:
|
||||
if str(track.id) in track_ids and str(track.id) not in clear_tracks:
|
||||
self.log.warning(f"Server CDM returned no content keys for track {track.id}")
|
||||
continue
|
||||
|
||||
|
||||
Reference in New Issue
Block a user