APK 축소

APK 크기를 최소화하는 것은 우수한 Android 앱을 개발하는 데 있어 중요한 부분입니다. 개발 중인 시장을 타겟팅할 때는 물론 Android 인스턴트 앱을 개발할 때도 특히 그렇습니다. 이러한 경우에는 APK에 포함된 ExoPlayer 라이브러리의 크기를 최소화하는 것이 바람직할 수 있습니다. 이 페이지에서는 이를 달성하는 데 도움이 되는 몇 가지 간단한 단계를 간략히 설명합니다.

필요한 종속 항목만 사용

실제로 필요한 라이브러리 모듈에만 종속됩니다. 예를 들어 다음은 DASH 콘텐츠만 재생하는 앱에 필요할 수 있는 ExoPlayer, DASH 및 UI 라이브러리 모듈에 관한 종속 항목을 추가합니다.

Kotlin

implementation("androidx.media3:media3-exoplayer:1.3.1")
implementation("androidx.media3:media3-exoplayer-dash:1.3.1")
implementation("androidx.media3:media3-ui:1.3.1")

Groovy

implementation "androidx.media3:media3-exoplayer:1.3.1"
implementation "androidx.media3:media3-exoplayer-dash:1.3.1"
implementation "androidx.media3:media3-ui:1.3.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 구현을 삭제할 수 있으므로 크기가 크게 줄어들 수 있습니다.

앱이 프로그레시브 콘텐츠를 전혀 재생하지 않으면 ExtractorsFactory.EMPTYDefaultMediaSourceFactory 생성자에 전달한 다음 이 mediaSourceFactoryExoPlayer.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.FactoryExoPlayer.Builder 생성자에 직접 전달해야 합니다.

Kotlin

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

Java

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

앱에서 MediaItem 대신 MediaSource를 직접 사용하는 경우 MediaSource.Factory.UNSUPPORTEDExoPlayer.Builder 생성자에 전달해야 합니다. 그래야 코드 축소로 DefaultMediaSourceFactoryDefaultExtractorsFactory를 제거할 수 있습니다.

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