Using a Global Ad Policy

Technology
Player API, Ad SDK
Required
Edition
Pro, Enterprise

Problem: You want to have an ad policy set to show an ad every other time (or every third time, every fourth time, etc.), but that only works for multi-playlist players. Any time the page reloads, the Flash player resets its state, which means the ad policy resets too. So, if you have single title players all over your site, but still want to maintain an ad policy that doesn't show an ad every single time, then this solution should fit the bill.

Solution: Brightcove offers a kind of plug-in option for advertising called an Ad Translator, which you may already be using if you've implemented a custom integration with your ad server. What we're going to do is use Flash's SharedObject (which you can think of as a Flash cookie) to keep track of the viewer's experience.

To use this solution, you have to develop a custom Ad Translator; at present, this approach cannot be used with our built-in Ad Translators. If you'd like to get more information on how to implement an Ad Translator, please take a look at this related help topic, as the rest of this solution assumes knowledge of how an Ad Translator is created. In a future release, we expect to enhance the functionality of the Ad SDK in a way that will allow this approach to be used with a built-in Ad Translator.

Set ad policy in the player

First, we need to set up the ad policy for the player properly. Since we're going to be controlling the frequency from our Ad Translator, we'll want to set up the policy on the player in a specific way. Make sure that only pre-roll ads are enabled for the player, and that you have a video-based policy set to make a call for 1 ad every 1 video.


Creating the global ad policy

This solution takes the form of an Ad Translator, written in ActionScript. We'll be looking at the important functions of this Ad Translator one at a time. You can download a zip file that includes the entire code sample. Since we've set up the policy to make an ad call at the start of every single video, we can control when to block that call and when to let it through in the Ad Translator. As mentioned before, we'll be using Flash's SharedObject to determine when to show an ad. Let's start diving into the code:

First, we're going to set up two instance variables to help us keep track of the "ad count."

private var mAdFrequency:uint = 0;
private var mAdCount:SharedObject = SharedObject.getLocal("brightcove_adCount");

The first value is the frequency, which will be set via a query parameter. When you assign an Ad Translator to a player, you'll be giving the player a URL to where that translator lives (for example, http://example.com/MyTranslator.swf). If you recall, we've set up the ad policy for the player to make an ad call for every video, but we know that we actually want it to be every other video (in this example), regardless if the page reloads or not. To let the translator know when to let an ad call pass through, we'll pass a query parameter with the URL named "frequency" (for example, http://example.com/MyTranslator.swf?frequency=2). Below, you'll see that we're attempting to get that value in the constructor function and assign it to our mAdFrequency variable for later use.

The second variable is our SharedObject. This is the "Flash cookie" that we'll be using to keep track of when it's time to show an ad to the viewer. Right now, we're simply getting the SharedObject if it already exists, or creating it if it doesn't. To read more about SharedObjects, please check Adobe's Actionscript 3.0 Language Reference.

public function GlobalAdPolicyExample()
{
    //Determines if a frequency was set on the translation swf as a query param
    try 
    {
        if(getRootParam("frequency"))
	{
	    mAdFrequency = int(getRootParam("frequency"));
	}
    } 
    catch (pError:Error) 
    {
        trace("page based policy frequency number was not set");
    }
}

If the value can't be found, then we've already set the mAdFrequency variable to 0 so that our translator knows to behave as it normally would. You could pass in any positive number here and have it work, but for our example we'll continue to use 2, which means an ad call will pass through for every second video.

Next, we're going to look at the actual ad call itself and how that's handled. If you recall, the fetchAd() function is what gets invoked in our Ad Translator when an ad call is made from the player. Here's our slimmed down version (for brevity):

override public function fetchAd(pContext:AdContext):void   
{
    if(timeForAdCall()) 
    {
        //here is where you would build your logic for an ad call
    } 
    else 	 
    {
        trace("not time for an ad call");
        setNoAd();
    }
}

We've obviously left out the details specific to the ad call itself since those details are unrelated to what we're trying to achieve here, and it helps prevent unnecessary confusion. We first check to see if its okay to allow the ad call to pass through with the timeForAdCall() function, which we'll look at shortly. If true gets returned, your ad logic will get processed, and if false gets returned, we call setNoAdO which gives control back to the player and allows content to start playback. Let's dig into the timeForAdCall() function now:

private function timeForAdCall():Boolean 
{
    if(mAdFrequency > 0)
    {
        if(!mAdCount.data.counter) 
        {
            mAdCount.data.counter = mAdFrequency;
        } 
        else if(mAdCount.data.counter >= mAdFrequency) 
        {
	    trace("ad counter was reset to 1");
	    mAdCount.data.counter = 1;
	} 
	else 
        {
	    mAdCount.data.counter++;
	    trace("ad counter set to: "+mAdCount.data.counter)
	}
	mAdCount.flush();
	return (mAdCount.data.counter >= mAdFrequency) ? true : false;
    }
    else
    {
        return true; //since the frequency wasn't set, just behave normally
    }
}

This function is where the real magic happens:

  • First, we check to see if the mAdFrequency variable is greater than 0. The instance variable gets set to 0 when the translator is initialized, and if the frequency query parameter is found, it gets updated to that number. In the event it's still 0 (or gets accidentally set to a negative number), we simply return true, which allows the ad call to pass through and everything will function as though the translator didn't exist at all.
  • If the frequency query parameter was found, and it's greater than 0, we start doing the necessary checks against our SharedObject. We'll be constantly setting and checking the counter property of the SharedObject's data Object. First, we see if it already exists, and if it doesn't exist, we set the counter to the mAdFrequency value (in this example, it's 2). If it does exist, then we check to see if the counter is greater or equal to the mAdFrequency value, and if that check passes, we reset the counter to 1, since the viewer just saw an ad. If the viewer didn't just see an ad, which means the counter is still less than mAdFrequency, we increment the counter.
  • Then, we call flush() on the SharedObject, which writes the information to a local file on the viewer's machine. Next is a ternary operator that checks if the counter is equal to or greater than mAdFrequency. If the counter property matches our mAdFrequency property (remember, if the viewer just saw a video and didn't see an ad, then we incremented our counter property by 1), then we know it's time to show an ad. So, if it's time to show the ad, this function will return true and the ad call will continue as normal. Otherwise, the function returns false and the ad call is prevented from going out.

The timeForAdCall() method is the bread and butter of how this all works, so that's the most vital piece to understand. Keep in mind that in this sample, there are currently no details in the fetchAd() function if timeForAdCall() returns true. Unless you pass back XML the way the player expects, or call setNoAd(), the player will hang waiting for a response and your video experience will appear frozen.

Deploying the global ad policy

Once you've created the Ad Translator that embodies your global ad policy, you need to deploy it, so that it applies to your Brightcove players. Read Developing Ad Translators for information about the next steps.