stormcloud-video-player 0.2.31 → 0.2.32
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/dist/stormcloud-vp.min.js +2 -2
- package/lib/index.cjs +293 -69
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +9 -1
- package/lib/index.d.ts +9 -1
- package/lib/index.js +293 -69
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +293 -69
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +9 -1
- package/lib/players/HlsPlayer.cjs +293 -69
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +293 -69
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +9 -0
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +293 -69
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +2 -2
|
@@ -639,6 +639,15 @@ function createImaController(video, options) {
|
|
|
639
639
|
"[IMA] Content video continues in background (Live mode)"
|
|
640
640
|
);
|
|
641
641
|
}
|
|
642
|
+
hideContentVideo();
|
|
643
|
+
if (adContainerEl) {
|
|
644
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
645
|
+
adContainerEl.style.display = "flex";
|
|
646
|
+
adContainerEl.style.backgroundColor = "#000";
|
|
647
|
+
adContainerEl.offsetHeight;
|
|
648
|
+
adContainerEl.style.opacity = "1";
|
|
649
|
+
console.log("[IMA] Ad container shown on content pause");
|
|
650
|
+
}
|
|
642
651
|
adPlaying = true;
|
|
643
652
|
setAdPlayingFlag(true);
|
|
644
653
|
emit("content_pause");
|
|
@@ -2173,6 +2182,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2173
2182
|
this.hasInitialBufferCompleted = false;
|
|
2174
2183
|
this.adPodAllUrls = [];
|
|
2175
2184
|
this.preloadingAdUrls = /* @__PURE__ */ new Set();
|
|
2185
|
+
this.vastToMediaUrlMap = /* @__PURE__ */ new Map();
|
|
2186
|
+
this.preloadedMediaUrls = /* @__PURE__ */ new Set();
|
|
2187
|
+
this.preloadingMediaUrls = /* @__PURE__ */ new Set();
|
|
2176
2188
|
initializePolyfills();
|
|
2177
2189
|
const browserOverrides = getBrowserConfigOverrides();
|
|
2178
2190
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2445,27 +2457,44 @@ var StormcloudVideoPlayer = class {
|
|
|
2445
2457
|
});
|
|
2446
2458
|
this.ima.on("ad_error", () => {
|
|
2447
2459
|
if (this.config.debugAdTiming) {
|
|
2448
|
-
console.log("[StormcloudVideoPlayer] IMA ad_error event received"
|
|
2460
|
+
console.log("[StormcloudVideoPlayer] IMA ad_error event received", {
|
|
2461
|
+
showAds: this.showAds,
|
|
2462
|
+
inAdBreak: this.inAdBreak,
|
|
2463
|
+
remainingAds: this.adPodQueue.length
|
|
2464
|
+
});
|
|
2449
2465
|
}
|
|
2450
|
-
if (this.
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2466
|
+
if (this.inAdBreak) {
|
|
2467
|
+
const remaining = this.getRemainingAdMs();
|
|
2468
|
+
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2469
|
+
const nextPreloaded = this.findNextPreloadedAd();
|
|
2470
|
+
if (nextPreloaded) {
|
|
2455
2471
|
this.currentAdIndex++;
|
|
2456
|
-
this.
|
|
2472
|
+
if (this.config.debugAdTiming) {
|
|
2473
|
+
console.log(
|
|
2474
|
+
`[StormcloudVideoPlayer] Skipping to next preloaded ad after error`
|
|
2475
|
+
);
|
|
2476
|
+
}
|
|
2477
|
+
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2478
|
+
this.handleAdFailure();
|
|
2457
2479
|
});
|
|
2458
2480
|
} else {
|
|
2481
|
+
if (this.config.debugAdTiming) {
|
|
2482
|
+
console.log(
|
|
2483
|
+
"[StormcloudVideoPlayer] No preloaded ads available, ending ad break"
|
|
2484
|
+
);
|
|
2485
|
+
}
|
|
2459
2486
|
this.handleAdFailure();
|
|
2460
2487
|
}
|
|
2461
2488
|
} else {
|
|
2462
|
-
if (this.config.debugAdTiming) {
|
|
2463
|
-
console.log(
|
|
2464
|
-
"[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
|
|
2465
|
-
);
|
|
2466
|
-
}
|
|
2467
2489
|
this.handleAdFailure();
|
|
2468
2490
|
}
|
|
2491
|
+
} else {
|
|
2492
|
+
if (this.config.debugAdTiming) {
|
|
2493
|
+
console.log(
|
|
2494
|
+
"[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
|
|
2495
|
+
);
|
|
2496
|
+
}
|
|
2497
|
+
this.handleAdFailure();
|
|
2469
2498
|
}
|
|
2470
2499
|
});
|
|
2471
2500
|
this.ima.on("content_pause", () => {
|
|
@@ -2496,22 +2525,31 @@ var StormcloudVideoPlayer = class {
|
|
|
2496
2525
|
}
|
|
2497
2526
|
const remaining = this.getRemainingAdMs();
|
|
2498
2527
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2499
|
-
const
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
console.log(
|
|
2504
|
-
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - IMMEDIATELY starting next ad`
|
|
2505
|
-
);
|
|
2506
|
-
}
|
|
2507
|
-
this.playSingleAd(next).catch(() => {
|
|
2528
|
+
const nextPreloaded = this.findNextPreloadedAd();
|
|
2529
|
+
if (nextPreloaded) {
|
|
2530
|
+
this.currentAdIndex++;
|
|
2531
|
+
this.enforceAdHoldState();
|
|
2508
2532
|
if (this.config.debugAdTiming) {
|
|
2509
|
-
console.
|
|
2510
|
-
|
|
2533
|
+
console.log(
|
|
2534
|
+
`[StormcloudVideoPlayer] Playing next preloaded ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak})`
|
|
2535
|
+
);
|
|
2536
|
+
}
|
|
2537
|
+
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2538
|
+
if (this.config.debugAdTiming) {
|
|
2539
|
+
console.error(
|
|
2540
|
+
"[StormcloudVideoPlayer] Failed to play next ad in pod"
|
|
2541
|
+
);
|
|
2542
|
+
}
|
|
2543
|
+
this.handleAdPodComplete();
|
|
2544
|
+
});
|
|
2545
|
+
} else {
|
|
2546
|
+
if (this.config.debugAdTiming) {
|
|
2547
|
+
console.log(
|
|
2548
|
+
"[StormcloudVideoPlayer] No preloaded ads available - completing ad break"
|
|
2511
2549
|
);
|
|
2512
2550
|
}
|
|
2513
2551
|
this.handleAdPodComplete();
|
|
2514
|
-
}
|
|
2552
|
+
}
|
|
2515
2553
|
} else {
|
|
2516
2554
|
if (this.config.debugAdTiming) {
|
|
2517
2555
|
console.log(
|
|
@@ -2756,6 +2794,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2756
2794
|
const first = tags[0];
|
|
2757
2795
|
const rest = tags.slice(1);
|
|
2758
2796
|
this.adPodQueue = rest;
|
|
2797
|
+
if (!this.showAds) {
|
|
2798
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
2799
|
+
}
|
|
2759
2800
|
this.playSingleAd(first).catch(() => {
|
|
2760
2801
|
});
|
|
2761
2802
|
}
|
|
@@ -3112,19 +3153,38 @@ var StormcloudVideoPlayer = class {
|
|
|
3112
3153
|
if (vastTagUrls.length > 0) {
|
|
3113
3154
|
this.adPodAllUrls = [...vastTagUrls];
|
|
3114
3155
|
this.preloadingAdUrls.clear();
|
|
3156
|
+
this.vastToMediaUrlMap.clear();
|
|
3157
|
+
this.preloadedMediaUrls.clear();
|
|
3158
|
+
this.preloadingMediaUrls.clear();
|
|
3115
3159
|
this.logQueuedAdUrls(this.adPodAllUrls);
|
|
3160
|
+
if (this.config.debugAdTiming) {
|
|
3161
|
+
console.log(
|
|
3162
|
+
`[StormcloudVideoPlayer] Capturing original audio state before ad break:`,
|
|
3163
|
+
{
|
|
3164
|
+
videoMuted: this.video.muted,
|
|
3165
|
+
videoVolume: this.video.volume
|
|
3166
|
+
}
|
|
3167
|
+
);
|
|
3168
|
+
}
|
|
3169
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3116
3170
|
this.inAdBreak = true;
|
|
3117
|
-
this.showAds = true;
|
|
3118
3171
|
this.currentAdIndex = 0;
|
|
3119
3172
|
this.totalAdsInBreak = vastTagUrls.length;
|
|
3120
3173
|
this.adPodQueue = [...vastTagUrls];
|
|
3121
3174
|
this.enforceAdHoldState();
|
|
3122
|
-
this.preloadUpcomingAds();
|
|
3123
3175
|
if (this.config.debugAdTiming) {
|
|
3124
3176
|
console.log(
|
|
3125
|
-
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads -
|
|
3177
|
+
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - preloading all ads in parallel`
|
|
3126
3178
|
);
|
|
3127
3179
|
}
|
|
3180
|
+
this.preloadAllAdsInBackground().catch((error) => {
|
|
3181
|
+
if (this.config.debugAdTiming) {
|
|
3182
|
+
console.warn(
|
|
3183
|
+
"[StormcloudVideoPlayer] Error in background preloading:",
|
|
3184
|
+
error
|
|
3185
|
+
);
|
|
3186
|
+
}
|
|
3187
|
+
});
|
|
3128
3188
|
try {
|
|
3129
3189
|
await this.playAdPod();
|
|
3130
3190
|
} catch (error) {
|
|
@@ -3150,14 +3210,28 @@ var StormcloudVideoPlayer = class {
|
|
|
3150
3210
|
}
|
|
3151
3211
|
return;
|
|
3152
3212
|
}
|
|
3153
|
-
|
|
3213
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
3214
|
+
const firstPreloaded = this.findNextPreloadedAd();
|
|
3215
|
+
if (!firstPreloaded) {
|
|
3216
|
+
if (this.config.debugAdTiming) {
|
|
3217
|
+
console.log(
|
|
3218
|
+
"[StormcloudVideoPlayer] No preloaded ads available after waiting, trying first ad anyway"
|
|
3219
|
+
);
|
|
3220
|
+
}
|
|
3221
|
+
const firstAd = this.adPodQueue.shift();
|
|
3222
|
+
if (firstAd) {
|
|
3223
|
+
this.currentAdIndex++;
|
|
3224
|
+
await this.playSingleAd(firstAd);
|
|
3225
|
+
}
|
|
3226
|
+
return;
|
|
3227
|
+
}
|
|
3154
3228
|
this.currentAdIndex++;
|
|
3155
3229
|
if (this.config.debugAdTiming) {
|
|
3156
3230
|
console.log(
|
|
3157
|
-
`[StormcloudVideoPlayer] Playing ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3231
|
+
`[StormcloudVideoPlayer] Playing first preloaded ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3158
3232
|
);
|
|
3159
3233
|
}
|
|
3160
|
-
await this.playSingleAd(
|
|
3234
|
+
await this.playSingleAd(firstPreloaded);
|
|
3161
3235
|
}
|
|
3162
3236
|
findCurrentOrNextBreak(nowMs) {
|
|
3163
3237
|
var _a;
|
|
@@ -3190,6 +3264,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3190
3264
|
const first = tags[0];
|
|
3191
3265
|
const rest = tags.slice(1);
|
|
3192
3266
|
this.adPodQueue = rest;
|
|
3267
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3193
3268
|
this.enforceAdHoldState();
|
|
3194
3269
|
await this.playSingleAd(first);
|
|
3195
3270
|
this.inAdBreak = true;
|
|
@@ -3310,27 +3385,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3310
3385
|
`[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
|
|
3311
3386
|
);
|
|
3312
3387
|
}
|
|
3313
|
-
if (!this.showAds) {
|
|
3314
|
-
if (this.config.debugAdTiming) {
|
|
3315
|
-
console.log(
|
|
3316
|
-
`[StormcloudVideoPlayer] Capturing original state before ad request:`,
|
|
3317
|
-
{
|
|
3318
|
-
videoMuted: this.video.muted,
|
|
3319
|
-
videoVolume: this.video.volume,
|
|
3320
|
-
showAds: this.showAds
|
|
3321
|
-
}
|
|
3322
|
-
);
|
|
3323
|
-
}
|
|
3324
|
-
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3325
|
-
} else if (this.config.debugAdTiming) {
|
|
3326
|
-
console.log(
|
|
3327
|
-
`[StormcloudVideoPlayer] Keeping existing original mute state (currently showing ads)`
|
|
3328
|
-
);
|
|
3329
|
-
}
|
|
3330
3388
|
this.startAdFailsafeTimer();
|
|
3331
3389
|
try {
|
|
3332
3390
|
await this.ima.requestAds(vastTagUrl);
|
|
3333
|
-
this.preloadUpcomingAds();
|
|
3334
3391
|
try {
|
|
3335
3392
|
if (this.config.debugAdTiming) {
|
|
3336
3393
|
console.log(
|
|
@@ -3339,9 +3396,10 @@ var StormcloudVideoPlayer = class {
|
|
|
3339
3396
|
}
|
|
3340
3397
|
this.enforceAdHoldState();
|
|
3341
3398
|
await this.ima.play();
|
|
3399
|
+
this.showAds = true;
|
|
3342
3400
|
if (this.config.debugAdTiming) {
|
|
3343
3401
|
console.log(
|
|
3344
|
-
"[StormcloudVideoPlayer] Ad playback started successfully"
|
|
3402
|
+
"[StormcloudVideoPlayer] Ad playback started successfully, showAds = true"
|
|
3345
3403
|
);
|
|
3346
3404
|
}
|
|
3347
3405
|
} catch (playError) {
|
|
@@ -3369,6 +3427,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3369
3427
|
}
|
|
3370
3428
|
this.releaseAdHoldState();
|
|
3371
3429
|
this.preloadingAdUrls.clear();
|
|
3430
|
+
this.vastToMediaUrlMap.clear();
|
|
3431
|
+
this.preloadedMediaUrls.clear();
|
|
3432
|
+
this.preloadingMediaUrls.clear();
|
|
3372
3433
|
this.inAdBreak = false;
|
|
3373
3434
|
this.expectedAdBreakDurationMs = void 0;
|
|
3374
3435
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
@@ -3478,44 +3539,204 @@ var StormcloudVideoPlayer = class {
|
|
|
3478
3539
|
this.ima.hidePlaceholder();
|
|
3479
3540
|
}
|
|
3480
3541
|
}
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3542
|
+
async fetchAndParseVastXml(vastTagUrl) {
|
|
3543
|
+
try {
|
|
3544
|
+
const response = await fetch(vastTagUrl, { mode: "cors" });
|
|
3545
|
+
if (!response.ok) {
|
|
3546
|
+
throw new Error(`Failed to fetch VAST: ${response.status}`);
|
|
3547
|
+
}
|
|
3548
|
+
const xmlText = await response.text();
|
|
3549
|
+
return this.extractMediaUrlsFromVast(xmlText);
|
|
3550
|
+
} catch (error) {
|
|
3551
|
+
if (this.config.debugAdTiming) {
|
|
3552
|
+
console.warn(
|
|
3553
|
+
`[StormcloudVideoPlayer] Failed to fetch/parse VAST XML: ${vastTagUrl}`,
|
|
3554
|
+
error
|
|
3555
|
+
);
|
|
3556
|
+
}
|
|
3557
|
+
return [];
|
|
3484
3558
|
}
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3559
|
+
}
|
|
3560
|
+
extractMediaUrlsFromVast(xmlText) {
|
|
3561
|
+
var _a;
|
|
3562
|
+
const mediaUrls = [];
|
|
3563
|
+
try {
|
|
3564
|
+
const parser = new DOMParser();
|
|
3565
|
+
const xmlDoc = parser.parseFromString(xmlText, "text/xml");
|
|
3566
|
+
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
3567
|
+
for (const mediaFile of Array.from(mediaFileElements)) {
|
|
3568
|
+
const url = (_a = mediaFile.textContent) == null ? void 0 : _a.trim();
|
|
3569
|
+
if (url) {
|
|
3570
|
+
const lowerUrl = url.toLowerCase();
|
|
3571
|
+
if (lowerUrl.endsWith(".mp4") || lowerUrl.endsWith(".webm") || lowerUrl.endsWith(".mov") || lowerUrl.endsWith(".avi") || lowerUrl.includes(".mp4?") || lowerUrl.includes(".webm?") || lowerUrl.includes("/mp4/") || lowerUrl.includes("type=video")) {
|
|
3572
|
+
mediaUrls.push(url);
|
|
3573
|
+
}
|
|
3574
|
+
}
|
|
3491
3575
|
}
|
|
3492
|
-
if (this.
|
|
3493
|
-
|
|
3576
|
+
if (this.config.debugAdTiming && mediaUrls.length > 0) {
|
|
3577
|
+
console.log(
|
|
3578
|
+
`[StormcloudVideoPlayer] Extracted ${mediaUrls.length} media URLs from VAST:`,
|
|
3579
|
+
mediaUrls
|
|
3580
|
+
);
|
|
3581
|
+
}
|
|
3582
|
+
} catch (error) {
|
|
3583
|
+
if (this.config.debugAdTiming) {
|
|
3584
|
+
console.warn(
|
|
3585
|
+
"[StormcloudVideoPlayer] Failed to parse VAST XML:",
|
|
3586
|
+
error
|
|
3587
|
+
);
|
|
3494
3588
|
}
|
|
3589
|
+
}
|
|
3590
|
+
return mediaUrls;
|
|
3591
|
+
}
|
|
3592
|
+
async preloadMediaFile(mediaUrl) {
|
|
3593
|
+
if (this.preloadedMediaUrls.has(mediaUrl)) {
|
|
3594
|
+
return;
|
|
3595
|
+
}
|
|
3596
|
+
if (this.preloadingMediaUrls.has(mediaUrl)) {
|
|
3597
|
+
return;
|
|
3598
|
+
}
|
|
3599
|
+
this.preloadingMediaUrls.add(mediaUrl);
|
|
3600
|
+
try {
|
|
3495
3601
|
if (this.config.debugAdTiming) {
|
|
3496
3602
|
console.log(
|
|
3497
|
-
`[StormcloudVideoPlayer]
|
|
3603
|
+
`[StormcloudVideoPlayer] Preloading video file: ${mediaUrl}`
|
|
3498
3604
|
);
|
|
3499
3605
|
}
|
|
3500
|
-
|
|
3501
|
-
|
|
3606
|
+
const response = await fetch(mediaUrl, {
|
|
3607
|
+
mode: "cors",
|
|
3608
|
+
method: "GET",
|
|
3609
|
+
headers: {
|
|
3610
|
+
Range: "bytes=0-1048576"
|
|
3611
|
+
}
|
|
3612
|
+
});
|
|
3613
|
+
if (response.ok || response.status === 206) {
|
|
3614
|
+
this.preloadedMediaUrls.add(mediaUrl);
|
|
3502
3615
|
if (this.config.debugAdTiming) {
|
|
3503
3616
|
console.log(
|
|
3504
|
-
`[StormcloudVideoPlayer]
|
|
3617
|
+
`[StormcloudVideoPlayer] Successfully preloaded video file: ${mediaUrl}`
|
|
3505
3618
|
);
|
|
3506
3619
|
}
|
|
3507
|
-
}
|
|
3620
|
+
}
|
|
3621
|
+
} catch (error) {
|
|
3622
|
+
if (this.config.debugAdTiming) {
|
|
3623
|
+
console.warn(
|
|
3624
|
+
`[StormcloudVideoPlayer] Failed to preload video file: ${mediaUrl}`,
|
|
3625
|
+
error
|
|
3626
|
+
);
|
|
3627
|
+
}
|
|
3628
|
+
} finally {
|
|
3629
|
+
this.preloadingMediaUrls.delete(mediaUrl);
|
|
3630
|
+
}
|
|
3631
|
+
}
|
|
3632
|
+
async preloadAllAdsInBackground() {
|
|
3633
|
+
if (this.adPodAllUrls.length === 0) {
|
|
3634
|
+
return;
|
|
3635
|
+
}
|
|
3636
|
+
if (this.config.debugAdTiming) {
|
|
3637
|
+
console.log(
|
|
3638
|
+
`[StormcloudVideoPlayer] Starting parallel preload of ${this.adPodAllUrls.length} ads`
|
|
3639
|
+
);
|
|
3640
|
+
}
|
|
3641
|
+
const preloadPromises = this.adPodAllUrls.map(
|
|
3642
|
+
(vastTagUrl) => this.preloadSingleAd(vastTagUrl).catch((error) => {
|
|
3508
3643
|
if (this.config.debugAdTiming) {
|
|
3509
3644
|
console.warn(
|
|
3510
|
-
`[StormcloudVideoPlayer]
|
|
3645
|
+
`[StormcloudVideoPlayer] Preload failed for ${vastTagUrl}:`,
|
|
3511
3646
|
error
|
|
3512
3647
|
);
|
|
3513
3648
|
}
|
|
3514
|
-
})
|
|
3515
|
-
|
|
3516
|
-
|
|
3649
|
+
})
|
|
3650
|
+
);
|
|
3651
|
+
await Promise.all(preloadPromises);
|
|
3652
|
+
if (this.config.debugAdTiming) {
|
|
3653
|
+
console.log(
|
|
3654
|
+
`[StormcloudVideoPlayer] Background preloading completed for all ads`
|
|
3655
|
+
);
|
|
3517
3656
|
}
|
|
3518
3657
|
}
|
|
3658
|
+
async preloadSingleAd(vastTagUrl) {
|
|
3659
|
+
if (!vastTagUrl) return;
|
|
3660
|
+
try {
|
|
3661
|
+
if (this.ima.preloadAds && !this.ima.hasPreloadedAd(vastTagUrl)) {
|
|
3662
|
+
if (!this.preloadingAdUrls.has(vastTagUrl)) {
|
|
3663
|
+
if (this.config.debugAdTiming) {
|
|
3664
|
+
console.log(
|
|
3665
|
+
`[StormcloudVideoPlayer] Preloading VAST: ${vastTagUrl}`
|
|
3666
|
+
);
|
|
3667
|
+
}
|
|
3668
|
+
this.preloadingAdUrls.add(vastTagUrl);
|
|
3669
|
+
await this.ima.preloadAds(vastTagUrl).then(() => {
|
|
3670
|
+
if (this.config.debugAdTiming) {
|
|
3671
|
+
console.log(
|
|
3672
|
+
`[StormcloudVideoPlayer] IMA VAST preload complete: ${vastTagUrl}`
|
|
3673
|
+
);
|
|
3674
|
+
}
|
|
3675
|
+
}).catch((error) => {
|
|
3676
|
+
if (this.config.debugAdTiming) {
|
|
3677
|
+
console.warn(
|
|
3678
|
+
`[StormcloudVideoPlayer] IMA VAST preload failed: ${vastTagUrl}`,
|
|
3679
|
+
error
|
|
3680
|
+
);
|
|
3681
|
+
}
|
|
3682
|
+
}).finally(() => {
|
|
3683
|
+
this.preloadingAdUrls.delete(vastTagUrl);
|
|
3684
|
+
});
|
|
3685
|
+
}
|
|
3686
|
+
}
|
|
3687
|
+
let mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3688
|
+
if (!mediaUrls) {
|
|
3689
|
+
if (this.config.debugAdTiming) {
|
|
3690
|
+
console.log(
|
|
3691
|
+
`[StormcloudVideoPlayer] Fetching and parsing VAST to extract media URLs: ${vastTagUrl}`
|
|
3692
|
+
);
|
|
3693
|
+
}
|
|
3694
|
+
mediaUrls = await this.fetchAndParseVastXml(vastTagUrl);
|
|
3695
|
+
if (mediaUrls.length > 0) {
|
|
3696
|
+
this.vastToMediaUrlMap.set(vastTagUrl, mediaUrls);
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
if (mediaUrls && mediaUrls.length > 0) {
|
|
3700
|
+
const primaryMediaUrl = mediaUrls[0];
|
|
3701
|
+
if (primaryMediaUrl && !this.preloadedMediaUrls.has(primaryMediaUrl)) {
|
|
3702
|
+
await this.preloadMediaFile(primaryMediaUrl);
|
|
3703
|
+
}
|
|
3704
|
+
}
|
|
3705
|
+
} catch (error) {
|
|
3706
|
+
if (this.config.debugAdTiming) {
|
|
3707
|
+
console.warn(
|
|
3708
|
+
`[StormcloudVideoPlayer] Failed to preload ad: ${vastTagUrl}`,
|
|
3709
|
+
error
|
|
3710
|
+
);
|
|
3711
|
+
}
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
findNextPreloadedAd() {
|
|
3715
|
+
var _a, _b, _c;
|
|
3716
|
+
for (let i = 0; i < this.adPodQueue.length; i++) {
|
|
3717
|
+
const vastTagUrl = this.adPodQueue[i];
|
|
3718
|
+
if (!vastTagUrl) continue;
|
|
3719
|
+
const hasImaPreload = (_c = (_b = (_a = this.ima).hasPreloadedAd) == null ? void 0 : _b.call(_a, vastTagUrl)) != null ? _c : false;
|
|
3720
|
+
const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3721
|
+
const hasMediaPreload = mediaUrls && mediaUrls.length > 0 ? this.preloadedMediaUrls.has(mediaUrls[0]) : false;
|
|
3722
|
+
if (hasImaPreload || hasMediaPreload) {
|
|
3723
|
+
if (this.config.debugAdTiming) {
|
|
3724
|
+
console.log(
|
|
3725
|
+
`[StormcloudVideoPlayer] Found preloaded ad at index ${i}: ${vastTagUrl}`,
|
|
3726
|
+
{ hasImaPreload, hasMediaPreload }
|
|
3727
|
+
);
|
|
3728
|
+
}
|
|
3729
|
+
this.adPodQueue.splice(0, i + 1);
|
|
3730
|
+
return vastTagUrl;
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3733
|
+
if (this.config.debugAdTiming) {
|
|
3734
|
+
console.log(
|
|
3735
|
+
"[StormcloudVideoPlayer] No preloaded ads found in queue"
|
|
3736
|
+
);
|
|
3737
|
+
}
|
|
3738
|
+
return void 0;
|
|
3739
|
+
}
|
|
3519
3740
|
getRemainingAdMs() {
|
|
3520
3741
|
if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)
|
|
3521
3742
|
return 0;
|
|
@@ -3684,6 +3905,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3684
3905
|
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
3685
3906
|
this.releaseAdHoldState();
|
|
3686
3907
|
this.preloadingAdUrls.clear();
|
|
3908
|
+
this.vastToMediaUrlMap.clear();
|
|
3909
|
+
this.preloadedMediaUrls.clear();
|
|
3910
|
+
this.preloadingMediaUrls.clear();
|
|
3687
3911
|
this.adPodAllUrls = [];
|
|
3688
3912
|
}
|
|
3689
3913
|
};
|