Commit Graph
4 Commits
Author SHA1 Message Date
ScarriffleandClaude Opus 5 4576eac67c Das Bild füllt den Schirm, und die Schrift bleibt darin
Vier Dinge am iPhone-Player, die zusammengehören, weil sie alle davon
handeln, wo der Bildschirm aufhört.

**Einpassen oder füllen.** `videoGravity` stand fest auf `.resizeAspect`,
und zwar in einer Zeile, die nach jedem Neuaufbau erneut läuft — eine
Wahl hätte dort also jeden Qualitätswechsel nicht überlebt. Jetzt steht
sie im Modell, und die Zeile liest sie. Umgelegt wird mit zwei Fingern
oder über einen Knopf; stufenlos wäre falsch, weil alles zwischen den
zwei Zuständen ein Bild ist, das weder ganz zu sehen ist noch den Schirm
füllt. Auf dem Mac erscheint der Knopf nicht: dort steht der
Vollbildknopf darüber, und zwei Knöpfe, die beide „grösser" bedeuten,
sind eine Zumutung.

**Untertitel im Füllmodus.** Dort reicht das Bild über die untere
Bildschirmkante hinaus, und genau dort zeichnet AVFoundation die
Untertitel. Statt sie anzuschneiden, wird die Bildebene um den
Sicherheitsrand eingerückt — rund zwanzig Punkt Bild gegen eine Zeile,
die man lesen kann. Dafür bekommt die Bildfläche echtes Layout: eine
`autoresizingMask` hält Ränder verhältnismässig, und ein fester Einzug
von zwanzig Punkten wäre im Querformat plötzlich vierzig gewesen.

**Die Bedienleiste kannte ihre Ränder nicht mehr.** Der Player bekommt
`ignoresSafeArea()` von der Wurzel und sieht danach überall null —
Schieberegler und Zeitangaben sassen im Home-Indikator, der Zurück-Pfeil
hinter der Dynamic Island, wo ihn niemand drücken konnte. Gemessen wird
jetzt eine Ebene weiter aussen, wo die Ränder noch gelten, und über die
Umgebung nach innen gereicht. Dieselbe Bauart wie der Akzent. Die Zeile
steht ganz am Ende der Kette: stünde sie vor dem Overlay, umschlösse das
Overlay sie, und ausgerechnet der Player ginge leer aus.

**Gedreht wird einmal, gesperrt wird nicht.** Die Maske blieb auf
`.landscape` stehen — wer im Bett auf der Seite lag, konnte nicht mehr
ins Hochformat drehen. Ein Film beginnt quer, weil er quer ist; danach
gehört die Entscheidung dem Nutzer. Dazu ein Drehknopf für den Fall,
dass die Ausrichtungssperre des Systems an ist, und ein Fehlerbehandler
an `requestGeometryUpdate`: eine abgelehnte Drehung ist dann eine
Einstellung und keine Panne.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-29 17:05:44 +02:00
ScarriffleandClaude Opus 5 d54954b9c2 macOS: die App läuft jetzt auf dem Mac
Und dein Argument dafür war das beste: auf dem Mac kann ich selbst hinsehen.
Kein Simulator-Tunnel, der mitten im Prüfen abstürzt — `screencapture` auf das
Fenster der App, und zwar nur auf ihres, nicht auf den Bildschirm.

**Ein eigenes Ziel, nicht ein gemeinsames.** Die Info.plist der iOS-App ist
voller iOS-Angaben: Startbildschirm, erlaubte Ausrichtungen, Live Activities.
Die alle bedingt zu machen hieße, dass jede spätere Änderung an der iOS-Seite
über eine Stelle geht, die auch den Mac betrifft. Zwei Ziele sind ein paar
Zeilen mehr und eine Sorge weniger.

**Was den Unterschied ausmacht, steht an einer Stelle.** Ein neuer
`PlatformShims` in FlixyDesign übersetzt, was auf beiden Seiten verschieden
heißt: schmale Titelzeile, halbhohes Blatt, Eingabefelder ohne
Großschreibung, die Plätze in der Werkzeugleiste, die Zwischenablage. Zwanzig
Ansichten benutzen ihn, statt zwanzigmal `#if os(iOS)` zu tragen — sonst
wandert die Fallunterscheidung in jede neue Datei und wird beim übernächsten
Bildschirm vergessen.

