mnemo_cards/games/ads_example/assets/vast_player_new.html

405 lines
17 KiB
HTML
Raw Normal View History

2025-11-10 23:55:41 +00:00
<!DOCTYPE html>
<html>
<head>
<title>Vast-Player Example</title>
<script src="https://cdn.jsdelivr.net/npm/vast-player@latest/dist/vast-player.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
background: #000;
font-family: Arial, sans-serif;
}
#container {
width: 100%;
height: 100vh;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.loading {
color: white;
text-align: center;
}
.error {
color: #ff6b6b;
text-align: center;
padding: 20px;
}
.ad-info {
position: absolute;
top: 10px;
left: 10px;
color: white;
background: rgba(0,0,0,0.7);
padding: 10px;
border-radius: 5px;
font-size: 12px;
z-index: 1000;
}
.skip-button {
position: absolute;
top: 10px;
right: 10px;
background: rgba(0,0,0,0.8);
color: white;
border: 2px solid white;
border-radius: 20px;
padding: 8px 16px;
font-size: 14px;
font-weight: bold;
cursor: pointer;
z-index: 1001;
display: none;
transition: all 0.3s ease;
}
.skip-button:hover {
background: rgba(255,255,255,0.2);
transform: scale(1.05);
}
.skip-button.visible {
display: block;
}
.skip-timer {
position: absolute;
top: 10px;
right: 10px;
background: rgba(0,0,0,0.8);
color: white;
border: 2px solid #ff6b6b;
border-radius: 20px;
padding: 8px 16px;
font-size: 14px;
font-weight: bold;
z-index: 1001;
display: none;
}
.skip-timer.visible {
display: block;
}
</style>
</head>
<body>
<div id="container">
<div class="loading">Загрузка рекламы...</div>
<button id="skipButton" class="skip-button" onclick="skipAd()">Пропустить рекламу</button>
<div id="skipTimer" class="skip-timer">Пропустить через: <span id="skipTime">5</span>с</div>
</div>
<script>
(function(VASTPlayer) {
'use strict';
var container = document.getElementById('container');
var player = new VASTPlayer(container);
// Элементы для кнопки пропуска
var skipButton = document.getElementById('skipButton');
var skipTimer = document.getElementById('skipTimer');
var skipTimeSpan = document.getElementById('skipTime');
var skipTimerInterval = null;
var skipOffset = 5; // секунд до возможности пропуска (по умолчанию)
var skipOffsetFromVast = null; // будет установлено из VAST данных
// Функция для отправки событий в Flutter
function sendToFlutter(eventName, data) {
console.log('Sending to Flutter:', eventName, data);
if (window.flutter_inappwebview) {
window.flutter_inappwebview.callHandler(eventName, data);
}
}
// Функция для парсинга времени из формата HH:MM:SS
function parseTimeToSeconds(timeString) {
if (!timeString) return 5; // по умолчанию 5 секунд
var parts = timeString.split(':');
if (parts.length === 3) {
var hours = parseInt(parts[0]) || 0;
var minutes = parseInt(parts[1]) || 0;
var seconds = parseInt(parts[2]) || 0;
return hours * 3600 + minutes * 60 + seconds;
}
return 5; // по умолчанию 5 секунд
}
// Функция для получения skipoffset из VAST данных
function getSkipOffsetFromVast() {
try {
// Пытаемся получить skipoffset из VAST данных
if (player && player.vastResponse && player.vastResponse.ads && player.vastResponse.ads.length > 0) {
var ad = player.vastResponse.ads[0];
if (ad.inLine && ad.inLine.creatives && ad.inLine.creatives.length > 0) {
var creative = ad.inLine.creatives[0];
if (creative.linear && creative.linear.skipoffset) {
return parseTimeToSeconds(creative.linear.skipoffset);
}
}
}
// Альтернативный способ - парсинг XML
if (player && player.vastResponse && player.vastResponse.xml) {
var xmlDoc = new DOMParser().parseFromString(player.vastResponse.xml, "text/xml");
var linearElement = xmlDoc.querySelector("Linear");
if (linearElement && linearElement.getAttribute("skipoffset")) {
var skipoffset = linearElement.getAttribute("skipoffset");
console.log('Found skipoffset in XML:', skipoffset);
return parseTimeToSeconds(skipoffset);
}
}
} catch (e) {
console.log('Error parsing VAST skipoffset:', e);
}
return skipOffset; // возвращаем значение по умолчанию
}
// Функция для пропуска рекламы
window.skipAd = function() {
console.log('Skipping ad');
player.skipAd();
hideSkipElements();
};
// Функция для показа кнопки пропуска
function showSkipButton() {
console.log('Showing skip button');
skipButton.classList.add('visible');
skipTimer.classList.remove('visible');
if (skipTimerInterval) {
clearInterval(skipTimerInterval);
skipTimerInterval = null;
}
}
// Функция для показа таймера пропуска
function showSkipTimer() {
console.log('Showing skip timer with offset:', skipOffsetFromVast);
skipTimer.classList.add('visible');
skipButton.classList.remove('visible');
var timeLeft = skipOffsetFromVast;
skipTimeSpan.textContent = timeLeft;
skipTimerInterval = setInterval(function() {
timeLeft--;
skipTimeSpan.textContent = timeLeft;
if (timeLeft <= 0) {
showSkipButton();
}
}, 1000);
}
// Функция для скрытия элементов пропуска
function hideSkipElements() {
console.log('Hiding skip elements');
skipButton.classList.remove('visible');
skipTimer.classList.remove('visible');
if (skipTimerInterval) {
clearInterval(skipTimerInterval);
skipTimerInterval = null;
}
}
// Функция для загрузки рекламы с URL
window.loadVastAd = function(vastUrl) {
console.log('Loading VAST ad from URL:', vastUrl);
container.innerHTML = '<div class="loading">Загрузка рекламы...</div>';
hideSkipElements(); // Скрываем элементы пропуска при загрузке
// Восстанавливаем элементы пропуска
container.innerHTML += '<button id="skipButton" class="skip-button" onclick="skipAd()">Пропустить рекламу</button>';
container.innerHTML += '<div id="skipTimer" class="skip-timer">Пропустить через: <span id="skipTime">5</span>с</div>';
// Обновляем ссылки на элементы
skipButton = document.getElementById('skipButton');
skipTimer = document.getElementById('skipTimer');
skipTimeSpan = document.getElementById('skipTime');
console.log('Skip elements restored:', {
skipButton: skipButton,
skipTimer: skipTimer,
skipTimeSpan: skipTimeSpan
});
player.load(vastUrl).then(function() {
console.log('VAST ad loaded successfully');
sendToFlutter('onAdLoaded');
return player.startAd();
}).catch(function(reason) {
console.error('Failed to load ad:', reason);
container.innerHTML = '<div class="error">Ошибка загрузки рекламы: ' + reason.message + '</div>';
sendToFlutter('onAdError', reason);
});
};
// Функция для загрузки пользовательского XML
window.loadCustomXml = function(xmlContent) {
console.log('Loading custom XML ad, content length:', xmlContent.length);
container.innerHTML = '<div class="loading">Загрузка пользовательской рекламы...</div>';
hideSkipElements(); // Скрываем элементы пропуска при загрузке
// Восстанавливаем элементы пропуска
container.innerHTML += '<button id="skipButton" class="skip-button" onclick="skipAd()">Пропустить рекламу</button>';
container.innerHTML += '<div id="skipTimer" class="skip-timer">Пропустить через: <span id="skipTime">5</span>с</div>';
// Обновляем ссылки на элементы
skipButton = document.getElementById('skipButton');
skipTimer = document.getElementById('skipTimer');
skipTimeSpan = document.getElementById('skipTime');
console.log('Skip elements restored for custom XML:', {
skipButton: skipButton,
skipTimer: skipTimer,
skipTimeSpan: skipTimeSpan
});
try {
// Создаем Blob URL для пользовательского XML
var blob = new Blob([xmlContent], {type: 'application/xml'});
var url = URL.createObjectURL(blob);
console.log('Custom XML blob URL created:', url);
player.load(url).then(function() {
console.log('Custom XML ad loaded successfully');
sendToFlutter('onAdLoaded');
return player.startAd();
}).catch(function(reason) {
console.error('Failed to load custom ad:', reason);
container.innerHTML = '<div class="error">Ошибка загрузки пользовательской рекламы: ' + reason.message + '</div>';
sendToFlutter('onAdError', reason);
});
} catch (error) {
console.error('Error creating blob URL for custom XML:', error);
container.innerHTML = '<div class="error">Ошибка создания пользовательской рекламы: ' + error.message + '</div>';
sendToFlutter('onAdError', error);
}
};
// Функция для остановки рекламы
window.stopAd = function() {
console.log('Stopping ad');
player.stopAd();
};
// Функция для паузы/возобновления рекламы
window.toggleAdPlayback = function() {
if (player.isPlaying()) {
player.pauseAd();
} else {
player.resumeAd();
}
};
// Обработчики всех событий
[
'AdLoaded',
'AdStarted',
'AdStopped',
'AdSkipped',
'AdSkippableStateChange',
'AdSizeChange',
'AdLinearChange',
'AdDurationChange',
'AdExpandedChange',
'AdRemainingTimeChange',
'AdVolumeChange',
'AdImpression',
'AdVideoStart',
'AdVideoFirstQuartile',
'AdVideoMidpoint',
'AdVideoThirdQuartile',
'AdVideoComplete',
'AdClickThru',
'AdInteraction',
'AdUserAcceptInvitation',
'AdUserMinimize',
'AdUserClose',
'AdPaused',
'AdPlaying',
'AdLog',
'AdError'
].forEach(function(type) {
player.on(type, function() {
var args = Array.prototype.slice.call(arguments);
console.log('EVENT: ' + type, args);
// Отправляем событие в Flutter
var eventName = 'on' + type;
sendToFlutter(eventName, args.length > 0 ? args[0] : null);
// Специальная обработка для завершения рекламы
if (type === 'AdStopped') {
sendToFlutter('onAdComplete');
hideSkipElements();
}
// Специальная обработка для пропуска рекламы
if (type === 'AdSkipped') {
sendToFlutter('onAdSkipped');
hideSkipElements();
}
// Специальная обработка для изменения состояния пропуска
if (type === 'AdSkippableStateChange') {
if (args.length > 0 && args[0]) {
// Получаем skipoffset из VAST данных
skipOffsetFromVast = getSkipOffsetFromVast();
console.log('Ad is skippable, skip offset from VAST:', skipOffsetFromVast);
showSkipTimer(); // Показываем таймер, если реклама стала пропускаемой
} else {
hideSkipElements(); // Скрываем, если реклама не пропускаемая
}
}
// Специальная обработка для начала рекламы
if (type === 'AdStarted') {
sendToFlutter('onAdStarted');
// Проверяем, пропускаемая ли реклама
if (player.isSkippable()) {
skipOffsetFromVast = getSkipOffsetFromVast();
console.log('Ad started and is skippable, skip offset:', skipOffsetFromVast);
showSkipTimer();
}
}
// Специальная обработка для загрузки рекламы
if (type === 'AdLoaded') {
sendToFlutter('onAdLoaded');
// Проверяем skipoffset сразу после загрузки
setTimeout(function() {
if (player.isSkippable()) {
skipOffsetFromVast = getSkipOffsetFromVast();
console.log('Ad loaded and is skippable, skip offset:', skipOffsetFromVast);
}
}, 100);
}
// Специальная обработка для кликов
if (type === 'AdClickThru') {
sendToFlutter('onAdClick');
// Пытаемся открыть ссылку
if (args.length > 0 && args[0]) {
console.log('Opening click URL:', args[0]);
try {
window.open(args[0], '_blank');
} catch (e) {
console.error('Error opening click URL:', e);
}
}
}
});
});
// Загружаем рекламу по умолчанию
loadVastAd('https://platform-staging.reelcontent.com/api/public/vast/2.0/tag?campaign=cam-e951792a909f17');
}(window.VASTPlayer));
</script>
</body>
</html>