Eigenes Produkt

Mira

Wie bleibt ein Film derselbe, wenn Netzwerk, Adresse oder Qualität wechseln?

Mira iOS zeigt die Startseite eines Jellyfin-Clients mit hervorgehobener Produktion und Medienreihen.
iOS-Entwicklungsstand im Simulator. Die Aufnahme zeigt die damalige Produktgestaltung; das Film-Artwork ist Inhalt des verbundenen Testservers.

Mira ist ein nativer Jellyfin-Client für Apple- und Android-Plattformen. Die zentrale Arbeit liegt in Wiedergabe, Routing und Systemintegration, nicht in einer austauschbaren Oberfläche.

Bereich
Medienwiedergabe für Jellyfin
Zeitraum
2026
Status
In Entwicklung
Plattformen
iPhone, iPad, Android, Android TV, Fire TV, Android Auto
Leistungen
Native iOS-App, Native Android-App, Medienwiedergabe, Geräteintegration

Ausgangslage

Ein eigener Medienserver kann zuhause über eine lokale Adresse und unterwegs über eine entfernte Adresse erreichbar sein. Wechsel im Netzwerk dürfen eine laufende Wiedergabe nicht unnötig neu starten.

Verantwortung

Produktkonzeption, getrennte native Clients, gemeinsame Architekturverträge, Netzwerk- und Playback-Koordination, TV- und Auto-Oberflächen sowie Gerätereife.

Ergebnis

Ein Android-Client für Gerätetests und ein fortlaufender iOS-Entwicklungsstand mit nativer Wiedergabe, Bibliothek, Downloads, Casting und synchroner Jam-Warteschlange.

Mira iOS zeigt eine Detailseite zu Big Buck Bunny mit Wiedergabeaktion und Metadaten.
Zweite Simulatoraufnahme desselben iOS-Entwicklungsstands. Sie belegt keine Aussage über den aktuellen Android-Playbackpfad.

Zwei native Apps sind eine bewusste Kostenentscheidung

Mira verwendet keinen gemeinsamen Cross-Platform-Client. iPhone und iPad werden mit Swift, SwiftUI und AVFoundation entwickelt. Android nutzt Kotlin, Jetpack Compose und Media3. Die Entscheidung entstand nicht aus einer pauschalen Vorliebe für native Entwicklung. Die schwierigen Teile des Produkts liegen ohnehin nahe am Betriebssystem: Decoderfähigkeiten, Picture in Picture, AirPlay oder Cast, Hintergrunddownloads, Fernbedienung, Auto-Oberfläche und Reaktionen auf Netzwerkwechsel.

Der Preis ist real. Gemeinsame Produktregeln müssen zweimal umgesetzt und auf Parität geprüft werden. Modulgrenzen und Typnamen folgen deshalb einem gemeinsamen Architekturvertrag, obwohl der Code getrennt bleibt. Eine ältere Entscheidungsschrift schätzt den gemeinsam formulierbaren Anteil am Nicht-UI-Code auf ungefähr ein Viertel. Das ist eine damalige Einschätzung, keine nachgemessene Kennzahl.

Für ein Kundenprojekt wäre „nativ“ deshalb kein Qualitätslabel an sich. Die relevante Frage lautet, wie viel des Produkts tatsächlich von Medienframeworks, Gerätekategorien und Systemdiensten abhängt. Mira beantwortet sie zugunsten tiefer Kontrolle und akzeptiert den zusätzlichen Pflegeaufwand ausdrücklich.

Eine Serversitzung hat eine Route und eine Epoche

Ein Jellyfin-Server kann dieselbe Bibliothek unter mehreren Adressen anbieten. Im Heimnetz ist eine lokale Route schneller und unabhängig vom externen Zugang. Unterwegs braucht die App eine Remote-Adresse. Das Umschalten darf nicht dazu führen, dass jeder Request eigenständig rät, welcher Endpunkt gerade funktioniert.

Mira verwaltet deshalb pro Serversitzung einen Endpoint-Resolver. Er veröffentlicht die aktive Route, eine Epoche, Prüfstatus und Diagnose gemeinsam als atomaren Zustand. HTTP liest diesen Zustand beim Absenden eines Requests. Der Playback-Coordinator beobachtet Änderungen. Interner Resolverzustand wird auf einem einzelnen Coroutine-Dispatcher verändert; Tests können virtuelle statt echter Zeit verwenden und problematische Reihenfolgen reproduzieren.