Wirklich verschieden sind nur fünf Stellen: die Bildfläche (`UIView` gegen
`NSView`), der AirPlay-Knopf, die Ausrichtungssperre (auf dem Mac gibt es
nichts zu sperren), der App-Delegat für Hintergrund-Downloads und das
Anmeldefenster, das ein anderes Fenster als Anker braucht.

**Das Karussell blättert jetzt mit einem einrastenden Streifen** statt mit
`TabView(.page)` — den Seitenstil gibt es auf dem Mac nicht. Das ist nebenbei
die bessere Lösung: das verschachtelte TabView hatte die Eigenschaft, beim
Wechsel kurz zwei Seiten gleichzeitig zu zeigen.

**Was auf dem Mac fehlt und warum:** VLC. Das Binärpaket ist auf iOS
festgelegt; sein xcframework enthält zwar Mac-Teile, aber das ist eine eigene
Runde. Solange fällt die Wiedergabe dort auf den Systemplayer zurück — MKV und
DTS gehen also noch nicht. Live Activities gibt es auf dem Mac nicht, Bild-in-
Bild startet von Hand statt beim Verlassen der App.

Gesehen: die App startet, der Anmeldebildschirm steht, beide Wege sind da.
Angemeldet habe ich mich auf dem Mac **nicht** — das ginge nur, indem ich
einen Token in deinen Schlüsselbund schreibe, und dann fragt macOS dich beim
ersten Zugriff nach dem Passwort. Das machst du mit einem Klick selbst.

iOS baut unverändert, 263 Tests grün.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 15:45:13 +02:00
ScarriffleandClaude Opus 5 dace5d1543 Einstellungen: sechs Bildschirme statt einer Liste — und was sie steuern
Deine Einstellungs-Bilder sind eine lange Liste. Ich habe sie durchgegangen
und getrennt: was etwas steuert, ist gebaut; was eine Einstellung für eine
Sache wäre, die es nicht gibt, ist nicht gebaut. Ein Schalter, der nichts
bewirkt, ist schlimmer als kein Schalter.

**Die Einstellungen sind jetzt eine Übersicht.** Vorher stand alles
untereinander auf einem Bildschirm — Serverangaben, Qualität, Wiedergabe, drei
Verweise, Downloads, Version, Abmelden. Das war beim Bauen bequem und beim
Suchen anstrengend. Jetzt führt jede Zeile in einen Bildschirm, der zu einer
Frage gehört: Server, Erscheinungsbild, Startseite, Wiedergabe, Ton &
Untertitel, Downloads, Diagnose.

**Neu, und jedes davon greift irgendwo:**

- Zurück- und Vorspulen getrennt einstellbar. Die Knöpfe im Player und die
  Doppeltipp-Flächen tragen danach auch das passende Symbol.
- Startgeschwindigkeit — die Engine kann es längst, gefragt wurde nie.
- „Im Querformat sperren" abschaltbar. Für die allermeisten Filme richtig, für
  den, der im Bett auf der Seite liegt, das Gegenteil.
- „Gewählte Qualität merken": die Stufe gilt dann auch für den nächsten Titel.
  Aufbewahrt wird eine **Zahl**, keine Sprosse — welche Sprossen es gibt, hängt
  von der Quelle ab, und eine 720p-Datei kennt keine Zwanzig-Megabit-Stufe.
  Dann kommt die nächstgelegene, nicht „automatisch".
- „Bitrate im Qualitätsmenü zeigen".
- Gleichzeitige Downloads. Der Wert gab es schon in der Engine, nur ohne
  Bedienung und ohne dass er einen Neustart überlebte.
- Aufmacher: wie viele Titel, und ob sie aus Angefangenem oder nur aus
  Neuzugängen kommen.
- „Weiterschauen und Als Nächstes zusammenlegen" und „Gesehenes aus
  Neuzugängen ausblenden" — beides in der Ansicht, nicht im Server: das sind
  Fragen der Darstellung, und so gelten sie für Plex und Jellyfin gleich.

