ExoPlayer는 여러 컨테이너 형식으로 HLS를 지원합니다. 포함된 오디오 및 동영상 샘플 형식도 지원되어야 합니다 (자세한 내용은 샘플 형식 섹션 참고). Google에서는 HLS 콘텐츠 제작자가 여기에 설명된 대로 고품질 HLS 스트림을 생성할 것을 적극 권장합니다.
기능 | 지원됨 | 댓글 |
---|---|---|
컨테이너 | ||
MPEG-TS | 예 | |
FMP4/CMAF | 예 | |
ADTS (AAC) | 예 | |
MP3 | 예 | |
자막 | ||
CEA-608 : CEA-608 | 예 | |
CEA-708 : CEA-708 | 예 | |
WebVTT | 예 | |
Metadata | ||
ID3 | 예 | |
SCTE-35 | NO | |
콘텐츠 보호 | ||
AES-128 | 예 | |
샘플 AES-128 | NO | |
Widevine | 예 | API 19 이상 ('cenc' 체계) 및 25 이상 ('cbcs' 체계) |
PlayReady SL2000 | 예 | Android TV만 |
서버 제어 | ||
델타 업데이트 | 예 | |
차단 재생목록 새로고침 | 예 | |
미리 로드 힌트의 차단 로드 | 예 | 길이가 정의되지 않은 바이트 범위 제외 |
실시간 재생 | ||
일반 라이브 재생 | 예 | |
지연 시간이 짧은 HLS (Apple) | 예 | |
지연 시간이 짧은 HLS (커뮤니티) | NO | |
CMCD (Common Media Client Data) | 예 | 통합 가이드 |
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_M3U8
를 MediaItem.Builder
의 setMimeType
에 전달하여 콘텐츠 유형을 명시적으로 나타낼 수 있습니다.
미디어 항목의 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.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. } } } )
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 재생에 관한 중간 게시물을 참고하세요. 주요 요점은 다음과 같습니다.
- 정확한 세그먼트 길이를 사용합니다.
- 연속적인 미디어 스트림을 사용합니다. 세그먼트 간에 미디어 구조를 변경하지 마세요.
#EXT-X-INDEPENDENT-SEGMENTS
태그를 사용합니다.- 동영상과 오디오를 모두 포함하는 파일보다는 역다중화된 스트림을 사용합니다.
- 다중 변형 재생목록에 포함할 수 있는 모든 정보를 포함합니다.
다음은 라이브 스트림에만 적용되는 가이드라인입니다.
#EXT-X-PROGRAM-DATE-TIME
태그를 사용합니다.#EXT-X-DISCONTINUITY-SEQUENCE
태그를 사용합니다.- 긴 수명 기간을 제공합니다. 1분 이상은 좋습니다.