네트워크 스택

ExoPlayer는 일반적으로 인터넷을 통한 미디어 스트리밍에 사용됩니다. 기본 네트워크 요청을 위해 여러 네트워크 스택을 지원합니다. 선택 스트리밍 성능에 상당한 영향을 미칠 수 있습니다.

이 페이지에서는 네트워크 스택을 사용하도록 ExoPlayer를 구성하는 방법을 설명합니다. 사용 가능한 옵션 나열, 선택 방법에 관한 안내 제공 네트워크 스택에 대한 자세한 내용과 스트리밍 서비스에 캐싱을 사용 설정하는 방법을 설명합니다. 있습니다.

특정 네트워크 스택을 사용하도록 ExoPlayer 구성

ExoPlayer는 DataSource 구성요소를 통해 데이터를 로드하며, 이 구성요소는 앱 코드에서 삽입된 DataSource.Factory 인스턴스에서 가져옵니다.

앱에서 http(s) 콘텐츠만 재생하면 되는 경우 네트워크 스택을 선택하는 것은 앱에서 삽입하는 모든 DataSource.Factory 인스턴스를 사용하려는 네트워크 스택에 해당하는 HttpDataSource.Factory 인스턴스로 업데이트하는 것만큼 간단합니다. 앱에서 로컬 파일과 같은 http(s)가 아닌 콘텐츠도 재생해야 하는 경우 DefaultDataSource.Factory를 사용하세요.

Kotlin

DefaultDataSource.Factory(
  ...
  /* baseDataSourceFactory= */ PreferredHttpDataSource.Factory(...))

자바

new DefaultDataSource.Factory(
    ...
    /* baseDataSourceFactory= */ new PreferredHttpDataSource.Factory(...));

이 예에서 PreferredHttpDataSource.Factory는 기본 네트워크 스택에 해당하는 팩토리입니다. DefaultDataSource.Factory 레이어는 http(s)가 아닌 소스(예: 로컬 파일)

다음 예는 Cronet을 사용할 ExoPlayer를 빌드하는 방법을 보여줍니다. 네트워크 스택에 있으며 http(s)가 아닌 콘텐츠의 재생도 지원합니다.

Kotlin

// Given a CronetEngine and Executor, build a CronetDataSource.Factory.
val cronetDataSourceFactory = CronetDataSource.Factory(cronetEngine, executor)

// Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds
// in support for requesting data from other sources (such as files, resources,
// etc).
val dataSourceFactory =
  DefaultDataSource.Factory(context, /* baseDataSourceFactory= */ cronetDataSourceFactory)

// Inject the DefaultDataSource.Factory when creating the player.
val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory)
    )
    .build()

자바

// Given a CronetEngine and Executor, build a CronetDataSource.Factory.
CronetDataSource.Factory cronetDataSourceFactory =
    new CronetDataSource.Factory(cronetEngine, executor);

// Wrap the CronetDataSource.Factory in a DefaultDataSource.Factory, which adds
// in support for requesting data from other sources (such as files, resources,
// etc).
DefaultDataSource.Factory dataSourceFactory =
    new DefaultDataSource.Factory(
        context, /* baseDataSourceFactory= */ cronetDataSourceFactory);

// Inject the DefaultDataSource.Factory when creating the player.
ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context).setDataSourceFactory(dataSourceFactory))
        .build();

지원되는 네트워크 스택

ExoPlayer는 HttpEngine, Cronet, OkHttp, Android의 내장 기본 네트워크 스택을 직접 지원합니다. ExoPlayer는 Android에서 작동하는 다른 모든 네트워크 스택을 지원하도록 확장할 수도 있습니다.

HttpEngine

HttpEngine은 API 34(또는 S 확장 프로그램 7)부터 Android에서 권장되는 기본 네트워크 스택입니다. 대부분의 경우 Cronet 네트워크 스택을 내부적으로 사용합니다. QUIC 프로토콜을 통해 HTTP, HTTP/2, HTTP/3을 지원합니다.

ExoPlayer는 HttpEngineDataSource.Factory로 HttpEngine을 지원합니다. 다음과 같은 작업을 할 수 있습니다. 인스턴스를 사용하도록 ExoPlayer 구성 구체적인 네트워크 스택에 관한 문제를 해결할 수 있습니다

Cronet