Die Epoche macht sichtbar, ob zwei Entscheidungen zur gleichen Netzwerkwelt gehören. Eine neue Route ist nicht nur ein anderer String. Sie kann laufende Requests, Cacheeinträge und Medien-URLs betreffen. Diese Modellierung verhindert, dass UI, Bibliothekszugriff und Player je einen eigenen, leicht abweichenden Fallbackmechanismus entwickeln.

Die Wiedergabe wechselt den Weg, nicht den Film

Ältere Projektdokumentation beschreibt noch einen vollständigen Playerwechsel bei einer neuen Route. Der aktuelle Android-Code geht weiter. Eine eigene Media3-Datenquelle merkt sich den Byte-Offset des laufenden Streams. Ändert sich die erreichbare Basisadresse, rebasiert sie die URL und öffnet den Datenstrom an derselben Position erneut. Decoder und Mediensitzung bleiben bestehen, soweit der Server denselben Inhalt unter der neuen Adresse liefert.

Das ist für lange Videos entscheidend. Ein Netzwerkwechsel wird nicht mit einem Nutzerwunsch nach einer anderen Qualität verwechselt. Eine Qualitätsänderung kann einen neuen Transcode oder eine andere Repräsentation bedeuten und braucht eine kontrollierte Playertransition. Eine neue Serverroute ist dagegen zunächst nur ein Transportproblem.

Die Trennung hat Grenzen. Der Server muss Bytebereiche konsistent unterstützen, Authentifizierung und Medienkennung müssen weiterhin gelten, und ein Wechsel kann trotzdem scheitern. Die Fallstudie behauptet daher keinen unsichtbaren Wechsel unter allen Bedingungen. Sie zeigt einen konkreten Mechanismus, der den häufigen Fall ohne kompletten Neuaufbau der Wiedergabe behandeln kann.

Gemeinsames Hören beginnt mit einer gemeinsamen Uhr

Miras Jam-Modus teilt eine Warteschlange zwischen mehreren Geräten. Ein Zeitstempel vom Server allein genügt nicht, weil Geräteuhren abweichen und Nachrichten unterschiedliche Laufzeiten haben. Der Client misst deshalb die Uhrabweichung in einer NTP-ähnlichen Folge und plant einen gemeinsamen Start relativ zu dieser Abweichung.

Jedes Gerät wartet seinen eigenen gemessenen Unterschied aus. WebSocket-Nachrichten halten Warteschlange und Zustände verbunden. Die Architektur versucht nicht, Latenz wegzureden; sie macht sie zu einer messbaren Eingabe. Eine seriöse Qualitätsaussage braucht dennoch reale Mehrgerätetests unter verschiedenen Netzen. „Sekundengenau“ beschreibt das Ziel des Modells, keine hier neu gemessene Garantie.

Ein Medienclient ist mehr als ein Telefonlayout

Android TV und Fire TV benötigen Fokusnavigation, größere Distanzen und einen anderen Browsefluss. Mira wird auch auf einem Fire TV Stick von 2018 mit Android 7.1 entwickelt. Android Auto erhält einen eigenen Browsebaum statt einer verkleinerten Telefonoberfläche. Downloads, Casting, Live-TV und Musik hängen jeweils an anderen Systemdiensten.

Diese Breite erklärt die Architekturentscheidung besser als eine Liste unterstützter Geräte. Eine gemeinsam aussehende Oberfläche hätte wenig Wert, wenn Medienknöpfe, Fernbedienung, Hintergrundwiedergabe oder Audiofokus gegen das jeweilige Betriebssystem arbeiten.

Was diese Arbeit für ähnliche Aufträge zeigt

Mira ist ein Beispiel für native Produktentwicklung an einer harten Plattformgrenze. CIDIX kann getrennte Clients so strukturieren, dass sie dasselbe Produktmodell verfolgen, ohne Systemintegration in eine zu enge gemeinsame Schicht zu drücken.

Für Streaming, Kommunikation, Sensorik oder andere dauerhafte Sitzungen ist die übertragbare Frage dieselbe: Was muss bei einem Infrastrukturwechsel erhalten bleiben? Mira beantwortet sie mit expliziter Route, Epoche und Mediensitzung. Ein neuer Auftrag würde diese Invarianten zuerst festlegen und erst danach entscheiden, ob nativ, Cross-Platform oder eine Mischform die richtige Umsetzung ist.

Technik und wofür sie da ist

Swift 6
iOS-Client
SwiftUI
Oberfläche auf Apple-Geräten
AVFoundation
Wiedergabe auf Apple-Geräten
Kotlin 2.3
Android-Client
Jetpack Compose
Oberfläche auf Android, TV und Auto
Media3
Wiedergabe und Datenquelle auf Android
WebSocket
Synchrones Hören
Jellyfin API
Medienserver-Schnittstelle