Radiant Media Player

Low latency live HLS streaming

Mobile applications documentation

What is latency in live media streaming and why HLS is not good at low-latency streaming

Latency in the context of live media streaming is the delay (generally expressed in seconds or milliseconds) between a timestamp in a live event and the moment when viewers consume this timestamp. High-latency in live media streaming is generally not a good thing: imagine a soccer game where you could only watch a goal 1 minute after it happened ... Twitter and Facebook updates are likely to spoil the suspense for you!

In the broadcasting industry (read traditional TV industry) years of experience and well-established processes have helped reduced latency to near-zero and there is no-reason why the online streaming media industry could not come up with such low-latency solutions.

When Flash was still a valid option for media playback in the online video world the RTMP Flash-specific protocol could help us stream with low-latency. As Flash is now no longer a viable option, we cannot use the RTMP protocol as a delivery protocol anymore. Most adaptive bitrate streaming is done with HLS those days, since it is the de-facto standard for reaching mobile devices and it also works well on a wide array of devices from desktop computers to set-top boxes.

Typical reasons for latency in today's HLS streaming include:

  • encoding/transcoding of media content, be it at origin point or on the server
  • distribution (packaging, CDN)
  • network congestion at origin point or last-mile
  • playback buffer requirements for HLS

As of mid-2017 Apple recommends a default of 10-second content chunks and a certain number of packets to create a meaningful playback buffer. This results in about 30 seconds of end-to-end delay from origin to viewers. Add a CDN to the party (which you should want for proper scaling) and you could navigate the 60 seconds latency waters ... so if you have a 45 seconds latency with your live HLS stream, you are within range of current industry standards for "classic" latency HLS.

How to produce low-latency live HLS streams?

You need to tune your streaming chain to achieve low-latency streaming with HLS. Most optimisations happen on the server. You can refer to your transcoder or streaming server manual for more information on how to best tune it for low-latency streaming with HLS. If you are a Wowza customer this guide will help you improve latency of HLS streams. You can also review this link for reference information even if you do not use Wowza software.

There are also a few player settings we can play with to improve latency but before we go any further one must ask this question: do you need low-latency streaming? There are cons that you must be aware of when setting-up a low-latency solution with HLS:

  • CPU/GPU requirements on the streaming server/transcoder are higher to achieve low-latency HLS live streaming (thus the cost of maintaining such solutions is also higher)
  • The risk of buffer stalls (stream interruption for buffering purposes), either server-side or client-side, is also higher
  • Older or low-end devices (typically older iOS and Android versions) do not cope well with reduced HLS chunks duration and user-experience may not be great on such devices

If you are sure low-latency streaming is for you then read on.

In our testing we used a low-latency tuned Wowza server receiving a signal from a FFmpeg-based transcoder, transcoding a 720p webcam recording into 3 renditions (720p at 2200 kbps, 540p at 1500 kbps, 360p at 600 kbps). We used 1 key-frame per second for transcoding each of our renditions and used a 1 second HLS chunk duration as explained in the above Wowza guide. We also used a CDN (Amazon Cloud Front) during our testing to make sure it would be relevant to a large scale deployment.

Knowing the above we used the below player code for our testing:

<!-- Include Radiant Media Player JavaScript file in your <body> or <head> -->
<script src="https://cdn.radiantmediatechs.com/rmp/4.3.9/js/rmp.min.js" 
<!-- Set up your wrapper div with its unique id -->
<div id="rmpPlayer"></div>
<!-- Set up player configuration options -->
var bitrates = {
  hls: 'live-streaming-url-optimised-for-low-latency'
var settings = {
  licenseKey: 'your-license-key',
  bitrates: bitrates,  
  delayToFade: 3000,
  width: 640,
  height: 360,
  // Here we have our relevant low-latency settings
  isLive: true,
  // We set a 12 seconds buffer target (playlist chunk count x chunk duration)
  hlsJSMaxBufferLength: 12,
  // We set hlsJSLiveSyncDuration to the minimal possible duration (3 x chunk duration)
  hlsJSLiveSyncDuration: 3,
  poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg'
// Reference to the wrapper div (unique id)
var elementID = 'rmpPlayer';
// Create an object based on RadiantMP constructor
var rmp = new RadiantMP(elementID);
// Initialization ... test your page and done!

We let our test run for over an hour and tested on various browsers and mobile devices, while frequently refreshing our test page, to insure we had consistent results. At best we were able to reach and maintain a 5 seconds latency for our live HLS test stream. On iOS and macOS Safari where we use native HLS playback in HTML5 video (as opposed to Media Source Extensions) latency was more in the 10 seconds range.