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