Advanced Playout

One of the key features of the Content Fabric is the ability to create just-in-time representations of content. Video playout is one example - the media source is stored in a given format, and all the adaptive bit rate representations are created just-in-time as requested by a player.

Other examples are image processing (resizing, change of format), bulk file download (just-in-time creation of a zip file containing the files), media download (just-in-time creation of an mp4 file at a required resolution), search, and more.

Media Playout

Video and audio playout is different from serving images or other static data. Playout uses one of the two standard adaptive-bitrate (ABR) protocols, DASH or HLS, and optionally encrypts content using one of the standard digital rights management (DRM) systems, Widevine or Fairplay.

Video and audio playout requires a DASH or an HLS player. There are many player options for browsers, mobile and embedded TV, both open source and commercial.

As described in the section Basic Ingest, playable media is stored in a playable mezzanine Content Object. A Content Object is referred to by its content hash, for example: hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv

Set Up Playout

Overview

A typical playout application follows these steps:

  1. Identify the content hash of the playable mezzanine object. This can be done through a Site or Collection object as described in the section Organizing Content, or through an external CMS or application configuration.

  2. Retrieve all playout options. Each playable mezzanine content object exposes all its playout options through an API. These include the supported protocols (DASH, HLS), DRM options, content offerings and the exact URLs to use for playout of each combination.

  3. Pick the playout options suitable for the playing device (for example “DASH Widevine”).

  4. Initialize your player using the playout URL and optionally license server URLs.

And you are done:

<iframe
  width=427 height=240 scrolling="no" marginheight="0"
  marginwidth="0" frameborder="0" type="text/html"
  src="https://embed.v3.contentfabric.io/?net=demo&p&ct=h&vid=hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv&mt=v"
  allowtransparency="true"
></iframe>

Tutorial

  1. Identify the content hash

We will be using content hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv on the ‘dev’ content fabric.

  1. Retrieve all playout options

Using elv-client-js function PlayoutOptions:

let playoutOptions = client.PlayoutOptions({
  offering: "default",
  versionHash: "hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv",
})

This returns the following object:

{
  "dash-clear": {
    "properties": {
      "protocol": "dash"
    },
    "uri": "dash-clear/dash.mpd?sid=6CC2F5C12867"
  },
  "dash-widevine": {
    "properties": {
      "drm": "widevine",
      "license_servers": [
        "https://host-76-74-29-9.contentfabric.io/ks/wv/?qhash=hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv",
        "https://host-76-74-28-233.contentfabric.io/ks/wv/?qhash=hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv"
      ],
      "protocol": "dash"
    },
    "uri": "dash-widevine/dash.mpd?sid=6CC2F5C12867"
  },
  "hls-aes128": {
    "properties": {
      "drm": "aes-128",
      "protocol": "hls",
      "start_offset_float": 0,
      "start_offset_rat": "0/1"
    },
    "uri": "hls-aes128/playlist.m3u8?sid=6CC2F5C12867"
  },
  "hls-clear": {
    "properties": {
      "protocol": "hls",
      "start_offset_float": 0,
      "start_offset_rat": "0/1"
    },
    "uri": "hls-clear/playlist.m3u8?sid=6CC2F5C12867"
  },
  "hls-fairplay": {
    "properties": {
      "cert": "MIIEx...z4A",
      "drm": "fairplay",
      "license_servers": [
        "https://host-76-74-29-9.contentfabric.io/ks/fps/",
        "https://host-76-74-28-233.contentfabric.io/ks/fps/"
      ],
      "protocol": "hls",
      "start_offset_float": 0,
      "start_offset_rat": "0/1"
    },
    "uri": "hls-fairplay/playlist.m3u8?sid=6CC2F5C12867"
  },
  "hls-sample-aes": {
    "properties": {
      "drm": "sample-aes",
      "protocol": "hls",
      "start_offset_float": 0,
      "start_offset_rat": "0/1"
    },
    "uri": "hls-sample-aes/playlist.m3u8?sid=6CC2F5C12867"
  }
}

Using the Fabric REST API directly:

curl -L 'https://demov3.net955210.contentfabric.io/s/demov3/q/hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv/rep/playout/default/options.json'
  1. Pick the playout options

For this example we will pick HLS clear (no DRM).

The playout URL is constructed from the base ‘playout options’ URL and the URL path returned under hls-clear.uri

hls-clear/playlist.m3u8?sid=6CC2F5C12867

The resulting HLS clear playout URL is:

https://demov3.net955210.contentfabric.io/s/demov3/q/hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv/rep/playout/default/hls-clear/playlist.m3u8?sid=6CC2F5C12867

This URL can be provided to any HLS player.

  1. Initialize your player

The Eluvio Player can be used as described below.

Eluvio Player

The open source Eluvio Player is available at: https://github.com/eluv-io/elv-player-js

It is a convenient JavaScript package that wraps the underlying HLS and DASH-specific players and embeds the elv-client-js Content Fabric SDK.

Another good reference app that can be used as a base for your application is the “Stream Sample”: https://github.com/eluv-io/elv-stream-sample

Eluvio Embedded Player App

The simplest and most convenient way to embed video into a web application is the Eluvio Embedded Player.

Use the ‘Embedded Player’ generator app to create a playable URL or embed code: https://embed.v3.contentfabric.io

For example for our example content hash: hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv

The playable URL is :

https://embed.v3.contentfabric.io/?net=demo&p&ct=h&vid=hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv&mt=v

And the embed JavaScript code:

<iframe
  width=854 height=480 scrolling="no" marginheight="0"
  marginwidth="0" frameborder="0" type="text/html"
  src="https://embed.v3.contentfabric.io/?net=demo&p&ct=h&vid=hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv&mt=v"
  allowtransparency="true"
></iframe>

Which generates this player frame:

Clip API

You can choose to play a specific clip of a playable mezzanine by simply specifying the clip start and end points, in seconds.

For example, using the embed URL (note the query parameters start and end):

https://embed.v3.contentfabric.io/?net=demo&p&ct=h&vid=hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv&mt=v&start=100&end=110

Or the JavaScript embed code (note the query parameters start and end):

<iframe
  width=854 height=480 scrolling="no" marginheight="0"
  marginwidth="0" frameborder="0" type="text/html"
  src="https://embed.v3.contentfabric.io/?net=demo&p&ct=h&vid=hq__4wUDVKQeFAKvhWiFQvU18ivsCjzrpqkyhKADeRxewKS1kLYPGLWhDdb3ZYjnjNTvRwpXSrPtSv&mt=v&start=100&end=110"
  allowtransparency="true"
></iframe>

Which generates this player frame: