HLS

ExoPlayer는 여러 컨테이너 형식으로 HLS를 지원합니다. 포함된 오디오 및 동영상 샘플 형식도 지원되어야 합니다 (자세한 내용은 샘플 형식 섹션 참고). 여기에 설명된 대로 HLS 콘텐츠 제작자가 고품질 HLS 스트림을 생성할 것을 적극 권장합니다.

기능 지원됨 댓글
컨테이너
MPEG-TS
FMP4/CMAF
ADTS (AAC)
MP3
자막
CEA-608
CEA-708
WebVTT
Metadata
ID3
SCTE-35 아니요
콘텐츠 보호
AES-128
샘플 AES-128 아니요
Widevine API 19 이상 ('cenc' 체계) 및 25 이상 ('cbcs' 체계)
PlayReady SL2000 Android TV만
서버 제어
델타 업데이트
재생목록 새로고침 차단 중
미리 로드 힌트 로드 차단 길이가 정의되지 않은 byterange 제외
실시간 재생
정기 라이브 재생
지연 시간이 짧은 HLS (Apple)
지연 시간이 짧은 HLS (커뮤니티) 아니요
Common Media Client Data (CMCD) 통합 가이드

MediaItem 사용

HLS 스트림을 재생하려면 HLS 모듈에 의존해야 합니다.

Kotlin

implementation("androidx.media3:media3-exoplayer-hls:1.3.1")

Groovy

implementation "androidx.media3:media3-exoplayer-hls:1.3.1"

그런 다음 HLS 재생목록 URI의 MediaItem를 만들어 플레이어에 전달할 수 있습니다.

Kotlin

// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(hlsUri))
// Prepare the player.
player.prepare()

Java

// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the media item to be played.
player.setMediaItem(MediaItem.fromUri(hlsUri));
// Prepare the player.
player.prepare();

URI가 .m3u8로 끝나지 않으면 MimeTypes.APPLICATION_M3U8MediaItem.BuildersetMimeType에 전달하여 콘텐츠 유형을 명시적으로 나타낼 수 있습니다.

미디어 항목의 URI는 미디어 재생목록이나 다중 변형 재생목록을 가리킬 수 있습니다. URI가 여러 #EXT-X-STREAM-INF 태그를 선언하는 다중 변형 재생목록을 가리키는 경우 ExoPlayer는 사용 가능한 대역폭과 기기 기능을 모두 고려하여 변형 간에 자동으로 조정합니다.

HlsMediaSource 사용

더 많은 맞춤설정 옵션을 보려면 HlsMediaSource를 만들어 MediaItem 대신 플레이어에 직접 전달하면 됩니다.

Kotlin

// Create a data source factory.
val dataSourceFactory: DataSource.Factory = DefaultHttpDataSource.Factory()
// Create a HLS media source pointing to a playlist uri.
val hlsMediaSource =
  HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri))
// Create a player instance.
val player = ExoPlayer.Builder(context).build()
// Set the HLS media source as the playlist with a single media item.
player.setMediaSource(hlsMediaSource)
// Prepare the player.
player.prepare()

Java

// Create a data source factory.
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
// Create a HLS media source pointing to a playlist uri.
HlsMediaSource hlsMediaSource =
    new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(MediaItem.fromUri(hlsUri));
// Create a player instance.
ExoPlayer player = new ExoPlayer.Builder(context).build();
// Set the HLS media source as the playlist with a single media item.
player.setMediaSource(hlsMediaSource);
// Prepare the player.
player.prepare();

매니페스트에 액세스

Player.getCurrentManifest를 호출하여 현재 매니페스트를 가져올 수 있습니다. HLS의 경우 반환된 객체를 HlsManifest로 변환해야 합니다. Player.ListeneronTimelineChanged 콜백도 매니페스트가 로드될 때마다 호출됩니다. 이 작업은 주문형 콘텐츠에 한 번, 라이브 콘텐츠에서 여러 번 발생할 수 있습니다. 다음 코드 스니펫은 매니페스트가 로드될 때마다 앱이 어떤 작업을 실행할 수 있는지 보여줍니다.

Kotlin

player.addListener(
  object : Player.Listener {
    override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) {
      val manifest = player.currentManifest
      if (manifest is HlsManifest) {
        // Do something with the manifest.
      }
    }
  }
)

Java

player.addListener(
    new Player.Listener() {
      @Override
      public void onTimelineChanged(
          Timeline timeline, @Player.TimelineChangeReason int reason) {
        Object manifest = player.getCurrentManifest();
        if (manifest != null) {
          HlsManifest hlsManifest = (HlsManifest) manifest;
          // Do something with the manifest.
        }
      }
    });

재생 맞춤설정

ExoPlayer는 앱의 요구사항에 따라 재생 환경을 맞춤설정할 수 있는 여러 방법을 제공합니다. 예시를 보려면 맞춤설정 페이지를 참조하세요.

청크 없는 준비 사용 중지

기본적으로 ExoPlayer는 청크 없는 준비를 사용합니다. 즉, ExoPlayer는 다중 변형 재생목록의 정보만 사용하여 스트림을 준비합니다. 이는 #EXT-X-STREAM-INF 태그에 CODECS 속성이 포함된 경우에 작동합니다.

미디어 세그먼트에 #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS 태그로 다중 변형 재생목록에 선언되지 않은 다중 자막 트랙이 포함된 경우 이 기능을 사용 중지해야 할 수 있습니다. 그렇지 않으면 자막 트랙이 감지 및 재생되지 않습니다. 다음 스니펫과 같이 HlsMediaSource.Factory에서 청크 없는 준비를 사용 중지할 수 있습니다. ExoPlayer에서 이러한 추가 트랙을 검색하기 위해 미디어 세그먼트를 다운로드해야 하므로 시작 시간이 늘어나며, 대신 다중 변형 재생목록에서 자막 트랙을 선언하는 것이 좋습니다.

Kotlin

val hlsMediaSource =
  HlsMediaSource.Factory(dataSourceFactory)
    .setAllowChunklessPreparation(false)
    .createMediaSource(MediaItem.fromUri(hlsUri))

Java

HlsMediaSource hlsMediaSource =
    new HlsMediaSource.Factory(dataSourceFactory)
        .setAllowChunklessPreparation(false)
        .createMediaSource(MediaItem.fromUri(hlsUri));

고품질 HLS 콘텐츠 만들기

ExoPlayer를 최대한 활용하려면 HLS 콘텐츠를 개선할 때 따라야 할 특정 가이드라인이 있습니다. 자세한 설명은 ExoPlayer의 HLS 재생에 관한 Medium 게시물을 참고하세요. 요점은 다음과 같습니다.

  • 정확한 세그먼트 길이를 사용합니다.
  • 연속적인 미디어 스트림을 사용합니다. 세그먼트 전반에서 미디어 구조를 변경하지 마세요.
  • #EXT-X-INDEPENDENT-SEGMENTS 태그를 사용합니다.
  • 동영상과 오디오를 모두 포함하는 파일보다 디믹스 스트림을 선호합니다.
  • 다중 변형 재생목록에 포함할 수 있는 모든 정보를 포함합니다.

다음 가이드라인은 특히 라이브 스트림에 적용됩니다.

  • #EXT-X-PROGRAM-DATE-TIME 태그를 사용합니다.
  • #EXT-X-DISCONTINUITY-SEQUENCE 태그를 사용합니다.
  • 긴 서비스 기간을 제공합니다. 1분 이상이면 좋습니다.