Skip to content

Commit

Permalink
Update ads logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniel Neto committed Jan 8, 2025
1 parent 8e56b54 commit a3c0325
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 1 deletion.
3 changes: 3 additions & 0 deletions plugin/AVideoPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -1740,6 +1740,8 @@ public static function isPaidUser($users_id)
*/
public static function getVideo()
{
global $_plugin_getVideo;
$_plugin_getVideo = '';
$plugins = Plugin::getAllEnabled();
$resp = null;
foreach ($plugins as $value) {
Expand All @@ -1748,6 +1750,7 @@ public static function getVideo()
if (is_object($p)) {
$video = $p->getVideo();
if (!empty($video)) {
$_plugin_getVideo = $value['dirName'];
return $video;
}
}
Expand Down
6 changes: 5 additions & 1 deletion plugin/PlayerSkins/PlayerSkins.php
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ static function getStartPlayerJSCode($noReadyFunction = false, $currentTime = 0)
player = videojs('mainVideo'" . (self::getDataSetup(implode(" ", $prepareStartPlayerJS_getDataSetup))) . ");";
//var_dump($IMAADTag, isVideoPlayerHasProgressBar());exit;
if (!empty($IMAADTag) && isVideoPlayerHasProgressBar()) {
$autoPlayAdBreaks = false; // this is to make it work on livestreams
$adTagOptions = array(
'id' => 'mainVideo',
'adTagUrl' => $IMAADTag,
Expand All @@ -660,10 +661,13 @@ static function getStartPlayerJSCode($noReadyFunction = false, $currentTime = 0)
// 'useStyledNonLinearAds' => true,
'forceNonLinearFullSlot' => true,
'adLabel' => __('Advertisement'),
// 'autoPlayAdBreaks' => false,
'autoPlayAdBreaks' => $autoPlayAdBreaks,
);
$js .= PHP_EOL . "adTagOptions = " . json_encode($adTagOptions) . ";" . PHP_EOL;
$js .= "player.ima(adTagOptions);";
if(empty($autoPlayAdBreaks)){
$js .= file_get_contents($global['systemRootPath'] . 'plugin/PlayerSkins/events/vmap_ad_scheduler.js') . PHP_EOL;
}
if (isMobile()) {
$js .= file_get_contents($global['systemRootPath'] . 'plugin/PlayerSkins/events/playerAdsEventsMobile.js') . PHP_EOL;
}
Expand Down
1 change: 1 addition & 0 deletions plugin/PlayerSkins/events/playerAdsEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ player.on('adsready', function () {
adsManager.addEventListener(google.ima.AdEvent.Type.SKIPPED, function () {
console.log('ADS: IMA SDK: Ad skipped.');
logAdEvent('AdSkipped');
player.play();
});

adsManager.addEventListener(google.ima.AdEvent.Type.CLICK, function () {
Expand Down
100 changes: 100 additions & 0 deletions plugin/PlayerSkins/events/vmap_ad_scheduler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// Queue to track skipped ads
let skippedAdsQueue = [];

// Fetch and parse VMAP
if (typeof _adTagUrl === 'string') {
fetch(_adTagUrl)
.then(response => response.text())
.then(vmapXml => {
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(vmapXml, 'text/xml');
var adBreaks = xmlDoc.getElementsByTagName('vmap:AdBreak');
Array.from(adBreaks).forEach(adBreak => {
var timeOffset = adBreak.getAttribute('timeOffset');
console.log('timeOffset found', timeOffset);

if (timeOffset === 'start') {
scheduleAd(0);
} else if (timeOffset === 'end') {
scheduleAdAtEnd();
} else if (timeOffset) {
var seconds = convertTimeOffsetToSeconds(timeOffset);
scheduleAd(seconds);
}
});
})
.catch(error => console.error('Error fetching VMAP:', error));
}

// Convert timeOffset to seconds
function convertTimeOffsetToSeconds(timeOffset) {
var parts = timeOffset.split(':');
return parts.length === 3
? parseInt(parts[0], 10) * 3600 + parseInt(parts[1], 10) * 60 + parseInt(parts[2], 10)
: parts.length === 2
? parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10)
: 0;
}

// Schedule ad with a check for playback state
function scheduleAd(seconds) {
if (seconds > 5) {
setTimeout(() => {
console.log(`Ad will play in 5 seconds at ${seconds} seconds`);
}, (seconds - 5) * 1000);
}

setTimeout(() => {
try {
if (!player.paused()) { // Play ad if video is playing
console.log(`Triggering ad at ${seconds} seconds`);
player.ima.requestAds();
player.ima.playAd();
} else {
console.log(`Skipped ad at ${seconds} seconds because the video is paused`);
skippedAdsQueue.push(() => {
console.log(`Playing skipped ad scheduled for ${seconds} seconds`);
player.ima.requestAds();
player.ima.playAd();
});
}
} catch (error) {
console.error(error);
}
}, seconds * 1000);
}

// Schedule ad at the end of the video
function scheduleAdAtEnd() {
player.on('timeupdate', function handleTimeUpdate() {
var remainingTime = player.duration() - player.currentTime();
try {
if (remainingTime <= 10 && remainingTime > 5) {
console.log('Ad will play in 5 seconds at the end of the video');
}
if (remainingTime <= 5 && !player.paused()) {
console.log('Triggering ad at the end of the video');
player.ima.requestAds();
player.ima.playAd();
player.off('timeupdate', handleTimeUpdate); // Remove listener after ad is triggered
} else if (remainingTime <= 5) {
skippedAdsQueue.push(() => {
console.log('Playing skipped ad at the end of the video');
player.ima.requestAds();
player.ima.playAd();
});
player.off('timeupdate', handleTimeUpdate);
}
} catch (error) {
console.error(error);
}
});
}

// Play skipped ads after the video resumes
player.on('play', () => {
while (skippedAdsQueue.length > 0) {
const playSkippedAd = skippedAdsQueue.shift();
playSkippedAd();
}
});

0 comments on commit a3c0325

Please sign in to comment.