Penyingkatan APK

Meminimalkan ukuran APK adalah aspek penting dalam mengembangkan aplikasi Android yang baik. Hal ini terutama berlaku saat menargetkan pasar berkembang, dan juga saat mengembangkan Aplikasi Instan Android. Untuk kasus tersebut, sebaiknya minimalkan ukuran library ExoPlayer yang disertakan dalam APK. Halaman ini menjelaskan beberapa langkah sederhana yang dapat membantu mencapainya.

Hanya menggunakan dependensi yang diperlukan

Hanya bergantung pada modul library yang benar-benar Anda perlukan. Misalnya, hal berikut akan menambahkan dependensi pada modul library ExoPlayer, DASH, dan UI, seperti yang mungkin diperlukan untuk aplikasi yang hanya memutar konten 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"

Mengaktifkan penyingkatan kode dan resource

Anda harus mengaktifkan penyingkatan kode dan resource untuk build rilis aplikasi. ExoPlayer disusun sedemikian rupa sehingga memungkinkan penyingkatan kode untuk menghapus fungsi yang tidak digunakan secara efektif. Misalnya, untuk aplikasi yang memutar konten DASH, kontribusi ExoPlayer terhadap ukuran APK dapat dikurangi sekitar 40% dengan mengaktifkan penyingkatan kode.

Baca Menyingkat, meng-obfuscate, dan mengoptimalkan aplikasi untuk mempelajari cara mengaktifkan penyingkatan kode dan resource.

Menentukan perender yang diperlukan aplikasi Anda

Secara default, perender pemutar akan dibuat menggunakan DefaultRenderersFactory. DefaultRenderersFactory bergantung pada semua implementasi Renderer yang disediakan di library ExoPlayer, dan akibatnya tidak satu pun dari implementasi tersebut yang akan dihapus dengan penyingkatan kode. Jika Anda tahu bahwa aplikasi hanya memerlukan sebagian perender, Anda dapat menentukan RenderersFactory Anda sendiri. Misalnya, aplikasi yang hanya memutar audio dapat menentukan factory seperti ini saat membuat instance 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();

Hal ini akan memungkinkan implementasi Renderer lain dihapus dengan penyingkatan kode. Dalam contoh video khusus ini, perender teks dan metadata akan dihapus (yang berarti subtitel atau metadata dalam streaming (misalnya ICY) tidak akan diproses atau dikeluarkan oleh pemutar).

Menentukan ekstraktor yang diperlukan aplikasi Anda

Secara default, pemutar membuat instance Extractor untuk memutar media progresif menggunakan DefaultExtractorsFactory. DefaultExtractorsFactory bergantung pada semua implementasi Extractor yang disediakan di library ExoPlayer, dan sebagai hasilnya tidak ada yang akan dihapus oleh penyingkatan kode. Jika Anda tahu bahwa aplikasi hanya perlu memutar sejumlah kecil format penampung, atau tidak memutar media progresif sama sekali, Anda dapat menentukan ExtractorsFactory Anda sendiri. Misalnya, aplikasi yang hanya perlu memutar file mp4 dapat menyediakan factory seperti:

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

Hal ini akan memungkinkan implementasi Extractor lainnya dihapus dengan pengecilan kode, yang dapat menyebabkan pengurangan ukuran yang signifikan.

Jika aplikasi tidak memutar konten progresif sama sekali, Anda harus meneruskan ExtractorsFactory.EMPTY ke konstruktor DefaultMediaSourceFactory, lalu meneruskan mediaSourceFactory tersebut ke konstruktor 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();

Pembuatan instance MediaSource kustom

Jika aplikasi Anda menggunakan MediaSource.Factory kustom dan Anda ingin DefaultMediaSourceFactory dihapus dengan penghapusan kode, Anda harus meneruskan MediaSource.Factory langsung ke konstruktor ExoPlayer.Builder.

Kotlin

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

Java

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

Jika aplikasi Anda menggunakan MediaSource secara langsung, bukan MediaItem, Anda harus meneruskan MediaSource.Factory.UNSUPPORTED ke konstruktor ExoPlayer.Builder, untuk memastikan DefaultMediaSourceFactory dan DefaultExtractorsFactory dapat dihapus dengan penyusutan kode.

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