Radiant Media Player

Related content



Documentation sections


Features

The related content module allows for multiple video items to play, one after another, with no delay in between. This approach is ideal for content that should be viewed in a particular order, such as episodes in a TV show. Ten seconds before the completion of a video item, an "up next" panel in the bottom left corner of the player will show, clearly identifying the next video item to be played.

Viewers can either use a next button in the control bar to skip the current video item or use the related module in the top-right corner to display an overlay element which will present the wall of related video items. See above for an example.

Video ads can be played each time a new video item is loaded within the player. The related UI is fully compatible with mobile devices. A built-in error-recovery mechanism is also provided to skip related items that may be unavailable.

The related module is compatible with most player features including HLS & DASH streaming, Google Analytics and a dedicated related API exists to programmatically control the related layout. With Radiant Media Player 4.5.9+ the related module is fully compatible with Google Cast and AirPlay allowing for a top-nocth second-screen viewing experience of multiple media items.


Related data set with a JSON file

The related player can be initialised by passing through the relatedLoc setting a URI to a JSON file holding related data. Here is a full example of well-formatted JSON file for related data.

The general structure is as follows. The required fields for each related item are:

  • src: streaming source for the related item
  • contentMetadata: { title: "Related Item 1", description: "Description for related item 1", thumbnail: "https://www.radiantmediaplayer.com/media/playlist/poster/item-1-thumbnail.jpg", duration: "09:56", poster: [ "https://www.radiantmediaplayer.com/media/playlist/poster/item-1.jpg" ] }
  • poster: poster frame for the related item - size should be equal to the initial player size (832x468 for the example above)
  • title: title for the related item
  • description: description for the playlist item - while this information is not displayed within the related UI it is useful for accessibility and ad-targeting purposes
  • duration: duration for the related item - expressed as hh:mm:ss
  • thumbnail (highly recommended): thumbnail frame for the related item (size should be 332x186) - if thumbnail information is not found poster data will be used

Optional fields for each related item are:

  • adTagUrl: URI to the adTag to be loaded when the related item starts - if you use ads you must also set the player setting ads to true
  • adTagWaterfall - an array of URI to be used fro client-side waterfalling - see here for more information
  • related: URI to a new related JSON specific to current related item
  • seekBarThumbnailsLoc - VTT file URI to be loaded with each related item to enable preview thumbnail support
  • ccFiles - WebVTT closed captions files - see documentation

All items within the related playlist must have the same src type (e.g. if you use HLS - each related item must have a HLS URI in its src information; if you use MP4 progressive download - each related item must have a MP4 URI in its src information)

The related content layout was designed to display 16:9 content. Video content, poster, thumbnail and player size should be at a 16:9 ratio for best results. Other ratio may work but you may need to adjust player CSS to best fit your custom ratio.

Example:

{
  "playlist": [ 
    {
      "src": {
        "hls": "https://your-hls-url-1.m3u8"
      },
      "contentMetadata": {
        "title": "Related Item 1",
        "description": "Description for related item 1",
        "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-1-thumbnail-related.jpg",
        "duration": "01:51",
        "poster": [
          "https://www.radiantmediaplayer.com/media/playlist/poster/item-1.jpg"
        ]
      },
      "adTagUrl": "https://www.radiantmediaplayer.com/vast/tags/inline-linear.xml",
      "related": "https://www.radiantmediaplayer.com/media/playlist/related-1.json"
    },
    {
      "src": {
        "hls": "https://your-hls-url-2.m3u8"
      },
      "contentMetadata": {
        "title": "Related Item 2",
        "description": "Description for related item 2",
        "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-2-thumbnail-related.jpg",
        "duration": "10:53",
        "poster": [
          "https://www.radiantmediaplayer.com/media/playlist/poster/item-2.jpg"
        ]
      },
      "adTagUrl": "https://www.radiantmediaplayer.com/vast/tags/inline-linear-skippable.xml",
      "related": "https://www.radiantmediaplayer.com/media/playlist/related-2.json"
    },
    {
      "src": {
        "hls": "https://your-hls-url-3.m3u8"
      },
      "contentMetadata": {
        "title": "Related Item 3",
        "description": "Description for related item 3",
        "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-3-thumbnail-related.jpg",
        "duration": "09:56",
        "poster": [
          "https://www.radiantmediaplayer.com/media/playlist/poster/item-3.jpg"
        ]
      },
      "adTagUrl": "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=",
      "related": "https://www.radiantmediaplayer.com/media/playlist/related-3.json"
    }  
  ]
}

