In der schnelllebigen Welt des Streamings steht die Benutzererfahrung an erster Stelle. Während viele Apps sich stark auf die Navigation und das Entdecken von Inhalten konzentrieren, bekommt der Videoplayer oft nicht die Aufmerksamkeit, die er verdient – obwohl es der Ort ist, an dem die Nutzer die meiste Zeit verbringen. Kürzlich haben wir an einem ehrgeizigen Projekt für einen Sender gearbeitet: Die Vereinheitlichung von 4 verschiedenen auf XIB basierenden Videoplayern für iPhone und iPad, die verschiedene Streaming-Formate unterstützen — SVOD, PVOD, AVOD, lineares Fernsehen, Live-Sport, Filme und Serien — zu einer einzigen, codebasierten Lösung mit Swift und UIKit.
Dieser Übergang machte den Player nicht nur flexibler und leichter zu warten, sondern verbesserte auch die Leistung auf allen Geräten erheblich, sodass die App des Senders mit allen Inhaltstypen, Ausrichtungen oder Geräten umgehen konnte. Hier ist, wie wir dieses Projekt angegangen sind.
Die Herausforderung: Mehrere Inhaltstypen verwalten
Die Streaming-App des Senders musste eine Vielzahl von Inhaltsanforderungen unterstützen. Beispielsweise verwendet AVOD HLS-Interstitials und erfordert, dass während der Werbewiedergabe Call-to-Action-Schaltflächen (CTA) angezeigt werden. Sportinhalte beinhalten oft Live-Statistiken oder eine Senderliste (für dasselbe Ereignis) in einem Seitenbereich. Je nach Abonnementplänen oder PVOD verhalten sich die Assets beim Start des Players unterschiedlich. Die Aufrechterhaltung separater, auf XIB basierender Player für jeden Inhaltstyp führte zu redundantem Code und langsameren Ladezeiten.
Das Ziel war es, einen einheitlichen Player zu erstellen, der sich dynamisch an all diese Umgebungen anpassen kann, verschiedene Steuerungssätze verwaltet und alle iOS- und iPadOS-Geräte unterstützt, während er gleichzeitig reaktionsschnell und benutzerfreundlich bleibt.
Die Stärke von AVPlayer: Native Leistung und erweiterte Funktionen
Im Herzen des Videoplayers befindet sich AVPlayer, Apples nativer Videowiedergabe-Engine. AVPlayer ist der leistungsfähigste Player für iOS und iPadOS, da er tief in das System integriert ist. Es bietet auch Zugriff auf das neueste Set an Streaming-Funktionen, die speziell für Apple-Geräte entwickelt wurden. Durch den Aufbau des Players auf AVPlayer konnten wir die volle Leistung der Medien-Frameworks von Apple nutzen und eine reibungslose Wiedergabe, Streaming mit geringer Latenz und eine nahtlose Integration mit den erweiterten Funktionen von Apple wie AirPlay, Picture-in-Picture, HLS-Interstitials und HDR sicherstellen. Die nativen Fähigkeiten von AVPlayer machten es zur idealen Grundlage für einen leistungsstarken Player und gaben uns eine starke Plattform, um eine flexible und anpassungsfähige Benutzeroberfläche zu entwickeln.
Das UX/UI-Design des Senders
Unter dem Player verwendeten wir AVPlayer als Grundlage für die Videowiedergabe, was eine gängige Wahl in Streaming-Apps ist. Das gesamte UX/UI-Design wurde jedoch auf der Grundlage der Figmas des Senders erstellt, wodurch der Player einzigartig und als Teil der App des Senders erkennbar wurde. Dieses unverwechselbare Design, das die Markenrichtlinien und Benutzererfahrung des Senders integrierte, stellte sicher, dass der Player nahtlos in den Rest der App passte und den charakteristischen Look des Senders beibehielt. Von der Art und Weise, wie die Steuerelemente angezeigt wurden, bis hin zum gesamten Benutzerinteraktionsfluss musste der Player die Vision des Senders verkörpern und gleichzeitig eine erstklassige Leistung erbringen.
Interoperabilität mit DRM und kurzen HLS-Segmenten
Einer der herausfordernderen Aspekte dieses Projekts war die nahtlose Interoperabilität zwischen AVPlayer und dem benutzerdefinierten Streaming-Setup des Senders, das die Verwendung von kurzen HLS-Segmenten (40 Bilder) für das Streaming mit geringer Latenz umfasste. Während AVPlayer das HLS-Streaming nativ unterstützt, erzeugen diese kurzen Segmente zusätzlichen Druck auf den Player, der auf fortschrittliche Inhalte angewiesen ist, um korrekt zu reagieren und Funktionen wie Picture-in-Picture (PiP), Pufferung und eine nahtlose Wiedergabe zu verwalten. Der kurze Puffer bedeutete, dass der Player sich kontinuierlich anpassen musste, um sicherzustellen, dass der Stream ohne Unterbrechungen flüssig bleibt.
Es ist erwähnenswert, dass die Segmentdauer, insbesondere für VOD-Inhalte, in Zukunft wahrscheinlich überarbeitet wird, um besser mit den Branchenstandards übereinzustimmen und die Benutzererfahrung insgesamt zu verbessern. Der einheitliche Player bewältigt diese Komplexitäten jedoch vorerst effizient und erfüllt die hohen Leistungsstandards, die für das vielfältige Angebot des Senders erwartet werden.
Explizites Haupt-Thread-Management mit UIKit
Bei der Arbeit mit UIKit ist einer der wichtigen Aspekte das Management der Art und Weise sowie des Zeitpunkts, wann die Benutzeroberfläche aktualisiert wird. Da UIKit alle seine Änderungen an der Benutzeroberfläche auf dem Haupt-Thread – dem Teil des Systems, der direkt mit dem interagiert, was der Benutzer sieht – verwaltet, müssen Entwickler explizit sicherstellen, dass Änderungen oder Updates zum richtigen Zeitpunkt durchgeführt werden. Wenn dies nicht sorgfältig gemacht wird, kann die App verlangsamt oder zum Absturz gebracht werden, oder bestimmte Funktionen wie Picture-in-Picture funktionieren nicht mehr richtig. Dies ist besonders wichtig, wenn in der App navigiert wird und gleichzeitig versucht wird, den Videoplayer reibungslos im Hintergrund laufen zu lassen (PiP).
Umgang mit Picture-in-Picture (PiP)
Eine der schwierigsten Funktionen ist in der Tat PiP, insbesondere das In-App-PiP, das die Videowiedergabe und die App-Navigation kombiniert. Da UIKit ein sorgfältiges Haupt-Thread-Management erfordert, war umfangreiches Testen notwendig, um sicherzustellen, dass PiP nahtlos funktioniert. Jedes Navigationsszenario in der App musste berücksichtigt werden, um sicherzustellen, dass PiP auch dann weiterhin reibungslos funktionierte, wenn Benutzer zwischen verschiedenen Bereichen der App wechselten. Ob systemweites PiP oder das benutzerdefinierte In-App-PiP des Senders verwendet wurde, die Leistung und das Benutzererlebnis hatten oberste Priorität.
Weitere Interaktionen während der Wiedergabe
Über die eigentliche Videowiedergabe hinaus musste der Player auch kontinuierliche Datenübertragungen mit externen Diensten verwalten. Beispielsweise ist die Statistikerfassung über Nice People At Work (NPAW) integriert, um die Qualität der Benutzererfahrung zu überwachen und zu optimieren. Dieses System sammelt in Echtzeit Daten, um eine reibungslose Wiedergabe sicherzustellen und Leistungsengpässe zu identifizieren. Darüber hinaus kommunizierte der Player regelmäßig mit der API des Senders, um die Position des Players im Video zu senden. Dies ermöglichte es den Benutzern, die Wiedergabe an derselben Stelle auf jedem Gerät fortzusetzen und so ein nahtloses Multi-Device-Seherlebnis zu gewährleisten. Diese Hintergrundinteraktionen mussten effizient verwaltet werden, ohne die Gesamtleistung der Wiedergabe zu beeinträchtigen.
Flexible Steuerelemente für verschiedene Inhaltstypen
Eine der wichtigsten Funktionen des Players sind seine flexiblen Steuerelemente, die sich dynamisch an den Inhaltstyp und die Benutzerumgebung anpassen. Zum Beispiel:
- Sprachsteuerungen (Audio und Untertitel) sind bei den meisten Inhalten unerlässlich.
- Eine „Nächste Episode“-Schaltfläche erscheint nur bei TV-Serien.
- Die Kanalauswahl ist nur für Live-Sport verfügbar.
- Echtzeitstatistiken werden nur bei Sportarten mit Statistiken angezeigt.
Diese Steuerelemente müssen sich auch basierend auf der Bildschirmorientierung und der Gerätegröße anpassen, um sicherzustellen, dass der Player intuitiv und übersichtlich bleibt. Wenn sich die Größe oder Ausrichtung des Players ändert, passen sich die Steuerelemente automatisch an, um das Benutzererlebnis zu optimieren.
Verbesserte Leistung: Der Fall für Code-basierte Player
Ein weiterer wichtiger Vorteil des Wechsels zu einem Code-basierten Player war die verbesserte Leistung. XIBs erfordern, dass alle Elemente im Voraus vorbereitet werden, was bedeutet, dass das System das gesamte XIB laden muss, bevor der Player angezeigt wird. Wenn vier separate XIBs verwendet werden, musste dieser Ladeprozess viermal wiederholt werden, was zu langsameren Leistungen und Speicherverwaltungsproblemen führte.
Im Gegensatz dazu ermöglicht ein Code-basierter Ansatz eine kontrolliertere Speicherverwaltung, bei der Ressourcen nur geladen werden, wenn sie benötigt werden, und freigegeben werden, wenn sie nicht mehr verwendet werden. Dieser Ansatz hat die Ladezeiten drastisch verkürzt und die Leistung verbessert, insbesondere auf älteren Geräten mit begrenzten CPU- und Speicherressourcen. Der neue Player ist schneller, effizienter und vermeidet die häufigen Probleme einer übermäßigen Verwendung von XIBs.
Tests während eines großen iOS-Updates
Das Projekt fiel mit der Veröffentlichung von iOS 18 zusammen, der ersten auf Swift 6 basierenden Version von iOS, was die Tests komplizierter machte. Es war nicht immer klar, ob die Probleme durch den Code, das System oder die Umgebung verursacht wurden. Besonderes Augenmerk wurde auf Tests auf älteren Geräten gelegt, bei denen die Leistungsverbesserungen aufgrund der begrenzten Ressourcen am deutlichsten waren.
Metriken und Benutzerfeedback (in Kürze)
Derzeit liegen noch keine konkreten Nutzermetriken vor – wie Absturzraten, Speichernutzung oder Feedback aus Bewertungen und NPS-Umfragen – aber erste Tests zeigen erhebliche Verbesserungen in Bezug auf Geschwindigkeit und Flexibilität. Diese Fallstudie wird aktualisiert, sobald mehr Benutzerdaten vorliegen.
Flexibilität und Leistung sind entscheidend
In modernen Streaming-Apps sind Flexibilität und Leistung entscheidend, um eine erstklassige Benutzererfahrung zu bieten. Durch die Vereinheitlichung der Videoplayer des Senders in einer einzigen, Code-basierten Lösung haben wir die Entwicklung vereinfacht, die Leistung verbessert und sichergestellt, dass sich der Player nahtlos an verschiedene Inhaltstypen und Umgebungen anpassen kann.
Dieses Projekt hebt die Bedeutung hervor, sich auf den Videoplayer selbst zu konzentrieren, und nicht nur auf die Navigation darum herum, da es letztlich der Ort ist, an dem die Benutzer die meiste Zeit verbringen.