mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-15 05:25:12 +00:00
feat(drm): let a track pin the DRM system it licenses with
Adds Track.drm_preference so a service can pin a track to Widevine or PlayReady when a manifest advertises both but only one will license it. Honoured in DASH/HLS selection, the dl licence path and the remote/API track round-trip. Also fixes quality-keyed CDM maps sending audio to the default entry, and a licence callable binding the CDM before the swap.
This commit is contained in:
@@ -7,6 +7,7 @@ from langcodes import Language
|
||||
|
||||
from unshackle.core.api.errors import APIError, APIErrorCode
|
||||
from unshackle.core.api.handlers import (
|
||||
drm_preference_name,
|
||||
sanitize_log,
|
||||
search_handler,
|
||||
serialize_audio_track,
|
||||
@@ -161,6 +162,31 @@ def test_serialize_audio_track_basic() -> None:
|
||||
assert d["descriptive"] is False
|
||||
|
||||
|
||||
def test_serialize_video_track_drm_preference_round_trip() -> None:
|
||||
d = serialize_video_track(video())
|
||||
assert d["drm_preference"] is None
|
||||
v = video()
|
||||
v.drm_preference = "pr"
|
||||
assert serialize_video_track(v)["drm_preference"] == "pr"
|
||||
|
||||
|
||||
def test_serialize_audio_track_drm_preference() -> None:
|
||||
a = audio()
|
||||
a.drm_preference = "widevine"
|
||||
assert serialize_audio_track(a)["drm_preference"] == "widevine"
|
||||
|
||||
|
||||
def test_drm_preference_name_maps_short_forms() -> None:
|
||||
v = video()
|
||||
assert drm_preference_name(v) is None
|
||||
v.drm_preference = "pr"
|
||||
assert drm_preference_name(v) == "playready"
|
||||
v.drm_preference = "wv"
|
||||
assert drm_preference_name(v) == "widevine"
|
||||
v.drm_preference = "widevine"
|
||||
assert drm_preference_name(v) == "widevine"
|
||||
|
||||
|
||||
def test_serialize_subtitle_track_basic() -> None:
|
||||
d = serialize_subtitle_track(subtitle(forced=True))
|
||||
assert d["id"] == "sub-001"
|
||||
|
||||
@@ -108,6 +108,23 @@ def test_build_tracks_aggregates() -> None:
|
||||
assert len(t.subtitles) == 1
|
||||
|
||||
|
||||
def test_build_tracks_restores_drm_preference() -> None:
|
||||
data = {
|
||||
"video": [{"id": "v", "codec": "AVC", "width": 1280, "height": 720, "drm_preference": "playready"}],
|
||||
"audio": [{"id": "a", "codec": "AAC", "channels": 2, "drm_preference": "wv"}],
|
||||
"subtitles": [],
|
||||
}
|
||||
t = build_tracks(data)
|
||||
assert t.videos[0].drm_preference == "playready"
|
||||
assert t.audio[0].drm_preference == "wv"
|
||||
|
||||
|
||||
def test_build_tracks_ignores_unknown_drm_preference() -> None:
|
||||
data = {"video": [{"id": "v", "codec": "AVC", "width": 1, "height": 1, "drm_preference": "fairplay"}]}
|
||||
t = build_tracks(data)
|
||||
assert t.videos[0].drm_preference is None
|
||||
|
||||
|
||||
def test_match_track_by_id() -> None:
|
||||
a = deserialize_video({"id": "v1", "codec": "AVC", "width": 1920, "height": 1080})
|
||||
b = deserialize_video({"id": "v2", "codec": "AVC", "width": 1280, "height": 720})
|
||||
|
||||
Reference in New Issue
Block a user