stevennick / videojs-ad-scheduler

Advertisement scheduler for video.js
http://stevennick.github.io/videojs-ad-scheduler
Other
6 stars 7 forks source link

In a VMAP with a large number of midrolls, most of the midrolls are pushed to the last midroll spot #10

Open DoomTay opened 6 years ago

DoomTay commented 6 years ago

Here is an example VMAP. It was made from a client-side maker I've been working on, and apart from the tag URLs and timecodes, the output looks just like this

<?xml version="1.0" encoding="UTF-8"?>
<vmap:VMAP xmlns:vmap="http://www.iab.net/videosuite/vmap" version="1.0">
    <vmap:AdBreak timeOffset="00:03:49.000" breakType="linear" breakId="midroll-1">
        <vmap:AdSource id="midroll-1-ad-1" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:03:49.000" breakType="linear" breakId="midroll-1">
        <vmap:AdSource id="midroll-1-ad-2" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:03:49.000" breakType="linear" breakId="midroll-1">
        <vmap:AdSource id="midroll-1-ad-3" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:05:35.000" breakType="linear" breakId="midroll-2">
        <vmap:AdSource id="midroll-2-ad-1" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:05:35.000" breakType="linear" breakId="midroll-2">
        <vmap:AdSource id="midroll-2-ad-2" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:05:35.000" breakType="linear" breakId="midroll-2">
        <vmap:AdSource id="midroll-2-ad-3" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:05:35.000" breakType="linear" breakId="midroll-2">
        <vmap:AdSource id="midroll-2-ad-4" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:07:04.000" breakType="linear" breakId="midroll-3">
        <vmap:AdSource id="midroll-3-ad-1" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:07:04.000" breakType="linear" breakId="midroll-3">
        <vmap:AdSource id="midroll-3-ad-2" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:07:04.000" breakType="linear" breakId="midroll-3">
        <vmap:AdSource id="midroll-3-ad-3" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
    <vmap:AdBreak timeOffset="00:07:04.000" breakType="linear" breakId="midroll-3">
        <vmap:AdSource id="midroll-3-ad-4" allowMultipleAds="false" followRedirects="true">
            <vmap:AdTagURI templateType="vast3"><![CDATA[https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=10000&vad_type=linear&vpos=midroll&pod=2&mridx=1&ppos=1&min_ad_duration=0&max_ad_duration=30000&vrid=7096&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpostlongpod&url=&video_doc_id=short_tencue&cmsid=496&kfa=0&tfcd=0]]></vmap:AdTagURI>
        </vmap:AdSource>
    </vmap:AdBreak>
</vmap:VMAP>

And the first pod only shows two ads, and all the rest are moved to the last spot

And here's the log when debug is set to true

Upon further digging, it seems the cause is

https://github.com/stevennick/videojs-ad-scheduler/blob/6133bc3d912eced3738b23701382a38714706c9a/src/videojs-ad-scheduler.js#L337

which sorts numbers like strings. What is the purpose of "sorting" the array anyway?

MichSimi commented 5 years ago

it happen with vjs7, with 5.19.x the order is correct

can you confirm @DoomTay ?

MichSimi commented 5 years ago

i think i resolve it, if it can be useful, i noticed in the videojs log that after the first group of midroll, the log not return anymore the string [ad-scheduler] Main content: X, next trigger: X so i guess it's not monitoring the timing, i also noticed an error on console: player.play().ready is not a function just before an timeUpdateHandler callback, thats trigger the timing monitoring for next trigger. So i replace: player.play().ready(function() {

with

player.ready(function() {

and it works like a charm

======================

Checking with group of midroll i also found an other bug, at the end of first ad, on the skip-button remain the "enabled" class, that prevent to show the "Skip this AD >>" text on the next ad. I change this: if (timeLeft > 0) { player.ottAdScheduler.skipButton.innerHTML = 'You can skip ad in ' + timeLeft + '...'; if (player.ottAdScheduler.skipButton.classList.contains('enabled')) { player.ottAdScheduler.skipButton.classList.remove('enabled'); } } else { if (!player.ottAdScheduler.skipButton.classList.contains('enabled')) { player.ottAdScheduler.skipButton.classList.add('enabled'); player.ottAdScheduler.skipButton.innerHTML = 'Skip this AD >>'; } }

with

if (timeLeft > 0) { player.ottAdScheduler.skipButton.innerHTML = 'You can skip ad in ' + timeLeft + '...'; if (player.ottAdScheduler.skipButton.classList.contains('enabled')) { player.ottAdScheduler.skipButton.classList.remove('enabled'); } } else { if (!player.ottAdScheduler.skipButton.classList.contains('enabled')) { player.ottAdScheduler.skipButton.classList.add('enabled'); player.ottAdScheduler.skipButton.innerHTML = 'Skip this AD >>'; } }

DoomTay commented 5 years ago

I don't know about the order being correct, but unfortunately the bug still manifests in videojs v7

MichSimi commented 5 years ago

try to activate the videojs debug, and in console you should see the current player time and the next ad marker, if not it can't works

VIDEOJS: [ad-scheduler] Main content: 3.9363, next trigger: 11

DoomTay commented 5 years ago

So at the beginning, I get a stream of something along the lines of VIDEOJS: [ad-scheduler] Main content: 1.028117, next trigger: 229, which is about 3:49. So then that adblock plays, then when it's done, I get VIDEOJS: [ad-scheduler] Main content: 229.409138, next trigger: 424, or 7:04. After the first ad is done, I get VIDEOJS: [ad-scheduler] Main content: 424.358169, next trigger: 229 again. After that it's VIDEOJS: [ad-scheduler] Main content: 424.358169, next trigger: 335 for four ads then TypeError: vast is null

MichSimi commented 5 years ago

Try to check the version of your libraries. I'm using: Video.js 7.6.3 videojs-ad-scheduler - v0.1.0 - 2016-5-25 videojs-contrib-ads @version 6.6.4 last vast-client (i'v no version) last vmap-client (i'v no version)

I've made many corrections and try with different version of contrib-ads, e.g.: with first script version the trigger(nopreroll) not working because no "nopreroll" implementation was in contrib-ads.

Also the XML is important, i've had some problems when XML output was minify

DoomTay commented 5 years ago

I checked the versions of all of the libraries and the bug still shows up, at least when using an XML exactly like what I've posted here

I've also found out that if sortedOffset.sort(); is replaced with sortedOffset.sort(function(a, b){return a-b}); the bug goes away