**Verkleinert herunterladen geht jetzt auch bei Jellyfin.** Da hatte ich zu
früh aufgegeben: ich hatte nur nach der Adresse zum *Abspielen* gesucht, und
die ist eine Abspielliste mit hunderten Schnipseln — als Datei unbrauchbar.
`/Videos/{id}/stream.mp4` gibt dieselbe Umrechnung als eine Datei heraus. Die
Größe bleibt eine Schätzung; eine Umrechnung, die erst beim Abruf beginnt,
kennt ihre eigene Länge nicht.

**Die Kontozeile ist jetzt eine Karte, die nach oben aufklappt**, kein
Systemmenü mehr. Ein Menü legt sich als eigene Ebene über alles und springt
dorthin, wo Platz ist; die Karte bleibt, wo sie ist, und lässt die Zeile mit
dem Namen stehen — man sieht also weiter, um wessen Konto es geht.

**Nicht gebaut, mit Grund:** Trailer im Karussell, Poster- und Sammlungsstil,
Untertitel-Aussehen, sekundäre Untertitel, lokale Intros, Modular Home,
App-Symbol. Für all das fehlt das, was die Einstellung steuern würde — es gibt
in Flixy weder Trailer noch Sammlungen, und der Player zeichnet Untertitel
nicht selbst.

263 Tests grün. **Nicht angesehen**: der Simulator-Tunnel ist weiterhin
abgestürzt und ließ sich nicht wieder aufbauen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 14:56:08 +02:00
GuidoandClaude Opus 5 222ac1c968 Vier Fehler aus dem ersten echten Gebrauch
Kein Video lief jemals an
  AVPlayerEngine.load() wartete auf asset.load(.duration) und die
  Spurenliste, BEVOR es zurückkehrte — und erst danach rief das Modell
  play(). AVFoundation muss für die Dauer aber so viel von der Datei
  holen, bis es den Index findet, und der sitzt bei MP4 wie MKV oft am
  Ende. Über eine langsame Leitung sind das Minuten, in denen nur ein
  Ladekreis zu sehen war, obwohl der Player längst hätte anfangen können.
  Jetzt kehrt load() zurück, sobald das Item hängt; Dauer und Spuren
  kommen nach und melden sich über den Ereignisstrom.
  Dazu AVURLAssetPreferPreciseDurationAndTimingKey: false — sonst
  durchsucht AVFoundation bei manchen Formaten die ganze Datei.

  Zweiter Fund an derselben Stelle: VLCMedia(url:) ist nullable. Ging es
  schief, blieb media still nil, play() tat nichts und es gab keinen
  Fehler — nur einen Ladekreis ohne Ende. Wird jetzt gemeldet.

Kein Querformat im Player
  requestGeometryUpdate allein dreht nicht: das System dreht sofort
  zurück, solange die erlaubten Ausrichtungen es nicht hergeben. Die
  Erlaubnis kommt nur über den App-Delegaten, deshalb OrientationLock
  als Brücke. Player dreht ins Querformat, beim Verlassen zurück. iPad
  bleibt frei — dort ist Querformat beim Blättern der Normalfall.

Uhrzeit über dem Film
  Die Statusleiste war nur ausgeblendet, solange die Bedienelemente weg
  waren. Jetzt immer.

Sehr langer Start
  Zwei Ursachen. Erstens legte der Initialisierer der App die
  Hintergrund-URLSession an — die spricht über XPC mit nsurlsessiond und
  verzögerte den allerersten Bildaufbau. Jetzt erst bei Bedarf, und wer
  keine Downloads hat, braucht sie nie. Zweitens fragte jeder Start erst
  plex.tv nach der Serverliste und suchte die Verbindung neu. Die zuletzt
  funktionierende wird jetzt gemerkt (Server-Token im Schlüsselbund) und
  mit kurzer Zeitgrenze zuerst probiert; die vollständige Suche greift
  nur noch, wenn sie nicht mehr antwortet — etwa wenn man von zuhause
  weggeht.

Dazu ein Hinweis im Player, wenn die Verbindung über die gedrosselte
Plex-Vermittlung läuft. Sonst sucht man den Fehler in der App.

132 Tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 20:43:26 +02:00