Wiedergabe: das Geräteprofil zerfiel in zwei Dutzend eigene Parameter

`URLComponents` kodiert `&` und `=` innerhalb eines Abfragewerts nicht.
Das Geräteprofil steckt voll davon:

    X-Plex-Client-Profile-Extra=add-transcode-target(type=videoProfile&
      context=streaming&protocol=hls&container=mpegts&…)

Der Server hat das nicht als ein Profil gelesen, sondern als zwei Dutzend
eigene Angaben — darunter ein zweites `protocol=`. Eine widersprüchliche
Anfrage, und die Antwort darauf ist eine nackte 400 ohne Hinweis.

Der Fehler steckte in jeder Transcoder-Adresse, seit es sie gibt. Bei
Dateien fiel er nicht auf, weil dort meist DirectPlay greift und der
Transcoder gar nicht gefragt wird.

Kodiert wird der **ursprüngliche** Wert, nicht der bereits von
`URLComponents` behandelte: den ein zweites Mal zu kodieren macht aus
`%3D` ein `%253D` — derselbe Fehler, nur eine Ebene tiefer. Der Test
prüft beides: dass das Profil ein einziger Parameter bleibt und dass
`protocol` genau einmal vorkommt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-12 15:32:20 +02:00
co-authored by Claude Opus 5
parent c24938590d
commit 3467f0f690
3 changed files with 73 additions and 20 deletions
@@ -691,16 +691,18 @@ extension PlexServer {
// angelegt hat, wird umgerechnet — nicht die Abspielliste darin und
// nicht meine eigene Kennung. Ihr Schlüssel steht in der Antwort.
if let sessionKey = Self.firstSessionKey(in: data) {
let outcome = await attemptStream(
path: sessionKey,
ratingKey: channel.id,
mediaIndex: 0,
includeProfile: true,
maximumBitrate: maximumBitrate,
session: session
)
probes.append(outcome.probe)
if let url = outcome.url { return (url, subscription, probes) }
for withProfile in [true, false] {
let outcome = await attemptStream(
path: sessionKey,
ratingKey: channel.id,
mediaIndex: 0,
includeProfile: withProfile,
maximumBitrate: maximumBitrate,
session: session
)
probes.append(outcome.probe)
if let url = outcome.url { return (url, subscription, probes) }
}
}
// Und die Abspielliste unmittelbar. Sie antwortete mit 404 statt 400: