mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-11-14 21:15:06 +00:00
fix(manifests): skip filtered dash periods after the main content and keep them over export
A manifest snapshot module now saves and restores DASH/ISM parser state for --remote and export/import, so an import keeps the service's period filter without fetching the manifest.
This commit is contained in:
@@ -7,6 +7,7 @@ from enum import Enum
|
||||
import pytest
|
||||
|
||||
from unshackle.core.api.handlers import serialize_audio_track, serialize_subtitle_track, serialize_video_track
|
||||
from unshackle.core.manifests.snapshot import match_track
|
||||
from unshackle.core.remote_service import (
|
||||
RemoteService,
|
||||
build_title,
|
||||
@@ -15,7 +16,6 @@ from unshackle.core.remote_service import (
|
||||
deserialize_subtitle,
|
||||
deserialize_video,
|
||||
enum_get,
|
||||
match_track,
|
||||
reconstruct_drm,
|
||||
)
|
||||
from unshackle.core.titles.episode import Episode
|
||||
@@ -524,7 +524,7 @@ def test_resolve_manifest_data_matches_across_per_range_manifests() -> None:
|
||||
from tests.core.test_ism_init import VIDEO_HEVC_PQ_CPD, VIDEO_HEVC_SDR_CPD
|
||||
from tests.core.test_ism_range import manifest_xml
|
||||
from unshackle.core.manifests import ISM
|
||||
from unshackle.core.remote_service import resolve_manifest_data
|
||||
from unshackle.core.manifests.snapshot import restore
|
||||
|
||||
urls = {"sdr": "https://x/sdr/manifest", "hdr": "https://x/hdr/manifest"}
|
||||
xml = {"sdr": manifest_xml(VIDEO_HEVC_SDR_CPD), "hdr": manifest_xml(VIDEO_HEVC_PQ_CPD)}
|
||||
@@ -549,7 +549,7 @@ def test_resolve_manifest_data_matches_across_per_range_manifests() -> None:
|
||||
for k in ("sdr", "hdr")
|
||||
]
|
||||
|
||||
resolve_manifest_data(tracks, manifests)
|
||||
restore(tracks, {"manifests": manifests})
|
||||
|
||||
assert remote_hdr.data["ism"]["quality_level"].get("CodecPrivateData") == VIDEO_HEVC_PQ_CPD
|
||||
|
||||
@@ -680,9 +680,8 @@ def test_no_dl_params_when_the_ctx_has_no_selection() -> None:
|
||||
def test_resolve_manifest_data_keeps_the_periods_the_server_filtered() -> None:
|
||||
"""A service drops periods (a mid-roll ad) on the server only. The client must skip the
|
||||
same periods after it re-parses the manifest, or a remote download joins them back in."""
|
||||
from unshackle.core.api.handlers import extract_manifests
|
||||
from unshackle.core.manifests import DASH
|
||||
from unshackle.core.remote_service import resolve_manifest_data
|
||||
from unshackle.core.manifests.snapshot import capture, restore
|
||||
|
||||
periods = "".join(
|
||||
f"""<Period id="{pid}" duration="PT1S"><AdaptationSet contentType="video" mimeType="video/mp4" lang="en">
|
||||
@@ -700,6 +699,6 @@ def test_resolve_manifest_data_keeps_the_periods_the_server_filtered() -> None:
|
||||
remote = deserialize_video(serialize_video_track(server.videos[0]))
|
||||
tracks = build_tracks({"video": [], "audio": [], "subtitles": []})
|
||||
tracks.videos.append(remote)
|
||||
resolve_manifest_data(tracks, extract_manifests(server))
|
||||
restore(tracks, capture(server))
|
||||
|
||||
assert remote.data["dash"]["filtered_period_ids"] == ["ad1"]
|
||||
|
||||
@@ -6,8 +6,7 @@ import pytest
|
||||
from langcodes import Language
|
||||
from lxml import etree
|
||||
|
||||
from unshackle.core.api.handlers import extract_track_manifests
|
||||
from unshackle.core.remote_service import resolve_track_manifests
|
||||
from unshackle.core.manifests.snapshot import capture, restore
|
||||
from unshackle.core.tracks import Subtitle, Tracks
|
||||
|
||||
pytestmark = pytest.mark.unit
|
||||
@@ -53,8 +52,8 @@ def test_detached_adaptation_set_round_trips() -> None:
|
||||
)
|
||||
tracks = Tracks([track])
|
||||
|
||||
fragments = extract_track_manifests(tracks)
|
||||
assert len(fragments) == 1
|
||||
snapshot = capture(tracks)
|
||||
assert len(snapshot["track_manifests"]) == 1
|
||||
|
||||
client_track = Subtitle(
|
||||
id_="abc123",
|
||||
@@ -63,7 +62,7 @@ def test_detached_adaptation_set_round_trips() -> None:
|
||||
language=Language.get("en"),
|
||||
descriptor=Subtitle.Descriptor.URL,
|
||||
)
|
||||
resolve_track_manifests(Tracks([client_track]), fragments)
|
||||
restore(Tracks([client_track]), snapshot)
|
||||
|
||||
dash = client_track.data["dash"]
|
||||
assert dash["manifest"].find("BaseURL").text == "https://cdn.example/base/"
|
||||
@@ -101,7 +100,7 @@ def test_single_track_manifest_round_trips_by_id() -> None:
|
||||
sdh=True,
|
||||
descriptor=Subtitle.Descriptor.URL,
|
||||
)
|
||||
resolve_track_manifests(Tracks([client_track]), extract_track_manifests(Tracks([track])))
|
||||
restore(Tracks([client_track]), capture(Tracks([track])))
|
||||
|
||||
assert client_track.descriptor == Subtitle.Descriptor.DASH
|
||||
assert client_track.data["dash"]["representation_id"] == "sub-0"
|
||||
@@ -127,7 +126,7 @@ def test_in_tree_adaptation_set_is_not_shipped() -> None:
|
||||
}
|
||||
},
|
||||
)
|
||||
assert extract_track_manifests(Tracks([track])) == []
|
||||
assert capture(Tracks([track]))["track_manifests"] == []
|
||||
|
||||
|
||||
def test_fragment_keeps_only_the_track_representation() -> None:
|
||||
@@ -153,7 +152,7 @@ def test_fragment_keeps_only_the_track_representation() -> None:
|
||||
language=Language.get("en"),
|
||||
descriptor=Subtitle.Descriptor.URL,
|
||||
)
|
||||
resolve_track_manifests(Tracks([client_track]), extract_track_manifests(Tracks([track])))
|
||||
restore(Tracks([client_track]), capture(Tracks([track])))
|
||||
|
||||
dash = client_track.data["dash"]
|
||||
assert dash["representation_id"] == "sub-1"
|
||||
|
||||
Reference in New Issue
Block a user