Minimizar el tamaño del APK es un aspecto importante para desarrollar una buena app para Android. Esto es especialmente cierto cuando se segmenta para mercados en desarrollo y también cuando se desarrolla una app para Android Instant. En esos casos, puede ser conveniente minimizar el tamaño de la biblioteca de ExoPlayer que se incluye en el APK. En esta página, se describen algunos pasos simples que pueden ayudarte a lograrlo.
Usa solo las dependencias requeridas
Depende solo de los módulos de biblioteca que realmente necesitas. Por ejemplo, lo siguiente agregará dependencias en los módulos de bibliotecas de ExoPlayer, DASH y UI, como podría ser necesario para una app que solo reproduce contenido 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"
Habilita la reducción de código y recursos
Debes habilitar la reducción de código y recursos para las compilaciones de lanzamiento de tu app. ExoPlayer está estructurado de una manera que permite que la reducción de código quite de manera eficaz la funcionalidad que no se usa. Por ejemplo, en el caso de una app que reproduce contenido DASH, la contribución de ExoPlayer al tamaño del APK se puede reducir en aproximadamente un 40% habilitando la reducción de código.
Lee Cómo reducir, ofuscar y optimizar tu app para obtener información sobre cómo habilitar la reducción de código y recursos.
Especifica qué renderizadores necesita tu app
De forma predeterminada, los renderizadores del reproductor se crearán con DefaultRenderersFactory
. DefaultRenderersFactory
depende de todas las implementaciones de Renderer
proporcionadas en la biblioteca de ExoPlayer y, como resultado, ninguna de ellas se quitará con la reducción de código. Si sabes que tu app solo necesita un subconjunto de renderizadores, puedes especificar tu propio RenderersFactory
. Por ejemplo, una app que solo reproduce audio puede definir una fábrica de la siguiente manera cuando se crean instancias de 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();
Esto permitirá que se quiten otras implementaciones de Renderer
mediante la reducción de código. En este video de ejemplo en particular, se quitan los renderizadores de texto y metadatos (lo que significa que el reproductor no procesará ni emitirá subtítulos ni metadatos in-stream (p.ej., ICY)).
Especifica qué extractores necesita tu app
De forma predeterminada, el reproductor crea instancias de Extractor
para reproducir contenido multimedia progresivo con DefaultExtractorsFactory
. DefaultExtractorsFactory
depende de todas las implementaciones de Extractor
proporcionadas en la biblioteca de ExoPlayer y, como resultado, ninguna de ellas se quitará con la reducción de código. Si sabes que tu app solo necesita reproducir una pequeña cantidad de formatos de contenedor o no reproduce contenido multimedia progresivo, puedes especificar tu propio ExtractorsFactory
. Por ejemplo, una app que solo necesita reproducir archivos mp4 puede proporcionar una fábrica como la siguiente:
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();
Esto permitirá que se quiten otras implementaciones de Extractor
mediante la reducción de código, lo que puede generar una reducción significativa de tamaño.
Si tu app no reproduce contenido progresivo, debes pasar ExtractorsFactory.EMPTY
al constructor DefaultMediaSourceFactory
y, luego, pasar ese mediaSourceFactory
al constructor 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();
Creación de instancias de MediaSource personalizadas
Si tu app usa un MediaSource.Factory
personalizado y deseas que DefaultMediaSourceFactory
se quite mediante la eliminación de código, debes pasar tu MediaSource.Factory
directamente al constructor ExoPlayer.Builder
.
Kotlin
val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();
Si tu app usa MediaSource
directamente en lugar de MediaItem
, debes pasar MediaSource.Factory.UNSUPPORTED
al constructor ExoPlayer.Builder
para asegurarte de que DefaultMediaSourceFactory
y DefaultExtractorsFactory
se puedan quitar con la reducción de código.
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));