fix(player): only the credits that end an item move on to the next one
An item can carry several credits blocks with mid- and post-credit scenes between them, and Plex flags the one that really ends it. The player left at the first block. Now the Plex-final block moves on (by the auto-skip or the Skip button), an earlier block is only skipped to its end by the button, and with no final flag the last block ends the item by the button alone.
This commit is contained in:
@@ -1274,7 +1274,8 @@ class PlexItem(Base, TimestampMixin, UpdatedAtMixin):
|
||||
# bit-depth/HDR. NULL = never (the backfill's work-list). Only HW-decodable transcode items are
|
||||
# probed (the rest are SW-only by codec and need no bit-depth); see `_probe_media_batch`.
|
||||
media_probed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
# Intro/credit markers: [{"type": "intro"|"credits", "start_s": int, "end_s": int}, ...]
|
||||
# Intro/credit markers: [{"type": "intro"|"credits", "start_s": int, "end_s": int}, ...] — unused:
|
||||
# the player reads them live from Plex (`routes/plex/detail.item_detail`, with Plex's `final`).
|
||||
markers: Mapped[list | None] = mapped_column(JSON)
|
||||
added_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), index=True)
|
||||
# Filterable / orderable metadata mirrored from the Plex section listing (no extra API calls;
|
||||
|
||||
@@ -404,6 +404,10 @@ def item_detail(
|
||||
"type": m.get("type"),
|
||||
"start_s": round((m.get("startTimeOffset") or 0) / 1000, 1),
|
||||
"end_s": round((m.get("endTimeOffset") or 0) / 1000, 1),
|
||||
# An item can carry several credits blocks with scenes between them; Plex
|
||||
# flags the one that really ends it. Which credits may leave the item is the
|
||||
# player's rule (`lib/plexMarkers`), so the flag goes over as Plex sent it.
|
||||
"final": bool(m.get("final")),
|
||||
}
|
||||
)
|
||||
# Audio + subtitle tracks (ordinals among their stream type — used to -map the selection).
|
||||
|
||||
@@ -401,3 +401,38 @@ def test_item_detail_names_tracks_from_their_language_not_plexs_title(
|
||||
("magyar Forced", "hu", True, False, None),
|
||||
("English SDH", "en", False, True, None),
|
||||
]
|
||||
|
||||
|
||||
def test_item_detail_markers_carry_plex_final_flag(db, monkeypatch, override_dep):
|
||||
"""An item can carry several credits markers — mid- and post-credit scenes sit between them —
|
||||
and only the one Plex flags `final` is the real end; the player needs that flag to know which
|
||||
credits may move on to the next item."""
|
||||
lib = PlexLibrary(plex_key="1", title="Movies", kind="movie", enabled=True)
|
||||
db.add(lib)
|
||||
db.flush()
|
||||
db.add(PlexItem(rating_key="m2", library_id=lib.id, kind="movie", title="Iron Man"))
|
||||
db.commit()
|
||||
user = _user(db, "markers@example.com")
|
||||
db.commit()
|
||||
|
||||
meta = {
|
||||
"Marker": [
|
||||
{"type": "intro", "startTimeOffset": 1000, "endTimeOffset": 60000},
|
||||
{"type": "credits", "startTimeOffset": 6811000, "endTimeOffset": 6831000},
|
||||
{
|
||||
"type": "credits",
|
||||
"startTimeOffset": 7549000,
|
||||
"endTimeOffset": 7559000,
|
||||
"final": True,
|
||||
},
|
||||
{"type": "commercial", "startTimeOffset": 1, "endTimeOffset": 2},
|
||||
]
|
||||
}
|
||||
monkeypatch.setattr(detail_routes, "PlexClient", lambda db: _StubClient(meta))
|
||||
resp = _get(db, user, monkeypatch, override_dep, "/api/plex/item/m2")
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert resp.json()["markers"] == [
|
||||
{"type": "intro", "start_s": 1.0, "end_s": 60.0, "final": False},
|
||||
{"type": "credits", "start_s": 6811.0, "end_s": 6831.0, "final": False},
|
||||
{"type": "credits", "start_s": 7549.0, "end_s": 7559.0, "final": True},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user