Zminimalizowanie rozmiaru pliku APK jest ważnym aspektem tworzenia dobrej aplikacji na Androida. Jest to szczególnie ważne w przypadku rynków rozwijających się, a także podczas tworzenia aplikacji natychmiastowej na Androida. W takich przypadkach warto zminimalizować rozmiar biblioteki ExoPlayer, która jest zawarta w pliku APK. Na tej stronie znajdziesz kilka prostych kroków, które mogą Ci w tym pomóc.
Używaj tylko wymaganych zależności
Zależ tylko od modułów biblioteki, których rzeczywiście potrzebujesz. Na przykład poniższy kod doda zależności od modułów biblioteki ExoPlayer, DASH i UI, które mogą być wymagane w przypadku aplikacji odtwarzającej tylko treści DASH:
Kotlin
implementation("androidx.media3:media3-exoplayer:1.10.0")
implementation("androidx.media3:media3-exoplayer-dash:1.10.0")
implementation("androidx.media3:media3-ui:1.10.0")
Dynamiczny
implementation "androidx.media3:media3-exoplayer:1.10.0"
implementation "androidx.media3:media3-exoplayer-dash:1.10.0"
implementation "androidx.media3:media3-ui:1.10.0"
Włącz kompresowanie kodu i zasobów
W przypadku kompilacji aplikacji do publikacji należy włączyć zmniejszanie kodu i zmniejszanie zasobów. ExoPlayer jest skonstruowany w taki sposób, że zmniejszanie kodu skutecznie usuwa nieużywane funkcje. Na przykład w przypadku aplikacji odtwarzającej treści DASH udział ExoPlayera w rozmiarze pliku APK można zmniejszyć o około 40% przez włączenie zmniejszania kodu.
Aby dowiedzieć się, jak włączyć kompresowanie kodu i zmniejszanie zasobów, przeczytaj artykuł Zmniejszanie, zaciemnianie i optymalizowanie aplikacji.
Określ, których rendererów potrzebuje Twoja aplikacja
Domyślnie renderery odtwarzacza są tworzone za pomocą DefaultRenderersFactory. DefaultRenderersFactory zależy od wszystkich implementacji
Renderer dostępnych w bibliotece ExoPlayer, dlatego
żadna z nich nie zostanie usunięta przez zmniejszanie kodu. Jeśli wiesz, że Twoja aplikacja potrzebuje tylko podzbioru rendererów, możesz zamiast tego określić własną RenderersFactory. Na przykład aplikacja, która odtwarza tylko dźwięk, może zdefiniować fabrykę w ten sposób podczas tworzenia instancji 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();
Dzięki temu inne implementacje Renderer mogą zostać usunięte przez kompresowanie kodu. W tym konkretnym przykładzie usunięto renderery tekstu i metadanych (co oznacza, że odtwarzacz nie będzie przetwarzać ani emitować żadnych napisów ani metadanych In-Stream (np. ICY)).
Określ, których ekstraktorów potrzebuje Twoja aplikacja
Domyślnie odtwarzacz tworzy Extractor instancje do odtwarzania progresywnych multimediów za pomocą
DefaultExtractorsFactory. DefaultExtractorsFactory zależy od wszystkich implementacji
Extractor dostępnych w bibliotece ExoPlayer, dlatego
żadna z nich nie zostanie usunięta przez zmniejszanie kodu. Jeśli wiesz, że Twoja aplikacja musi odtwarzać tylko niewielką liczbę formatów kontenerów lub w ogóle nie odtwarza progresywnych multimediów, możesz zamiast tego określić własną ExtractorsFactory. Na przykład aplikacja, która musi odtwarzać tylko pliki mp4, może udostępnić fabrykę w ten sposób:
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();
Dzięki temu inne implementacje Extractor mogą zostać usunięte przez kompresowanie kodu, co może znacznie zmniejszyć rozmiar aplikacji.
Jeśli Twoja aplikacja w ogóle nie odtwarza treści progresywnych, przekaż ExtractorsFactory.EMPTY do konstruktora DefaultMediaSourceFactory, a następnie przekaż tę mediaSourceFactory do konstruktora 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();
Niestandardowe tworzenie instancji MediaSource
Jeśli Twoja aplikacja używa niestandardowej MediaSource.Factory i chcesz, aby DefaultMediaSourceFactory została usunięta przez usuwanie kodu, przekaż swoją MediaSource.Factory bezpośrednio do konstruktora ExoPlayer.Builder.
Kotlin
val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();
Jeśli Twoja aplikacja używa MediaSource bezpośrednio zamiast MediaItem, przekaż MediaSource.Factory.UNSUPPORTED do konstruktora ExoPlayer.Builder, aby mieć pewność, że DefaultMediaSourceFactory i DefaultExtractorsFactory mogą zostać usunięte przez zmniejszanie kodu.
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));