Commit Graph
6 Commits
Author SHA1 Message Date
ScarriffleandClaude Opus 5 5b2b86b66b MediaKit: die Grundschicht, auf der Plex und Jellyfin dasselbe meinen
Erster Schritt zu Jellyfin, und er besteht vor allem aus Wegnehmen.

`PlaybackDecider` nahm bisher Plex-Modelle entgegen und las daraus sechs
Felder. Das band die Entscheidung an einen bestimmten Server, obwohl an
der Frage „kann iOS das öffnen?" nichts serverspezifisch ist. Jetzt nimmt
er ein `MediaProfile` — Container, Codecs, Bitrate, ob die Datei
untersucht ist.

Wie ernst die Kopplung war, zeigte der Player selbst: für die
Offline-Wiedergabe baute er sich **erfundene** Plex-Werte zusammen — eine
Media mit Kennung 0, ein Part mit dem Dateinamen als Schlüssel,
zusammengesetzte Spurlisten —, nur damit die Signatur passte. Für eine
Datei, die längst auf dem Gerät lag und mit Plex nichts mehr zu tun
hatte. Dieser Hack ist weg.

Neu ist das Target `MediaKit`: Typen und Rechnungen, die für jeden Server
gelten, ohne eine einzige Abhängigkeit. Darin `MediaProfile` und die
`Duration`-Brücke, die bisher in PlexKit stand — „weil es die unterste
Schicht ist". Das stimmte, solange es nur einen Server gab.

Damit kennen Wiedergabe und Downloads Plex nicht mehr. Zwei der
Abhängigkeiten waren ohnehin tot; die dritte trug nur diese Brücke.

Die wichtigste Testtabelle des Projekts ist mitgewandert und dabei
kürzer geworden: dort steht jetzt, worauf es ankommt, statt vollständiger
Modelle mit Kennungen und Dateipfaden, von denen niemand etwas las.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 12:26:19 +02:00
ScarriffleandClaude Opus 5 f628819765 Player: eine gewählte Stufe wurde gar nicht umgerechnet
Der Decider rechnet nur um, wenn die Datei die Grenze überschreitet. Für
den Normalfall ist das richtig — für eine ausdrückliche Wahl im Player
nicht: wer für eine 8-Mbit-Datei „12 Mbit" wählt, bekam DirectPlay, weil
die Datei ja darunter liegt. Gemeint ist aber „rechne es mir auf diese
Stufe um", nicht „gib mir die Datei, falls sie so vorliegt".

Die Richtlinie kann eine Umrechnung jetzt erzwingen, und die Wahl im
Player tut das.

Dazu verschluckte `select(quality:)` den eigentlichen Grund: lehnte der
Server ab und sagte im Klartext warum, wurde diese Meldung danach durch
das allgemeine „keine abspielbare Datei" ersetzt — der eine brauchbare
Hinweis war damit weg. Jetzt bleibt stehen, was der Server gesagt hat.

Und das Menü war zu viel. Vorn steht die kurze Liste — automatisch,
Original, je eine brauchbare Stufe pro Auflösung, nur Ton. Wer eine
bestimmte Bitrate erzwingen muss, klappt „Alle Stufen" auf; im Alltag
will man „eine Stufe kleiner" und nicht die Wahl zwischen zehn und zwölf
Megabit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 22:05:27 +02:00
ScarriffleandClaude Opus 5 12bb49615b Player: die Qualitätsleiter des Servers, Bitrate im Blick, Doppeltipp
Die vier erfundenen Stufen weichen der Leiter, die der Server selbst
meldet: 64, 96, 208, 320, 720, 1500, 2000, 3000, 4000, 8000, 10000,
12000, 20000 kbps mit den Auflösungen, die Plex dafür vorsieht. Eine
eigene Leiter hieße, Stufen anzubieten, die der Transcoder nicht kennt —
er rundet dann still auf die nächste, und die Anzeige log.

Angeboten wird nur, was zur Quelle passt. Eine 720p-Datei auf 1080p
hochzurechnen bringt kein Bild dazu, und die Stufen sähen alle gleich aus.

Oben im Blatt steht, was tatsächlich über die Leitung kommt — gemessene
Bitrate, Auflösung, verworfene Bilder. Der Unterschied zur gewählten
Stufe ist keine Haarspalterei: die eine sagt, was erlaubt ist, die andere,
was ankommt. Ruckelt es trotz hoher Stufe, steht die Antwort dort.

„Nur Ton" gibt es, aber ehrlich beschriftet: Plex kennt für Videos keinen
reinen Tonstrom, also wird die unterste Sprosse geholt und das Bild
ausgeblendet.

Dazu Doppeltipp links und rechts für zehn Sekunden zurück und vor. Die
Reihenfolge der Gesten ist entscheidend — das einfache Tippen verschluckt
sonst das doppelte.

Die Kachel hängt nicht mehr in vier Ecken fest, sondern klebt links oder
rechts und ist in der Höhe frei. Vier Ecken sind schnell gebaut, aber im
Weg: steht sie über einem Knopf, bleiben drei Orte, die ebenso stören.
Größer wird sie durch Zusammen- und Auseinanderziehen; der Griff ist weg,
er saß zwangsläufig auf dem Bild und stritt sich mit dem Verschieben.

Und die Begriffe: „Motor" für engine sagt kein deutscher Entwickler.
Fachwörter, die im Deutschen englisch bleiben, bleiben jetzt englisch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 21:50:39 +02:00
GuidoandClaude Opus 5 bf0a63a924 Vier Punkte aus dem Praxistest
Download-Knopf tat nichts
  DownloadService.plan gab still nil zurück, wenn es keinen Auftrag
  bauen konnte, und download() reichte das als nil weiter. Der Knopf sah
  aus, als wäre er kaputt, dabei war der Grund jedes Mal bekannt. Es
  gibt jetzt einen eigenen Ablehnungsgrund mit vier unterschiedlichen
  Begründungen — keine Verbindung, keine Datei, kein abrufbarer Teil,
  keine Adresse. Eine Funktion, die kommentarlos nichts tut, ist selbst
  der Fehler.

