Developing Custom Client Modules for HTML5 Player V3

The Ooyala Player enables you to build JavaScript custom modules using our Event Model and JavaScript APIs.

To create a custom module for your player, you simply need the player and the tools you normally use to create your HTML5 web pages and JavaScript code. You can load your custom player plugins directly on your web page and then attach them to your Ooyala player.

Note: The Player V3 custom module plug-in (JavaScript-based) for HTML5 serves a similar customization role as the Player V2 Open Player Framework (OPF) module does for Flash. You can load the Player V3 custom modules directly on your web page.

JavaScript Example

The following sample JavaScript, sampleV3module.js, illustrates how to build a custom UI without loading our default UI. You need to define your custom module using the OO.plugin method. You can use this sample as a template for building custom modules that can be embedded within an Ooyala player for syndication. This example:
  • Creates a UI with a play and pause button located outside the video display and also lists the Current Time and Duration of the video. A slider bar is positioned beneath the play/pause button row.

  • Makes use of an external jquery-ui.css file for theming.

  • Subscribes to three events. Note that the events are prefixed with OO.EVENTS.

  • Publishes play, pause, and seek events.

  • Returns the module class constructor so that the Ooyala player can instantiate the custom module correctly.

/**
* ©2012-2013 Ooyala, Inc.All Rights Reserved.*/
// sampleV3module.js
// Each custom module must be defined using the OO.plugin method
// The first parameter is the module name
// The second parameter is a factory function that will be called by
// the player to create an instance of the module. This function must
// return a constructor for the module class (see the end of this example)

