APK wird kleiner

Die Minimierung der APK-Größe ist ein wichtiger Aspekt bei der Entwicklung einer guten Android-App. Dies gilt insbesondere für aufstrebende Märkte und auch für die Entwicklung einer Android Instant App. In solchen Fällen kann es sinnvoll sein, die Größe der im APK enthaltenen ExoPlayer-Bibliothek zu minimieren. Auf dieser Seite werden einige einfache Schritte beschrieben, die Ihnen dabei helfen können.

Nur erforderliche Abhängigkeiten verwenden

Nur von den Bibliotheksmodulen abhängig, die Sie tatsächlich benötigen. Im folgenden Beispiel werden Abhängigkeiten zu den ExoPlayer-, DASH- und UI-Bibliotheksmodulen hinzugefügt. Dies kann für eine App erforderlich sein, die nur DASH-Inhalte wiedergibt:

Kotlin

implementation("androidx.media3:media3-exoplayer:1.3.1")
implementation("androidx.media3:media3-exoplayer-dash:1.3.1")
implementation("androidx.media3:media3-ui:1.3.1")

Groovig

implementation "androidx.media3:media3-exoplayer:1.3.1"
implementation "androidx.media3:media3-exoplayer-dash:1.3.1"
implementation "androidx.media3:media3-ui:1.3.1"

Verkleinern von Code und Ressourcen aktivieren

Sie sollten die Code- und Ressourcenreduzierung für die Release-Builds Ihrer Anwendung aktivieren. ExoPlayer ist so strukturiert, dass durch Codereduzierung ungenutzte Funktionen effektiv entfernt werden. Bei einer App, die DASH-Inhalte abspielt, kann der Beitrag von ExoPlayer zur APK-Größe beispielsweise um ca. 40% reduziert werden, indem die Codeverkleinerung aktiviert wird.

Unter Anwendung verkleinern, verschleiern und optimieren erfahren Sie, wie Sie die Code- und Ressourcenreduzierung aktivieren.

Festlegen, welche Renderer die App benötigt

Die Renderer des Players werden standardmäßig mit DefaultRenderersFactory erstellt. DefaultRenderersFactory hängt von allen Renderer-Implementierungen in der ExoPlayer-Bibliothek ab. Daher wird keine davon durch Codereduzierung entfernt. Wenn Sie wissen, dass Ihre Anwendung nur einen Teil der Renderer benötigt, können Sie stattdessen Ihre eigene RenderersFactory angeben. Eine App, die nur Audio wiedergibt, kann beispielsweise bei der Instanziierung von ExoPlayer-Instanzen eine Factory so definieren:

Kotlin

val audioOnlyRenderersFactory =
  RenderersFactory {
    handler: Handler,
    videoListener: VideoRendererEventListener,
    audioListener: AudioRendererEventListener,
    textOutput: TextOutput,
    metadataOutput: MetadataOutput,
    ->
    arrayOf<Renderer>(
      MediaCodecAudioRenderer(context, MediaCodecSelector.DEFAULT, handler, audioListener)
    )
}
val player = ExoPlayer.Builder(context, audioOnlyRenderersFactory).build()

Java

RenderersFactory audioOnlyRenderersFactory =
    (handler, videoListener, audioListener, textOutput, metadataOutput) ->
        new Renderer[] {
            new MediaCodecAudioRenderer(
                context, MediaCodecSelector.DEFAULT, handler, audioListener)
        };
ExoPlayer player = new ExoPlayer.Builder(context, audioOnlyRenderersFactory).build();

Dadurch können andere Renderer-Implementierungen durch Codereduzierung entfernt werden. In diesem Beispiel werden Video-, Text- und Metadaten-Renderer entfernt. Das bedeutet, dass Untertitel oder In-Stream-Metadaten (z. B. ICY) nicht vom Player verarbeitet oder ausgegeben werden.

Geben Sie an, welche Extraktoren die Anwendung benötigt

Standardmäßig erstellt der Player Extractor-Instanzen für die Wiedergabe von progressiven Medien mit DefaultExtractorsFactory. DefaultExtractorsFactory hängt von allen Extractor-Implementierungen in der ExoPlayer-Bibliothek ab. Daher wird keine davon durch Codereduzierung entfernt. Wenn Sie wissen, dass Ihre Anwendung nur eine kleine Anzahl von Containerformaten wiedergeben muss oder überhaupt keine Progressive-Medien wiedergibt, können Sie stattdessen Ihre eigene ExtractorsFactory angeben. Eine App, die nur MP4-Dateien abspielen muss, kann beispielsweise folgende Factory bereitstellen:

Kotlin

val mp4ExtractorFactory = ExtractorsFactory {
  arrayOf<Extractor>(Mp4Extractor(DefaultSubtitleParserFactory()))
}
val player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, mp4ExtractorFactory)).build()

Java

ExtractorsFactory mp4ExtractorFactory =
    () -> new Extractor[] {new Mp4Extractor(new DefaultSubtitleParserFactory())};
ExoPlayer player =
    new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, mp4ExtractorFactory))
        .build();

Dadurch können andere Extractor-Implementierungen durch Codereduzierung entfernt werden, was zu einer erheblichen Größenreduzierung führen kann.

Wenn in Ihrer App überhaupt keine progressiven Inhalte wiedergegeben werden, sollten Sie ExtractorsFactory.EMPTY an den DefaultMediaSourceFactory-Konstruktor und dann an den mediaSourceFactory-Konstruktor an den ExoPlayer.Builder-Konstruktor übergeben.

Kotlin

val player =
  ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY)).build()

Java

ExoPlayer player =
    new ExoPlayer.Builder(
            context, new DefaultMediaSourceFactory(context, ExtractorsFactory.EMPTY))
        .build();

Instanziierung von benutzerdefinierten MediaSource

Wenn Ihre Anwendung ein benutzerdefiniertes MediaSource.Factory verwendet und Sie möchten, dass DefaultMediaSourceFactory durch Codeentfernung entfernt wird, sollten Sie MediaSource.Factory direkt an den ExoPlayer.Builder-Konstruktor übergeben.

Kotlin

val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()

Java

ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();

Wenn Ihre Anwendung MediaSource direkt anstelle von MediaItem verwendet, sollten Sie MediaSource.Factory.UNSUPPORTED an den ExoPlayer.Builder-Konstruktor übergeben, damit DefaultMediaSourceFactory und DefaultExtractorsFactory durch Codeschrumpfung entfernt werden können.

Kotlin

val player = ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build()
val mediaSource =
  ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory)
    .createMediaSource(MediaItem.fromUri(uri))

Java

ExoPlayer player = new ExoPlayer.Builder(context, MediaSource.Factory.UNSUPPORTED).build();
ProgressiveMediaSource mediaSource =
    new ProgressiveMediaSource.Factory(dataSourceFactory, customExtractorsFactory)
        .createMediaSource(MediaItem.fromUri(uri));