If you are using MP4 progressive download instead of HLS, each item in the related list would look like the following. Remember that all items in the related list must have the same streaming protocol.

{
  "src": {
    "mp4": [
      "https://your-mp4-url-1.mp4"
    ]
  },
  "contentMetadata": {
    "title": "Related Item 1",
    "description": "Description for related item 1",
    "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-1-thumbnail-related.jpg",
    "duration": "01:51",
    "poster": [
      "https://www.radiantmediaplayer.com/media/playlist/poster/item-1.jpg"
    ]
  },
  "adTagUrl": "https://www.radiantmediaplayer.com/vast/tags/inline-linear.xml",
  "related": "https://www.radiantmediaplayer.com/media/playlist/related-1.json"
}

You can also use a combination of streaming protocols, like DASH + MP4 fallback. In this case all items in the related list must have the same combination of streaming protocols.

{
  "src": {
    "dash": "https://your-dash-url-1.mpd",
    "mp4": [
      "https://your-mp4-url-1.mp4"
    ]
  },
  "contentMetadata": {
    "title": "Related Item 1",
    "description": "Description for related item 1",
    "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-1-thumbnail-related.jpg",
    "duration": "01:51",
    "poster": [
      "https://www.radiantmediaplayer.com/media/playlist/poster/item-1.jpg"
    ]
  },
  "adTagUrl": "https://www.radiantmediaplayer.com/vast/tags/inline-linear.xml",
  "related": "https://www.radiantmediaplayer.com/media/playlist/related-1.json"
}

Client-side ad waterfalling with related items:

{
  "src": {
    "hls": "https://your-hls-url-1.m3u8"
  },
  "contentMetadata": {
    "title": "Related Item 1",
    "description": "Description for related item 1",
    "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-1-thumbnail-related.jpg",
    "duration": "01:51",
    "poster": [
      "https://www.radiantmediaplayer.com/media/playlist/poster/item-1.jpg"
    ]
  },
  "adTagUrl": "https://www.radiantmediaplayer.com/vast/tags/inline-linear.xml",
  "adTagWaterfall": [
    "https://www.radiantmediaplayer.com/vast/tags/inline-linear-1.xml?cb=__random-number__",
    "https://www.radiantmediaplayer.com/vast/tags/inline-linear-2.xml?url=__page-url__"
  ],
  "related": "https://www.radiantmediaplayer.com/media/playlist/related-1.json"
}

WebVTT closed captions through the ccFiles setting:

