ExoPlayer ist eine Open-Source-Mediaplayer-Bibliothek für Android, die von Google als Alternative zum integrierten MediaPlayer entwickelt wurde. ExoPlayer bietet Audio- und Videowiedergabe in verschiedenen Formaten, darunter DASH, HLS, SmoothStreaming und normale Mediendateien, über eine einzige API mit Unterstützung für adaptives Streaming. Laut Google I/O (2024) wird ExoPlayer in über 60.000 Android-Apps verwendet, darunter YouTube, Google TV und Netflix.
Wichtige Punkte
ExoPlayer ist eine Open-Source (Apache 2.0) Multimedia-Wiedergabebibliothek für Android, deren erste Version 2014 von Google veröffentlicht wurde. Im Gegensatz zum integrierten MediaPlayer, der eine dünne Hülle um den systemeigenen MediaCodec darstellt, ist ExoPlayer vollständig auf Java/Kotlin-Ebene implementiert, was Entwicklern die volle Kontrolle über jede Phase der Wiedergabe gibt.
Architektonisch basiert ExoPlayer auf einem modularen Prinzip: jeder Aspekt der Wiedergabe wird durch eine separate Komponente implementiert. Das Kernmodul (exoplayer-core) enthält den Player, Renderer, Track-Selektoren und die Pufferverwaltung. Zusätzliche Module (exoplayer-dash, exoplayer-hls, exoplayer-rtsp, exoplayer-smoothstreaming) fügen Unterstützung für die entsprechenden Streaming-Protokolle hinzu. Diese Architektur ermöglicht es Anwendungen, nur die notwendigen Komponenten einzubinden und so die APK-Größe zu minimieren.
ExoPlayer 2 (die aktuelle Hauptversion) wurde 2018 veröffentlicht und brachte eine grundlegende Überarbeitung der API: Einführung des Player-Interface, Compose-Unterstützung über AndroidX Media3, verbesserte Fehlerbehandlung und adaptive Track-Auswahlalgorithmen. Ab Version 2.19 (2024) wurde ExoPlayer Teil der AndroidX Media-Bibliothek, was die Integration und Aktualisierung über den standardmäßigen Android-Abhängigkeitsmanager vereinfachte.
Im Kern von ExoPlayer liegt die Komponente ExoPlayerImpl, die den Wiedergabelebenszyklus verwaltet. Sie enthält MediaSource (Medienquelle), TrackSelector (Track-Auswahl), LoadControl (Pufferverwaltung) und eine Liste von Renderern (Renderer für Video, Audio, Untertitel und Metadaten). Jede Komponente kann über Builder oder Factory-Methoden durch eine eigene Implementierung ersetzt werden.
Für die Videowiedergabe verwendet ExoPlayer SurfaceView, TextureView oder SphericalSurfaceView (für 360-Grad-Video). Die empfohlene Option ist SurfaceView, da es Hardwarebeschleunigung und minimalen Stromverbrauch bietet. Für Jetpack Compose stellt die AndroidX Media3-Bibliothek die Komponente `AndroidView` (die SurfaceView kapselt) und das experimentelle `Media3Compose` mit nativer Compose-Integration bereit.
ExoPlayer bietet eine breite Palette von Funktionen über einen normalen Mediaplayer hinaus. Zu den wichtigsten Funktionen gehören die Unterstützung aller gängigen Streaming-Protokolle, ein flexibles DRM-System, adaptive Bitratenumschaltung (ABR) und Wiedergabeanalysetools.
| Funktion | Beschreibung | Modul |
|---|---|---|
| DASH | Adaptives Streaming nach MPEG-Standard | exoplayer-dash |
| HLS | HTTP Live Streaming von Apple | exoplayer-hls |
| SmoothStreaming | Adaptives Streaming von Microsoft | exoplayer-smoothstreaming |
| RTSP | Echtzeit-Streaming-Protokoll für Live | exoplayer-rtsp |
| Widevine | DRM-Inhaltsschutz | exoplayer-drm |
| Concatenation | Zusammenführen mehrerer Mediendateien | exoplayer-core |
| Ads | IMA SDK-Integration für Werbung | exoplayer-ima |
ABR (Adaptive Bitrate) wird in ExoPlayer über das AdaptiveTrackSelection-Interface implementiert. Standardmäßig wird AdaptiveTrackSelectionFactory verwendet, die DefaultAdaptiveTrackSelection erstellt — einen ausgewogenen Algorithmus, der Netzwerkbandbreite und Puffergröße berücksichtigt. Für spezifische Szenarien können alternative Implementierungen angeschlossen werden: BOLA (Minimierung von Umschaltungen), RandomAdaptiveTrackSelection (Tests) oder eine eigene Implementierung über das TrackSelection-Interface.
BandwidthMeter — eine weitere Schlüsselkomponente, die für die Messung der Netzwerkbandbreite zuständig ist. Standardmäßig wird DefaultBandwidthMeter verwendet, das Statistiken über alle HTTP-Anfragen des Players sammelt. Der Entwickler kann es erweitern, um zusätzliche Faktoren zu berücksichtigen: Netzwerktyp (Wi-Fi, 4G, 5G), Signalsärke oder Datenkosten für den Benutzer.
ExoPlayer unterstützt Widevine (L1, L3), PlayReady und ClearKey DRM. Die Lizenzbeschaffung wird über DrmSessionManager konfiguriert, der mit dem Lizenzserver interagiert. Für Premium-Video (4K HDR) ist Hardwareunterstützung für Widevine L1 erforderlich, die Schutz auf Chipebene bietet und Bildschirmaufnahmen verhindert. Die Wahl des DRM-Systems hängt von der Zielplattform ab: Widevine wird auf Android und Chromecast verwendet, PlayReady auf Xbox und Windows, FairPlay auf iOS und Apple TV. ExoPlayer ermittelt automatisch das verfügbare DRM-System basierend auf der MPD-Datei und erfordert keine manuelle Konfiguration für grundlegende Szenarien.
Die Verbindung von ExoPlayer mit einem Android-Projekt erfolgt über Gradle-Abhängigkeiten. Ab Version 2.19 ist ExoPlayer Teil von AndroidX Media (androidx.media3), was die Kompatibilität mit Jetpack Compose und anderen AndroidX-Komponenten gewährleistet. Sehen wir uns eine schrittweise Integration in Kotlin an.
Fügen Sie die ExoPlayer-Module zur build.gradle-Datei (Module) hinzu. Das Mindestmaß umfasst core, ui und das Modul für das benötigte Streaming-Protokoll. Für die Wiedergabe von DASH-Inhalten wird exoplayer-dash benötigt, für HLS — exoplayer-hls.
dependencies {
implementation "androidx.media3:media3-exoplayer:1.5.0"
implementation "androidx.media3:media3-ui:1.5.0"
implementation "androidx.media3:media3-exoplayer-dash:1.5.0"
implementation "androidx.media3:media3-exoplayer-hls:1.5.0"
}
Erstellen und Konfigurieren des Players in einer Activity oder einem Fragment. ExoPlayer verwendet PlayerView (oder StyledPlayerView zur Anpassung) zur Anzeige von Video und integrierten Steuerelementen. Die Mindestkonfiguration umfasst das Erstellen des Players über ExoPlayer.Builder und das Übergeben einer MediaItem mit der Quell-URI.
class PlayerActivity : AppCompatActivity() {
private var player: ExoPlayer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_player)
player = ExoPlayer.Builder(this).build()
val playerView = findViewById<StyledPlayerView>(R.id.playerView)
playerView.player = player
val mediaItem = MediaItem
.Builder()
.setUri("https://example.com/video.mp4")
.build()
player?.setMediaItem(mediaItem)
player?.prepare()
}
override fun onDestroy() {
player?.release()
super.onDestroy()
}
}
Für Produktionsanwendungen ist die Behandlung möglicher Wiedergabefehler erforderlich: Netzwerkausfälle, nicht unterstützte Formate, DRM-Lizenzierungsfehler. ExoPlayer bietet das Player.Listener-Interface mit den Methoden onPlayerError, onPlaybackStateChanged und onPlayWhenReadyChanged. Es wird empfohlen, dem Benutzer informative Fehlermeldungen mit Wiederholungsoption anzuzeigen.
Die Wahl zwischen ExoPlayer und dem integrierten MediaPlayer ist eine häufige Frage bei der Entwicklung von Android-Apps. MediaPlayer ist seit Version 1.0 Teil des Android SDK, während ExoPlayer eine Bibliothek ist, die eine Gradle-Abhängigkeit erfordert. Sehen wir uns die Unterschiede anhand wichtiger Kriterien an.
| Kriterium | ExoPlayer | MediaPlayer |
|---|---|---|
| Architektur | Modular, vollständig in Java/Kotlin | Hülle über systemeigene C++-Komponenten |
| Streaming | DASH, HLS, SmoothStreaming, RTSP | Nur lokale Dateien und HLS (Android 9+) |
| Anpassung | Vollständig (jede Komponente austauschbar) | Minimal (nur Parameter) |
| Updates | Über Google Play oder APK (OS-unabhängig) | Nur über Android-Update (OTA) |
| APK-Größe | +1–3 MB (je nach Modulen) | 0 (Teil des Betriebssystems) |
| Min SDK | API 16+ (Android 4.1) | API 1+ |
| DRM | Widevine, PlayReady, ClearKey | Widevine (eingeschränkt) |
ExoPlayer gewinnt in Szenarien, die Streaming (DASH, HLS), UI-Anpassung, DRM-Unterstützung und Unabhängigkeit von der Android-Version erfordern. MediaPlayer eignet sich für einfache Anwendungen, die lokale Mediendateien abspielen, bei denen die APK-Größe kritisch ist und keine Anforderungen an adaptives Streaming bestehen. Für moderne Anwendungen mit Inhalten aus dem Netzwerk ist ExoPlayer die eindeutige Wahl.
Ausnahme — Anwendungen mit einem Mindest-SDK unter API 16 (Android 4.1), die es auf dem Markt praktisch nicht mehr gibt. Für alle Anwendungen mit targetSdk 33+ und Mindest-SDK 21+ ist ExoPlayer nicht nur vorzuziehen, sondern notwendig, um moderne Formate wie AV1 und Dolby Vision über entsprechende Erweiterungen zu unterstützen.
Für Produktionsanwendungen erfordert die grundlegende ExoPlayer-Integration häufig eine zusätzliche Konfiguration: Cache-Verwaltung, Pufferoptimierung für Mobilfunknetze, Analyseintegration und Anpassung der Audiospurauswahl. Sehen wir uns erweiterte Nutzungsszenarien an.
CacheDataSourceFactory ermöglicht das Zwischenspeichern heruntergeladener Segmente im lokalen Speicher, was Traffic bei wiederholter Ansicht spart und Offline-Wiedergabe ermöglicht. ExoPlayer verwendet SimpleCache aus der Bibliothek exoplayer-cas — dateibasiertes Caching mit LRU-Evakuierungsunterstützung und Größenbeschränkungen.
val cache = SimpleCache(
cacheDir,
LeastRecentlyUsedCacheEvictor(50 * 1024 * 1024),
AppDatabaseProvider(this)
)
val cacheDataSourceFactory = CacheDataSource
.Factory()
.setCache(cache)
val player = ExoPlayer.Builder(this)
.setMediaSourceFactory(
DefaultMediaSourceFactory(cacheDataSourceFactory)
)
.build()
In mobilen Anwendungen ist die Behandlung der Umschaltung zwischen WLAN und Mobilfunknetz kritisch. ExoPlayer stellt ConnectivityManager zur Verfügung, um den Netzwerkstatus zu verfolgen. Bei Verbindungsverlust wird empfohlen, den Player nicht zu stoppen, sondern in den Zustand PAUSED zu versetzen, wobei die Position erhalten bleibt. Nach Wiederherstellung der Verbindung wird die Wiedergabe mit erneuter Segmentladung fortgesetzt.
Mit der Veröffentlichung von AndroidX Media3 erhielt die Bibliothek experimentelle Unterstützung für Jetpack Compose. Die Komponente `AndroidView` kapselt SurfaceView oder PlayerView und gewährleistet die Kompatibilität mit der Compose-Hierarchie. Für eine tiefere Integration wird die Bibliothek `androidx.media3:media3-ui-compose` verwendet, die Compose-kompatible Player-Steuerelemente bereitstellt.
@Composable
fun VideoPlayer(uri: String) {
val context = LocalContext.current
val player = remember {
ExoPlayer.Builder(context).build()
.also { it.setMediaItem(MediaItem.fromUri(uri)) }
}
DisposableEffect(key = null) {
player.prepare()
onDispose { player.release() }
}
AndroidView(
factory = { StyledPlayerView(context).also { it.player = player } }
)
}
Häufig gestellte Fragen
ExoPlayer unterstützt Android API 16+ (Android 4.1 Jelly Bean). Für DASH und HLS mit fMP4-Segmenten wird jedoch API 21+ (Android 5.0 Lollipop) empfohlen. DRM-Module (Widevine) erfordern API 19+, und Hardware-HEVC-Dekodierung ist ab API 21 verfügbar.
Ja, ExoPlayer eignet sich hervorragend für Audio. Für reine Audiowiedergabe ist weder SurfaceView noch PlayerView erforderlich. ExoPlayer wählt automatisch den Audio-Renderer aus und arbeitet im Hintergrund. Für die Hintergrundwiedergabe wird die Verwendung von MediaSessionService zur Integration mit den Systemsteuerelementen empfohlen.
Der TrackSelector in ExoPlayer verwaltet die Auswahl von Audiospuren. Zum Wechseln verwenden Sie player.getCurrentTracks().groups und player.setTrackSelectionParameters() mit Angabe der bevorzugten Audiosprache. Bei DASH- und HLS-Streams mit mehreren Audiospuren erfolgt der Wechsel ohne Unterbrechung der Wiedergabe.
Ja, ExoPlayer unterstützt eingebettete (in MP4-, WebM-Containern) und externe Untertitel in den Formaten TTML, SRT, VTT und CEA-608. Für externe Untertitel wird SingleSampleMediaSource oder MergingMediaSource verwendet, um sie mit dem Videostream zusammenzuführen. Die Anzeige gestylter Untertitel wird über CaptionStyleCompat konfiguriert.
Für Low-Latency-Streaming konfigurieren Sie LoadControl mit kleineren Zielpufferwerten: Verwenden Sie DefaultLoadControl.Builder().setTargetBufferBytes(1024 * 512).setBufferDurationsMs(500, 2000, 500, 1000) für HLS LL und DASH LL. Setzen Sie außerdem minPlaybackSpeed = 1.02 für eine beschleunigte Pufferfüllung, wenn Sie hinter der Live-Übertragung zurückliegen.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch