APK サイズを最小限に抑えることは、優れた Android アプリを開発するうえで重要です。これは特に、発展途上市場を対象とする場合や Android Instant App を開発する場合に当てはまります。そのような場合は、APK に含まれる ExoPlayer ライブラリのサイズを最小限に抑えることが望ましい場合があります。このページでは、この目標を達成するために役立つ簡単な手順を説明します。
必要な依存関係のみを使用する
実際に必要なライブラリ モジュールにのみ依存します。たとえば、次のコードは、DASH コンテンツのみを再生するアプリに必要な場合がある、ExoPlayer、DASH、UI ライブラリ モジュールへの依存関係を追加します。
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"
コードとリソースの圧縮を有効にする
アプリのリリースビルドでは、コードとリソースの圧縮を有効にする必要があります。ExoPlayer は、コード圧縮によって未使用の機能を効果的に削除できるように構成されています。たとえば、DASH コンテンツを再生するアプリの場合、コード圧縮を有効にすると、ExoPlayer が APK サイズに占める割合を約 40% 削減できます。
コードとリソースの圧縮を有効にする方法については、アプリの圧縮、難読化、最適化をご覧ください。
アプリに必要なレンダラを指定する
デフォルトでは、プレーヤーのレンダラは DefaultRenderersFactory
を使用して作成されます。DefaultRenderersFactory
は ExoPlayer ライブラリで提供されるすべての Renderer
実装に依存しているため、コード圧縮によって削除されることはありません。アプリで必要なレンダラのサブセットのみが判明している場合は、代わりに独自の RenderersFactory
を指定できます。たとえば、音声のみを再生するアプリは、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();
これにより、コードの圧縮によって他の Renderer
の実装を削除できるようになります。この特定の動画の例では、テキストとメタデータのレンダラが削除されています(つまり、字幕やインストリーム メタデータ(ICY など)はプレーヤーによって処理または出力されません)。
アプリに必要なエクストラクタを指定する
デフォルトでは、プレーヤーは Extractor
インスタンスを作成し、DefaultExtractorsFactory
を使用してプログレッシブ メディアを再生します。DefaultExtractorsFactory
は、ExoPlayer ライブラリで提供されるすべての Extractor
実装に依存しているため、コードの圧縮によって削除されることはありません。アプリで再生する必要があるコンテナ形式が少数に限られている場合や、プログレッシブ メディアをまったく再生しない場合は、代わりに独自の ExtractorsFactory
を指定できます。たとえば、mp4 ファイルの再生のみが必要なアプリでは、次のようなファクトリを提供できます。
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();
これにより、コード圧縮によって他の Extractor
実装を削除できるため、サイズを大幅に削減できます。
アプリでプログレッシブ コンテンツがまったく再生されない場合は、ExtractorsFactory.EMPTY
を DefaultMediaSourceFactory
コンストラクタに渡し、その mediaSourceFactory
を 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();
カスタム MediaSource のインスタンス化
アプリでカスタム MediaSource.Factory
を使用していて、コード除去によって DefaultMediaSourceFactory
を削除する場合は、MediaSource.Factory
を ExoPlayer.Builder
コンストラクタに直接渡す必要があります。
Kotlin
val player = ExoPlayer.Builder(context, customMediaSourceFactory).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context, mediaSourceFactory).build();
アプリで MediaItem
ではなく MediaSource
を直接使用している場合は、MediaSource.Factory.UNSUPPORTED
を ExoPlayer.Builder
コンストラクタに渡して、コード圧縮によって DefaultMediaSourceFactory
と DefaultExtractorsFactory
を削除できるようにする必要があります。
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));