Dynamically Loading Media into Players

Technology
Player API
Required
Edition
Express, Pro, Enterprise

Most content programming of playlists and videos into Brightcove players is done using the Brightcove Media module or by specifying them at run time using publishing parameters. So what if you want to change or add to the content in your Brightcove player after it loads? This would allow you to do things like add a playlist to your player based on where it is published, create a list of videos on the fly by using results you've grabbed from our Media APIs or display a list of videos you are maintaining on your website that contains the viewer's favorite videos. While I can't list every reason why you'd want to change content in a Brightcove player, I can show you how to accomplish it using the Player APIs.

By using JavaScript on the page, or ActionScript in a container SWF, non-visual Module SWF, or visual SWFLoader, you can access the methods of the ContentModule to request playlists and videos that were not included in the player when it loaded.

  • getMediaCollectionAsynch() allows you to request the contents of a playlist you've defined previously in the Media module.
  • getMediaInGroupAsynch() allows you to request multiple videos by providing it an array of the video IDs that you want to be returned.

Both methods will cause the mediaCollectionLoad event to be fired when the content you have requested is returned from the Brightcove service and is available in the player.

At this point you have options. While the new content is available in the player nothing is going to be done with it until you take further action. In this example I'm going to use a playlist and a list of random videos to replace the videos displayed in the Tile list of a Widescreen with Vertical Video List player. To see this in action, visit one of the following examples:

You could also use these videos to replace or add a tab to a Tabbed Navigation player. For more information about working with the TabBar component to handle multiple playlists, reference the API documentation for the appendTab() method of this component.

No matter which method you use to interact with the APIs, the steps involved are the same. For this example, I'll go through the JavaScript version and include the source for all three versions.

Enable the APIs

Remember, before you can use the Player APIs, you need to enable the APIs for the player in the Publishing module. To make sure all the classes necessary are loaded with the player, the player publishing code must include a reference to the APIModules_all.js file on Brightcove's servers:

<script src="http://admin.brightcove.com/js/APIModules_all.js"> </script>

This line does not get added to the player publishing code automatically, even if you have selected "Enable ActionScript/JavaScript APIs" for the player in the Publishing module.

Getting Started

This article assumes you are familar with interacting with the Brightcove Player APIs using JavaScript. If you are not confortable with this you should review the "Using JavaScript with the Player API" article before continuing.

For starters you need to publish your player on a web page using the JavaScript publishing code provided in the Publishing module. You will also need to include the APIModules_all.js file to access the player APIs using Javascript. Your publishing code should look similar to this: 

<script language="JavaScript" type="text/javascript" src="http://admin.brightcove.com/js/BrightcoveExperiences.js"></script>
<script type="text/javascript" src="http://admin.brightcove.com/js/APIModules_all.js"></script>
<object id="myExperience" class="BrightcoveExperience">
    <param name="bgcolor" value="#FFFFFF" />
    <param name="width" value="588" />
    <param name="height" value="410" />
    <param name="playerID" value="23876338001" />
    <param name="publisherID" value="1370912864"/>
    <param name="isVid" value="true" />
    <param name="isUI" value="true" />
</object>

Initial Setup

To interact with the player APIs via JavaScript, you need to set up:

  • the standard global variables,
  • onTemplateLoaded method,
  • references to the player and its modules, and
  • event listeners for templateReady so you know when the player is fully initialized.

We will also be adding an event listener to the ContentModule, because we will need to know when new media has been loaded into the player, but we'll discuss this later.

var player;
var content, exp;      
var videoList;         
function onTemplateLoaded(id)    {
    alert("templateLoaded");

    player = brightcove.getExperience(id);

    content = player.getModule(APIModules.CONTENT);
    exp     = player.getModule(APIModules.EXPERIENCE);
    exp.addEventListener(BCExperienceEvent.TEMPLATE_READY, onTemplateReady);
    content.addEventListener(BCContentEvent.MEDIA_COLLECTION_LOAD, onMediaCollectionLoad);
}

