APK сжимается

Минимизация размера APK — важный аспект разработки хорошего приложения для Android. Это особенно актуально при ориентации на развивающиеся рынки, а также при разработке мгновенного приложения для Android. В таких случаях может оказаться желательным минимизировать размер библиотеки ExoPlayer, включенной в APK. На этой странице описаны несколько простых шагов, которые могут помочь в этом.

Используйте только необходимые зависимости

Полагайтесь только на те библиотечные модули, которые вам действительно нужны. Например, следующее добавит зависимости от модулей библиотеки ExoPlayer, DASH и UI, что может потребоваться для приложения, которое воспроизводит только контент DASH:

Котлин

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

классный

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"

Включить сокращение кода и ресурсов

Вам следует включить сокращение кода и ресурсов для сборок выпуска вашего приложения. ExoPlayer структурирован таким образом, что позволяет сокращать код для эффективного удаления неиспользуемых функций. Например, для приложения, воспроизводящего контент DASH, вклад ExoPlayer в размер APK можно уменьшить примерно на 40 %, включив сжатие кода.

Прочтите статью «Сжимайте, запутывайте и оптимизируйте свое приложение», чтобы узнать, как включить сокращение кода и ресурсов.

Укажите, какие средства визуализации нужны вашему приложению

По умолчанию рендереры проигрывателя будут созданы с использованием DefaultRenderersFactory . DefaultRenderersFactory зависит от всех реализаций Renderer , представленных в библиотеке ExoPlayer, и в результате ни одна из них не будет удалена путем сжатия кода. Если вы знаете, что вашему приложению требуется только подмножество средств визуализации, вместо этого вы можете указать собственную RenderersFactory . Например, приложение, воспроизводящее только аудио, может определить такую ​​фабрику при создании экземпляров ExoPlayer :

Котлин

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

Ява

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

Это позволит удалить другие реализации Renderer путем сжатия кода. В этом конкретном примере средства визуализации видео, текста и метаданных удаляются (что означает, что любые субтитры или метаданные в потоке (например, ICY ) не будут обрабатываться или воспроизводиться проигрывателем).

Укажите, какие экстракторы нужны вашему приложению

По умолчанию проигрыватель создает экземпляры Extractor для воспроизведения прогрессивного мультимедиа с помощью DefaultExtractorsFactory . DefaultExtractorsFactory зависит от всех реализаций Extractor , представленных в библиотеке ExoPlayer, и в результате ни одна из них не будет удалена путем сжатия кода. Если вы знаете, что вашему приложению необходимо воспроизводить только небольшое количество форматов контейнеров или вообще не воспроизводить прогрессивные медиа, вы можете вместо этого указать собственную ExtractorsFactory . Например, приложение, которому нужно только воспроизводить файлы mp4, может предоставить такую ​​фабрику:

Котлин

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

Ява

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

Это позволит удалить другие реализации Extractor путем сжатия кода, что может привести к значительному уменьшению размера.

Если ваше приложение вообще не воспроизводит прогрессивный контент, вам следует передать ExtractorsFactory.EMPTY в конструктор DefaultMediaSourceFactory , а затем передать этот mediaSourceFactory в конструктор ExoPlayer.Builder .

Котлин

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

Ява

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

Пользовательское создание экземпляра MediaSource

Если ваше приложение использует собственный MediaSource.Factory и вы хотите, чтобы DefaultMediaSourceFactory был удален путем удаления кода, вам следует передать свой MediaSource.Factory непосредственно в конструктор ExoPlayer.Builder .

Котлин

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

Ява

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

Если ваше приложение использует MediaSource напрямую вместо MediaItem вам следует передать MediaSource.Factory.UNSUPPORTED в конструктор ExoPlayer.Builder , чтобы гарантировать возможность удаления DefaultMediaSourceFactory и DefaultExtractorsFactory путем сжатия кода.

Котлин

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

Ява

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