VOD

Learning Outcomes

  • Understand dynamic packaging workflow
  • Understand types of deployment
  • Knowledge of advanced features

Diagram

../_images/origin.png

Schematically

@startditaa

      /--------+     GET      /----------------+
      | origin | <----------  |hds,hls,hss,dash|
      +--------/              +----------------/
          |
          |
 +-----------------+
 |{s}              |
 | (http) storage  |
 | (mp4, fmp4, hls)|
 +-----------------+

@endditaa

Use Cases

Unified Origin dynamically packages media on-the-fly into the output requested by the player client-side.

The origin supports the following formats:

Format Input Output Notes
CMAF y n  
HDS n y  
HLS y y Ingest only when requirements are met
HSS/MSS/Smooth y y  
MP4 y y Progressive download and Download to Own
MPEG-DASH y y  

Streaming a title from a content library using Unified Origin VOD requires the original source content and a server manifest. The client manifest and media content is created dynamically, all formats are produced from the one stored format.

Streaming Content Explained

A server manifest is a file that references media content. It can contain additional information about the content and lists the locations of all available video, audio and text tracks. It is created with Unified Packager.

Important: Only the source content and the server manifest are stored on disk. Both the client manifest and the media are generated on-the-fly, based on the client request.

Manifests are necessary because, typically, ABR content consists of multiple fragmented MP4 files. While it is possible to use MP4 we recommend fragmented MP4, especially for large files.

The server manifest must be generated beforehand and is used by Origin, the client manifests are created dynamically and are used by players. The server manifest references the source content, while client manifests reference the content in the playout format.

Encoding

H.264 Base, Main and High profile may be used. Mixing profiles is possible, but care must be taken so that the different GOPs of the ABR set align.

The key frame interval (GOP size) should be two seconds using a closed GOP. This segment size of two seconds is optimal for fast bitrate adaptation and efficient encoding.

UHD/4K/HDR

Other supported codecs include HEVC, with HDR, Dolby Vision and HLG and various multichannel audio formats (DTS, Dolby and HE-AAC). See the factsheet for a comprehensive list [3]

In fact, Unified Origin will serve Apple 4K devices (tvOS), Xbox and Android (DASH) giving viewers a full UHD experience dynamically, by just-in-time packaging the content.

Dynamic Manifests

Using the IsmProxyPass keyword it is possible to specify a proxy from where the origin fetches the server manifest.

This allows for dynamically updating options such as DRM settings or encryption keys.

Schematically

@startditaa

      /---+    GET     /--------+     GET     /--------------+
      |CMS| <--------- | origin | <---------- |client request|
      +---/            +--------/             +--------------/
    video.ism         IsmProxyPass

@endditaa

In Apache:

<Location "/proxy" >
  IsmProxyPass http://other-server/
</Location>

How it works

When IsmProxyPass is present, the webserver module requests the server manifest file from the server specified by the URL.

For example, a request for:

http://${aws_hostname}/proxy/alvin/alvin.ism/alvin.m3u8

would proxy the request via the Location directive to the ‘other-server’ as follows:

http://other-server/alvin/alvin.ism

All URLs with ‘proxy’ in the path will map to the ‘other-server.’ Please note that ‘proxy’ is just a word, another word can be used too!

Please note the trailing / http://other-server/ used for IsmProxyPass is mandatory.

The directive should be in the vhost config: /etc/apache2/sites-enabled/vhost.conf and not the global webserver config, /etc/apache2/apache2.conf.

Note

In Storage Proxy you can find more details: caching, headers and latency are discussed in more depth there.

Playout Control

Some devices cannot play certain types of video or audio, mostly because they do not support certain codecs. However packaging all the videos with different codecs in one server manifest may not the best approach.

Here are some different approaches to such a use case: [1]

  • Create different manifests for the various devices
  • Use dynamic manifest creation for manifest creation (for instance updating tracks when content is added e.g. subtitles or changing DRM keys)
  • Use dynamic track selection to select only the tracks required
  • Use a rewrite map to hide the complex track selection url
  • In HLS, use variants and groups to define order
  • It’s also possible to emulate IIS and strictly passthrough any content requested (HSS only)

