Adotube logo


Adotube OfferRenderer as JW FLV Player Plugin


Above you see a demo of the Adotube OfferRenderer integrated as a plugin into the popular open source JW FLV Player (version 2.99).

Source & Documentation

The source code archive for the above integration is available.

This integration was performed according to the Adotube OfferRenderer Plugin Integration For AS2 Players Specification.

Input Parameters

You will need the input parameters offerRendererURL (the URL of the OfferRenderer.swf) and offerMLSource (the URL of the offer description source) in order for the integration to function. For your integration testing, you can use the parameters used for the embed above (by grabbing them from the HTML source of this page). Before your integrated system will go live, you will register as a publisher with Adotube, and the actual live parameters will be provided to you as part of the embed code in the Adotube Publisher Management Console.

Technical details

The OfferRenderer integration into the JW FLV Player is accomplished via creation of a new View class, com.adotube.JWFLVOfferRendererAdapter, which is added into the com.jeroenwijering.players.MediaPlayer's setupMCV() method in the standard way:

...
var orPlugin = new com.adotube.JWFLVOfferRendererAdapter(controller,config,feeder);
var vws:Array = new Array(dpv,cbv,orPlugin);
...

These 2 lines of code replace the following already existing line of code:

var vws:Array = new Array(dpv,cbv);

The com.adotube.JWFLVOfferRendererAdapter Class creates an empty container MovieClip on top of the JW FLV Player's display stack and loads the OfferRenderer instance into it. Once the OfferRenderer is loaded, the JWFLVOfferRendererAdapter sets up the necessary interface between the OfferRenderer and the JW FLV Player. The com.adotube.JWFLVOfferRendererAdapter Class code is listed below. No other modifications were made to the JW FLV Player.

import com.jeroenwijering.players.*;
import mx.utils.Delegate;

/**
 *
 * @author us@adotube.com
 * @version 1.1
 **/
class com.adotube.JWFLVOfferRendererAdapter extends AbstractView {

	var orURL:String; // OfferRenderer.swf source URL
	var orContainer:MovieClip; // Reference to the container MovieClip into which OfferRenderer.swf is loaded

	var orLoaded:Boolean = false; // Is OfferRenderer.swf loaded?
	var orShowContentPending:Boolean=false;// Should we show the OfferRenderer content as soon as it's loaded?
	var fullScreen_obj:Object = new Object  ;

	function JWFLVOfferRendererAdapter(ctr:AbstractController,cfg:Object,fed:Object) {
		super(ctr,cfg,fed);
		orURL = _root.offerRendererURL;
		createORContainer();
		loadOfferRenderer();
	}
	/*
	* Create the container MovieClip into which the OfferRenderer.swf will be loaded.
	*/
	function createORContainer() {
		var jwClip:MovieClip = config["clip"];
		orContainer = jwClip.createEmptyMovieClip("orContainer",jwClip.getNextHighestDepth());
	}
	
	/*
	* Load the OfferRenderer. 
	*/
	function loadOfferRenderer() {
		if (orURL) {
			var mcl:MovieClipLoader=new MovieClipLoader  ;
			mcl.addListener(this);
			mcl.loadClip(orURL,orContainer);
		}
	}
	
	//////////// MovieClipLoader Callbacks ////////////////////////

	function onLoadInit(orContainer:MovieClip) {

		System.security.allowDomain(orContainer._url);
		// If offerMLSource parameter is passed via initialization params for the player,
		// pass it to the OfferRenderer. (The alternative is to pass it via the query string
		// of the the OfferRenderer.swf.)
		if (_root.offerMLSource) {
			orContainer.offerMLSource=_root.offerMLSource;
		}

		///////////// Enable Player-Plugin Interface.
		orContainer.interactionComplete=Delegate.create(this,interactionComplete);
		orContainer.getPlayerState=Delegate.create(this,getPlayerState);
		orContainer.requestPlayerPlay=Delegate.create(this,requestPlayerPlay);
		orContainer.requestPlayerPause=Delegate.create(this,requestPlayerPause);
		orContainer.userHasInteracted=Delegate.create(this,userHasInteracted);

		///////////// Setting up FullScreen listener.
		Stage.addListener(fullScreen_obj);
		fullScreen_obj.target_mc=orContainer;
		fullScreen_obj.theWidth = config["displaywidth"];
		fullScreen_obj.theHeight = config["displayheight"];
		fullScreen_obj.onFullScreen=function(bFull:Boolean) {
			if (bFull) {
				this.target_mc.doLayout(Stage.width,Stage.height);
			} else {
				this.target_mc.doLayout(this.theWidth,this.theHeight);
			}
		};
		
		///////////// Layout the OfferRenderer in the available space.
		orContainer.doLayout(config["displaywidth"],config["displayheight"]);
		orLoaded=true;
	
		if (orShowContentPending) {
			showORContent();
		}
	}

	///////////// Player-Plugin Interface /////////////////
	function interactionComplete() {
		// nop
	}
	
	function getPlayerState():String {
		return controller["isPlaying"]?"playing":"paused";
	}
	
	function requestPlayerPlay() {
		if (getPlayerState() != "playing") {
			sendEvent("playpause");
		}
	}
	
	function requestPlayerPause() {
		if (getPlayerState() != "paused") {
			sendEvent("playpause");
		}
	}
	
	/*
	* This function is optional and not implemented here. When implemented, it should return true
	* if the user has interacted with the player controls (play/pause/drag playhead) 
	* while the OfferRenderer is being shown, in which case the OfferRenderer will not attempt to 
	* restore the play state upon the offer being closed.
	*/
	function userHasInteracted():Boolean {
		return false;
	}
	////////////////////////////////////////////////////////

	private function setState(stt:Number) {
		if (stt == 2) {
			// If the state is "playing", show the OR content.
			showORContent();
		}
	}
	
	private function showORContent() {
		if (orLoaded) {
			// OfferRenderer has loaded, show its content.
			orContainer.showContent();
		} else {
			// OfferRenderer has not yet loaded, show its content as soon as it loads.
			orShowContentPending = true;
		}
	}

}

Note: In the example above, the Offer is shown after the video starts to play. If you would like the offer to show as soon as it is loaded (but before the video has started to play - for example in the case when the autostart is set to false), modify the above code to move the showORContent(); call from the setState() method to the end of the Class Constructor, like so:

// ...
	function JWFLVOfferRendererAdapter(ctr:AbstractController,cfg:Object,fed:Object) { 
		super(ctr,cfg,fed);
		orURL = _root.offerRendererURL;
		createORContainer();
		loadOfferRenderer();
		showORContent();
	}
// ...	
	private function setState(stt:Number) {
		// showORContent() call moved to constructor above
		/*
		if (stt == 2) {
			// If the state is "playing", show the OR content.
			showORContent();
		}
		*/
	}