{
  "src": {
    "hls": "https://your-hls-url-1.m3u8"
  },
  "contentMetadata": {
    "title": "Related Item 1",
    "description": "Description for related item 1",
    "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-1-thumbnail-related.jpg",
    "duration": "01:51",
    "poster": [
      "https://www.radiantmediaplayer.com/media/playlist/poster/item-1.jpg"
    ]
    "ccFiles": [
      [
        "en",
        "English",
        "https://www.radiantmediaplayer.com/media/vtt/captions/cc.vtt"
      ],
      [
        "fr",
        "Fran├žais",
        "https://www.radiantmediaplayer.com/media/vtt/captions/cc-fr.vtt"
      ]
    ]
}

Related data set with a JavaScript array of objects

Alternatively to passing related data as a JSON file you can pass those data through the relatedData setting as an array of objects. Each item of the array is an object representing a related item. The structure of this object follows the same pattern as the one described in the JSON file section above. Example:

var relatedData = [{
  src: {
    hls: "https://your-hls-url-1.m3u8"
  },
  "contentMetadata": {
    "title": "Related Item 1",
    "description": "Description for related item 1",
    "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-1-thumbnail-related.jpg",
    "duration": "01:51",
    "poster": [
      "https://www.radiantmediaplayer.com/media/playlist/poster/item-1.jpg"
    ]
  },
  related: "https://www.radiantmediaplayer.com/media/playlist/related-1.json"
}, {
  src: {
    hls: "https://your-hls-url-2.m3u8"
  },
  "contentMetadata": {
    "title": "Related Item 2",
    "description": "Description for related item 2",
    "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-2-thumbnail-related.jpg",
    "duration": "10:53",
    "poster": [
      "https://www.radiantmediaplayer.com/media/playlist/poster/item-2.jpg"
    ]
  },
  related: "https://www.radiantmediaplayer.com/media/playlist/related-2.json"
}];
...
var settings = {
  licenseKey: 'your-license-key',
  width: 832,
  height: 468,
  // if you want ads to show uncomment this next setting
  // ads: true,
  // our related settings
  relatedUpNextOffset: 10,
  relatedUpNextAutoplay: true,
  relatedEndedLoop: false,
  relatedData: relatedData
};

Player settings

relatedLoc: String

This set the path to the JSON file that hold information about the related content to display within the player. It can either be a fully qualified URL or a local/absolute path. Note that the related JSON file is loaded with XMLHttpRequest and thus it must be delivered with proper CORS setting for cross-site requests.

relatedUpNextOffset: Number

The time to end of content (in seconds) before the "up next" panel is shown to the viewer. Default: 10.

relatedUpNextAutoplay: Boolean

By default when a video item ends in the related list the next item is automatically played. Default: true. Setting this setting to false will cause the related engine to display the wall of related video item when the current video item ends (e.g. it will not autoplay next item).

relatedEndedLoop: Boolean

By default when the last item of a related list ends the player stops and does not jump to the next available item. When relatedEndedLoop is set to true and the last item of the related list ends the player will automatically start loading and displaying the next available item (e.g. playlist loop). Default: false. When relatedEndedLoop is set to true relatedUpNextAutoplay must also be set to true to have effect.

relatedCallback: Function

This setting allows for a custom callback (Promise) to be run during the related item loading mechanism after a new related item has been requested (including the first item) but before it actually starts loading related data for that item. The related item loading process will only resume when the Promise from the custom callback resolves or rejects. This allows for use-cases that require the related item loading process to pause, like header bidding for video ads, to be handled in a related scenario. Default: null. Usage example:

var adTags = [
  'https://www.radiantmediaplayer.com/vast/tags/inline-linear-1.xml',
  'https://www.radiantmediaplayer.com/vast/tags/inline-linear.xml',
  'https://www.radiantmediaplayer.com/vast/tags/inline-linear-skippable.xml',
  'https://www.radiantmediaplayer.com/vast/tags/non-linear.xml'
];
var adIndex = 0;
var relatedCallback = function () {
  return new Promise((resolve, reject) => {
    // run something async
    setTimeout(function() {
      if (adIndex === 4) {
        adIndex = 0;
      }
      rmp.loadAds(adTags[adIndex]);
      adIndex++;
      resolve();
    }, 1000);
  });
};
var settings = {
  licenseKey: 'your-license-key',
  width: 640,
  height: 360,
  ads: true,
  // pass async playlist callback
  relatedCallback: relatedCallback,
  relatedLoc: 'https://www.radiantmediaplayer.com/media/playlist/related-mp4.json'
};
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
rmp.init(settings);

Player code example - see this example here

The below code is used to display the example at top of this page:

<script src="https://cdn.radiantmediatechs.com/rmp/5.9.2/js/rmp.min.js"></script>
<div id="rmpPlayer"></div>
<script>
var settings = {
  licenseKey: 'your-license-key',
  width: 832,
  height: 468,
  // if you want ads to show uncomment this next setting
  // ads: true,
  // our related settings
  relatedUpNextOffset: 10,
  relatedUpNextAutoplay: true,
  relatedEndedLoop: false,
  relatedLoc: 'https://www.radiantmediaplayer.com/media/playlist/related.json'
};
var elementID = 'rmpPlayer';
var rmp = new RadiantMP(elementID);
rmp.init(settings);
</script>

  • relateditem: this event will fire when a new related item has successfully loaded
  • related: this event will fire when a new complete related has successfully loaded
  • relatedcomplete: this event will fire when a related list has reached its end
  • error: this event will fire when a new playlist item has failed to load
isRelated()
rmp.isRelated();

This method returns Boolean stating if the player is used with a related layout.

getCurrentRelatedItemIndex()
rmp.getCurrentRelatedItemIndex();

This getter returns Number representing the index of the current related item being displayed. Index starts at 0.

getRelatedItem(index)
rmp.getRelatedItem(index);

This getter returns an Object representing the related item at index index. If no index value input is provided, then the current related item is returned. Example:

{
  adTagUrl: "https://www.radiantmediaplayer.com/vast/tags/inline-linear.xml",
  src: { 
    hls : "https://your-hls-url.m3u8"
  },
  "contentMetadata": {
    "title": "Related Item 1",
    "description": "Description for related item 1",
    "thumbnail": "https://www.radiantmediaplayer.com/media/playlist/poster/item-1-thumbnail.jpg",
    "contentDuration": "01:51",
    "poster": [
      "https://www.radiantmediaplayer.com/media/playlist/poster/item-1.jpg"
    ]
  }
}
setRelatedItem(index) asynchronous
rmp.setRelatedItem(1);

This method sets the current related item being displayed. index input parameter should be a number representing the desired related item to be displayed. srcchanged or error event will fire when this method has completed (see setSrc API docs for more information).

getRelatedData()
rmp.getRelatedData();

This method returns an ordered Array of Object where each Object represents a related item.

setRelatedData(relatedLoc|relatedData) asynchronous
rmp.setRelatedData('https://www.radiantmediaplayer.com/media/playlist/related.json');
rmp.setRelatedData(relatedData);

This method allows to dynamically update the related player with a new set of data. You can either pass a URI to new JSON file (see relatedLoc setting) or a new array of object (see relatedData setting). srcchanged or error event will fire when this method has completed (see setSrc API docs for more information).

setRelatedItemCallback(Function)
rmp.setRelatedItemCallback(customCallback);

This method sets dynamically the relatedCallback setting. This setting allows for a custom callback (Promise) to be run during the related item changing mechanism after a new related item has been requested (including the first item) but before it actually starts loading related data for that item. The related item loading process will only resume when the Promise from the custom callback resolves or rejects. This allows for use-cases that requires the related item loading process to pause, like header bidding for video ads, to be handled in a related scenario.

resetRelatedItemCallback()
rmp.resetRelatedItemCallback();

This method resets the relatedCallback setting to null therefore allowing the related loading process to run without interruption.


Additional support notes


Live content

You can use live content with the related layout but all items from the related list must be live content.


Logging & billing considerations

Each time a new item starts in the related layout, a player start is counted (PLATFORM Edition).


Analytics consideration

Each time a new item starts in the related layout, a playerstart event is sent to Google Analytics, but it will use as label the contentTitle of the new item. This allows to identify when a specific related item is started. Other events, like adimpression or enterfullscreen, will also be sent to Google Analytics when a new media item starts in the related layout, but with the updated label as well.


Unsupported features with the related layout:

  • Ad scheduler
  • 360 video content
  • DVR content will be treated as simple live content
  • DRM content
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License.