Live-TV: die Sitzung des Servers umrechnen, und hasMDE mitschicken

Nachgelesen im Quelltext des Plex-Clients, Funktion `video`:

    path: server.resolveUrl(item.get("key")),   // /livetv/sessions/1268be73-…
    hasMDE: 1, mediaIndex: …, partIndex: …,
    protocol: "hls", …

Zwei Dinge fehlten. Umgerechnet wird die **Sitzung, die der Server beim
Belegen angelegt hat** — nicht die Abspielliste darin, nicht die Sendung
beim Programmführer, und schon gar nicht die Kennung, die ich selbst
erzeuge. Genau die hatte ich mehrfach eingesetzt und mich über 404
gewundert.

Und `hasMDE=1` — „ich verstehe die Entscheidungsantwort". Plex' Client
schickt das bei jeder Wiedergabe mit. Es fehlte bei allen bisherigen
Versuchen, auch bei denen, die sonst richtig waren.

Der Schlüssel wird suchend gelesen und dabei von der Abspielliste
unterschieden: beide beginnen mit /livetv/sessions/, aber nur eine endet
auf .m3u8.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-12 15:28:49 +02:00
co-authored by Claude Opus 5
parent a9563be1e1
commit c24938590d
3 changed files with 77 additions and 3 deletions
@@ -334,6 +334,32 @@ struct LiveTVGuideTests {
#expect(result.subscriptionKey == "77")
}
@Test("Umgerechnet wird die Sitzung des Servers, nicht die eigene Kennung")
func transcodesTheServersSession() throws {
// `/livetv/sessions/1268be73-…` ist die Sitzung, die der Server beim
// Belegen angelegt hat. Ich habe mehrfach meine eigene erzeugte
// Kennung eingesetzt und mich über 404 gewundert.
let json = Data("""
{"MediaContainer":{"MediaSubscription":[{"key":"77","MetadataItem":{
"key":"/livetv/sessions/1268be73-1598-4fb9-ac9e-35825eba3fdd","live":"1",
"Media":[{"id":1,"Part":[{"key":"/livetv/sessions/1268be73/ABC/index.m3u8?offset=-1"}]}]}}]}}
""".utf8)
// Die Abspielliste selbst ist nicht gemeint — sie endet auf .m3u8.
#expect(PlexServer.firstSessionKey(in: json)
== "/livetv/sessions/1268be73-1598-4fb9-ac9e-35825eba3fdd")
}
@Test("Jede Wiedergabe meldet, dass sie die Entscheidungsantwort versteht")
func alwaysSendsHasMDE() {
// Plex' eigener Client schickt `hasMDE=1` bei jeder Wiedergabe mit.
// Ohne diese Angabe lehnt der Server eine Live-Sitzung mit einer
// nackten 400 ab — ohne zu sagen, was ihm fehlt.
let items = TranscodeRequest(ratingKey: "5", isLocal: true).queryItems
#expect(items.contains { $0.name == "hasMDE" && $0.value == "1" })
}
@Test("Die Teil-Adresse wird gefunden, egal wie tief sie liegt")
func findsPartAtAnyDepth() throws {
// Der Vorgang liegt je nach Serverfassung unterschiedlich tief