Riduzione APK

Ridurre al minimo le dimensioni dell'APK è un aspetto importante dello sviluppo di una buona app per Android. Ciò è particolarmente vero quando si prendono di mira i mercati in via di sviluppo e anche quando si sviluppa un'app istantanea per Android. In questi casi, potrebbe essere opportuno ridurre al minimo le dimensioni della libreria ExoPlayer inclusa nell'APK. Questa pagina descrive alcuni semplici passaggi che possono aiutarti a raggiungere questo obiettivo.

Utilizza solo le dipendenze richieste

Dipendi solo dai moduli della libreria di cui hai effettivamente bisogno. Ad esempio, il seguente aggiungerà dipendenze dai moduli delle librerie ExoPlayer, DASH e UI, come potrebbe essere richiesto per un'app che riproduce solo contenuti DASH:

Kotlin

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

Groovy

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

Attivare la riduzione del codice e delle risorse

Devi attivare la riduzione del codice e delle risorse per le build di rilascio della tua app. ExoPlayer è strutturato in modo da consentire la riduzione del codice per rimuovere efficacemente le funzionalità inutilizzate. Ad esempio, per un'app che riproduce contenuti DASH, il contributo di ExoPlayer alle dimensioni dell'APK può essere ridotto di circa il 40% attivando la riduzione del codice.

Leggi l'articolo Ridurre, offuscare e ottimizzare l'app per scoprire come attivare la riduzione di codice e risorse.

Specifica i renderer necessari per la tua app

Per impostazione predefinita, i renderer del player verranno creati utilizzando DefaultRenderersFactory. DefaultRenderersFactory dipende da tutte le implementazioni di Renderer fornite nella libreria ExoPlayer e, di conseguenza, nessuna di queste verrà rimossa dalla riduzione del codice. Se sai che la tua app ha bisogno solo di un sottoinsieme di renderer, puoi specificare il tuo RenderersFactory. Ad esempio, un'app che riproduce solo audio può definire una factory come questa quando crea istanze di ExoPlayer:

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();

In questo modo, altre implementazioni di Renderer possono essere rimosse tramite la riduzione del codice. In questo video di esempio specifico, i renderer di testo e metadati vengono rimossi (il che significa che i sottotitoli codificati o i metadati in streaming (ad es. ICY) non verranno elaborati o emessi dal player).

Specifica gli estrattori necessari per la tua app

Per impostazione predefinita, il player crea Extractor istanze per riprodurre contenuti multimediali progressivi utilizzando DefaultExtractorsFactory. DefaultExtractorsFactory dipende da tutte le implementazioni di Extractor fornite nella libreria ExoPlayer e, di conseguenza, nessuna di queste verrà rimossa dalla riduzione del codice. Se sai che la tua app deve riprodurre solo un numero ridotto di formati contenitore o non riproduce affatto contenuti multimediali progressivi, puoi specificare un ExtractorsFactory personalizzato. Ad esempio, un'app che deve riprodurre solo file MP4 può fornire una factory come:

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();

Ciò consentirà di rimuovere altre implementazioni di Extractor tramite la riduzione del codice, il che può comportare una riduzione significativa delle dimensioni.

Se la tua app non riproduce contenuti progressivi, devi passare ExtractorsFactory.EMPTY al costruttore DefaultMediaSourceFactory, quindi passare mediaSourceFactory al costruttore ExoPlayer.Builder.

Kotlin

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

Java

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

Creazione di un'istanza di MediaSource personalizzata

Se la tua app utilizza un MediaSource.Factory personalizzato e vuoi che DefaultMediaSourceFactory venga rimosso tramite l'eliminazione del codice, devi passare il tuo MediaSource.Factory direttamente al costruttore ExoPlayer.Builder.

Kotlin

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

Java

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

Se la tua app utilizza MediaSource direttamente anziché MediaItem, devi passare MediaSource.Factory.UNSUPPORTED al costruttore ExoPlayer.Builder, per assicurarti che DefaultMediaSourceFactory e DefaultExtractorsFactory possano essere rimossi dalla riduzione del codice.

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));