Note that according to the DASH and HSS specifications, the order in which tracks are presented in the client manifest has no meaning. Players are expected to use their own logic when selecting a track. This is different for HLS, where the specification does add meaning to the order in which variants are presented in the Master Playlist: a client is expected to start initial playback with the first variant that is listed.

Downloads

You may wish to support devices that can only handle progressive downloads or allow users to download a video that can be accessed without a (proper) internet connection.

For this you can: [2]

  • Use progressive download by creating a ‘dref’ mp4 file that points to the original content (and is not a copy)
  • Use download to own for HLS and provide a FairPlay protected HLS download
  • Use download to own for HSS and provide a PlayReady proteced HSS download

Resuming downloads and scrubbing is also supported.

Alternate Audio

One feature of Unified Origin is the ability to create all possible combinations of audio, video and subtitles on request. Similar to subtitles, you may wish to have alternate audio tracks: [4]

  • Multiple languages (English, Spanish, French).
  • Multiple codecs (AAC, DTS, Dolby Digital).
  • Multiple bitrates (Adaptive Bitrate).

Note that in HSS and HDS identical audio tracks in different bitrates are not allowed.

These options can be provided from the same presentation all at once or, when using dynamic track selection, a selection can be made dynamically e.g. AAC for device X only.

Subtitles

Unified Origin supports playout to all formats of TTML subtitles (EBU-TT, SMPTE-TT, DFXP or CFF-TT) stored in an MP4 container. [5] [6]

Unified Origin also supports playout of fragmented WebVTT to HLS and MPEG DASH players that support the wvtt codec.

We recommend using fragmented DFXP for maximal interoperability as it is the most constrained format. You may use Unified Packager to convert SRT or (Web)VTT to TTML or to create (fragmented) MP4 files from WebVTT or TTML, see packaging subtitles. The packaged subtitles can then be added to the manifest, the origin will add them to the outgoing stream dynamically.

Metadata

It is also possible to add timed metadata, Origin can add ID3 tags (where applicable). For example ‘Attached Picture’ (APIC) which indicates the presence of a picture in an audio only stream.

Nielsen markers are also embeddedable, present as a metadata track in the server manifest - where Unified Packager has been used to create the metadata track. [7] [8]

Storage

Alongside block storage (e.g. a mount point) Unified Origin also supports object storage platforms, such as Amazon S3, Microsoft Azure or Google Cloud Storage.

Unified Origin is very efficient and will only request the data needed to serve a request. However, as Origin is stateless, regardless of fragmented or progressive MP4, creating additional dref MP4’s and adding a caching layer between a remote object storage solution and Origin is crucial for minimizing traffic and latency issues in a production environment. The (local) caching layer stores the dref MP4’s to minimize the lookups into the remote storage (which would cause latency).

This is achieved by using the Storage Proxy setup: a combination of IsmProxyPass, Apache’s subrequest feature and (local) caching as described in the Storage Proxy and Storage Proxy Reducing Latency documentation. [9] [10]

Deployment and Workflows

A VOD setup has very different characteristics to a Live platform: with Live, viewers are typically requesting the lastest fragment, so most requests can be resolved against the CDN (more on Live in the Live chapter). [11]

VOD users typically watch content whenever they wish. With this in mind the following should be taken into account when designing a video-on-demand streaming platform:

  • Amount of storage required for the entire video collection
  • Number of concurrent users viewing at the peak times
  • Distribution of content popularity, from popular to non-popular
  • Variety of devices and connection speeds that needs to be served
  • Distribution of the physical location of users

Typically the 80/20 rule applies: 80% of the viewers watch 20% of the content. This implies that caching can be employed for the popular content while the ‘longtail’ can be served from slower storage (a small overview of setups can be found in the ‘cases’ section on our website).

