Zminimalizowanie rozmiaru pliku APK jest ważnym aspektem tworzenia dobrej aplikacji na Androida. Dotyczy to zwłaszcza rynków rozwijających się, a także tworzenia aplikacji błyskawicznej na Androida. W takich przypadkach warto zminimalizować rozmiar biblioteki ExoPlayer dołączonej do pliku APK. Na tej stronie znajdziesz kilka prostych kroków, które pomogą Ci to osiągnąć.
Używaj tylko wymaganych zależności
Zależ od modułów biblioteki, których faktycznie 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.11.1")
implementation("androidx.media3:media3-exoplayer-dash:1.11.1")
implementation("androidx.media3:media3-ui:1.11.1")
Dynamiczny
implementation "androidx.media3:media3-exoplayer:1.11.1"
implementation "androidx.media3:media3-exoplayer-dash:1.11.1"
implementation "androidx.media3:media3-ui:1.11.1"
Włączanie zmniejszania kodu i zasobów
W kompilacjach do publikacji aplikacji należy włączyć zmniejszanie kodu i zasobów. ExoPlayer ma strukturę, która umożliwia zmniejszanie kodu w celu skutecznego usuwania nieużywanych funkcji. Na przykład w przypadku aplikacji, która odtwarza treści DASH, włączenie zmniejszania kodu może zmniejszyć wpływ ExoPlayera na rozmiar pliku APK o około 40%.
Aby dowiedzieć się, jak włączyć zmniejszanie kodu i zasobów, przeczytaj artykuł Zmniejszanie, zaciemnianie i optymalizowanie aplikacji.
Określanie, których mechanizmów renderowania potrzebuje aplikacja
Domyślnie renderery odtwarzacza będą tworzone za pomocą DefaultRenderersFactory. DefaultRenderersFactory zależy od wszystkich implementacji Renderer dostępnych w bibliotece ExoPlayer, dlatego żadna z nich nie zostanie usunięta podczas zmniejszania kodu. Jeśli wiesz, że Twoja aplikacja potrzebuje tylko podzbioru modułów renderujących, możesz określić własny element 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 będzie można usunąć przez zmniejszanie kodu. W tym konkretnym przykładowym filmie renderery tekstu i metadanych są usuwane (co oznacza, że napisy lub metadane w strumieniu, np. ICY, nie będą przetwarzane ani emitowane przez odtwarzacz).
Określanie ekstraktorów, których potrzebuje aplikacja
Domyślnie odtwarzacz tworzy instancje Extractor do odtwarzania multimediów progresywnych za pomocą DefaultExtractorsFactory. DefaultExtractorsFactory zależy od wszystkich implementacji Extractor dostępnych w bibliotece ExoPlayer, dlatego żadna z nich nie zostanie usunięta podczas zmniejszania kodu. Jeśli wiesz, że aplikacja musi odtwarzać tylko niewielką liczbę formatów kontenerów lub w ogóle nie odtwarza multimediów progresywnych, możesz zamiast tego określić własny obiekt ExtractorsFactory. Na przykład aplikacja, która musi odtwarzać tylko pliki MP4, może udostępniać 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 można usunąć przez zmniejszenie kodu, co może znacznie zmniejszyć rozmiar.
Jeśli aplikacja w ogóle nie odtwarza treści progresywnych, przekaż ExtractorsFactory.EMPTY do konstruktora DefaultMediaSourceFactory, a następnie przekaż 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 niestandardowego obiektu MediaSource.Factory i chcesz, aby obiekt DefaultMediaSourceFactory został usunięty przez usuwanie kodu, przekaż obiekt 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 bezpośrednio MediaSource zamiast MediaItem, musisz przekazać 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));