How to Play HLS Live Stream using ExoPlayer

27 / Jul / 2016 by Asif Khan 0 comments

In the previous blog, we have discussed the basics of Android ExoPlayer, advantages & disadvantages. You can find its link here Introduction to Android ExoPlayer.

In this blog, we are going to learn how to play live stream using ExoPlayer. We will be using HLS (HTTP Live Streaming) technology as communication protocol to serve the multimedia content. HLS is an adaptive streaming communications protocol. At first lets discuss adaptive streaming since it is used in HLS.

Adaptive Streaming:
Adaptive streaming provides the multiple bit-rate streams to end users. Best stream get played at user’s end, which is decided by client player on the basis of some parameters like client computational capacity (CPU), internet bandwidth and memory utilization. Adaptive streaming provides the best user experience.

HLS_streaming

The Index File .m3u8 contains the index of all different version streams and manages the continuity and consistency of streams during playback. Hence for adaptive streaming it choses the files from low, medium or high resolution w.r.t. internet connection and indexes of those files are provided by .m3u8 file. This is the brief introduction of HLS, now jump directly to the implementation of ExoPlayer.

Implementation:
ExoPlayer supports HLS adaptive playbacks through use of HlsSampleSource. ThisHlsSampleSource loads chunks of media data and from that chunk of data individual samples are extracted.

HlsSampleSource is a SampleSource for HLS streams. This class contains various constructors & methods which are very effective in media playback. Some of them are listed below-

Methods:
continueBuffering(int track, long playbackPositionUs)
Indicates to the source that it should still be buffering data for the specified track.

disable(int track)
Disable the specified track.

enable(int track, long positionUs)
Enable the specified track.

getBufferedPositionUs()
Returns an estimate of the position up to which data is buffered.

getFormat(int track)
Returns the format of the specified track.

getTrackCount()
Returns the number of tracks exposed by the source.

Constructors:
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, MAIN_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE);

Hence its clear from the constructor that HlsSampleSource needs HlsChunkSource and for HlsChunkSource we need DataSource. Refer to below figure:

Object model for HLS playbacks using ExoPlayer

HlsChunkSource is a temporary test source for HLS chunks. It contains chunks of video and audio before it is passed to HlsSampleSource.

Now we will see the code based implementation-

  1. LoadControl loadControl = new DefaultLoadControl(new DefaultAllocator(BUFFER_SEGMENT_SIZE));
  2. DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
  3. PtsTimestampAdjusterProvider timestampAdjusterProvider = new PtsTimestampAdjusterProvider();
  4. DataSource dataSource = new DefaultUriDataSource(context, bandwidthMeter, userAgent);
  5. HlsChunkSource chunkSource = new HlsChunkSource(true /* isMaster */, dataSource, url, manifest, DefaultHlsTrackSelector.newDefaultInstance(context), bandwidthMeter, timestampAdjusterProvider, HlsChunkSource.ADAPTIVE_MODE_SPLICE);
  6. HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl, MAIN_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE);
  7. MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(context, sampleSource, MediaCodecSelector.DEFAULT, MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
  8. MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource, MediaCodecSelector.DEFAULT);

Description:
In Line 1, LoadControl object is created and BUFFER_SEGMENT_SIZE is provided in the constructor. By default we keep this value as  64*1024.

In Line 2 & 3, DefaultBandwidthMeter & PtsTimestampAdjusterProvider objects are created which will be needed in the Renderer implementation.

In Line 4, DataSource object is created by passing context, bandwidthMeter object and userAgent. For obtaining userAgent we can use below code-

String userAgent = Util.getUserAgent(this, "ExoPlayerDemo");

In Line 5, HlsChunkSource object is created via DataSource object and in Line 6, HlsSampleSource object is created via HlsChunkSource object.

Now in Line 7 & 8, we can get the objects of MediaCodecVideoTrackRenderer & MediaCodecAudioTrackRenderer with the SampleSource object.

For more understanding you can refer to the sample project, which is the modified version of standard google exoplayer project:

https://github.com/asifkhan11/ExoPlayer-Demo

In this sample you just need to enter the url which needs to be played and it starts playing seamlessly.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *