HLS Protocol in Video Surveillance; How It Works with Viinex

When creating and developing our embedded video system we at Viinex from the very beginning were aiming at web technologies and full compatibility with HTML5. That’s why the first thing we did was adding HLS (HTTP Live Streaming) video streaming protocol support. It happened in the end of 2016, simultaneously with development of embedded web server for accessing the media data and managing Viinex via HTTP RESTful API. Back then it was a minimum basic functionality that Viinex had: receiving video, recording and HLS streaming.

At the time, in summer and fall of 2016, we were facing a pretty hard choice: what should we use as a basic video streaming protocol for the first release: robust HLS or thriving MPEG DASH, while the latter seemed to us easier for implementation. We have chosen HLS.
Looking back and analyzing the past we are glad we have made the right choice, since HLS is still the most popular video streaming protocol – both by our estimates and according to numerous reports from the companies that professionally develop video solutions and platforms.

Since Apple presented HLS in 2009, so many articles and opinions have been published that it seems hard to tell anything new about the protocol itself. That’s why this article mostly refers to how our product works with HLS. The protocol had a number of advantages. From client’s side it allowed to work on configured infrastructure aimed at work with HTTP traffic, which is important for last mile administrators. It was also convenient for developers – it required no difficult modification of browsers and offered a possibility to use common web services like Apache HTTP Server. What we have at the moment – the protocol is supported by almost all platforms and browsers and can be played back practically on any device, it is reliable and time proved, easily integrated when developing web services.

Viinex supports HLS protocol both for streaming video archives and online video. In both cases the solution works by a process of client receiving the video chunks, duration of which can be set on Viinex server side, and later these chunks are put together by a client so the user can enjoy a seamless playback.

The picture below shows the workflow of interaction with Viinex web server to receive video stream. To get new video chunks, an application in user’s browser which is received from your web server, periodically updates data in M3U8 format according to HLS specification, which provides the user with constantly added list of video chunks.

If it is necessary to adapt the video stream to user’s needs – like reducing frame rate or resolution using a renderer object included in Viinex or switching a camera to other ONVIF profile – Viinex API allows to create temporary copies of video stream with specified settings. Temporary video streams can be deleted when they are no longer needed – for instance, when a session of work with the user that requested the video stream is over. Below you can find an extended version of a diagram showing this aspect.

The mechanism of video streaming in HLS is based on consecutive playback of video chunks that are downloaded from the links specified in playlist. In accordance with HLS specification to start playing each playlist the media player has to buffer not less than three video chunks, which leads to some latency while watching a live video stream. Length of every chunk defines possible latency. To lower this latency the duration of video chunks can be reduced, but that adds some risk of missing some video fragments. Since the length of the video chunk is the time we have to download the next chunk, the more time we have, the more chances there are that everything downloads properly. And if not – the respective chunk will not be shown to the user. In unstable networks, where bandwidth capacity may vary, like a cellular network, there’s a higher possibility that we’ll need more time to download the next chunk than playing all the chunks we have already downloaded can take.

We at Viinex managed to get a minimal latency of 2-3 seconds by means of reducing a chunk duration and playlist length as an experiment. Needless to say, we do not recommend these test settings – on the contrary, it’s better to use Apple default settings. Besides, it’s important that video source coder worked in a certain way: we define HLS chunks by GOP (group of pictures). So when key frames come once in 30 seconds – like, for instance, Axis cameras in zipstream mode do – the chank will be at least 30 seconds long. That’s why all these attempts to lower HLS latency are possible not with just any camera settings.

Actually, initially HLS was made for another task, and it is solved using video buffering by a browser. To provide video streaming with minimum latency and no issues it’s better to use another standard – WebRTC – which we have also added to Viinex, but that’s a different story.

Hls is still being developed, at WWDC 2019 an extension of the protocol was announced (a preliminary specification for Low Latency HLS) that allows for transmitting media data with low latency.

As we mentioned earlier, HLS has an apparent advantage of easy integration and work of client application with Viinex server, both with live video and video archive (search, playback, stop, pause, etc.). It covers all its video surveillance related tasks by far. In real-case scenario after Viinex server is installed we need to connect a camera (cam 1 in our case) and create a simple HTML file in accordance with HTML5 specification. Here’s an example:

<!DOCTYPE html>



<title>A simple example of HLS streaming based on Viinex Video Management SDK</title>



<video id="livevideo" controls>

<!-- IP address, port and path to the video stream -->

<source src="" />


<script src="hls.min.js"></script>


var isAndroid = /(android)/i.test(navigator.userAgent);

function startLive(videoElementId, cameraName)


  if(Hls.isSupported()) {

    var video = document.getElementById(videoElementId);

    var hls = new Hls();



    hls.on(Hls.Events.MANIFEST_PARSED,function() {


        video.controls = false;






if(Hls.isSupported()) {


  document.write("Playback via hls.js<br/>");


else {

  document.write("Native iOS HLS playback");





This works even without JavaScript in a simpler Safari browser, but all the rest need a short JavaScript code for HLS playback.

Leave a Reply