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
package/lib/players/index.cjs
CHANGED
|
@@ -681,6 +681,15 @@ function createImaController(video, options) {
|
|
|
681
681
|
"[IMA] Content video continues in background (Live mode)"
|
|
682
682
|
);
|
|
683
683
|
}
|
|
684
|
+
hideContentVideo();
|
|
685
|
+
if (adContainerEl) {
|
|
686
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
687
|
+
adContainerEl.style.display = "flex";
|
|
688
|
+
adContainerEl.style.backgroundColor = "#000";
|
|
689
|
+
adContainerEl.offsetHeight;
|
|
690
|
+
adContainerEl.style.opacity = "1";
|
|
691
|
+
console.log("[IMA] Ad container shown on content pause");
|
|
692
|
+
}
|
|
684
693
|
adPlaying = true;
|
|
685
694
|
setAdPlayingFlag(true);
|
|
686
695
|
emit("content_pause");
|
|
@@ -2215,6 +2224,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2215
2224
|
this.hasInitialBufferCompleted = false;
|
|
2216
2225
|
this.adPodAllUrls = [];
|
|
2217
2226
|
this.preloadingAdUrls = /* @__PURE__ */ new Set();
|
|
2227
|
+
this.vastToMediaUrlMap = /* @__PURE__ */ new Map();
|
|
2228
|
+
this.preloadedMediaUrls = /* @__PURE__ */ new Set();
|
|
2229
|
+
this.preloadingMediaUrls = /* @__PURE__ */ new Set();
|
|
2218
2230
|
initializePolyfills();
|
|
2219
2231
|
const browserOverrides = getBrowserConfigOverrides();
|
|
2220
2232
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2487,27 +2499,44 @@ var StormcloudVideoPlayer = class {
|
|
|
2487
2499
|
});
|
|
2488
2500
|
this.ima.on("ad_error", () => {
|
|
2489
2501
|
if (this.config.debugAdTiming) {
|
|
2490
|
-
console.log("[StormcloudVideoPlayer] IMA ad_error event received"
|
|
2502
|
+
console.log("[StormcloudVideoPlayer] IMA ad_error event received", {
|
|
2503
|
+
showAds: this.showAds,
|
|
2504
|
+
inAdBreak: this.inAdBreak,
|
|
2505
|
+
remainingAds: this.adPodQueue.length
|
|
2506
|
+
});
|
|
2491
2507
|
}
|
|
2492
|
-
if (this.
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2508
|
+
if (this.inAdBreak) {
|
|
2509
|
+
const remaining = this.getRemainingAdMs();
|
|
2510
|
+
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2511
|
+
const nextPreloaded = this.findNextPreloadedAd();
|
|
2512
|
+
if (nextPreloaded) {
|
|
2497
2513
|
this.currentAdIndex++;
|
|
2498
|
-
this.
|
|
2514
|
+
if (this.config.debugAdTiming) {
|
|
2515
|
+
console.log(
|
|
2516
|
+
`[StormcloudVideoPlayer] Skipping to next preloaded ad after error`
|
|
2517
|
+
);
|
|
2518
|
+
}
|
|
2519
|
+
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2520
|
+
this.handleAdFailure();
|
|
2499
2521
|
});
|
|
2500
2522
|
} else {
|
|
2523
|
+
if (this.config.debugAdTiming) {
|
|
2524
|
+
console.log(
|
|
2525
|
+
"[StormcloudVideoPlayer] No preloaded ads available, ending ad break"
|
|
2526
|
+
);
|
|
2527
|
+
}
|
|
2501
2528
|
this.handleAdFailure();
|
|
2502
2529
|
}
|
|
2503
2530
|
} else {
|
|
2504
|
-
if (this.config.debugAdTiming) {
|
|
2505
|
-
console.log(
|
|
2506
|
-
"[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
|
|
2507
|
-
);
|
|
2508
|
-
}
|
|
2509
2531
|
this.handleAdFailure();
|
|
2510
2532
|
}
|
|
2533
|
+
} else {
|
|
2534
|
+
if (this.config.debugAdTiming) {
|
|
2535
|
+
console.log(
|
|
2536
|
+
"[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
|
|
2537
|
+
);
|
|
2538
|
+
}
|
|
2539
|
+
this.handleAdFailure();
|
|
2511
2540
|
}
|
|
2512
2541
|
});
|
|
2513
2542
|
this.ima.on("content_pause", () => {
|
|
@@ -2538,22 +2567,31 @@ var StormcloudVideoPlayer = class {
|
|
|
2538
2567
|
}
|
|
2539
2568
|
const remaining = this.getRemainingAdMs();
|
|
2540
2569
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2541
|
-
const
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
console.log(
|
|
2546
|
-
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - IMMEDIATELY starting next ad`
|
|
2547
|
-
);
|
|
2548
|
-
}
|
|
2549
|
-
this.playSingleAd(next).catch(() => {
|
|
2570
|
+
const nextPreloaded = this.findNextPreloadedAd();
|
|
2571
|
+
if (nextPreloaded) {
|
|
2572
|
+
this.currentAdIndex++;
|
|
2573
|
+
this.enforceAdHoldState();
|
|
2550
2574
|
if (this.config.debugAdTiming) {
|
|
2551
|
-
console.
|
|
2552
|
-
|
|
2575
|
+
console.log(
|
|
2576
|
+
`[StormcloudVideoPlayer] Playing next preloaded ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak})`
|
|
2577
|
+
);
|
|
2578
|
+
}
|
|
2579
|
+
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2580
|
+
if (this.config.debugAdTiming) {
|
|
2581
|
+
console.error(
|
|
2582
|
+
"[StormcloudVideoPlayer] Failed to play next ad in pod"
|
|
2583
|
+
);
|
|
2584
|
+
}
|
|
2585
|
+
this.handleAdPodComplete();
|
|
2586
|
+
});
|
|
2587
|
+
} else {
|
|
2588
|
+
if (this.config.debugAdTiming) {
|
|
2589
|
+
console.log(
|
|
2590
|
+
"[StormcloudVideoPlayer] No preloaded ads available - completing ad break"
|
|
2553
2591
|
);
|
|
2554
2592
|
}
|
|
2555
2593
|
this.handleAdPodComplete();
|
|
2556
|
-
}
|
|
2594
|
+
}
|
|
2557
2595
|
} else {
|
|
2558
2596
|
if (this.config.debugAdTiming) {
|
|
2559
2597
|
console.log(
|
|
@@ -2798,6 +2836,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2798
2836
|
const first = tags[0];
|
|
2799
2837
|
const rest = tags.slice(1);
|
|
2800
2838
|
this.adPodQueue = rest;
|
|
2839
|
+
if (!this.showAds) {
|
|
2840
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
2841
|
+
}
|
|
2801
2842
|
this.playSingleAd(first).catch(() => {
|
|
2802
2843
|
});
|
|
2803
2844
|
}
|
|
@@ -3154,19 +3195,38 @@ var StormcloudVideoPlayer = class {
|
|
|
3154
3195
|
if (vastTagUrls.length > 0) {
|
|
3155
3196
|
this.adPodAllUrls = [...vastTagUrls];
|
|
3156
3197
|
this.preloadingAdUrls.clear();
|
|
3198
|
+
this.vastToMediaUrlMap.clear();
|
|
3199
|
+
this.preloadedMediaUrls.clear();
|
|
3200
|
+
this.preloadingMediaUrls.clear();
|
|
3157
3201
|
this.logQueuedAdUrls(this.adPodAllUrls);
|
|
3202
|
+
if (this.config.debugAdTiming) {
|
|
3203
|
+
console.log(
|
|
3204
|
+
`[StormcloudVideoPlayer] Capturing original audio state before ad break:`,
|
|
3205
|
+
{
|
|
3206
|
+
videoMuted: this.video.muted,
|
|
3207
|
+
videoVolume: this.video.volume
|
|
3208
|
+
}
|
|
3209
|
+
);
|
|
3210
|
+
}
|
|
3211
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3158
3212
|
this.inAdBreak = true;
|
|
3159
|
-
this.showAds = true;
|
|
3160
3213
|
this.currentAdIndex = 0;
|
|
3161
3214
|
this.totalAdsInBreak = vastTagUrls.length;
|
|
3162
3215
|
this.adPodQueue = [...vastTagUrls];
|
|
3163
3216
|
this.enforceAdHoldState();
|
|
3164
|
-
this.preloadUpcomingAds();
|
|
3165
3217
|
if (this.config.debugAdTiming) {
|
|
3166
3218
|
console.log(
|
|
3167
|
-
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads -
|
|
3219
|
+
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - preloading all ads in parallel`
|
|
3168
3220
|
);
|
|
3169
3221
|
}
|
|
3222
|
+
this.preloadAllAdsInBackground().catch((error) => {
|
|
3223
|
+
if (this.config.debugAdTiming) {
|
|
3224
|
+
console.warn(
|
|
3225
|
+
"[StormcloudVideoPlayer] Error in background preloading:",
|
|
3226
|
+
error
|
|
3227
|
+
);
|
|
3228
|
+
}
|
|
3229
|
+
});
|
|
3170
3230
|
try {
|
|
3171
3231
|
await this.playAdPod();
|
|
3172
3232
|
} catch (error) {
|
|
@@ -3192,14 +3252,28 @@ var StormcloudVideoPlayer = class {
|
|
|
3192
3252
|
}
|
|
3193
3253
|
return;
|
|
3194
3254
|
}
|
|
3195
|
-
|
|
3255
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
3256
|
+
const firstPreloaded = this.findNextPreloadedAd();
|
|
3257
|
+
if (!firstPreloaded) {
|
|
3258
|
+
if (this.config.debugAdTiming) {
|
|
3259
|
+
console.log(
|
|
3260
|
+
"[StormcloudVideoPlayer] No preloaded ads available after waiting, trying first ad anyway"
|
|
3261
|
+
);
|
|
3262
|
+
}
|
|
3263
|
+
const firstAd = this.adPodQueue.shift();
|
|
3264
|
+
if (firstAd) {
|
|
3265
|
+
this.currentAdIndex++;
|
|
3266
|
+
await this.playSingleAd(firstAd);
|
|
3267
|
+
}
|
|
3268
|
+
return;
|
|
3269
|
+
}
|
|
3196
3270
|
this.currentAdIndex++;
|
|
3197
3271
|
if (this.config.debugAdTiming) {
|
|
3198
3272
|
console.log(
|
|
3199
|
-
`[StormcloudVideoPlayer] Playing ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3273
|
+
`[StormcloudVideoPlayer] Playing first preloaded ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3200
3274
|
);
|
|
3201
3275
|
}
|
|
3202
|
-
await this.playSingleAd(
|
|
3276
|
+
await this.playSingleAd(firstPreloaded);
|
|
3203
3277
|
}
|
|
3204
3278
|
findCurrentOrNextBreak(nowMs) {
|
|
3205
3279
|
var _a;
|
|
@@ -3232,6 +3306,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3232
3306
|
const first = tags[0];
|
|
3233
3307
|
const rest = tags.slice(1);
|
|
3234
3308
|
this.adPodQueue = rest;
|
|
3309
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3235
3310
|
this.enforceAdHoldState();
|
|
3236
3311
|
await this.playSingleAd(first);
|
|
3237
3312
|
this.inAdBreak = true;
|
|
@@ -3352,27 +3427,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3352
3427
|
`[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
|
|
3353
3428
|
);
|
|
3354
3429
|
}
|
|
3355
|
-
if (!this.showAds) {
|
|
3356
|
-
if (this.config.debugAdTiming) {
|
|
3357
|
-
console.log(
|
|
3358
|
-
`[StormcloudVideoPlayer] Capturing original state before ad request:`,
|
|
3359
|
-
{
|
|
3360
|
-
videoMuted: this.video.muted,
|
|
3361
|
-
videoVolume: this.video.volume,
|
|
3362
|
-
showAds: this.showAds
|
|
3363
|
-
}
|
|
3364
|
-
);
|
|
3365
|
-
}
|
|
3366
|
-
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3367
|
-
} else if (this.config.debugAdTiming) {
|
|
3368
|
-
console.log(
|
|
3369
|
-
`[StormcloudVideoPlayer] Keeping existing original mute state (currently showing ads)`
|
|
3370
|
-
);
|
|
3371
|
-
}
|
|
3372
3430
|
this.startAdFailsafeTimer();
|
|
3373
3431
|
try {
|
|
3374
3432
|
await this.ima.requestAds(vastTagUrl);
|
|
3375
|
-
this.preloadUpcomingAds();
|
|
3376
3433
|
try {
|
|
3377
3434
|
if (this.config.debugAdTiming) {
|
|
3378
3435
|
console.log(
|
|
@@ -3381,9 +3438,10 @@ var StormcloudVideoPlayer = class {
|
|
|
3381
3438
|
}
|
|
3382
3439
|
this.enforceAdHoldState();
|
|
3383
3440
|
await this.ima.play();
|
|
3441
|
+
this.showAds = true;
|
|
3384
3442
|
if (this.config.debugAdTiming) {
|
|
3385
3443
|
console.log(
|
|
3386
|
-
"[StormcloudVideoPlayer] Ad playback started successfully"
|
|
3444
|
+
"[StormcloudVideoPlayer] Ad playback started successfully, showAds = true"
|
|
3387
3445
|
);
|
|
3388
3446
|
}
|
|
3389
3447
|
} catch (playError) {
|
|
@@ -3411,6 +3469,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3411
3469
|
}
|
|
3412
3470
|
this.releaseAdHoldState();
|
|
3413
3471
|
this.preloadingAdUrls.clear();
|
|
3472
|
+
this.vastToMediaUrlMap.clear();
|
|
3473
|
+
this.preloadedMediaUrls.clear();
|
|
3474
|
+
this.preloadingMediaUrls.clear();
|
|
3414
3475
|
this.inAdBreak = false;
|
|
3415
3476
|
this.expectedAdBreakDurationMs = void 0;
|
|
3416
3477
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
@@ -3520,44 +3581,204 @@ var StormcloudVideoPlayer = class {
|
|
|
3520
3581
|
this.ima.hidePlaceholder();
|
|
3521
3582
|
}
|
|
3522
3583
|
}
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3584
|
+
async fetchAndParseVastXml(vastTagUrl) {
|
|
3585
|
+
try {
|
|
3586
|
+
const response = await fetch(vastTagUrl, { mode: "cors" });
|
|
3587
|
+
if (!response.ok) {
|
|
3588
|
+
throw new Error(`Failed to fetch VAST: ${response.status}`);
|
|
3589
|
+
}
|
|
3590
|
+
const xmlText = await response.text();
|
|
3591
|
+
return this.extractMediaUrlsFromVast(xmlText);
|
|
3592
|
+
} catch (error) {
|
|
3593
|
+
if (this.config.debugAdTiming) {
|
|
3594
|
+
console.warn(
|
|
3595
|
+
`[StormcloudVideoPlayer] Failed to fetch/parse VAST XML: ${vastTagUrl}`,
|
|
3596
|
+
error
|
|
3597
|
+
);
|
|
3598
|
+
}
|
|
3599
|
+
return [];
|
|
3526
3600
|
}
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3532
|
-
|
|
3601
|
+
}
|
|
3602
|
+
extractMediaUrlsFromVast(xmlText) {
|
|
3603
|
+
var _a;
|
|
3604
|
+
const mediaUrls = [];
|
|
3605
|
+
try {
|
|
3606
|
+
const parser = new DOMParser();
|
|
3607
|
+
const xmlDoc = parser.parseFromString(xmlText, "text/xml");
|
|
3608
|
+
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
3609
|
+
for (const mediaFile of Array.from(mediaFileElements)) {
|
|
3610
|
+
const url = (_a = mediaFile.textContent) == null ? void 0 : _a.trim();
|
|
3611
|
+
if (url) {
|
|
3612
|
+
const lowerUrl = url.toLowerCase();
|
|
3613
|
+
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")) {
|
|
3614
|
+
mediaUrls.push(url);
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3533
3617
|
}
|
|
3534
|
-
if (this.
|
|
3535
|
-
|
|
3618
|
+
if (this.config.debugAdTiming && mediaUrls.length > 0) {
|
|
3619
|
+
console.log(
|
|
3620
|
+
`[StormcloudVideoPlayer] Extracted ${mediaUrls.length} media URLs from VAST:`,
|
|
3621
|
+
mediaUrls
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3624
|
+
} catch (error) {
|
|
3625
|
+
if (this.config.debugAdTiming) {
|
|
3626
|
+
console.warn(
|
|
3627
|
+
"[StormcloudVideoPlayer] Failed to parse VAST XML:",
|
|
3628
|
+
error
|
|
3629
|
+
);
|
|
3536
3630
|
}
|
|
3631
|
+
}
|
|
3632
|
+
return mediaUrls;
|
|
3633
|
+
}
|
|
3634
|
+
async preloadMediaFile(mediaUrl) {
|
|
3635
|
+
if (this.preloadedMediaUrls.has(mediaUrl)) {
|
|
3636
|
+
return;
|
|
3637
|
+
}
|
|
3638
|
+
if (this.preloadingMediaUrls.has(mediaUrl)) {
|
|
3639
|
+
return;
|
|
3640
|
+
}
|
|
3641
|
+
this.preloadingMediaUrls.add(mediaUrl);
|
|
3642
|
+
try {
|
|
3537
3643
|
if (this.config.debugAdTiming) {
|
|
3538
3644
|
console.log(
|
|
3539
|
-
`[StormcloudVideoPlayer]
|
|
3645
|
+
`[StormcloudVideoPlayer] Preloading video file: ${mediaUrl}`
|
|
3540
3646
|
);
|
|
3541
3647
|
}
|
|
3542
|
-
|
|
3543
|
-
|
|
3648
|
+
const response = await fetch(mediaUrl, {
|
|
3649
|
+
mode: "cors",
|
|
3650
|
+
method: "GET",
|
|
3651
|
+
headers: {
|
|
3652
|
+
Range: "bytes=0-1048576"
|
|
3653
|
+
}
|
|
3654
|
+
});
|
|
3655
|
+
if (response.ok || response.status === 206) {
|
|
3656
|
+
this.preloadedMediaUrls.add(mediaUrl);
|
|
3544
3657
|
if (this.config.debugAdTiming) {
|
|
3545
3658
|
console.log(
|
|
3546
|
-
`[StormcloudVideoPlayer]
|
|
3659
|
+
`[StormcloudVideoPlayer] Successfully preloaded video file: ${mediaUrl}`
|
|
3547
3660
|
);
|
|
3548
3661
|
}
|
|
3549
|
-
}
|
|
3662
|
+
}
|
|
3663
|
+
} catch (error) {
|
|
3664
|
+
if (this.config.debugAdTiming) {
|
|
3665
|
+
console.warn(
|
|
3666
|
+
`[StormcloudVideoPlayer] Failed to preload video file: ${mediaUrl}`,
|
|
3667
|
+
error
|
|
3668
|
+
);
|
|
3669
|
+
}
|
|
3670
|
+
} finally {
|
|
3671
|
+
this.preloadingMediaUrls.delete(mediaUrl);
|
|
3672
|
+
}
|
|
3673
|
+
}
|
|
3674
|
+
async preloadAllAdsInBackground() {
|
|
3675
|
+
if (this.adPodAllUrls.length === 0) {
|
|
3676
|
+
return;
|
|
3677
|
+
}
|
|
3678
|
+
if (this.config.debugAdTiming) {
|
|
3679
|
+
console.log(
|
|
3680
|
+
`[StormcloudVideoPlayer] Starting parallel preload of ${this.adPodAllUrls.length} ads`
|
|
3681
|
+
);
|
|
3682
|
+
}
|
|
3683
|
+
const preloadPromises = this.adPodAllUrls.map(
|
|
3684
|
+
(vastTagUrl) => this.preloadSingleAd(vastTagUrl).catch((error) => {
|
|
3550
3685
|
if (this.config.debugAdTiming) {
|
|
3551
3686
|
console.warn(
|
|
3552
|
-
`[StormcloudVideoPlayer]
|
|
3687
|
+
`[StormcloudVideoPlayer] Preload failed for ${vastTagUrl}:`,
|
|
3553
3688
|
error
|
|
3554
3689
|
);
|
|
3555
3690
|
}
|
|
3556
|
-
})
|
|
3557
|
-
|
|
3558
|
-
|
|
3691
|
+
})
|
|
3692
|
+
);
|
|
3693
|
+
await Promise.all(preloadPromises);
|
|
3694
|
+
if (this.config.debugAdTiming) {
|
|
3695
|
+
console.log(
|
|
3696
|
+
`[StormcloudVideoPlayer] Background preloading completed for all ads`
|
|
3697
|
+
);
|
|
3559
3698
|
}
|
|
3560
3699
|
}
|
|
3700
|
+
async preloadSingleAd(vastTagUrl) {
|
|
3701
|
+
if (!vastTagUrl) return;
|
|
3702
|
+
try {
|
|
3703
|
+
if (this.ima.preloadAds && !this.ima.hasPreloadedAd(vastTagUrl)) {
|
|
3704
|
+
if (!this.preloadingAdUrls.has(vastTagUrl)) {
|
|
3705
|
+
if (this.config.debugAdTiming) {
|
|
3706
|
+
console.log(
|
|
3707
|
+
`[StormcloudVideoPlayer] Preloading VAST: ${vastTagUrl}`
|
|
3708
|
+
);
|
|
3709
|
+
}
|
|
3710
|
+
this.preloadingAdUrls.add(vastTagUrl);
|
|
3711
|
+
await this.ima.preloadAds(vastTagUrl).then(() => {
|
|
3712
|
+
if (this.config.debugAdTiming) {
|
|
3713
|
+
console.log(
|
|
3714
|
+
`[StormcloudVideoPlayer] IMA VAST preload complete: ${vastTagUrl}`
|
|
3715
|
+
);
|
|
3716
|
+
}
|
|
3717
|
+
}).catch((error) => {
|
|
3718
|
+
if (this.config.debugAdTiming) {
|
|
3719
|
+
console.warn(
|
|
3720
|
+
`[StormcloudVideoPlayer] IMA VAST preload failed: ${vastTagUrl}`,
|
|
3721
|
+
error
|
|
3722
|
+
);
|
|
3723
|
+
}
|
|
3724
|
+
}).finally(() => {
|
|
3725
|
+
this.preloadingAdUrls.delete(vastTagUrl);
|
|
3726
|
+
});
|
|
3727
|
+
}
|
|
3728
|
+
}
|
|
3729
|
+
let mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3730
|
+
if (!mediaUrls) {
|
|
3731
|
+
if (this.config.debugAdTiming) {
|
|
3732
|
+
console.log(
|
|
3733
|
+
`[StormcloudVideoPlayer] Fetching and parsing VAST to extract media URLs: ${vastTagUrl}`
|
|
3734
|
+
);
|
|
3735
|
+
}
|
|
3736
|
+
mediaUrls = await this.fetchAndParseVastXml(vastTagUrl);
|
|
3737
|
+
if (mediaUrls.length > 0) {
|
|
3738
|
+
this.vastToMediaUrlMap.set(vastTagUrl, mediaUrls);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
if (mediaUrls && mediaUrls.length > 0) {
|
|
3742
|
+
const primaryMediaUrl = mediaUrls[0];
|
|
3743
|
+
if (primaryMediaUrl && !this.preloadedMediaUrls.has(primaryMediaUrl)) {
|
|
3744
|
+
await this.preloadMediaFile(primaryMediaUrl);
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
} catch (error) {
|
|
3748
|
+
if (this.config.debugAdTiming) {
|
|
3749
|
+
console.warn(
|
|
3750
|
+
`[StormcloudVideoPlayer] Failed to preload ad: ${vastTagUrl}`,
|
|
3751
|
+
error
|
|
3752
|
+
);
|
|
3753
|
+
}
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
findNextPreloadedAd() {
|
|
3757
|
+
var _a, _b, _c;
|
|
3758
|
+
for (let i = 0; i < this.adPodQueue.length; i++) {
|
|
3759
|
+
const vastTagUrl = this.adPodQueue[i];
|
|
3760
|
+
if (!vastTagUrl) continue;
|
|
3761
|
+
const hasImaPreload = (_c = (_b = (_a = this.ima).hasPreloadedAd) == null ? void 0 : _b.call(_a, vastTagUrl)) != null ? _c : false;
|
|
3762
|
+
const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3763
|
+
const hasMediaPreload = mediaUrls && mediaUrls.length > 0 ? this.preloadedMediaUrls.has(mediaUrls[0]) : false;
|
|
3764
|
+
if (hasImaPreload || hasMediaPreload) {
|
|
3765
|
+
if (this.config.debugAdTiming) {
|
|
3766
|
+
console.log(
|
|
3767
|
+
`[StormcloudVideoPlayer] Found preloaded ad at index ${i}: ${vastTagUrl}`,
|
|
3768
|
+
{ hasImaPreload, hasMediaPreload }
|
|
3769
|
+
);
|
|
3770
|
+
}
|
|
3771
|
+
this.adPodQueue.splice(0, i + 1);
|
|
3772
|
+
return vastTagUrl;
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
if (this.config.debugAdTiming) {
|
|
3776
|
+
console.log(
|
|
3777
|
+
"[StormcloudVideoPlayer] No preloaded ads found in queue"
|
|
3778
|
+
);
|
|
3779
|
+
}
|
|
3780
|
+
return void 0;
|
|
3781
|
+
}
|
|
3561
3782
|
getRemainingAdMs() {
|
|
3562
3783
|
if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)
|
|
3563
3784
|
return 0;
|
|
@@ -3726,6 +3947,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3726
3947
|
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
3727
3948
|
this.releaseAdHoldState();
|
|
3728
3949
|
this.preloadingAdUrls.clear();
|
|
3950
|
+
this.vastToMediaUrlMap.clear();
|
|
3951
|
+
this.preloadedMediaUrls.clear();
|
|
3952
|
+
this.preloadingMediaUrls.clear();
|
|
3729
3953
|
this.adPodAllUrls = [];
|
|
3730
3954
|
}
|
|
3731
3955
|
};
|