Once figures are known for the above variables, the number of servers needed is a function of disk speed (throughput) versus number of concurrent viewers. While network IO is important it does not typically cause a bottleneck.

Possible load on the setup is always related to IO (as content has to be fetched and streamed out) and never to CPU or network - even when encryption/DRM is applied dynamically.

However for object storage it is advisable to use a memory optimised instance as the webserver will need RAM for processes that resolve requests against caches.

Caching and Scaling

A CDN is employed to provide scale however it makes sense to use a local cache setup as well e.g. a setup with Apache and Nginx. CDNs may request the same content multiple times from many POPs at once, request collapsing is typically not used. A local cache will prevent load on the origin, working as a so-called ‘shield cache’. [12]

In a typical scenario of live, most users will watch the livestream, which results in those users calling for only a small amount of data. Thus, many of the scalability challenges for live are handled by the cache layer, which in a majority of scenarios will come down to CDNs like Amazon or Akamai.

For VOD, the first thing to keep in mind is that, depending on the size of the content library because video on demand will require a significant amount of storage.

The second thing to take into consideration when dimensioning a VOD system is the number of concurrent users that will be watching the content at peak hours. As VOD enables users to watch what they want, when they want, caching becomes decreasingly likely the larger a content library will be. This can result in a high frequency of calls from clients to the Unified Origin server (because the content cannot be served from cache).

A third important aspect is the popularity of content. When only a small part of the content is watched by many users (say 90%), a well-designed caching layer can help to reduce the load on the Unified Origin server significantly.

The conclusion, for VOD cases there are more variants needed to take into consideration hence scaling VOD requires more throughput on the level of your Origin servers, while improving your caching is sufficient for scaling Live.

Virtualisation, Cloud and Container

Next to ‘on-prem’ installations with, for example, local caching other deployments are also possible:

  • Cloud based (AWS, Azure, Google or other), possibly through a Marketplace
  • Using AWS Cloudformation
  • Using Terraform (infrastructure as code)
  • Containerised e.g. Docker, Kubernetes or ECS

Monitoring

As for monitoring, system metrics and webserver, logs may be fed into an monitoring tools. The origin outputs status codes to the webserver logfiles, the level can be raised for debugging purpose (‘info’ to ‘debug’), but as there are many monitoring setups possible we do not provide a single predefined recommendation.

An ELK stack and netdata setup is one of the many possibilities, the choice should be determined by your unique requirements.

A full list of status codes is listed in the documentation. [13]

Hands-On

Stream an MP4

First we will get an SBR stream up and running. With the network panel open, start playback of the stream using the player from the test install by pasting the following URL in to the browser address bar. ‘YOUR_IP_ADDRESS’ is the specfic address of your instance:

http://ec2-YOUR_IP_ADDRESS.eu-west-1.compute.amazonaws.com

The player url, for MPEG-DASH, will be: [14]

http://ec2-YOUR_IP_ADDRESS.eu-west-1.compute.amazonaws.com/tears-of-steel-avc1-400k.mp4/.mpd

Remember to append the URL of the server manifest, specifying the format in which you want to play the stream; .mpd, .m3u8, Manifest.

Having played back the stream in the format of your choice, try the other formats as well and notice the differences in the requests made by the player.

Use curl to download the client manifests for both DASH and HLS and check how these look.

In this and the rest of the examples it is assumed you execute the Bash commands in a Bash shell on the AWS instance, so the aws_hostname variable can be used and you can simply copy/paste all following examples.

#!/bin/bash

curl -v http://${aws_hostname}/tears-of-steel-avc1-400k.mp4/.mpd

curl -v http://${aws_hostname}/tears-of-steel-avc1-400k.mp4/.m3u8

Configure your stream

The focus of this part of the tutorial will be configuring your stream. You will get an understanding of how to use some of the options that are available to you when packaging tracks and generating a server manifest. You can use Unified Streaming’s documentation to investigate different options.

