APK сжимается

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

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

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

Котлин

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

Круто

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"

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

Вам следует включить сокращение кода и ресурсов для релизных сборок вашего приложения. Структура 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));