logo

How to display visual cues on the timeline to mark mid-rolls?

You may ask this question if you want to let the user know when and how many mid-rolls there are during the video.

Similar questions may be:

  • Can I show where my ad is during the video?
  • How can I let the user know when the ads will be during the video like in YouTube?
  • Can ad markers be added to the timeline?

Showing visual cues indicating the moment in which the ads will start is certainly useful. This is not (yet) a THEOplayer standard feature, but what follows is a first step in that direction. Please keep in mind that this solution is still in development and has to date several limitations.

Table of Contents

Prerequisites and limitations

  • It only works for THEOplayer ad integration
  • A timeOffset for each roll must be included in the AdDescription
  • timeOffset values must be one of the following:
  • a keyword (“start” and “end” allowed);
  • a number (seconds from video beginning);
  • undefined (which indicates a pre-roll).
  • it has only been tested on Chrome, Firefox and Edge for Win 10 and with the standard THEOplayer UI.

The code

Add this line to your CSS

.adCue {width:.3em; height:100%; background-color: white; position:absolute; top:0;}

Your AdDescription should look something like this

player.source.ads: [
    {
        "sources": "path/to/your-pre/midroll1.xml",
            "timeOffset": value //valid values: ["start", "end", numbers] 
    }, 
    {
        "sources": "path/to/your-pre/midroll2.xml",
            "timeOffset": value //valid values: ["start", "end", numbers] 
    },
    {...}
]

Include (or call) this Javascript snippet on your page:

THEOdisplayCues.js

var adsPresent = !!player.source.ads;
var contentDuration = 0;
var to = [];
var checker = true;
var playedAds = [];

player.addEventListener('pause', ()=>{checker=false;});
player.addEventListener('playing', ()=>{
    var adIsPlaying = player.ads.playing;
    detectTimeOffset();
    detectDuration(adIsPlaying);
    if(!checker){checker = adIsPlaying}
    if(checker){
        !adIsPlaying ? drawCues() : destroyCues();
    }
});

player.addEventListener('sourcechange', function () {
    playedAds.length = 0;
});

player.ads.addEventListener('adend', (adEvent)=> {
    playedAds.push(adEvent.ad.adBreak.timeOffset);
});

function drawCues() {
    var progressBar = element.querySelector('.vjs-progress-control.vjs-control');

    for (var i=0; i<to.length; i++){
        var timeOffset = to[i];

        if (playedAds.indexOf(timeOffset) === -1) {
            var left = to[i] * progressBar.offsetWidth/contentDuration;
            var div = document.createElement("div");
            div.setAttribute('to', to[i]);
            div.classList.add("adCue");
            div.style.left = left +"px";
            progressBar.children[0].appendChild(div);
        }
    }
}

function destroyCues() {
    var cues = element.querySelectorAll('.vjs-progress-control.vjs-control .adCue');
    for (cue of cues){
        cue.parentNode.removeChild(cue);
    }
}

function detectDuration(adIsPlaying) {

    if (!adIsPlaying) {
        contentDuration = player.duration;
        //console.log("Duration ",contentDuration)
    }
    var t = 0;
    for (var ad of player.source.ads){
        to[t] = to[t] == "end" ? contentDuration : to[t];
        t++;
    }
}

function detectTimeOffset() {
    if(adsPresent){
        var t = 0;
        for (var ad of player.source.ads){
            to[t]= ad.timeOffset==undefined ? 0: ad.timeOffset=="start"? 0: ad.timeOffset;
            t++;
        }
    }
    //console.log("TimeOffsets ",to);
}
github
Make sure to follow us on GitHub!
THEO-logo-white
twitter
facebook
linkedin
Copyright © 2020. All Rights Reserved.
Leuven
New York
San Francisco
Singapore
Barcelona