Live-TV galt als „nicht eingerichtet"
  Plex legt die Empfängerliste unter dem Schlüssel `Dvr` ab, die Hülle
  kannte aber nur Metadata, Directory und Hub. Sie las eine leere Liste
  und zog daraus die falsche Schlussfolgerung — auf einem Server, auf
  dem ein Empfänger eingerichtet war. Dasselbe galt für die
  Anbieterliste unter `MediaProvider`, ohne die es keinen
  Programmführer gibt.

  Beim Umbau wäre beinahe die Fehlerdiagnose verloren gegangen: mit
  `try?` über alle Schlüssel verschwände auch ein echter Dekodierfehler
  und ergäbe stillschweigend eine leere Liste. Aus „ein Feld heißt jetzt
  anders" würde „die Mediathek ist leer". Jetzt wird erst geprüft, ob
  der Schlüssel da ist, und dann ohne try? dekodiert. Fünf Tests halten
  beides fest.

Qualität im Player wählbar
  Automatisch, Original, 1080p, 720p, 480p. Der Eingriff wird genau dann
  gebraucht, wenn es ruckelt — dafür will niemand den Film verlassen.
  Ein Wechsel baut den Strom neu auf (die Stufe steckt in der Adresse),
  merkt sich die Stelle und fährt sie wieder an. Der alte Transcoder
  wird vorher angehalten, sonst rechnet der Server zwei Ströme für einen
  Zuschauer.

AVPlayer-Anzeige entfernt
  Sie war eine Prüfhilfe aus Phase 1. Dieselbe Angabe steht weiterhin
  unter Einstellungen → Diagnose, wo sie hingehört.

137 Tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 21:44:20 +02:00
GuidoandClaude Opus 5 55bcfe2fbf Phase 2: Transcoding, adaptive Bitrate, Spuren, Marker, Sync
Der Decider brauchte keine Änderung — nur eine andere Richtlinie.
Genau dafür war er gebaut.

Transcoding
- TranscodeRequest baut die Parameter für /video/:/transcode/universal.
  directStream=1 lässt Plex nur umpacken, wenn der Bildcodec passt,
  statt pauschal neu zu kodieren.
- Vor dem Start wird der Server gefragt (decision); sagt er nein, steht
  der Grund im Klartext da statt eines schwarzen Bildes.
- Beim Verlassen wird der Transcoder angehalten. Ohne dieses Signal
  rechnet der Server minutenlang für niemanden weiter.
- Die adaptive Bitrate kommt mit HLS: AVPlayer wechselt sie selbst.

Qualitätseinstellungen
- Getrennt für WLAN und Mobilfunk, fünf spürbare Stufen.
  Voreinstellung: zuhause Original, unterwegs 4 Mbit.
- NetworkConditions erkennt Mobilfunk über isExpensive — das deckt auch
  den Hotspot ab, der technisch WLAN ist und trotzdem Volumen kostet.

Spuren und Marken
- Ton- und Untertitelwahl im Player, bevorzugte Sprache in den
  Einstellungen, nachsichtiger Sprachvergleich (de/deu/ger/de-DE).
- Intro- und Abspann-Marken mit Überspringen-Knopf, optional
  automatisch. Bereits übersprungene Marken werden gemerkt, sonst käme
  man nach einem Rücksprung nie ins Intro zurück.
- Nächste Folge inkl. Staffelwechsel; Specials in Staffel 0 werden
  nicht vorgezogen.

Fortschritt
- Alle zehn Sekunden an den Server, plus Schlussmeldung beim Verlassen.
  Erst die nimmt den Titel aus „wird gerade abgespielt" heraus.
- markWatched/markUnwatched/rate/refreshLibrary stehen bereit.

86 Tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 17:24:17 +02:00
GuidoandClaude Opus 5 1ed64bf166 Phase 0: Projektgerüst, Design-Tokens und Navigation
Legt das Fundament für den Plex-Client an:

- XcodeGen-Projekt nach dem Muster von Onyx (com.scarriffleservices,
  strict concurrency, Projektdatei nicht eingecheckt)
- FlixyKit mit vier Modulen: PlexKit, FlixyDesign, FlixyPlayback,
  FlixyDownloads. macOS steht als Plattform mit drin, damit die
  Logik-Tests ohne Simulator laufen.
- FlixyDesign: dunkle Farb-Tokens, Schriftskala, Poster- und
  Querformat-Kacheln, Aufmacher-Bild. Die Akzentfarbe fließt über die
  Umgebung und wird per WCAG-Rechnung lesbar gehalten.
- PlexKit: Kopfzeilen-Identität, Transport-Protokoll, Fehlerarten und
  die Medienmodelle samt nachsichtigem Decoder.
- FlixyPlayback: VideoPlayerEngine-Protokoll und PlaybackDecider — die
  eine Funktion, an der Phase 2 das Transcoding andockt.
- Ausfahrbare Seitenleiste auf dem iPhone, Split-View auf dem iPad.
- 45 Tests, alle grün.

VLCKit 4.0.0-a24 ist vorab geprüft: baut über SPM unter Swift 6 mit
strict concurrency. Die iOS-Slice ist mit 239 MB allerdings gewichtig,
deshalb bekommt sie in Phase 1 ein eigenes Target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 16:04:40 +02:00