APK サイズを最小限に抑えることは、優れた Android アプリを開発するうえで重要な要素です。これは、新興市場をターゲットとする場合や、Android インスタント アプリを開発する場合に特に当てはまります。このような場合、APK に含まれる ExoPlayer ライブラリのサイズを最小限に抑えることが望ましいことがあります。このページでは、それを実現するための簡単な手順を説明します。
必要な依存関係のみを使用する
実際に必要なライブラリ モジュールのみに依存します。たとえば、DASH コンテンツのみを再生するアプリに必要な場合、次のように ExoPlayer、DASH、UI ライブラリ モジュールへの依存関係を追加します。
Kotlin
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")
Groovy
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 コンテンツを再生するアプリの場合、コード圧縮を有効にすると、APK サイズに対する ExoPlayer の影響を約 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 など)はプレーヤーによって処理または出力されません)。
アプリに必要なエクストラクタを指定する
デフォルトでは、プレーヤーは DefaultExtractorsFactory
を使用してプログレッシブ メディアを再生するために Extractor
インスタンスを作成します。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
実装を削除できるようになり、サイズを大幅に削減できます。
アプリでプログレッシブ コンテンツがまったく再生されない場合は、DefaultMediaSourceFactory
コンストラクタに ExtractorsFactory.EMPTY
を渡し、その 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
を直接使用している場合は、ExoPlayer.Builder
コンストラクタに MediaSource.Factory.UNSUPPORTED
を渡して、コード圧縮で 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));