Cronet은 Android 앱에서 라이브러리로 사용하도록 제공되는 Chromium 네트워크 스택입니다. Cronet은 여러 기술을 활용하여 지연 시간을 줄이고 앱이 작동해야 하는 네트워크 요청의 처리량 제작되었습니다. QUIC 프로토콜을 통해 HTTP, HTTP/2, HTTP/3을 기본적으로 지원합니다. Cronet은 세계 최대의 스트리밍 앱인 (YouTube 포함)

ExoPlayer는 Cronet 라이브러리. 사용 방법에 관한 자세한 내용은 라이브러리의 README.md를 참고하세요. Cronet 라이브러리는 세 가지 기본 Cronet을 사용할 수 있습니다. 구현:

  1. Google Play 서비스: 대부분의 경우 이 구현을 사용하는 것이 좋습니다. 다시 Android의 내장 네트워크 스택으로 돌아가 (DefaultHttpDataSource)(Google Play 서비스를 사용할 수 없는 경우)
  2. Cronet Embedded: 사용자의 다수가 Google Play 서비스가 널리 제공되지 않는 시장에 거주하거나 사용되는 Cronet 구현의 정확한 버전을 제어하려는 경우 Cronet Embedded의 주요 단점은 앱에 약 8MB가 추가된다는 점입니다.
  3. Cronet 대체: Cronet 구현의 대체 구현입니다. Android의 내장 네트워크 스택을 둘러싼 래퍼로서의 Cronet API Android의 내장 네트워크 스택을 직접(DefaultHttpDataSource 사용) 사용하는 것이 더 효율적이므로 ExoPlayer와 함께 사용해서는 안 됩니다.

OkHttp

OkHttp는 많은 인기 Android 앱에서 널리 사용되는 또 다른 최신 네트워크 스택입니다. 또한 HTTP 및 HTTP/2를 지원하지만 아직 QUIC를 통한 HTTP/3는 지원하지 않습니다.

ExoPlayer는 OkHttp 라이브러리를 사용합니다. 사용 방법에 관한 자세한 안내는 라이브러리의 README.md를 참고하세요. 있습니다. OkHttp 라이브러리를 사용하면 네트워크 스택이 앱 내에 삽입됩니다. 이는 Cronet Embedded와 유사하지만 OkHttp는 훨씬 작아 앱에 1MB 미만이 추가됩니다.

Android의 내장 네트워크 스택

ExoPlayer는 핵심 ExoPlayer 라이브러리의 일부인 DefaultHttpDataSourceDefaultHttpDataSource.Factory를 사용하여 Android의 내장 네트워크 스택을 사용하는 것을 지원합니다.

정확한 네트워크 스택 구현은 액세스할 수 있습니다 대부분의 기기에서는 HTTP만 지원됩니다 (즉, QUIC를 통한 HTTP/2 및 HTTP/3는 지원되지 않음).

기타 네트워크 스택

앱은 다른 네트워크 스택을 ExoPlayer와 통합할 수도 있습니다. 이렇게 하려면 네트워크 스택을 래핑하는 HttpDataSource를 상응하는 HttpDataSource.Factory와 함께 구현합니다. ExoPlayer의 Cronet 및 OkHttp 라이브러리는 이를 수행하는 방법을 보여주는 좋은 예입니다.

순수 Java 네트워크 스택과 통합할 때는 DataSourceContractTest: HttpDataSource 구현 확인 있습니다. OkHttp 라이브러리의 OkHttpDataSourceContractTest는 이를 수행하는 방법을 보여주는 좋은 예입니다.

네트워크 스택 선택

다음 표에는 ExoPlayer.

네트워크 스택 프로토콜 APK 크기 영향 참고
HttpEngine HTTP
HTTP/2
QUIC을 통한 HTTP/3
없음 API 34 또는 S 확장 프로그램 7에서만 사용할 수 있습니다.
Cronet (Google Play 서비스) HTTP
HTTP/2
QUIC을 통한 HTTP/3
작게
(100KB 미만)
Google Play 서비스가 필요합니다. Cronet 버전이 자동으로 업데이트됨
Cronet(임베디드) HTTP
HTTP/2
QUIC을 통한 HTTP/3
대용량
(약 8MB)
앱 개발자가 제어하는 Cronet 버전
Cronet(대체) HTTP
(기기에 따라 다름)
소형
(100KB 미만)
ExoPlayer에 권장되지 않음
OkHttp HTTP
HTTP/2
소형
(1MB 미만)
내장 네트워크 스택 HTTP
(기기에 따라 다름)
없음 기기에 따라 구현 방식이 다름

