unified-video-framework 1.4.405 β 1.4.407
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/packages/web/dist/WebPlayer.d.ts.map +1 -1
- package/packages/web/dist/WebPlayer.js +50 -5
- package/packages/web/dist/WebPlayer.js.map +1 -1
- package/packages/web/dist/ads/GoogleAdsManager.d.ts +15 -8
- package/packages/web/dist/ads/GoogleAdsManager.d.ts.map +1 -1
- package/packages/web/dist/ads/GoogleAdsManager.js +41 -69
- package/packages/web/dist/ads/GoogleAdsManager.js.map +1 -1
- package/packages/web/dist/react/WebPlayerView.d.ts +5 -6
- package/packages/web/dist/react/WebPlayerView.d.ts.map +1 -1
- package/packages/web/dist/react/WebPlayerView.js +66 -125
- package/packages/web/dist/react/WebPlayerView.js.map +1 -1
- package/packages/web/src/WebPlayer.ts +53 -5
- package/packages/web/src/ads/GoogleAdsManager.ts +82 -113
- package/packages/web/src/react/WebPlayerView.tsx +29 -101
- package/packages/web/src/ads/LiveStreamAdsManager.ts +0 -255
|
@@ -4,7 +4,6 @@ import type { CSSProperties } from 'react';
|
|
|
4
4
|
import type { VideoSource, SubtitleTrack, VideoMetadata, PlayerConfig } from '../../core/dist';
|
|
5
5
|
import { WebPlayer } from '../WebPlayer';
|
|
6
6
|
import { GoogleAdsManager } from '../ads/GoogleAdsManager';
|
|
7
|
-
import { LiveStreamAdsManager } from '../ads/LiveStreamAdsManager';
|
|
8
7
|
// EPG imports - conditionally loaded
|
|
9
8
|
import type { EPGData, EPGConfig, EPGProgram, EPGProgramRow } from './types/EPGTypes';
|
|
10
9
|
import type { VCManifest, VCProduct, VCEvent } from './types/VideoCommerceTypes';
|
|
@@ -407,26 +406,24 @@ export type WebPlayerViewProps = {
|
|
|
407
406
|
// Google Ads Configuration
|
|
408
407
|
googleAds?: {
|
|
409
408
|
adTagUrl: string; // VAST/VMAP ad tag URL
|
|
410
|
-
midrollTimes?: number[]; // Mid-roll ad times in seconds [30, 60, 120]
|
|
409
|
+
midrollTimes?: number[]; // Mid-roll ad times in seconds [30, 60, 120]
|
|
410
|
+
|
|
411
|
+
// Periodic ad breaks (for live streams or automatic scheduling)
|
|
412
|
+
liveAdBreakMode?: 'periodic' | 'manual'; // 'periodic' = auto-schedule at intervals, 'manual' = use midrollTimes
|
|
413
|
+
periodicAdInterval?: number; // Interval in seconds between ads (e.g., 30 = ad every 30 seconds)
|
|
414
|
+
syncToLiveEdge?: boolean; // For live streams: sync back to live edge after ad
|
|
415
|
+
pauseStreamDuringAd?: boolean; // Pause underlying stream during ad playback
|
|
416
|
+
liveEdgeOffset?: number; // Seconds behind live edge to resume at (default: 3)
|
|
417
|
+
|
|
411
418
|
companionAdSlots?: Array<{ // Companion ad containers
|
|
412
419
|
containerId: string;
|
|
413
420
|
width: number;
|
|
414
421
|
height: number;
|
|
415
422
|
}>;
|
|
416
|
-
|
|
417
|
-
// Live Stream Options
|
|
418
|
-
liveAdBreakMode?: 'periodic' | 'manual'; // Live stream ad mode
|
|
419
|
-
periodicAdInterval?: number; // Seconds between ads (default: 300)
|
|
420
|
-
syncToLiveEdge?: boolean; // Jump to live edge after ad (default: false)
|
|
421
|
-
liveEdgeOffset?: number; // Seconds behind live edge (default: 3)
|
|
422
|
-
pauseStreamDuringAd?: boolean; // Pause stream during ad (default: true)
|
|
423
|
-
|
|
424
|
-
// Callbacks
|
|
425
423
|
onAdStart?: () => void; // Called when ad starts
|
|
426
424
|
onAdEnd?: () => void; // Called when ad ends
|
|
427
425
|
onAdError?: (error: any) => void; // Called on ad error
|
|
428
426
|
onAllAdsComplete?: () => void; // Called when all ads complete
|
|
429
|
-
onAdBreakScheduled?: (scheduledTime: number) => void; // Called when ad is scheduled (periodic mode)
|
|
430
427
|
};
|
|
431
428
|
|
|
432
429
|
// Chapter Event Callbacks
|
|
@@ -1281,82 +1278,22 @@ export const WebPlayerView: React.FC<WebPlayerViewProps> = (props) => {
|
|
|
1281
1278
|
return true;
|
|
1282
1279
|
};
|
|
1283
1280
|
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
onAdStart: () => {
|
|
1301
|
-
setIsAdPlaying(true);
|
|
1302
|
-
|
|
1303
|
-
// Check if this is a pre-roll ad
|
|
1304
|
-
if (videoElement.currentTime < 1) {
|
|
1305
|
-
console.log('π¬ Pre-roll ad starting');
|
|
1306
|
-
isPrerollPlaying = true;
|
|
1307
|
-
hasPrerollAd = true;
|
|
1308
|
-
videoElement.addEventListener('play', blockVideoUntilPreroll);
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
if (typeof (player as any).setAdPlaying === 'function') {
|
|
1312
|
-
(player as any).setAdPlaying(true);
|
|
1313
|
-
}
|
|
1314
|
-
props.googleAds?.onAdStart?.();
|
|
1315
|
-
},
|
|
1316
|
-
onAdBreakScheduled: props.googleAds.onAdBreakScheduled,
|
|
1317
|
-
onAdEnd: () => {
|
|
1318
|
-
setIsAdPlaying(false);
|
|
1319
|
-
|
|
1320
|
-
if (isPrerollPlaying) {
|
|
1321
|
-
console.log('β
Pre-roll ad completed - unblocking video');
|
|
1322
|
-
isPrerollPlaying = false;
|
|
1323
|
-
videoElement.removeEventListener('play', blockVideoUntilPreroll);
|
|
1324
|
-
videoElement.play().catch(() => {});
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
if (typeof (player as any).setAdPlaying === 'function') {
|
|
1328
|
-
(player as any).setAdPlaying(false);
|
|
1329
|
-
}
|
|
1330
|
-
props.googleAds?.onAdEnd?.();
|
|
1331
|
-
},
|
|
1332
|
-
onAdError: (error) => {
|
|
1333
|
-
setIsAdPlaying(false);
|
|
1334
|
-
isPrerollPlaying = false;
|
|
1335
|
-
videoElement.removeEventListener('play', blockVideoUntilPreroll);
|
|
1336
|
-
if (typeof (player as any).setAdPlaying === 'function') {
|
|
1337
|
-
(player as any).setAdPlaying(false);
|
|
1338
|
-
}
|
|
1339
|
-
props.googleAds?.onAdError?.(error);
|
|
1340
|
-
},
|
|
1341
|
-
onAllAdsComplete: () => {
|
|
1342
|
-
setIsAdPlaying(false);
|
|
1343
|
-
isPrerollPlaying = false;
|
|
1344
|
-
videoElement.removeEventListener('play', blockVideoUntilPreroll);
|
|
1345
|
-
if (typeof (player as any).setAdPlaying === 'function') {
|
|
1346
|
-
(player as any).setAdPlaying(false);
|
|
1347
|
-
}
|
|
1348
|
-
props.googleAds?.onAllAdsComplete?.();
|
|
1349
|
-
},
|
|
1350
|
-
}
|
|
1351
|
-
)
|
|
1352
|
-
: new GoogleAdsManager(
|
|
1353
|
-
videoElement,
|
|
1354
|
-
adContainer,
|
|
1355
|
-
{
|
|
1356
|
-
adTagUrl: props.googleAds.adTagUrl,
|
|
1357
|
-
midrollTimes: props.googleAds.midrollTimes,
|
|
1358
|
-
companionAdSlots: props.googleAds.companionAdSlots,
|
|
1359
|
-
onAdStart: () => {
|
|
1281
|
+
const adsManager = new GoogleAdsManager(
|
|
1282
|
+
videoElement,
|
|
1283
|
+
adContainer,
|
|
1284
|
+
{
|
|
1285
|
+
adTagUrl: props.googleAds.adTagUrl,
|
|
1286
|
+
midrollTimes: props.googleAds.midrollTimes,
|
|
1287
|
+
companionAdSlots: props.googleAds.companionAdSlots,
|
|
1288
|
+
|
|
1289
|
+
// Periodic ad configuration
|
|
1290
|
+
liveAdBreakMode: props.googleAds.liveAdBreakMode,
|
|
1291
|
+
periodicAdInterval: props.googleAds.periodicAdInterval,
|
|
1292
|
+
syncToLiveEdge: props.googleAds.syncToLiveEdge,
|
|
1293
|
+
pauseStreamDuringAd: props.googleAds.pauseStreamDuringAd,
|
|
1294
|
+
liveEdgeOffset: props.googleAds.liveEdgeOffset,
|
|
1295
|
+
|
|
1296
|
+
onAdStart: () => {
|
|
1360
1297
|
setIsAdPlaying(true);
|
|
1361
1298
|
|
|
1362
1299
|
// Check if this is a pre-roll ad (video time near 0)
|
|
@@ -1440,21 +1377,12 @@ export const WebPlayerView: React.FC<WebPlayerViewProps> = (props) => {
|
|
|
1440
1377
|
},
|
|
1441
1378
|
}
|
|
1442
1379
|
);
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
if (isLiveAdMode) {
|
|
1446
|
-
// For LiveStreamAdsManager, pass HLS instance for live edge detection
|
|
1447
|
-
const hlsInstance = (player as any).hls || (player as any).getHlsInstance?.();
|
|
1448
|
-
await (adsManager as LiveStreamAdsManager).initializeLiveAds(hlsInstance);
|
|
1449
|
-
console.log('β
Live Stream Ads initialized successfully');
|
|
1450
|
-
} else {
|
|
1451
|
-
// For regular GoogleAdsManager
|
|
1452
|
-
await adsManager.initialize();
|
|
1453
|
-
console.log('β
Google Ads initialized successfully');
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1380
|
+
|
|
1381
|
+
await adsManager.initialize();
|
|
1456
1382
|
adsManagerRef.current = adsManager;
|
|
1457
1383
|
|
|
1384
|
+
console.log('β
Google Ads initialized successfully');
|
|
1385
|
+
|
|
1458
1386
|
// Move ad container into player wrapper for fullscreen support
|
|
1459
1387
|
const playerWrapper = containerRef.current?.querySelector('.uvf-player-wrapper');
|
|
1460
1388
|
if (playerWrapper && adContainerRef.current && adContainerRef.current.parentElement) {
|
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Live Stream Ads Manager
|
|
3
|
-
* Extends GoogleAdsManager with periodic ad break support for live streams
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { GoogleAdsManager, GoogleAdsConfig } from './GoogleAdsManager';
|
|
7
|
-
|
|
8
|
-
export interface LiveStreamAdsConfig extends GoogleAdsConfig {
|
|
9
|
-
liveAdBreakMode?: 'periodic' | 'manual';
|
|
10
|
-
periodicAdInterval?: number; // Seconds between ads (default: 300)
|
|
11
|
-
syncToLiveEdge?: boolean; // Jump to live edge after ad (default: false)
|
|
12
|
-
liveEdgeOffset?: number; // Seconds behind live edge (default: 3)
|
|
13
|
-
pauseStreamDuringAd?: boolean; // Pause stream download during ads (default: true)
|
|
14
|
-
|
|
15
|
-
// Callbacks
|
|
16
|
-
onAdBreakScheduled?: (scheduledTime: number) => void;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class LiveStreamAdsManager extends GoogleAdsManager {
|
|
20
|
-
private liveConfig: LiveStreamAdsConfig;
|
|
21
|
-
private isLiveStream = false;
|
|
22
|
-
private periodicAdTimer: any = null;
|
|
23
|
-
private lastAdBreakTime = 0;
|
|
24
|
-
private playbackStartTime = 0;
|
|
25
|
-
private streamStartTime = 0;
|
|
26
|
-
private hlsInstance: any = null;
|
|
27
|
-
|
|
28
|
-
constructor(video: HTMLVideoElement, adContainer: HTMLElement, config: LiveStreamAdsConfig) {
|
|
29
|
-
super(video, adContainer, config);
|
|
30
|
-
this.liveConfig = {
|
|
31
|
-
periodicAdInterval: 300,
|
|
32
|
-
syncToLiveEdge: false,
|
|
33
|
-
liveEdgeOffset: 3,
|
|
34
|
-
pauseStreamDuringAd: true,
|
|
35
|
-
...config
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Initialize live stream ads with periodic mode
|
|
41
|
-
*/
|
|
42
|
-
async initializeLiveAds(hlsInstance?: any): Promise<void> {
|
|
43
|
-
// Initialize parent (Google IMA SDK)
|
|
44
|
-
await this.initialize();
|
|
45
|
-
|
|
46
|
-
this.isLiveStream = true;
|
|
47
|
-
this.hlsInstance = hlsInstance;
|
|
48
|
-
this.playbackStartTime = this.video.currentTime || 0;
|
|
49
|
-
this.streamStartTime = Date.now();
|
|
50
|
-
|
|
51
|
-
const mode = this.liveConfig.liveAdBreakMode || 'periodic';
|
|
52
|
-
|
|
53
|
-
console.log(`π΄ Live Stream Ads initialized`);
|
|
54
|
-
console.log(` Mode: ${mode}`);
|
|
55
|
-
console.log(` Periodic interval: ${this.liveConfig.periodicAdInterval}s`);
|
|
56
|
-
|
|
57
|
-
if (mode === 'periodic') {
|
|
58
|
-
this.setupPeriodicAdBreaks();
|
|
59
|
-
} else {
|
|
60
|
-
console.log('Manual mode - call triggerAdBreak() to show ads');
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Setup periodic timer-based ad breaks
|
|
66
|
-
*/
|
|
67
|
-
private setupPeriodicAdBreaks(): void {
|
|
68
|
-
const interval = this.liveConfig.periodicAdInterval || 300;
|
|
69
|
-
console.log(`β° Setting up periodic ad breaks every ${interval}s`);
|
|
70
|
-
|
|
71
|
-
let accumulatedPlaybackTime = 0;
|
|
72
|
-
let lastCheckTime = this.video.currentTime;
|
|
73
|
-
|
|
74
|
-
this.periodicAdTimer = setInterval(() => {
|
|
75
|
-
if (!this.video.paused && !this.isPlayingAd()) {
|
|
76
|
-
const currentTime = this.video.currentTime || 0;
|
|
77
|
-
const timeDelta = currentTime - lastCheckTime;
|
|
78
|
-
|
|
79
|
-
// Only accumulate if delta is reasonable (< 5 seconds)
|
|
80
|
-
if (timeDelta > 0 && timeDelta < 5) {
|
|
81
|
-
accumulatedPlaybackTime += timeDelta;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
lastCheckTime = currentTime;
|
|
85
|
-
|
|
86
|
-
const timeSinceLastAd = accumulatedPlaybackTime - this.lastAdBreakTime;
|
|
87
|
-
|
|
88
|
-
if (timeSinceLastAd >= interval) {
|
|
89
|
-
console.log('β° Periodic ad break triggered');
|
|
90
|
-
console.log(` Playback time: ${Math.floor(accumulatedPlaybackTime)}s`);
|
|
91
|
-
console.log(` Time since last ad: ${Math.floor(timeSinceLastAd)}s`);
|
|
92
|
-
|
|
93
|
-
this.liveConfig.onAdBreakScheduled?.(accumulatedPlaybackTime);
|
|
94
|
-
this.triggerAdBreak();
|
|
95
|
-
this.lastAdBreakTime = accumulatedPlaybackTime;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}, 1000); // Check every second
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Manually trigger an ad break
|
|
103
|
-
*/
|
|
104
|
-
triggerAdBreak(): void {
|
|
105
|
-
if (!this.adsManager) {
|
|
106
|
-
console.error('β Ads manager not initialized');
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (this.isPlayingAd()) {
|
|
111
|
-
console.warn('β οΈ Ad already playing, skipping trigger');
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
console.log('π¬ Triggering ad break for live stream');
|
|
116
|
-
|
|
117
|
-
const currentTime = this.video.currentTime;
|
|
118
|
-
console.log(`π Stream position before ad: ${currentTime.toFixed(2)}s`);
|
|
119
|
-
|
|
120
|
-
// Pause stream download if configured
|
|
121
|
-
if (this.liveConfig.pauseStreamDuringAd) {
|
|
122
|
-
this.pauseStreamDownload();
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
// Store position for DVR-style resume
|
|
126
|
-
(this.video as any).__positionBeforeAd = currentTime;
|
|
127
|
-
|
|
128
|
-
// Request ads
|
|
129
|
-
this.adsManager.start();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Pause stream download during ad
|
|
134
|
-
*/
|
|
135
|
-
private pauseStreamDownload(): void {
|
|
136
|
-
try {
|
|
137
|
-
if (this.hlsInstance && this.hlsInstance.stopLoad) {
|
|
138
|
-
console.log('βΈοΈ Pausing stream download during ad');
|
|
139
|
-
this.hlsInstance.stopLoad();
|
|
140
|
-
}
|
|
141
|
-
} catch (error) {
|
|
142
|
-
console.warn('Could not pause stream download:', error);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Resume stream download after ad
|
|
148
|
-
*/
|
|
149
|
-
private resumeStreamDownload(): void {
|
|
150
|
-
try {
|
|
151
|
-
if (this.hlsInstance && this.hlsInstance.startLoad) {
|
|
152
|
-
console.log('βΆοΈ Resuming stream download after ad');
|
|
153
|
-
this.hlsInstance.startLoad();
|
|
154
|
-
}
|
|
155
|
-
} catch (error) {
|
|
156
|
-
console.warn('Could not resume stream download:', error);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Override parent onAdEnd to add live stream logic
|
|
162
|
-
*/
|
|
163
|
-
protected setupLiveEdgeResume(): void {
|
|
164
|
-
const originalOnAdEnd = this.liveConfig.onAdEnd;
|
|
165
|
-
|
|
166
|
-
this.liveConfig.onAdEnd = () => {
|
|
167
|
-
const positionBeforeAd = (this.video as any).__positionBeforeAd;
|
|
168
|
-
|
|
169
|
-
if (this.liveConfig.syncToLiveEdge) {
|
|
170
|
-
// Live edge sync mode - jump to live
|
|
171
|
-
console.log('πΊ Ad ended, syncing to live edge (skipping content)');
|
|
172
|
-
this.resumeStreamDownload();
|
|
173
|
-
this.syncToLiveEdge();
|
|
174
|
-
} else {
|
|
175
|
-
// DVR mode - resume from pause point
|
|
176
|
-
console.log('πΊ Ad ended, resuming from pause point (DVR-style)');
|
|
177
|
-
this.resumeFromPausePoint(positionBeforeAd);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Call original callback
|
|
181
|
-
originalOnAdEnd?.();
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Resume from paused position (DVR-style)
|
|
187
|
-
*/
|
|
188
|
-
private resumeFromPausePoint(pausedTime: number): void {
|
|
189
|
-
setTimeout(() => {
|
|
190
|
-
try {
|
|
191
|
-
console.log(`β―οΈ Resuming from paused position: ${pausedTime.toFixed(2)}s`);
|
|
192
|
-
|
|
193
|
-
// Resume stream downloading first
|
|
194
|
-
if (this.liveConfig.pauseStreamDuringAd) {
|
|
195
|
-
this.resumeStreamDownload();
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Resume from exact pause point
|
|
199
|
-
this.video.currentTime = pausedTime;
|
|
200
|
-
|
|
201
|
-
// Calculate how far behind live
|
|
202
|
-
if (this.hlsInstance && this.hlsInstance.liveSyncPosition !== undefined) {
|
|
203
|
-
const liveEdge = this.hlsInstance.liveSyncPosition;
|
|
204
|
-
const behindLive = liveEdge - pausedTime;
|
|
205
|
-
console.log(` Behind live by: ${behindLive.toFixed(1)} seconds`);
|
|
206
|
-
}
|
|
207
|
-
} catch (error) {
|
|
208
|
-
console.error('β Error resuming from pause point:', error);
|
|
209
|
-
}
|
|
210
|
-
}, 100);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Sync to live edge
|
|
215
|
-
*/
|
|
216
|
-
private syncToLiveEdge(): void {
|
|
217
|
-
setTimeout(() => {
|
|
218
|
-
try {
|
|
219
|
-
// Resume stream download
|
|
220
|
-
this.resumeStreamDownload();
|
|
221
|
-
|
|
222
|
-
// Get live edge position
|
|
223
|
-
let liveEdgePosition: number | undefined;
|
|
224
|
-
|
|
225
|
-
if (this.hlsInstance && this.hlsInstance.liveSyncPosition !== undefined) {
|
|
226
|
-
console.log(`π HLS.js live edge: ${this.hlsInstance.liveSyncPosition.toFixed(2)}s`);
|
|
227
|
-
liveEdgePosition = this.hlsInstance.liveSyncPosition;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (liveEdgePosition !== undefined) {
|
|
231
|
-
const offset = this.liveConfig.liveEdgeOffset || 3;
|
|
232
|
-
const targetPosition = liveEdgePosition - offset;
|
|
233
|
-
console.log(`β© Syncing to live edge: ${targetPosition.toFixed(2)}s (offset: ${offset}s)`);
|
|
234
|
-
this.video.currentTime = targetPosition;
|
|
235
|
-
} else {
|
|
236
|
-
console.warn('β οΈ Could not determine live edge position');
|
|
237
|
-
}
|
|
238
|
-
} catch (error) {
|
|
239
|
-
console.error('β Error syncing to live edge:', error);
|
|
240
|
-
}
|
|
241
|
-
}, 100);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Cleanup
|
|
246
|
-
*/
|
|
247
|
-
destroy(): void {
|
|
248
|
-
if (this.periodicAdTimer) {
|
|
249
|
-
clearInterval(this.periodicAdTimer);
|
|
250
|
-
this.periodicAdTimer = null;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
super.destroy();
|
|
254
|
-
}
|
|
255
|
-
}
|