ab0adef8d4799623f3bed3df437795b01cf65a17
6
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5696254034 |
Jellyfin: der Anmeldebildschirm bietet jetzt beides an
Der Anmeldebildschirm kannte nur Plex. JellyfinKit war fertig, aber von der App aus nicht erreichbar — „ich sehe nix von Jellyfin". Quick Connect steht vorn: der Server nennt einen sechsstelligen Code, den man in einem bereits angemeldeten Client bestätigt. Das Passwort erreicht Flixy dabei nie, dieselbe Zusage wie bei Plex. Benutzername und Passwort sind der Rückfall für Server, auf denen Quick Connect abgeschaltet ist; das Passwort wird dann für die Dauer einer Anfrage gehalten und danach weggeworfen. Die Adresse wird nicht erraten, sondern durchprobiert. „192.168.1.50" kann alles Mögliche heißen, und die Reihenfolge ist der Kern von JellyfinAddress: eine IP-Adresse im eigenen Netz spricht fast nie HTTPS, ein Domänenname fast immer. Andersherum wartet man bei jedem Server ohne Zertifikat erst auf eine Zeitüberschreitung. Die Sitzung hält von hier an einen Server hinter dem neutralen Vertrag, nicht mehr einen Plex-Server. Die Ansichten haben das nicht gemerkt — genau dafür war MediaKit da. Dabei fällt ab, was Jellyfin kann und Plex nicht: Favoriten stehen im Aktionsmenü, sobald der Server sie kennt, Sterne nur dort, wo es sie gibt. Was noch nicht geht und deshalb auch nicht behauptet wird: Wiedergabe und Live-TV sprechen weiter unmittelbar mit Plex. Bei Jellyfin verschwindet der Live-TV-Eintrag aus der Seitenleiste, und der Player sagt, dass die Wiedergabe der nächste Schritt ist, statt „Server nicht erreichbar" zu melden — er ist ja erreichbar. Nebenbei zwei Stellen, die der Übersetzer aus Plex hinterlassen hat: `catch is CancellationError` griff seit den getippten Fehlern nie mehr, weil eine abgebrochene Netzanfrage als Übertragungsfehler zurückkommt; und das Ersatz-Hintergrundbild einer Folge war toter Code, weil die linke Seite des `??` gar nicht optional war. TokenStore wandert nach MediaKit — Tokens sind nichts Plex-Eigenes. Die Konten sind nach Server getrennt, damit ein späteres Umschalten nicht jedes Mal eine neue Anmeldung kostet; „Abmelden" räumt trotzdem beide ab. 248 Tests grün. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
fe2d730c00 |
Die Ansichten sprechen nicht mehr mit Plex
Start, Suche, Mediathek, Detailseiten und Downloads arbeiten jetzt mit `MediaItem` und dem `MediaBackend`-Vertrag. Damit sind sie fertig für einen zweiten Server, ohne dass an ihnen noch etwas zu tun wäre. Dabei sind ein paar Namen ehrlicher geworden: aus `grandparentTitle` wurde `seriesTitle`, aus `viewedLeafCount` `playedEpisodeCount`. Und `TagStrip` nahm bisher Plex-Marken mit Kennung und Rolle entgegen, um davon nur den Namen anzuzeigen — Genres sind jetzt schlicht Zeichenketten. `Arrangement` ist aus PlexKit heraus und generisch: dieselbe Rechnung gilt für jede Liste, die jemand selbst zusammenstellt. Phase 3 baut die konfigurierbare Seitenleiste darauf, statt sie ein zweites Mal — und ein zweites Mal falsch — zu schreiben. Die Fehlerübersetzung gibt es nur noch einmal. Es waren zwei, und sie waren bereits auseinandergelaufen: derselbe Fehler bekam je nach Bildschirm eine andere Erklärung. Das Nachladen der Mediathek bleibt unangetastet: eine lange Liste, die fünf Einträge vor dem Ende nachlädt. `MediaPage` heißt zwar Seite, ist aber eine technische Portion — Blättern mit „weiter zu Seite 2" gehört nicht in eine Mediathek, in der man stöbert. Der Kommentar dort sagt das jetzt ausdrücklich, damit es niemand später „aufräumt". Player, Live-TV und die Download-Engine sprechen noch unmittelbar mit Plex. Sie folgen als Nächstes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
6150b018ec |
Vier Punkte: Player-Hänger, kaputte Downloads, Stufenliste, Kopfleiste
Player hing sich auf Die Qualitätsauswahl war ein Menu. Schloss man es durch einen Tipp ins Bild, blieb eine unsichtbare Ebene zurück, die alle weiteren Tipps schluckte — die Bedienelemente kamen nicht mehr, pausieren ging nicht mehr. Jetzt ein confirmationDialog, der sich selbst wegräumt. Nach dem Schließen werden die Bedienelemente eingeblendet und die Ausblendfrist neu gestartet. Downloads galten als fertig, waren aber leer Zwei Fehler übereinander. Erstens gilt ein URLSessionDownloadTask auch bei 404 oder 500 als erfolgreich und legt die Fehlerseite als Datei ab. Zweitens überschrieb ich danach die erwartete Größe mit der empfangenen — womit die Anzeige auf hundert Prozent stand und der Beweis weg war. 873 MB waren in einer Sekunde „fertig", und beim Abspielen kam nur „Wiedergabe wurde unterbrochen". Jetzt wird der Statuscode geprüft, die erwartete Größe bleibt stehen, und eine unplausible Datei wird verworfen statt verbucht: unter 100 KB ist keine Videodatei, unter der Hälfte der angekündigten Größe ist eine abgebrochene Übertragung. Sechs Tests dazu. Stufenliste ergab keinen Sinn Für einen 720p-Inhalt standen Original, Full HD und HD mit derselben geschätzten Größe untereinander — das sah aus, als wäre die Schätzung kaputt. Sie war es nicht, die Stufen waren es: hochrechnen bringt nur eine größere Datei. Angeboten wird jetzt nur noch, was unter der Auflösung der Datei liegt, und beim Original steht dabei, was es ist: „Original · 720p · 873 MB". Kopfleiste Kein Hintergrund mehr statt eines weichgezeichneten — die Knöpfe bringen ihre eigene Glasfläche mit. Der Titel ist weg: der Name der App gehört auf den Homescreen, nicht über jeden Bildschirm. 145 Tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
ac0c27c026 |
Fünf Punkte aus dem Praxistest
iPad meldete sich nie an Die Ursache ist unangenehm speziell: Wer im Browser schon bei Plex angemeldet ist, wird von app.plex.tv/auth sofort auf watch.plex.tv weitergeschickt — OHNE dass der Code verknüpft wird. Man sieht sich angemeldet, die App wartet vergeblich, und es gibt keinerlei Hinweis. Jetzt wird plex.tv/link mit eingetragenem Code geöffnet. Diese Seite tut nur eine Sache: den Code bestätigen. Die Gerätekennung steckt ohnehin schon im PIN. Dazu ein Ausweg: bleibt es nach fünfzehn Sekunden ohne Token, erscheint der Code im Anmeldebildschirm zum Abtippen. Schließt man das Fenster ohne Erfolg, bleibt er stehen statt abzumelden — er gilt weiter. Download fragte nicht nach der Qualität Jetzt Original, Full HD, HD oder Sparsam, jeweils mit geschätzter Größe. Die Größe ist das eigentliche Entscheidungskriterium — „Full HD" allein sagt nicht, ob es aufs Telefon passt. Die komprimierten Stufen laufen über den Universal-Transcoder und sind weiterhin NICHT am Server geprüft; steht so im Quelltext. Schwarzes Bild ohne Anzeige Der Player kannte nur „spielt" und „spielt nicht". Wartete er auf Daten, stand man vor einem Standbild ohne Hinweis. Es gibt jetzt einen eigenen Pufferzustand mit Anzeige. Aufmacher war beschnitten Er stand auf 3:4, Plex liefert als `art` aber 16:9 — mit scaledToFill ging links und rechts je ein Viertel verloren, ohne dass man es dem Bild ansah. Die Seitenverhältnisse liegen jetzt an einer Stelle in FlixyAspectRatio. Schwarze Leiste über dem Aufmacher .ultraThinMaterial statt undurchsichtigem Grund: das Bild läuft unscharf hinter der Leiste weiter, statt an einer harten Kante zu enden. Weichgezeichnet, nicht abgedunkelt. 139 Tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
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> |
||
|
|
62158303a2 |
Phase 3: Download-Engine und Offline-Wiedergabe
Engine - Hintergrund-URLSession: läuft weiter, wenn die App zu ist. Der ganze Zustand liegt in SwiftData, weil es nach einem Neustart kein anderes Gedächtnis gibt. - Pausieren über cancel(byProducingResumeData:) — nur so lässt sich weiterladen statt neu zu beginnen. Bei 40 GB der Unterschied zwischen brauchbar und unbrauchbar. - Zwei Übertragungen gleichzeitig, Folgen in Staffel-/Folgenreihenfolge. Alles parallel zu laden hieße: keine Folge wird fertig. - Speicherlimit und Geräteplatz werden vor dem Annehmen geprüft, ein Gigabyte bleibt als Puffer frei. - Verwaiste Dateien werden beim Start entfernt; sie entstehen, wenn die App genau beim Abschluss beendet wird. - Downloads liegen in Application Support, nicht in Caches (iOS räumt den eigenmächtig leer) und sind von der iCloud-Sicherung ausgenommen. Oberfläche - Download-Knopf auf Detailseiten mit vier Zuständen in einem Knopf. - „Alle Folgen laden" für Staffel und Serie; ein abgelehnter Titel stoppt den Stapel nicht. - Downloads-Ansicht mit Belegung, WLAN-Schalter, Pausieren, Fortsetzen, Löschen — nach Serie gruppiert. Offline - Der Player bevorzugt die lokale Datei, auch ohne erreichbaren Server. - Beim Herunterladen wird ein Abzug der Serverangaben mitgesichert: offline lässt sich nichts nachfragen, und der PlaybackDecider braucht Container und Codecs. Ein Fehler, den die Tests aufgedeckt haben: der Koordinator hielt nur den ModelContext, nicht den ModelContainer. Ein ModelContext hält seinen Container nicht am Leben — wird der anderswo freigegeben, stürzt jeder Zugriff auf einen Eintrag ab, und die Meldung zeigt auf ModelContext.reset statt auf die Ursache. Jetzt liegt die Zuständigkeit beim Koordinator. 102 Tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |