Saturday, August 1, 2020

Streaming Media using Http Live Streaming (HLS)


Streaming media is a process in which media is played at the same time as media is downloaded. 

Streaming can be made either from a file or directly from the devices. 

Examples of streaming from file include shows and content distribution from a recorded file. Examples of streaming from devices include creating a live feed from your cameras such as using Facebook or youtube app on your phone or more professionally, the high-end recording camera that is used in broadcasting sports, news events, etc. 

Streaming over the internet is commonly done using HTTP Live Streaming, commonly known as (HLS). Another alternative is to use MPEG-DASH or Smooth Streaming which are not subject of this post. In this article, I will go over a basic example of how to make a prototype HLS setup using commonly available tools and techniques from a general purpose computer using systems, namely Windows 10 and macOS Catalina.

Architecture


HLS uses a web server to distribute the media content. The media content is segemented into a multiple chunks or more commonly segments and an index file, often called playlist. The index file (with extension .m3u8) enumerate all the chunks. The segments are typically in MPEG-2 TS file (.ts files). The server accepts requests from the client for mime-type of mpegurl  matching the TS and delivers playlist and segments needed for streaming. The client, typically an HSL player requests and download the segments and plays the media file. 

The playback is driven by a playlist (file with extension .m3u8) and segments (file with extension .ts). For example, a playlist could look like the following where individual segments indicated by .ts are defined  
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:17
#EXTINF:16.733333,file000.ts
#EXTINF:8.333333,file001.ts
#EXTINF:5.033333,file002.ts
#EXT-X-ENDLIST
Tools and Software and Setup

FFmpeg, a common opensource software can be used to transcode a file and to generate content for HLS. One can chose to use Apache server for MacOS or Internet Information Services (IIS) server in Windows 10. One can always create server and serve the content, but this woudl be beyond the scope of this post.  

In order to be able to stream the content, we need to enable certain mpegurl mimetype (Multipurpose Internet Mail Extensions) type to the server so that .m3u8 can be served. In addition, the ts (segments) support must also be added to the server. 

I am using Apache server  in macOS and IIS in Windows machine. In macOS, in Apache, add the following in the /etc/apache2/mime.types:

  • application/vnd.apple.mpegurl m3u8
  • video/mp2t ts
For windows, in IIS Manager, support for m3u8 can be added by going to mimetypes. If the list already contains an entry for .m3u8, ignore this step.The .mp2 extension representing the mime-type of video/mpeg is inherited automatically in IIS. If .mp2 is present in the list of mime types, add one entry for the same. 

To install ffmpeg in mac OS, I used homebrew. First I installed dependencies and then ffmpeg using the following commands in the terminal.  
brew install nasm pkg-config texi2html aom fontconfig freetype frei0r gnutls lame libass libbluray libsoxr libvorbis libvpx opencore-amr openjpeg opus rtmpdump rubberband sdl2 snappy speex tesseract theora x264 x265 xvid xz
brew install ffmpeg

For Windows, an installer matching the specificaiton can be used. For example, I got the installer for windows 64 bit from https://ffmpeg.org/download.html and worked through it.


Create playlist and segments

ffmpeg can be used to encode the media and create segments. This also creates the playlist


ffmpeg
   -i file.mp4   -map 0   -codec:v libx264   -codec:a aac   -f ssegment   -segment_list file.m3u8   -segment_list_flags +live   -segment_time 10   file%03d.ts

In the command above, the ffmpeg is called with parameters that specifies the input with -i file.mp4 (file name). Arguments -codec:v and -codec:a are for encoding video and audio respectively. It is often common to keep the audio and video codec same as original which can be achived by using 'copy' for -codec. The ssegement specifies the length of each segment. Typically, a 5-7 second chunks are ideal. However, for some adavance anlaysis, a longer may be suitable. Note that larger the chunk size, more time is needed to download the content. 

For example, I have a file named file.mp4 which is of 40 seconds duration and when I run a command to make HLS with chunk size of 5 secconds, the output a list of files where one is of extension .m3u8 and rest of the files are of .ts extension. For this case, we will have one m3u8 file and 8 .ts files. 

Serve Media
Now that the appropriate files have been created, it is time to put these files into server and serve up. 

Copy the generated files, i.e., the file with .m3u8 and all the .ts file to the document folder of the webserver. For simplicity, I am putting the file in the root folder.


Browse/Play Media

Use a client, an http live streaming capable player such as VLC or chrome browser extension and navigate to localhost/file.m3u8. you have now successfully started streaming the media using HSL.


Reference
  • FFmpeg. A complete, cross-platform solution to record, convert and stream audio and video