Next you will need to define the templateReady event handler. This function will execute when the player is fully initialized and ready to be interacted with. With the player fully initialized, we can also create the videoList variable, which will be a reference to the TileList component on the right side of the player so we can alter the videos displayed there. Finally, just for clarity, I've shown how you can display information about the playlist that was loaded into the player by default (having been programmed into this player in the Media module).

function onTemplateReady(e) {
    alert(e.type);

    videoList = exp.getElementByID("videoList");

    alert("[Default Playlist] displayName: " +
          content.getAllMediaCollections("playlist")[0].displayName +
          " ID: " + content.getAllMediaCollections("playlist")[0].id);

}

Requesting the New Content

In this example, I've created two standard HTML buttons that will be used to trigger the requests for new content for clarity purposes only. In the real world these requests could be triggered automatically by any type of event. Each button will execute functions that we will define shortly, one to load a playlist and the other to load a list of video Ids.

<input type="button" id="loadPlaylist" value="Load Playlist By Id" onclick="loadPlaylistById()" />
<input type="button" value="Load Group of Videos By Ids" onclick="loadVideosById()" />

The loadPlaylistById() and loadVideosById() functions will both check to make sure the player is initialized and then request the new content using methods of the ContentModule.

function loadPlaylistById() {
if(exp == null || !(exp.getReady())) {
alert("Player not initialized yet. Wait till after templateReady event.");
} else {
content.getMediaCollectionAsynch(1375772162, "id", 0, 100);
}
}
function loadVideosById() {
if(exp == null || !(exp.getReady())) {
alert("Player not initialized yet. Wait till after templateReady event.");
} else {
var mediaIdsToRequest = [1375772128, 1375780106, 1375772127, 1375772126, 1375772125];
content.getMediaInGroupAsynch(mediaIdsToRequest);
}
}

After these methods are run, the Brightcove service has to deliver the content back to the player. This is done asynchronously because you can not know how long it will take for this data to return and load into the player. This is why we set up an event listener for mediaCollectionLoad earlier, as when this event fires, we know we can continue.

Using the New Content

At this point, you know that your request has been fulfilled so you should attempt to figure out exactly what was returned. Both methods, getMediaCollectionAsynch() and getMediaInGroupAsync(), will trigger the same event so if you want to be able to differenciate between a playlist and a group of videos you can do so by checking the event object. Attributes such as displayName and id will only contain values if the content returned was a playlist.

The first scenario you want to be able to deal with is when no content was returned. This could happen if you request content that doesn't exist in your account or if the playlist you requested is empty. You can check for this by seeing if the mediaCollection attribute of the event object equals null.

The second scenario is that the request resulted in the return of a playlist or a group of videos.

function onMediaCollectionLoad(e) {
alert(e.type);
if(e.mediaCollection == null) {
// This means there was no media returned
} else {
// This means the mediaCollection is a playlist or group of videos
}
}

Now that you know you have content, you need to assign the content to the TileList in your player so viewers can see the new videos and interact with them.

For playlists as well as groups of videos, you need to create an array of the VideoDTOs that you want displayed. Because there is an array of MediaIDs in the event object returned, you can quickly make the required array by using the getMedia() method of the Content module. Finally you pass this array of VideoDTOs to the setData() method of the TileList component and the videos will be displayed.

var mediaDTOs = new Array();
for(var i = 0; i < e.mediaCollection.mediaCount; i++) 
{
	mediaDTOs[i] = content.getMedia(e.mediaCollection.mediaIds[i]);
}
videoList.setData(mediaDTOs);

Source Code

You can download zip files that include JavaScript or ActionScript versions of the code, as well as the SWFLoader component:

Javascript: js-dynamic-media-loading.zip
ActionScript SWF: as-swf-dynamic-media-loading.zip
ActionScript SWFLoader: as-swfloader-dynamic-media-loading.zip