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