ExoPlayer는 여러 컨테이너 형식으로 HLS를 지원합니다. 포함된 오디오 및 동영상 샘플 형식도 지원되어야 합니다 (자세한 내용은 샘플 형식 섹션 참고). HLS 콘텐츠 제작자는 여기에 설명된 대로 고품질 HLS 스트림을 생성하는 것이 좋습니다.
기능 | 지원됨 | 비고 |
---|---|---|
컨테이너 | ||
MPEG-TS | 예 | |
FMP4/CMAF | 예 | |
ADTS (AAC) | 예 | |
MP3 | 예 | |
자막 | ||
CEA-608 | 예 | |
CEA-708 | 예 | |
WebVTT | 예 | |
메타데이터 | ||
ID3 | 예 | |
SCTE-35 | 아니요 | |
콘텐츠 보호 | ||
AES-128 | 예 | |
샘플 AES-128 | 아니요 | |
Widevine | 예 | API 19 이상 ('cenc' 스키마) 및 25 이상 ('cbcs' 스키마) |
PlayReady SL2000 | 예 | Android TV만 |
서버 제어 | ||
델타 업데이트 | 예 | |
재생목록 새로고침 차단 | 예 | |
미리 로드 힌트 로드 차단 | 예 | 길이가 정의되지 않은 바이트 범위 제외 |
실시간 재생 | ||
일반 라이브 재생 | 예 | |
지연 시간이 짧은 HLS (Apple) | 예 | |
지연 시간이 짧은 HLS (커뮤니티) | 아니요 | |
CMCD (Common Media Client Data) | 예 | 통합 가이드 |
MediaItem 사용
HLS 스트림을 재생하려면 HLS 모듈에 종속되어야 합니다.
Kotlin
implementation("androidx.media3:media3-exoplayer-hls:1.4.1")
Groovy
implementation "androidx.media3:media3-exoplayer-hls:1.4.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()
자바
// 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
로 끝나지 않으면 MediaItem.Builder
의 setMimeType
에 MimeTypes.APPLICATION_M3U8
를 전달하여 콘텐츠 유형을 명시적으로 표시할 수 있습니다.
미디어 항목의 URI는 미디어 재생목록 또는 다중 변형 재생목록을 가리킬 수 있습니다. URI가 여러 #EXT-X-STREAM-INF
태그를 선언하는 다중 변형 재생목록을 가리키는 경우 ExoPlayer는 사용 가능한 대역폭과 기기 기능을 모두 고려하여 변형 간에 자동으로 조정합니다.
HlsMediaSource 사용
더 많은 맞춤설정 옵션을 사용하려면 MediaItem
대신 HlsMediaSource
를 만들어 플레이어에 직접 전달하면 됩니다.
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()
자바
// 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.Listener
의 onTimelineChanged
콜백은 매니페스트가 로드될 때마다 호출됩니다. 주문형 콘텐츠의 경우 한 번, 라이브 콘텐츠의 경우 여러 번 발생할 수 있습니다. 다음 코드 스니펫은 매니페스트가 로드될 때마다 앱이 어떤 작업을 실행할 수 있는지 보여줍니다.
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. } } } )
자바
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))
자바
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분 이상이면 좋습니다.