QUIC 프로토콜을 통한 HTTP/2 및 HTTP/3는 미디어를 크게 개선할 수 있습니다. 성능을 향상시킬 수 있습니다 특히, 10~15%의 속도로 적응형 미디어를 스트리밍할 때 콘텐츠 배포 네트워크 (CDN)를 통해 배포된 콘텐츠보다 이러한 프로토콜을 사용하면 CDN이 훨씬 더 효율적으로 작동할 수 있습니다. 따라서 HttpEngine 및 Cronet은 HTTP/2와 HTTP/3를 모두 지원합니다. QUIC (및 OkHttp의 HTTP/2 지원)를 통한 HTTP/2 프로토콜 프로토콜에 비해 단, Android의 내장 네트워크 스택을 사용하고 콘텐츠도 이러한 프로토콜을 지원합니다

미디어 스트리밍을 단독으로 고려할 때는 Google Play 서비스에서 제공하는 HttpEngine 또는 Cronet을 사용하는 것이 좋으며, Google Play 서비스를 사용할 수 없는 경우 DefaultHttpDataSource로 대체합니다. 이 권장사항은 대부분의 기기에서 QUIC를 통해 HTTP/2 및 HTTP/3을 사용 설정하고 APK 크기가 크게 증가하지 않도록 하는 것 사이에서 적절한 균형을 유지합니다. 이 권장사항에는 예외가 있습니다. 앱을 실행할 기기 중 상당 부분에서 Google Play 서비스를 사용할 수 없는 경우 Cronet Embedded 또는 OkHttp를 사용하는 것이 더 적절할 수 있습니다. 내장된 APK 크기가 중요한 문제가 되는 경우 또는 미디어가 스트리밍은 앱 기능의 사소한 부분일 뿐입니다.

미디어뿐만 아니라 일반적으로 앱에서 실행하는 모든 네트워킹에 단일 네트워크 스택을 선택하는 것이 좋습니다. 이렇게 하면 리소스(예: 소켓)를 ExoPlayer와 다른 앱 구성요소 간에 효율적으로 풀링하고 공유할 수 있습니다.

앱은 미디어 재생과 관련 없는 네트워킹을 실행해야 할 가능성이 높으므로 네트워크 스택을 선택할 때는 궁극적으로 미디어 스트리밍을 단독으로 사용하는 경우의 위 권장사항, 네트워킹을 실행하는 다른 구성요소의 요구사항, 앱에 대한 상대적 중요성을 고려해야 합니다.

미디어 캐싱

ExoPlayer는 네트워크에서 동일한 바이트를 반복적으로 로드하지 않도록 로드된 바이트를 디스크에 캐싱하는 기능을 지원합니다. 이는 현재 동일한 항목을 반복하기만 하면 됩니다.

캐싱에는 전용 캐시 디렉터리와 CacheDataSource.Factory를 가리키는 SimpleCache 인스턴스가 필요합니다.

Kotlin

// Note: This should be a singleton in your app.
val databaseProvider = StandaloneDatabaseProvider(context)

// An on-the-fly cache should evict media when reaching a maximum disk space limit.
val cache =
    SimpleCache(
        downloadDirectory, LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider)

// Configure the DataSource.Factory with the cache and factory for the desired HTTP stack.
val cacheDataSourceFactory =
    CacheDataSource.Factory()
        .setCache(cache)
        .setUpstreamDataSourceFactory(httpDataSourceFactory)

// Inject the DefaultDataSource.Factory when creating the player.
val player =
    ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory))
        .build()

Java

// Note: This should be a singleton in your app.
DatabaseProvider databaseProvider = new StandaloneDatabaseProvider(context);

// An on-the-fly cache should evict media when reaching a maximum disk space limit.
Cache cache =
    new SimpleCache(
        downloadDirectory, new LeastRecentlyUsedCacheEvictor(maxBytes), databaseProvider);

// Configure the DataSource.Factory with the cache and factory for the desired HTTP stack.
DataSource.Factory cacheDataSourceFactory =
    new CacheDataSource.Factory()
        .setCache(cache)
        .setUpstreamDataSourceFactory(httpDataSourceFactory);

// Inject the DefaultDataSource.Factory when creating the player.
ExoPlayer player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context).setDataSourceFactory(cacheDataSourceFactory))
        .build();