Embed an HLS adaptive streaming video

An HLS adaptive streaming video consists of various playlists (m3u8 manifests) with video segments to serve different bitrate versions depending on the internet connection of the visitor. You can let the Elastic Transcoder service in the AWS console create these manifests and video segments if you don't have the software or experience to convert a master video into HLS.
Manifests contain hardcoded links, therefore you can normally only create public video segments as opposed to the other protocols. However, there is a small loophole we found: You can keep the bucket and the files private and only make the web distribution public. That way the files remain safe in the bucket, although they are accessible via the web distribution. Because HLS exists of video segments of 10 seconds each, illegally downloading them is quite a job, therefore the risk of stealing is somewhat diminished. 

Automated hacker scripts can't get a list of items via the web distribution because an item can only be accessed when you know its name. Nor can someone embed the link to a m3u8 playlist in a player because only your site has permission to access it. So, leeching is prevented this way.

Footprint Player with VideoJS serves HLS it via HTML5 using CORS headers because Flash will be deprecated by most browsers quite soon. Contrary to the other video formats, HLS is quite complicated to set up. If you run into trouble, This email address is being protected from spambots. You need JavaScript enabled to view it. isn't far away. :-)

Setting up CORS Headers

The first thing you need to do is to follow this tutorial to set CORS headers in your bucket and web distribution in order to make access to the HLS segments HTML5 compatible. When you have done that, come back here and proceed.

How to create manifests and video segments using Elastic transcoder

Although you can create video segments with a video converter, Elastic transcoder makes life easy for you by creating the segments and the relevant manifests in one go. It also goes exceptionally quickly. So, we thought it would be worthwhile to explain how it works: What you need to start with is to have 2 buckets:

  1. A private bucket that contains the master video you want to process.
  2. A private bucket for the output of the video in segments and manifests.

Creating the buckets
Whether you have already created buckets or not, it is best to have separate buckets for HLS adaptive streaming for organizational reasons as this media type requires quite a few files. If you haven't followed the Preparations upfront for Footprint Player 1.x, please do so in order to know how to create a bucket.
To make it easy to recognize the function of each bucket later on, best use a naming convention like this:

  1. mybucket-input > used for master video's.
  2. mybucket-hls > used for video segments and m3u8 manifests.

 Create those buckets and return here. You should have something like this now:

AWS bucket list

Upload the master video

Open the mybucket-input bucket and Upload the master video to the bucket :


Click the Upload button and locate your video via the Add files button or just drag it into the folder icon:  


Then interface changes as soon as your video is selected:


Click Next (right bottom).  The following options appear:


Check that Don not grant public read access to this object(s) is selected (normally it is).
Click Next. Now you get quite a few options:


Makes sure the Standard Storage class is selected.  Other options might be tempting but are less reliable.
Scroll down until you see Encryption:


Default this is set to None, but we recommend to select Amazon S3 master-key or AWS KMS master-key.
See How to protect data with Server side AES-encryption to understand the difference between the two. We recommend for master videos to use Amazon S3 master-key since master videos are not used for embedding and you may delete them when you are done, unless you want to keep them as a backup.
Make your choice. The next Header and Tag section are not important, just click Next.  The properties for the master video are shown:


Click Upload. A progress bar shows how far the upload is evolved:


Don't navigate away from the page until it is done, although you can do other stuff on your computer in the meanwhile. Once the video is uploaded, it is automatically listed on the left. We we are going to use Elastic Transcoder of AWS to convert that video in chunks of 10 seconds which will be placed in the other bucket.

Creating a M3u8 manifest and process the video

Elastic Transcoder is an online video and audio converter with many options. Although you can use your own video editor, Elastic transcoder is very fast and creates the m3u8 manifests for you. What it involves:

  1. Create a Pipeline, which determines the input and output buckets and the Preset to use.
  2. Create a Job, to break up the video in segments and create the m3u8 manifest in one go.

If that sounds like Chinese to you, don't worry, all will be explained.

Creating a Pipeline