The first step is to generate a new server manifest using the same tracks as before, but with additional options.

Notice that both options are specified directly after the filename of the server manifest.

#!/bin/bash

mp4split -o tears-of-steel_hls_v4.ism \
  --hls.client_manifest_version=4 \
  --hls.minimum_fragment_length=6 \
  /var/www/tears-of-steel/tears-of-steel-aac-64k.mp4 \
  /var/www/tears-of-steel/tears-of-steel-aac-128k.mp4 \
  /var/www/tears-of-steel/tears-of-steel-avc1-400k.mp4 \
  /var/www/tears-of-steel/tears-of-steel-avc1-750k.mp4 \
  /var/www/tears-of-steel/tears-of-steel-avc1-1000k.mp4 \
  /var/www/tears-of-steel/tears-of-steel-avc1-1500k.mp4

The second step is to download the MPD and Master Playlist:

#!/bin/bash

sudo mv tears-of-steel_hls_v4.ism /var/www/tears-of-steel

curl -v http://${aws_hostname}/tears-of-steel_hls_v4.ism/.mpd

curl -v http://${aws_hostname}/tears-of-steel_hls_v4.ism/.m3u8

Compare these and previous (SBR) versions of the MPD and HLS Master Playlist: what are obvious differences?

Try to download and inspect the server manifest with curl, using curl’s --verbose option. Notice that this is not allowed.

Check Origin’s virtual host access and error logs for messages related to the failed request for the server manifest.

Access the server manifest locally and inspect it. Notice its configuration in the <head> of the XML-file as well as the listed tracks in the <body>.

The Use of Query Parameters

Query parameters can also be used to configure most command-line options.

This way you can change the behaviour without having to change the server manifest.

You just created configured the Tears of Steel stream to use HLS version 4. You can change it back to version 1 by adding the following query parameter:

#!/bin/bash

curl -v http://${aws_hostname}/tears-of-steel_hls_v4.ism/.m3u8?hls_client_manifest_version=1

Or create fMP4 HLS output:

#!/bin/bash

curl -v http://${aws_hostname}/tears-of-steel_hls_v4.ism/.m3u8?hls_fmp4=true

Note that the commandline option has a dot (‘.’), in the query parameter this is replaced by an underscore (‘_’) as dots have a special meaning in URIs (paths and urls).

Experiment with a few more options e.g. minimum_fragment_length.

IsmProxyPass

Since we wish to create a server manifest file dynamically for any given audio/video URLs we first need to set up IsmProxyPass. We need to add the following to /etc/apache2/sites-enabled/usp-evaluation.conf:

<Directory "/var/www/tears-of-steel/proxy">
  IsmProxyPass http://demo.unified-streaming.com/smil.php/
</Directory>

Restart Apache:

#!/bin/bash

sudo service apache2 restart

The webserver module now requests the server manifest file using the given smil.php script for any URL with ‘proxy’ in the path:

#!/bin/bash

curl -v http://${aws_hostname}/proxy/test.ism/Manifest?url=http%3A%2F%2Fcontent.bitsontherun.com%2Fvideos%2F3XnJSIm4-kNspJqnJ.mp4

This pattern can be used for any server manifest manipulation: the PHP script, or other tools, can change the server manifest or insert variables at will.

Progressive Download

Rather than storing an additional copy of the presentation to enable progressive download, you can create an MP4 file on disk that only contains the necessary metadata and references the actual movie data of the original (fragmented) video.

The MP4 file stored on disk will be around 10K - 100K in size. When requested by the client, the webserver reads this MP4 file and ‘expands’ it into a single progressive video.

Create a progresssive version running the following (note if you have not finished the packager hands-on you will need to create the cmfv file first):

#!/bin/bash

cp /var/www/tears-of-steel/tears-of-steel-avc1-1500k.mp4 /home/ubuntu/

mp4split -o tears-of-steel-avc1-1500k-dref.mp4 \
  --use_dref \
  tears-of-steel-avc1-1500k.mp4

