Riduzione APK

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

Utilizza solo le dipendenze richieste

Dipendere solo dai moduli della libreria di cui hai effettivamente bisogno. Ad esempio, il codice riportato di seguito aggiungerà dipendenze ai moduli della libreria ExoPlayer, DASH e UI, come potrebbe essere necessario per un'app che riproduce solo contenuti DASH:

Kotlin

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

Groovy

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

Attiva la riduzione del codice e delle risorse

Devi attivare la riduzione del codice e delle risorse per le build di release 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 Riduci, offusca e ottimizza la tua app per scoprire come attivare la riduzione del codice e delle risorse.

Specifica i renderer di cui ha bisogno 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 dal ridimensionamento del codice. Se sai che la tua app necessita solo di un sottoinsieme di visualizzatori, puoi specificare il tuo RenderersFactory. Ad esempio, un'app che riproduce solo audio può definire un'attività di fabbrica come questa al momento dell'inizializzazione di istanze 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, le altre implementazioni di Renderer potranno essere rimosse tramite la riduzione del codice. In questo video di esempio, i visualizzatori di testo e metadati vengono rimossi, il che significa che i sottotitoli o i metadati in-stream (ad es. ICY) non verranno elaborati o emessi dal player.

Specifica gli estrattori di cui ha bisogno la tua app

Per impostazione predefinita, il player crea istanze Extractor 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 dal ridimensionamento del codice. Se sai che la tua app deve riprodurre solo un numero limitato di formati contenitore o non riproduce affatto i contenuti media progressivi, puoi specificare il tuo ExtractorsFactory. Ad esempio, un'app che deve solo riprodurre 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();

In questo modo, le altre implementazioni di Extractor possono essere rimosse mediante 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();

Istanziazione di MediaSource personalizzato

Se la tua app utilizza un MediaSource.Factory personalizzato e vuoi che DefaultMediaSourceFactory venga rimosso tramite lo stripping del codice, devi passare 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 direttamente MediaSource anziché MediaItem, devi passare MediaSource.Factory.UNSUPPORTED al costruttore ExoPlayer.Builder per assicurarti che DefaultMediaSourceFactory e DefaultExtractorsFactory possano essere rimossi tramite il ridimensionamento 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));