To find the Elastic Transcoder service (you don't need to sign up for this), you best use the Search box to find it because it changes position (and look) quite frequently.  Just type Elastic  in the search box and you'll get a list to choose from.

On the left, you see links to the Pipeline, Jobs and Presets:


Possibly, you have already Pipelines setup, which are listed on the right.  But for HLS Streaming, we need to setup a new one. Click the Create New Pipeline button. In the following screen, fill in the details as described below:

aws-create-pipeline Pipeline Name: Give this a convenient name to remember. 

Input Bucket: When you click in the field, you get a dropdown with buckets. Select the input bucket which contains your video. 

IAM Role: Leave as is. If you don't have one already, it will be created for you.

Bucket: is where the converted segments of the video and the m3u8 manifests are placed. In our example mybucket-hls.

Storage class: Standard. Other options are not useful in this case.


The next step is not strictly necessary. But if you want Elastic Transcoder to create a thumbnail for you to use as a poster image (the preview image in the player), then scroll down to designate the bucket for poster images:


This follows the same rules as previously described, except that you select the mybucket-thumbs bucket. To be honest, it is often better to create a poster image by hand and upload it to the same bucket where the video segments are located. But the method above may speed up things for you. Scroll down and on the bottom right, click on the blue Create Pipeline button. The next thing we have to do is create a Job.

Create a Job

This is where everything is going to happen. With a Job, you create the video segments and the m3u8 manifests. Click on the link Job on the left and click on the Create Job button:


In the following panel, fill in the first group of details:


Pipeline: Select the one you just created.

Output Key Prefix: Optional, but to organize HLS files properly, it is best to put them in a folder. When you fill this in, the folder is automatically created on the fly. Don't forget the trailing slash.

Input Key: Select the video by clicking in that field to open the dropdown box with existing videos in the mybucket-input bucket.

Scroll down to Output Details:

aws-create-job3 Preset: The system HLS presets are fine. Select first System preset: HLS 400k.

Segment duration: Apple recommends segments of 10 seconds. You can change that if you like, but this is the ideal length.

Output Key: Give a prefix for each segment.  Since you chose the 400 kbs bitrate preset, indicate it more or less as shown.

Segment Filename Preview: is a preview of the segment names influenced by the previous field.

Create Thumbnails: Leave it to No, this resolution is not good enough to create a poster image.

Ouput Rotation: Auto.


Now, we setup a preset for 600kbs, 1MBs, 2MBs, 4MBs. Scroll a little down until you see the +Add Another Output link:


A new group of Output Details shows up. Repeat the same as previously, but this time select System Preset HLS 600k, Segmentation: 10, Output Key: something similar like hls_600k.
Add another one and select System Preset HLS 1M, after that create the last one with System Preset HLS 2M. With this done, we create 4 formats in one go, respectively 400k, 600k, 1MB and 2MB bitrate segments, all neatly named according to the Output key prefixes. But we are not done yet with this Job. We have to create the manifests as well.
Scroll down to where you see a button Add Playlist:

Add playlist

In the following part you get the following fields:

Create playlist

Master Playlist Name: Usually we call this index since it is the master manifest which will call the others.

Playlist Format: Select HLSv3

Outputs in Master Playlist: Select first the 400k version. Now click the + sign next to that field to add the following Output:


This time, select hls_600k, then repeat this until all 4 formats are included.  This will create separate manifests for each bitrate version. Then scroll down until you see the blue Create Job button.  Click on it.
Elastic Transcoder now processes everything for you.  It shows a status of the job and all the details involved:

Job details panel

With the example video I used, which is 7 minutes in length, it took about 5 minutes. You can refresh the screen from time to time to see if it is finished yet. If the status is Complete, the job is done.
You can check the bucket, to see everything is there. Go to the S3 service and select the bucket which should contain the video segments, in this example mybucket-hls. You will notice that there is a folder with the name you designated in the Output Key Prefix. Click on the folder to open it. There should be a a whole range of .ts files and .m3u8 manifests. The one we will need is the index. m3u8 manifest to load into the player.  Since we have setup the bucket and web distribution with CORS headers, we don't have to rely on Flash, hence we don't need to create a crossdomain file.

We are ready now to embed the HLS adaptive streaming video.

Embed HLS adaptive streaming video

We provide here two methods of working of which the wizard is the easiest to start with. Select the method you want to use below:

Using the wizard

For more info about where the wizard is located ad how it works, see Using the shortcode wizards
Click the Insert Footprint Player button in the article editor. This opens the Wizard popup. As a mininum, we need to fill in:

  1. Title (title in shortcode)
  2. Media Type (mediatype in shortcode)
  3. Media File (mediafile in shortcode)
  4. Source 2 (source2 in shortcode)
  5. Web distribution (bucket in shortcode)
  6. URL expiration (expireseconds in shortcode)

Below you see highlighted the fields that are important:

wizard hls

Title is required because it is the hyperlink text. The title can contain any alphanumeric characters, including spaces. This is the only attribute that can contain spaces. For instance: Download my book. Don't place spaces anywhere else in the fields.

Media Type: Select Protected download link. or leave as is if it is already set in the default settings.

Media File is the full path to the HLS manifest. Since the video segments and manifests are all together in the same folder that we generated using Elastic Transcoder, we construct the link to the main manifest like this:  https://dxxxxx.cloudfront.net/myfolder/index.m3u8 where myfolder is replaced by the name you chose during the pricess of conversion and https://dxxxxx.cloudfront.net is the web distribution for the bucket mybucket-hls.

Source 2 is a fallaback option for HLS adaptive streaming.  Although most browsers support HLS via HTML5, some don't. If you want to make sure they are served as well, you can set the an alternative version like webm. It's easier to download a webm video, so filling in this field is a matter of choice. You might also say to your customers that Firefox or Chrome is required. In any case, don't place a webm version in the same bucket as that of the HLS segments. Consider using a bucket with a AWS KMS master-key (see How to protect data with Server side AES-encryption).
Like the Media File field, give a full path to the webm file.

URL expiration is for HLS not really necessary, but it doesn't hurt. If you use a fallback (source2 and/or source3), it is a must. This is a numerical value in seconds to create the signed URL, like expireseconds=600.
You can set this as a default in the default settings if you like.

You should now have something like this:

wizard hls3

All other attributes are explained in the default settings and Footprint Player - Short codes
Poster Image (posterimage in shortcode) might be useful if the first frame of the video isn't exactly what you like to show as a static image. So, you can prepare an image that is more interesting or explanatory and link to it via that field. If you uploaded the image to the images folder of your Joomla installation, then just give the name of the file or preceded by a folder name if appropriate. External images require the full path.

When you are ready, click Insert Shortcode. This generates the shortcode for you, like this example:

{footprint }title=My hls video about ducks|mediatye=video|mediafile=https://dxxxxxx.cloudfront.net/myfolder/index.m3u8|source2=https://danother.cloudfront.net/myvideo.webm|expireseconds=600{/footprint}

Does it work for you?

Working with Shortcode

Embedding a HLS adaptive streaming video is the same process as embedding a progressive download video with the difference that we link to a manifest playlist instead of a video directly.

Open an article and place the cursor where you want to add the video.
Note: in all shortcode examples on this site, there is a space after footprint right before the end of the opening tag. This is to prevent the extension from showing a player on this site. Therefore, remove this space on your site if you copy the shortcode from here.

{footprint }....{/footprint}

The minimum attributes you probably need are:

  1. mediatype
  2. title
  3. mediafile
  4. aspectratio
  5. posterimage
  6. expireseconds

Basic example shortcode

{footprint }mediatype=video|title=This is the title|mediafile=https://dxxxxx.cloudfront.net/myvideo.mp4|posterimage=https://.....myposter.jpg|aspectratio=16:9{/footprint}

If set as default in the default settings you can leave this out attribute out. The extension will process the shortcode anyway.

title is optional, primarily used for SEO. In later versions of Footprint Player it will  show at the top of the video area. It can contain any alphanumeric characters, including spaces. This is the only attribute that can contain spaces. Don't place spaces anywhere else in the shortcode.

mediafile is the full path to the manifest. Thus, we get:

{footprint }title=This is the title|mediatype=video|mediafile=https://dxxxxx.cloudfront.net/presentation/index.m3u8|posterimage=https://.....myposter.jpg|aspectratio=16:9{/footprint}

aspectratio is the relationship between width and height of the video. For HD, this is 16:9 and for SD 4:3. Any custom values are possible, like 160:85, 14:9 etc.
aspectratio can be set with the default settings so that you can leave them out in the shortcode. Go to Extensions > Plugin Manager and locate Content - Footprint Player to set those defaults. Below you find an example with width and aspectratio excluded:

{footprint }title=This is the title|mediatype=video|mediafile=https://dxxxxx.cloudfront.net/presentation/index.m3u8|posterimage=https://.....myposter.jpg{/footprint}

posterimage sets a poster image as the preview as you can see in the screenshot above. If omitted, you get a black rectangle instead.

expireseconds is a numerical value in seconds to create the signed URL for private video, like expireseconds=600.

Note: in this particular case, signed URLs are purely cosmetic, because the web distribution itself is public.  The player would work without it as well. That said, we recommend to use it anyway.

{footprint }title=This is the title|mediatype=video|mediafile=https://dxxxxx.cloudfront.net/presentation/index.m3u8|posterimage=https://.....myposter.jpg|expireseconds=800{/footprint}

The full list of shortcode attributes can be found here: Footprint Player - Shortcodes overview

Advanced settings

We continue to use the basic example, adding more atrributes as we go along (without source2).

Adding a watermark

Watermarks can be used sitewide or per instance. Generally, you may want to set this in the default settings, only overriding it where needed. You could have the logo of your site in the default settings, while an individual instance could have an image of a book, linking to a Buy now page. 
This attribute has a set of 3 options that go together: logologopositionlogolink. Yet, they must be divided by a | pipe character, like this:


If you only use the name of the image for the logo, the extension presumes you placed it in the images folder of your site. Subfolders are possible when you include them, like myfolder/mywatermark.png, which resort to: http://mydomain.com/images/mywatermark.png.
It is also possible to link a logo from external locations, like https://dxxxxx.coudfront.net/mywatermark.png
Note: the name watermark.png is reserved for the Dynamic watermark feature which shows the name of the user, IP address and date. This can be activated by downloading the watermark script in the download area. It is a separate script you have to place via FTP. See Dynamic watermark to prevent screen capturing.

The logoposition has 4 locations: top-left, top-right, bottom-left, bottom-right

The logolink is always full path and it can go to any page.

{footprint }mediatype=video|title=This is the title|mediafile=https://dxxxxx.cloudfront.net/presentation/index.m3u8|posterimage=https://.....myposter.jpg|expireseconds=800|aspectratio=16:9|logo=mywatermark.png|logoposition=top-left|logolink=https://mydomain.com{/footprint}

Adding Captions/Subtitles


It is possible to set multiple language versions of subtitles/captions. This has 2 options that belong together; captionslink and captionsstate, Yet, they must be divided by a | pipe character, like the logo attribute. But captionsstate can be set via the Default settings plugin. Therefore, you don't need to add it in the shortcode but you can overrule the default setting if you like.
In order for subtitles to display properly accross browsers, we need to indicate, apart from the name, the language label and the language code. Therefore, we need to use a fixed convention for the name of the subtitle file ( .vtt format only).  For example: mysubtitle-English-en where English is the label for the language and en is the language code. name, language label and language code are divided by a hyphen.

If you only use one language, this choice won't show, but best use this convention anyway.

captionsstate (1 or 0) gives the choice to have the subtitles show immediately upon play (Captions behavior), or use the subtile behavior, which requires the user to activate subtitles via the CC button. Default is 0, meaning it doesn't show up automatically. Below an example with one subtitle file:

{footprint }mediatype=video|title=This is the title|mediafile=https://dxxxxx.cloudfront.net/presentation/index.m3u8|posterimage=https://.....myposter.jpg|expireseconds=800|aspectratio=16:9|logo=mywatermark.png|logoposition=top-left|logolink=https://mydomain.com|

and here an example with 3 diferent language versions:

{footprint }mediatype=video|title=This is the title|mediafile=https://dxxxxx.cloudfront.net/presentation/index.m3u8|posterimage=https://.....myposter.jpg|

Note that multiple subtitles are divided by a comma without space. Again, note also that the .vtt extension shouldn't be included. The web tools console will give an error when the naming convention is not respected. It also gives an error is the wrong kind of subtitle file is used or if it contains errors.

If the defaults are set, ommit the last two options, like this:

{footprint }title=This is the title|mediafile=https://dxxxxx.cloudfront.net/presentation/index.m3u8|posterimage=https://.....myposter.jpg||logo=mywatermark.png|logoposition=top-left|logolink=https://mydomain.com|captionslink=mysubtitle-English-en,mysubtitle-Francais-fr,mysubtitle-Deutsch-de{/footprint}

When you are done adapting the example shortcode, save the article.  Does the video play on the front end?  Congratulations!
If not, check out below:

Trouble shooting

Problems with shortcodes when pasting

Sometimes, the added code changes into a link.  if that happens, select the link part of the shortcode and break the link because it can prevent the video from showing up since the editor added unwanted code. You recognize it when it looks like this:

{footprint }title=This is the title|mediafile=https://dxxxxx.cloudfront.net/presentation/index.m3u8|posterimage=https://.....myposter.jpg||logo=mywatermark.png|logoposition=top-left|logolink=https://mydomain.com|captionslink=mysubtitle-English-en,mysubtitle-Francais-fr,mysubtitle-Deutsch-de{/footprint}

Sometimes, the short code is partially linked.  Remove any links within the short code without removing the short code itself.

Hidden formatting in shortcode

Sometimes when you copy and paste short codes from other documents,hidden formatting may be included. The player may show up as a black rectangle or not at all. Check the short code in Code view and remove any formatting.  Or select the shortcode and push the Remove formatting icon.

File cannot be found

You made a typo in the path to the video or you forgot to include expiringseconds with a private video.

Format not accepted or a similar message

Something is wrong with the format of the video. You may need to reconvert it. 

Crossdomain access denied

It generally has nothing to do with crossdomain settings because the player doesn't use Flash the way we have set it up here. Usually a problem with permissions on AWS or a typo in the mediafile field.
This errors may stay in the cache of the browser for some time, so if you corrected the typo, it is possible that it takes a few hours to be resolved. This is an unique issue with HLS.