네트워크 스택

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를 확장하여 모든 다른 네트워크 스택과는 다릅니다.

HTTP 엔진

HttpEngine API 34 (또는 S)부터 Android에 권장되는 기본 네트워크 스택입니다. 확장 7). 대부분의 경우 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의 주요 단점은 있습니다.
  3. Cronet 대체: Cronet 구현의 대체 구현입니다. Android의 내장 네트워크 스택을 둘러싼 래퍼로서의 Cronet API 또한 Android의 내장 네트워크 스택을 사용하기 때문에 ExoPlayer와 함께 사용하면 안 됩니다. 직접 (DefaultHttpDataSource 사용)하는 것이 더 효율적입니다.

OkHttp

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

ExoPlayer는 OkHttp 라이브러리를 사용합니다. 사용 방법에 관한 자세한 안내는 라이브러리의 README.md를 참고하세요. 있습니다. OkHttp 라이브러리 사용 시 네트워크 스택이 있습니다. Cronet Embedded와 유사하지만 OkHttp는 상당히 유용함 용량이 작아서 앱에 1MB 미만으로 추가합니다.

Android의 내장 네트워크 스택

ExoPlayer는 Android의 내장 네트워크 스택 사용을 지원하며 DefaultHttpDataSourceDefaultHttpDataSource.Factory은 핵심 ExoPlayer 라이브러리입니다.

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

기타 네트워크 스택

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

순수 Java 네트워크 스택과 통합할 때는 DataSourceContractTest를 통해 HttpDataSource 구현 확인 있습니다. OkHttp 라이브러리의 OkHttpDataSourceContractTest는 좋은 예입니다.

네트워크 스택 선택

다음 표에는 ExoPlayer.

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

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

미디어 스트리밍을 개별적으로 고려한다면 HttpEngine 또는 Google Play 서비스에서 제공하는 Cronet이 DefaultHttpDataSource로 대체됩니다. Google Play 서비스를 사용할 수 없는 경우 이 추천은 대부분의 기기에서 QUIC를 통한 HTTP/2 및 HTTP/3 사용 설정 APK 크기가 크게 증가하는 것을 방지할 수 있습니다. 여기에는 추천을 제공합니다 Google Play 서비스를 사용할 수 없는 경우 상당한 양의 기기에서 광고가 게재됩니다. Cronet Embedded 또는 OkHttp를 사용하는 것이 더 적합할 수 있습니다. 내장된 APK 크기가 중요한 문제가 되는 경우 또는 미디어가 스트리밍은 앱 기능의 사소한 부분일 뿐입니다.

미디어 외에도 일반적으로는 단일 네트워크 스택을 선택하고 네트워킹에 대해 설명합니다. 이렇게 하면 리소스가 효율적으로 풀링되고 ExoPlayer 및 다른 시스템 간에 공유될 수 있습니다. 앱 구성요소의 경우와 다릅니다.

앱이 관련성이 없는 네트워킹을 수행해야 할 가능성이 높기 때문입니다. 미디어 재생과 관련해서는 네트워크 스택 선택은 궁극적으로 분리하는 미디어 스트리밍에 대해서는 위에 나온 권장사항을 참조하세요. 네트워킹을 수행하는 다른 구성 요소 및 운영 체제에 대한 상대적 중요성, 있습니다.

미디어 캐싱

ExoPlayer는 반복 로드를 방지하기 위해 로드된 바이트를 디스크에 캐시하는 것을 지원합니다. 동일한 바이트를 전송하는 데 사용됩니다 이는 현재 동일한 항목을 반복하기만 하면 됩니다.

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

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