sudo mv tears-of-steel-avc1-1500k-dref.mp4 /var/www/tears-of-steel

curl -v http://${aws_hostname}/tears-of-steel-avc1-1500k-dref.mp4 -O

You will find the full MP4 on disk: the Origin expands the ‘dref’ MP4 while downloading.

Hint

Lookup the ‘Download to Own’ feature and compare it with Progressive Download: what is the difference? [15]

Remote Storage

Content can be hosted on ‘remote storage’ (S3, Azure, Google or other like Scality) in various ways:

  • local manifest and local content
  • local manifest and remote content
  • remote manifest and remote content

We look at a third option below.

Using remote manifests

The web server module must have access to the server manifest file. You can either store the manifest file on the webserver so it has local file access or store it in the S3 bucket.

The latter is only supported by the Apache and Nginx version of the webserver module as it uses the IsmProxyPass configuration.

@startditaa

      /-------+    GET     /--------+     GET     /--------------+
      |storage| <--------- | origin | <---------- |client request|
      +-------/            +--------/             +--------------/
      video.ism           IsmProxyPass
      video1.ismv
      video2.ismv
      audio1.isma

@endditaa

This configuration will tell the webserver the content should be read from S3 rather than local disk.

Both fragmented mp4 or mp4 can be used as source: content that normally sits on disk or is created (e.g. a server manifest, or CMAF files etc.) now is moved to S3 and hosted from there.

Details on how to do upload to forn instance AWS can be found in our documentation [16], as well as in the AWS documentation.

For this hands-on we will use a previously created S3 bucket called ups-s3-storage.

To stream this you need to setup IsmProxyPass in the virtual host:

<Directory "/var/www/tears-of-steel/remote" >
  IsmProxyPass http://usp-s3-storage.s3-eu-central-1.amazonaws.com/
</Directory>

Then restart Apache.

You can now stream the S3 based content:

#!/bin/bash

curl -v http://${aws_hostname}/remote/tears-of-steel/tears-of-steel.ism/.mpd

The origin will make the mapping from request to S3 via the virtual path, remote in above example (other names could equally be chosen).

Hint

Look at ‘Object Storage Reducing Latency’ to see how to optimise this setup. [17]

If the MPD is not returned, the first step is to check the server manifest (.ism) can be fetched:

#!/bin/bash

curl -v http://usp-s3-storage.s3-eu-central-1.amazonaws.com/tears-of-steel/tears-of-steel.ism

Footnotes

[1]http://docs.unified-streaming.com/documentation/vod/playout-control.html
[2]http://docs.unified-streaming.com/documentation/vod/progressive-download.html
[3]http://docs.unified-streaming.com/faqs/factsheet.html
[4]http://docs.unified-streaming.com/documentation/vod/alternate-audio.html
[5]http://www.unified-streaming.com/blog/welcome-jungle-caption-and-subtitle-formats-video-streaming
[6]http://docs.unified-streaming.com/documentation/vod/subtitles.html
[7]http://www.unified-streaming.com/blog/how-make-your-media-streams-smarter-using-timed-metadata
[8]http://docs.unified-streaming.com/documentation/vod/id3.html
[9]https://docs.unified-streaming.com/documentation/vod/storage_proxy.html
[10]https://docs.unified-streaming.com/documentation/vod/reduce_object_storage_latency.html
[11]http://www.unified-streaming.com/blog/scaling-video-streaming-live-versus-vod
[12]http://docs.unified-streaming.com/tutorials/caching/index.html
[13]http://docs.unified-streaming.com/documentation/package/usage.html#option-status-codes
[14]http://docs.unified-streaming.com/documentation/vod/player-urls.html
[15]http://docs.unified-streaming.com/documentation/vod/progressive-download.html
[16]http://docs.unified-streaming.com/documentation/vod/remote-storage.html#amazon-s3
[17]http://docs.unified-streaming.com/documentation/vod/optimizing-storage-caching.html