xref: /aosp_15_r20/external/exoplayer/tree_8e57d3715f9092d5ec54ebe2e538f34bfcc34479/docs/hls.md (revision 30877f796caf59d855b10b687a5d6b3918d765cb)
1---
2title: HLS
3---
4
5{% include_relative _page_fragments/supported-formats-hls.md %}
6
7## Using MediaItem ##
8
9To play an HLS stream, you need to depend on the HLS module.
10
11~~~
12implementation 'com.google.android.exoplayer:exoplayer-hls:2.X.X'
13~~~
14{: .language-gradle}
15
16You can then create a `MediaItem` for an HLS playlist URI and pass it to the
17player.
18
19~~~
20// Create a player instance.
21ExoPlayer player = new ExoPlayer.Builder(context).build();
22// Set the media item to be played.
23player.setMediaItem(MediaItem.fromUri(hlsUri));
24// Prepare the player.
25player.prepare();
26~~~
27{: .language-java}
28
29If your URI doesn't end with `.m3u8`, you can pass `MimeTypes.APPLICATION_M3U8`
30to `setMimeType` of `MediaItem.Builder` to explicitly indicate the type of the
31content.
32
33The URI of the media item may point to either a media playlist or a multivariant
34playlist. If the URI points to a multivariant playlist that declares multiple
35`#EXT-X-STREAM-INF` tags then ExoPlayer will automatically adapt between
36variants, taking into account both available bandwidth and device capabilities.
37
38## Using HlsMediaSource ##
39
40For more customization options, you can create a `HlsMediaSource` and pass it
41directly to the player instead of a `MediaItem`.
42
43~~~
44// Create a data source factory.
45DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory();
46// Create a HLS media source pointing to a playlist uri.
47HlsMediaSource hlsMediaSource =
48    new HlsMediaSource.Factory(dataSourceFactory)
49        .createMediaSource(MediaItem.fromUri(hlsUri));
50// Create a player instance.
51ExoPlayer player = new ExoPlayer.Builder(context).build();
52// Set the media source to be played.
53player.setMediaSource(hlsMediaSource);
54// Prepare the player.
55player.prepare();
56~~~
57{: .language-java}
58
59## Accessing the manifest ##
60
61You can retrieve the current manifest by calling `Player.getCurrentManifest`.
62For HLS you should cast the returned object to `HlsManifest`. The
63`onTimelineChanged` callback of `Player.Listener` is also called whenever
64the manifest is loaded. This will happen once for a on-demand content, and
65possibly many times for live content. The code snippet below shows how an app
66can do something whenever the manifest is loaded.
67
68~~~
69player.addListener(
70    new Player.Listener() {
71      @Override
72      public void onTimelineChanged(
73          Timeline timeline, @Player.TimelineChangeReason int reason) {
74        Object manifest = player.getCurrentManifest();
75        if (manifest != null) {
76          HlsManifest hlsManifest = (HlsManifest) manifest;
77          // Do something with the manifest.
78        }
79      }
80    });
81~~~
82{: .language-java}
83
84## Customizing playback ##
85
86ExoPlayer provides multiple ways for you to tailor playback experience to your
87app's needs. See the [Customization page][] for examples.
88
89### Disabling chunkless preparation ###
90
91By default, ExoPlayer will use chunkless preparation. This means that ExoPlayer
92will only use the information in the multivariant playlist to prepare the
93stream, which works if the `#EXT-X-STREAM-INF` tags contain the `CODECS`
94attribute.
95
96You may need to disable this feature if your media segments contain muxed
97closed-caption tracks that are not declared in the multivariant playlist with a
98`#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS` tag. Otherwise, these closed-caption tracks
99won't be detected and played. You can disable chunkless preparation in the
100`HlsMediaSource.Factory` as shown in the following snippet. Note that this
101will increase start up time as ExoPlayer needs to download a media segment to
102discover these additional tracks and it is preferable to declare the
103closed-caption tracks in the multivariant playlist instead.
104~~~
105HlsMediaSource hlsMediaSource =
106    new HlsMediaSource.Factory(dataSourceFactory)
107        .setAllowChunklessPreparation(false)
108        .createMediaSource(MediaItem.fromUri(hlsUri));
109~~~
110{: .language-java}
111
112## Creating high quality HLS content ##
113
114In order to get the most out of ExoPlayer, there are certain guidelines you can
115follow to improve your HLS content. Read our [Medium post about HLS playback in
116ExoPlayer][] for a full explanation. The main points are:
117
118* Use precise segment durations.
119* Use a continuous media stream; avoid changes in the media structure across
120  segments.
121* Use the `#EXT-X-INDEPENDENT-SEGMENTS` tag.
122* Prefer demuxed streams, as opposed to files that include both video and audio.
123* Include all information you can in the Multivariant Playlist.
124
125The following guidelines apply specifically for live streams:
126
127* Use the `#EXT-X-PROGRAM-DATE-TIME` tag.
128* Use the `#EXT-X-DISCONTINUITY-SEQUENCE` tag.
129* Provide a long live window. One minute or more is great.
130
131[HlsMediaSource]: {{ site.exo_sdk }}/source/hls/HlsMediaSource.html
132[HTTP Live Streaming]: https://tools.ietf.org/html/rfc8216
133[Customization page]: {{ site.baseurl }}/customization.html
134[Medium post about HLS playback in ExoPlayer]: https://medium.com/google-exoplayer/hls-playback-in-exoplayer-a33959a47be7
135