OO.plugin("SampleUIModule", function (OO, _, $, W) {
    /**
     * Custom UI Sample Module
     * Modules developed using this template can later be embedded 
     * within Ooyala's™ player for syndication.
     *
     * A sample UI module to demonstrate how to build a custom UI
     * instead of loading our default UI. This module contains a 
     * simple play/pause button and scrubber bar. 
     * Parameters:
     * OO, namespace for PlayerV3
     * _, a reference to underscore.js lib.
     * $, a reference to jQuery lib.
     * W, a reference to window object.
     */

    // load jquery UI lib and css:
    var Sample = {};
    $('head').append('<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css">');

    // This section contains the HTML content to be used as the UI
    var CUSTOMER_TEMPLATE = 
         '<div class="customer_ui" style="position:relative; top:20px;' +
         'height:80px; left:31px; width:640px;">' +
            '<input class="playButton" type="button" value="play">' +
            '<input class="pauseButton" type="button" value="pause">' +
            '<span>Current Time:</span><span class="currentTime"></span>' +
            '<span>Duration:</span><span class="duration"></span>' +
            '<div class="slider" style="margin-top:20px; width:640px;"></div>' + 
          '</div>';

    // A constructor for the module class
    // will be called by the player to create an instance of the module
    // First parameter is a reference to a message bus object, which
    // is required to be able to pub/sub to player events.
    // Second parameter is a unique id assigned to the module for 
    // debugging purposes
    Sample.SampleUIModule = function (mb, id) {
        this.mb = mb; // save message bus reference for later use
        this.id = id;
        this.duration = NaN;
        this.playing = false;
        this.init(); // subscribe to relevant events
    };

    // public functions of the module object
    Sample.SampleUIModule.prototype = {
        init: function () {
            // subscribe to relevant player events
            this.mb.subscribe(OO.EVENTS.PLAYER_CREATED, 'customerUi',
            _.bind(this.onPlayerCreate, this));
            this.mb.subscribe(OO.EVENTS.PLAYHEAD_TIME_CHANGED,
                'customerUi', _.bind(this.onTimeUpdate, this));
            console.log("before CONTENT_TREE_FETCHED");
            this.mb.subscribe(OO.EVENTS.CONTENT_TREE_FETCHED,
                'customerUi', _.bind(this.onContentReady, this));
        },

        // Handles the PLAYER_CREATED event
        // First parameter is the event name
        // Second parameter is the elementId of player container
        // Third parameter is the list of parameters which were passed into
        // player upon creation.
        // In this section, we use this opportunity to create the custom UI
        onPlayerCreate: function (event, elementId, params) {
            this.playerRoot = $("#" + elementId);
            this.rootElement = this.playerRoot.parent();
            this.playerRoot.find(".plugins").append("<div class='fooMessage' " +
                "style='color:red; text-align:center; font-size:2em;'>" + 
                "Hello this is a custom UI</div>");

            console.log("hello, init here!!!", this.rootElement, this.id);
            $(CUSTOMER_TEMPLATE).insertAfter("#" + elementId);

            W.$( ".slider" ).slider({
                stop: _.bind(this.onSliderStop, this),
                slide: _.bind(this.onSlide, this)
            });
            this.playButton = this.rootElement.find('.playButton');
            this.pauseButton = this.rootElement.find('.pauseButton');
            this.playButton.click(_.bind(this.onPlay, this));
            this.pauseButton.click(_.bind(this.onPause, this));
        },


        // Handles CONTENT_TREE_FETCHED event
        // Second parameter is a content object with details about the
        // content that was loaded into the player
        // In this example, we use the parameter to update duration
        onContentReady: function (event, content) {
            this.duration = content.duration / 1000;
            this.rootElement.find(".duration").html(this.duration);
            W.$( ".slider" ).slider("option", "max", this.duration);
        },

        // Handles PLAYHEAD_TIME_CHANGED event
        // In this example, we use it to move the slider as content is played
        onTimeUpdate: function (event, time, duration, buffer) {
            // update scrubber bar.
            if (duration > 0) {
                this.duration = duration;
            }
            this.rootElement.find(".currentTime").html(Math.round(time));
            this.rootElement.find(".duration").html(Math.round(this.duration));
            W.$( ".slider" ).slider("option", "max", this.duration);
            W.$( ".slider" ).slider("option", "value", time);
        },

        onPlay: function () {
            this.playerRoot.find(".fooMessage").remove();
            this.rootElement.find('video.video').css('left', '0px'); 
            //this is temporary code.
            this.play();
            this.playing = true;
        },

        onPause: function () {
            this.pause();
            this.playing = false;
        },

        // Sends PLAY event to start playing the video
        play: function () {
            this.mb.publish(OO.EVENTS.PLAY);
        },

        // Sends PAUSE event to pause the video
        pause: function () {
            this.mb.publish(OO.EVENTS.PAUSE);
        },

        // Sends SEEK event to seek to specified position
        seek: function (seconds) {
            this.mb.publish(OO.EVENTS.SEEK, seconds);
        },

        onSlide: function (event, ui) {
            console.log("onSlide");
            if (this.playing) {
                this.pause();
            }
        },

        onSliderStop: function (event, ui) {
            this.seek(ui.value);
            if (this.playing) {
                this.play();
            }
        },

        __end_marker: true
    };

    // Return the constructor of the module class.
    // This is required so that Ooyala's player can instantiate the custom
    // module correctly.
    return Sample.SampleUIModule;
});

Custom Module HTML Example

The following HTML file uses the custom module JavaScript code shown above. In this file:
  1. We have included jquery, jquery UI, and and jquery CSS for theming.
  2. We have set the platform parameter to HTML5 priority.
  3. We call the sampleV3module.jscode that we created earlier.
/**
* ©2012-2013 Ooyala, Inc.All Rights Reserved.*/

<html>

<head>
<title>Sample Player Module</title>
<script src="http://code.jquery.com/jquery-1.10.1.js"></script>
<script src="http://underscorejs.org/underscore.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link href='http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/
jquery-ui.css' rel='stylesheet' type='text/css'>
<script src="http://player.ooyala.com/v3/<replace with player branding id>
?platform=html5-priority"></script>
<script src="sampleV3module.js" type="text/javascript"></script>

</head>

<body>

<div id='ooyalaplayer' style='width:640px;height:360px'></div>
<script>
	OO.ready(function() {
		OO.Player.create('ooyalaplayer', 
		<'replace with video embed code'>);
	});
</script>
<noscript><div>You must enable Javascript to watch this video</div></noscript>

</body>
</html>
Note: In this example, the div container represents the physical space in the HTML page. When we create the player, we need to pass it the player location in the web page. This requires that we give the div container and the player name the same name. The player name ooyalaplayer provides a reference to the location of the player on the page. The first use of ooyalaplyaer occurs in the HTML to name the div container and the second reference to ooyalaplayer occurs within the JavaScript to create the player within the div container location.

Was this article helpful?