hls, Video HTML streaming

HLS – encrypting and playing video

This solution works for all common web browsers including Internet Explorer, Microsoft Edge, Google Chrome (PC, Android), Mozilla Firefox, Safari (Mac, iOS). It will not work on IE on Windows 7 and less. It took me a lot of time to create working player for encrypted HLS. I you already have encrypted HLS video, click here for creating cross browser video player. Here is how I created encrypted HLS files from source.mp4 (choose your own key and key URL).

key: 617D8A125A284DF48E3C6B1866348A3F

You need these files:
key.bin – binary file representing key
key.info – text file with key information
master.m3u8 – text file with information about HLS sources

key.info file:

http://localhost:52523/api/hlskey
key.bin

note: The player will send GET request for key to this url http://localhost:52523/api/hlskey. On third line in this file can be IV.

Here is an example of implementation of HlsKeyController in C#:

public class HlsKeyController : ApiController
   {
      [HttpGet]
      [ActionName("get")]
      public HttpResponseMessage Get()
      {
         var response = Request.CreateResponse(HttpStatusCode.OK);
         response.Content = new ByteArrayContent(Guid.Parse("617D8A125A284DF48E3C6B1866348A3F").ToByteArray());
         response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
         return response;
      }
   }

master.m3u8 file:

#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="eng",NAME="English",AUTOSELECT=YES,DEFAULT=YES,URI="audio/stream.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=500000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=426x240,AUDIO="audio"
video240/stream.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1000000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=640x360,AUDIO="audio"
video360/stream.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1500000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=852x480,AUDIO="audio"
video480/stream.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2000000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=1280x720,AUDIO="audio"
video720/stream.m3u8

note: output is generated in .\hls directory

Here is a run.bat file. You will need this tool:
ffmpeg

mkdir hls\video720
mkdir hls\video480
mkdir hls\video360
mkdir hls\video240
mkdir hls\audio

ffmpeg -y -i source.mp4 -an -c:v libx264 -preset veryslow -profile:v high -level 4.2 -b:v 2000k -minrate 2000k -maxrate 2000k -bufsize 4000k -g 96 -keyint_min 96 -sc_threshold 0 -filter:v "scale='trunc(oh*a/2)*2:720'" -pix_fmt yuvj420p -hls_time 5 -hls_key_info_file key.info -hls_playlist_type vod -hls_segment_filename "hls\video720\fileSequence%%d.ts" hls\video720\stream.m3u8 ^
-an -c:v libx264 -preset veryslow -profile:v high -level 4.2 -b:v 1500k -minrate 1500k -maxrate 1500k -bufsize 3000k -g 96 -keyint_min 96 -sc_threshold 0 -filter:v "scale='trunc(oh*a/2)*2:480'" -pix_fmt yuvj420p -hls_time 5 -hls_key_info_file key.info -hls_playlist_type vod -hls_segment_filename "hls\video480\fileSequence%%d.ts" hls\video480\stream.m3u8 ^
-an -c:v libx264 -preset veryslow -profile:v high -level 4.2 -b:v 1000k -minrate 1000k -maxrate 1000k -bufsize 2000k -g 96 -keyint_min 96 -sc_threshold 0 -filter:v "scale='trunc(oh*a/2)*2:360'" -pix_fmt yuvj420p -hls_time 5 -hls_key_info_file key.info -hls_playlist_type vod -hls_segment_filename "hls\video360\fileSequence%%d.ts" hls\video360\stream.m3u8 ^
-an -c:v libx264 -preset veryslow -profile:v high -level 4.2 -b:v 500k -minrate 500k -maxrate 500k -bufsize 1000k -g 96 -keyint_min 96 -sc_threshold 0 -filter:v "scale='trunc(oh*a/2)*2:240'" -pix_fmt yuvj420p -hls_time 5 -hls_key_info_file key.info -hls_playlist_type vod -hls_segment_filename "hls\video240\fileSequence%%d.ts" hls\video240\stream.m3u8 ^
-vn -acodec aac -ab 128k -hls_time 1 -hls_key_info_file key.info -hls_playlist_type vod -hls_segment_filename "hls\audio\fileSequence%%d.ts" hls\audio\stream.m3u8

copy master.m3u8 hls\master.m3u8

If you wish to use this commands in CMD instead of calling run.bat file, please replace “fileSequence%%d” with “fileSequence%d”. Otherwise It will not work. Now you have created encrypted files for HLS and you can now play it in web browser using JavaScript.

You will need this library:
hls.js

Here is example of index.html file:

<html>
<head>
   <title></title>
   <meta charset="utf-8"   />
   <script src="Static/js/hls.js"></script>
   <script src="Static/js/test.js"></script>
</head>
<body>
   <video id='example-video'  controls>
      <source src="hls/master.m3u8" type="application/x-mpegURL" />
      Your browser does not support the HLS video or the video tag.
   </video>
</body>
</html>

Here is example of my test.js file:

$(document).ready(function () {
   if (Hls.isSupported()) {
      var video = document.getElementById('example-video');
      var hls = new Hls();
      hls.loadSource('hls/master.m3u8');
      hls.attachMedia(video);
      hls.on(Hls.Events.MANIFEST_PARSED, function () {
         video.play();
      });
   }
});

I hope this will help somebody. I was doing research for HLS and it took me a lot of time to understand this. If you don’t understand this or there is something wrong, leave a comment.

Note: For adding quality options (buttons) to videojs player, click here. Videojs player has some problems with Safari on MacOS. Recommending creating your own video player.
For adding watermarks to your video, click here.