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/index.cjs
CHANGED
|
@@ -706,6 +706,15 @@ function createImaController(video, options) {
|
|
|
706
706
|
"[IMA] Content video continues in background (Live mode)"
|
|
707
707
|
);
|
|
708
708
|
}
|
|
709
|
+
hideContentVideo();
|
|
710
|
+
if (adContainerEl) {
|
|
711
|
+
adContainerEl.style.pointerEvents = "auto";
|
|
712
|
+
adContainerEl.style.display = "flex";
|
|
713
|
+
adContainerEl.style.backgroundColor = "#000";
|
|
714
|
+
adContainerEl.offsetHeight;
|
|
715
|
+
adContainerEl.style.opacity = "1";
|
|
716
|
+
console.log("[IMA] Ad container shown on content pause");
|
|
717
|
+
}
|
|
709
718
|
adPlaying = true;
|
|
710
719
|
setAdPlayingFlag(true);
|
|
711
720
|
emit("content_pause");
|
|
@@ -2240,6 +2249,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2240
2249
|
this.hasInitialBufferCompleted = false;
|
|
2241
2250
|
this.adPodAllUrls = [];
|
|
2242
2251
|
this.preloadingAdUrls = /* @__PURE__ */ new Set();
|
|
2252
|
+
this.vastToMediaUrlMap = /* @__PURE__ */ new Map();
|
|
2253
|
+
this.preloadedMediaUrls = /* @__PURE__ */ new Set();
|
|
2254
|
+
this.preloadingMediaUrls = /* @__PURE__ */ new Set();
|
|
2243
2255
|
initializePolyfills();
|
|
2244
2256
|
const browserOverrides = getBrowserConfigOverrides();
|
|
2245
2257
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2512,27 +2524,44 @@ var StormcloudVideoPlayer = class {
|
|
|
2512
2524
|
});
|
|
2513
2525
|
this.ima.on("ad_error", () => {
|
|
2514
2526
|
if (this.config.debugAdTiming) {
|
|
2515
|
-
console.log("[StormcloudVideoPlayer] IMA ad_error event received"
|
|
2527
|
+
console.log("[StormcloudVideoPlayer] IMA ad_error event received", {
|
|
2528
|
+
showAds: this.showAds,
|
|
2529
|
+
inAdBreak: this.inAdBreak,
|
|
2530
|
+
remainingAds: this.adPodQueue.length
|
|
2531
|
+
});
|
|
2516
2532
|
}
|
|
2517
|
-
if (this.
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2533
|
+
if (this.inAdBreak) {
|
|
2534
|
+
const remaining = this.getRemainingAdMs();
|
|
2535
|
+
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2536
|
+
const nextPreloaded = this.findNextPreloadedAd();
|
|
2537
|
+
if (nextPreloaded) {
|
|
2522
2538
|
this.currentAdIndex++;
|
|
2523
|
-
this.
|
|
2539
|
+
if (this.config.debugAdTiming) {
|
|
2540
|
+
console.log(
|
|
2541
|
+
`[StormcloudVideoPlayer] Skipping to next preloaded ad after error`
|
|
2542
|
+
);
|
|
2543
|
+
}
|
|
2544
|
+
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2545
|
+
this.handleAdFailure();
|
|
2524
2546
|
});
|
|
2525
2547
|
} else {
|
|
2548
|
+
if (this.config.debugAdTiming) {
|
|
2549
|
+
console.log(
|
|
2550
|
+
"[StormcloudVideoPlayer] No preloaded ads available, ending ad break"
|
|
2551
|
+
);
|
|
2552
|
+
}
|
|
2526
2553
|
this.handleAdFailure();
|
|
2527
2554
|
}
|
|
2528
2555
|
} else {
|
|
2529
|
-
if (this.config.debugAdTiming) {
|
|
2530
|
-
console.log(
|
|
2531
|
-
"[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
|
|
2532
|
-
);
|
|
2533
|
-
}
|
|
2534
2556
|
this.handleAdFailure();
|
|
2535
2557
|
}
|
|
2558
|
+
} else {
|
|
2559
|
+
if (this.config.debugAdTiming) {
|
|
2560
|
+
console.log(
|
|
2561
|
+
"[StormcloudVideoPlayer] Ad error before ad break established - cleaning up"
|
|
2562
|
+
);
|
|
2563
|
+
}
|
|
2564
|
+
this.handleAdFailure();
|
|
2536
2565
|
}
|
|
2537
2566
|
});
|
|
2538
2567
|
this.ima.on("content_pause", () => {
|
|
@@ -2563,22 +2592,31 @@ var StormcloudVideoPlayer = class {
|
|
|
2563
2592
|
}
|
|
2564
2593
|
const remaining = this.getRemainingAdMs();
|
|
2565
2594
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2566
|
-
const
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
console.log(
|
|
2571
|
-
`[StormcloudVideoPlayer] Playing next ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak}) - IMMEDIATELY starting next ad`
|
|
2572
|
-
);
|
|
2573
|
-
}
|
|
2574
|
-
this.playSingleAd(next).catch(() => {
|
|
2595
|
+
const nextPreloaded = this.findNextPreloadedAd();
|
|
2596
|
+
if (nextPreloaded) {
|
|
2597
|
+
this.currentAdIndex++;
|
|
2598
|
+
this.enforceAdHoldState();
|
|
2575
2599
|
if (this.config.debugAdTiming) {
|
|
2576
|
-
console.
|
|
2577
|
-
|
|
2600
|
+
console.log(
|
|
2601
|
+
`[StormcloudVideoPlayer] Playing next preloaded ad in pod (${this.currentAdIndex}/${this.totalAdsInBreak})`
|
|
2602
|
+
);
|
|
2603
|
+
}
|
|
2604
|
+
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2605
|
+
if (this.config.debugAdTiming) {
|
|
2606
|
+
console.error(
|
|
2607
|
+
"[StormcloudVideoPlayer] Failed to play next ad in pod"
|
|
2608
|
+
);
|
|
2609
|
+
}
|
|
2610
|
+
this.handleAdPodComplete();
|
|
2611
|
+
});
|
|
2612
|
+
} else {
|
|
2613
|
+
if (this.config.debugAdTiming) {
|
|
2614
|
+
console.log(
|
|
2615
|
+
"[StormcloudVideoPlayer] No preloaded ads available - completing ad break"
|
|
2578
2616
|
);
|
|
2579
2617
|
}
|
|
2580
2618
|
this.handleAdPodComplete();
|
|
2581
|
-
}
|
|
2619
|
+
}
|
|
2582
2620
|
} else {
|
|
2583
2621
|
if (this.config.debugAdTiming) {
|
|
2584
2622
|
console.log(
|
|
@@ -2823,6 +2861,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2823
2861
|
const first = tags[0];
|
|
2824
2862
|
const rest = tags.slice(1);
|
|
2825
2863
|
this.adPodQueue = rest;
|
|
2864
|
+
if (!this.showAds) {
|
|
2865
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
2866
|
+
}
|
|
2826
2867
|
this.playSingleAd(first).catch(() => {
|
|
2827
2868
|
});
|
|
2828
2869
|
}
|
|
@@ -3179,19 +3220,38 @@ var StormcloudVideoPlayer = class {
|
|
|
3179
3220
|
if (vastTagUrls.length > 0) {
|
|
3180
3221
|
this.adPodAllUrls = [...vastTagUrls];
|
|
3181
3222
|
this.preloadingAdUrls.clear();
|
|
3223
|
+
this.vastToMediaUrlMap.clear();
|
|
3224
|
+
this.preloadedMediaUrls.clear();
|
|
3225
|
+
this.preloadingMediaUrls.clear();
|
|
3182
3226
|
this.logQueuedAdUrls(this.adPodAllUrls);
|
|
3227
|
+
if (this.config.debugAdTiming) {
|
|
3228
|
+
console.log(
|
|
3229
|
+
`[StormcloudVideoPlayer] Capturing original audio state before ad break:`,
|
|
3230
|
+
{
|
|
3231
|
+
videoMuted: this.video.muted,
|
|
3232
|
+
videoVolume: this.video.volume
|
|
3233
|
+
}
|
|
3234
|
+
);
|
|
3235
|
+
}
|
|
3236
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3183
3237
|
this.inAdBreak = true;
|
|
3184
|
-
this.showAds = true;
|
|
3185
3238
|
this.currentAdIndex = 0;
|
|
3186
3239
|
this.totalAdsInBreak = vastTagUrls.length;
|
|
3187
3240
|
this.adPodQueue = [...vastTagUrls];
|
|
3188
3241
|
this.enforceAdHoldState();
|
|
3189
|
-
this.preloadUpcomingAds();
|
|
3190
3242
|
if (this.config.debugAdTiming) {
|
|
3191
3243
|
console.log(
|
|
3192
|
-
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads -
|
|
3244
|
+
`[StormcloudVideoPlayer] Starting ad pod with ${vastTagUrls.length} ads - preloading all ads in parallel`
|
|
3193
3245
|
);
|
|
3194
3246
|
}
|
|
3247
|
+
this.preloadAllAdsInBackground().catch((error) => {
|
|
3248
|
+
if (this.config.debugAdTiming) {
|
|
3249
|
+
console.warn(
|
|
3250
|
+
"[StormcloudVideoPlayer] Error in background preloading:",
|
|
3251
|
+
error
|
|
3252
|
+
);
|
|
3253
|
+
}
|
|
3254
|
+
});
|
|
3195
3255
|
try {
|
|
3196
3256
|
await this.playAdPod();
|
|
3197
3257
|
} catch (error) {
|
|
@@ -3217,14 +3277,28 @@ var StormcloudVideoPlayer = class {
|
|
|
3217
3277
|
}
|
|
3218
3278
|
return;
|
|
3219
3279
|
}
|
|
3220
|
-
|
|
3280
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
3281
|
+
const firstPreloaded = this.findNextPreloadedAd();
|
|
3282
|
+
if (!firstPreloaded) {
|
|
3283
|
+
if (this.config.debugAdTiming) {
|
|
3284
|
+
console.log(
|
|
3285
|
+
"[StormcloudVideoPlayer] No preloaded ads available after waiting, trying first ad anyway"
|
|
3286
|
+
);
|
|
3287
|
+
}
|
|
3288
|
+
const firstAd = this.adPodQueue.shift();
|
|
3289
|
+
if (firstAd) {
|
|
3290
|
+
this.currentAdIndex++;
|
|
3291
|
+
await this.playSingleAd(firstAd);
|
|
3292
|
+
}
|
|
3293
|
+
return;
|
|
3294
|
+
}
|
|
3221
3295
|
this.currentAdIndex++;
|
|
3222
3296
|
if (this.config.debugAdTiming) {
|
|
3223
3297
|
console.log(
|
|
3224
|
-
`[StormcloudVideoPlayer] Playing ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3298
|
+
`[StormcloudVideoPlayer] Playing first preloaded ad ${this.currentAdIndex}/${this.totalAdsInBreak}`
|
|
3225
3299
|
);
|
|
3226
3300
|
}
|
|
3227
|
-
await this.playSingleAd(
|
|
3301
|
+
await this.playSingleAd(firstPreloaded);
|
|
3228
3302
|
}
|
|
3229
3303
|
findCurrentOrNextBreak(nowMs) {
|
|
3230
3304
|
var _a;
|
|
@@ -3257,6 +3331,7 @@ var StormcloudVideoPlayer = class {
|
|
|
3257
3331
|
const first = tags[0];
|
|
3258
3332
|
const rest = tags.slice(1);
|
|
3259
3333
|
this.adPodQueue = rest;
|
|
3334
|
+
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3260
3335
|
this.enforceAdHoldState();
|
|
3261
3336
|
await this.playSingleAd(first);
|
|
3262
3337
|
this.inAdBreak = true;
|
|
@@ -3377,27 +3452,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3377
3452
|
`[StormcloudVideoPlayer] IMA SDK preloaded this ad already: ${vastTagUrl}`
|
|
3378
3453
|
);
|
|
3379
3454
|
}
|
|
3380
|
-
if (!this.showAds) {
|
|
3381
|
-
if (this.config.debugAdTiming) {
|
|
3382
|
-
console.log(
|
|
3383
|
-
`[StormcloudVideoPlayer] Capturing original state before ad request:`,
|
|
3384
|
-
{
|
|
3385
|
-
videoMuted: this.video.muted,
|
|
3386
|
-
videoVolume: this.video.volume,
|
|
3387
|
-
showAds: this.showAds
|
|
3388
|
-
}
|
|
3389
|
-
);
|
|
3390
|
-
}
|
|
3391
|
-
this.ima.updateOriginalMutedState(this.video.muted, this.video.volume);
|
|
3392
|
-
} else if (this.config.debugAdTiming) {
|
|
3393
|
-
console.log(
|
|
3394
|
-
`[StormcloudVideoPlayer] Keeping existing original mute state (currently showing ads)`
|
|
3395
|
-
);
|
|
3396
|
-
}
|
|
3397
3455
|
this.startAdFailsafeTimer();
|
|
3398
3456
|
try {
|
|
3399
3457
|
await this.ima.requestAds(vastTagUrl);
|
|
3400
|
-
this.preloadUpcomingAds();
|
|
3401
3458
|
try {
|
|
3402
3459
|
if (this.config.debugAdTiming) {
|
|
3403
3460
|
console.log(
|
|
@@ -3406,9 +3463,10 @@ var StormcloudVideoPlayer = class {
|
|
|
3406
3463
|
}
|
|
3407
3464
|
this.enforceAdHoldState();
|
|
3408
3465
|
await this.ima.play();
|
|
3466
|
+
this.showAds = true;
|
|
3409
3467
|
if (this.config.debugAdTiming) {
|
|
3410
3468
|
console.log(
|
|
3411
|
-
"[StormcloudVideoPlayer] Ad playback started successfully"
|
|
3469
|
+
"[StormcloudVideoPlayer] Ad playback started successfully, showAds = true"
|
|
3412
3470
|
);
|
|
3413
3471
|
}
|
|
3414
3472
|
} catch (playError) {
|
|
@@ -3436,6 +3494,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3436
3494
|
}
|
|
3437
3495
|
this.releaseAdHoldState();
|
|
3438
3496
|
this.preloadingAdUrls.clear();
|
|
3497
|
+
this.vastToMediaUrlMap.clear();
|
|
3498
|
+
this.preloadedMediaUrls.clear();
|
|
3499
|
+
this.preloadingMediaUrls.clear();
|
|
3439
3500
|
this.inAdBreak = false;
|
|
3440
3501
|
this.expectedAdBreakDurationMs = void 0;
|
|
3441
3502
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
@@ -3545,44 +3606,204 @@ var StormcloudVideoPlayer = class {
|
|
|
3545
3606
|
this.ima.hidePlaceholder();
|
|
3546
3607
|
}
|
|
3547
3608
|
}
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3609
|
+
async fetchAndParseVastXml(vastTagUrl) {
|
|
3610
|
+
try {
|
|
3611
|
+
const response = await fetch(vastTagUrl, { mode: "cors" });
|
|
3612
|
+
if (!response.ok) {
|
|
3613
|
+
throw new Error(`Failed to fetch VAST: ${response.status}`);
|
|
3614
|
+
}
|
|
3615
|
+
const xmlText = await response.text();
|
|
3616
|
+
return this.extractMediaUrlsFromVast(xmlText);
|
|
3617
|
+
} catch (error) {
|
|
3618
|
+
if (this.config.debugAdTiming) {
|
|
3619
|
+
console.warn(
|
|
3620
|
+
`[StormcloudVideoPlayer] Failed to fetch/parse VAST XML: ${vastTagUrl}`,
|
|
3621
|
+
error
|
|
3622
|
+
);
|
|
3623
|
+
}
|
|
3624
|
+
return [];
|
|
3551
3625
|
}
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3626
|
+
}
|
|
3627
|
+
extractMediaUrlsFromVast(xmlText) {
|
|
3628
|
+
var _a;
|
|
3629
|
+
const mediaUrls = [];
|
|
3630
|
+
try {
|
|
3631
|
+
const parser = new DOMParser();
|
|
3632
|
+
const xmlDoc = parser.parseFromString(xmlText, "text/xml");
|
|
3633
|
+
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
3634
|
+
for (const mediaFile of Array.from(mediaFileElements)) {
|
|
3635
|
+
const url = (_a = mediaFile.textContent) == null ? void 0 : _a.trim();
|
|
3636
|
+
if (url) {
|
|
3637
|
+
const lowerUrl = url.toLowerCase();
|
|
3638
|
+
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")) {
|
|
3639
|
+
mediaUrls.push(url);
|
|
3640
|
+
}
|
|
3641
|
+
}
|
|
3558
3642
|
}
|
|
3559
|
-
if (this.
|
|
3560
|
-
|
|
3643
|
+
if (this.config.debugAdTiming && mediaUrls.length > 0) {
|
|
3644
|
+
console.log(
|
|
3645
|
+
`[StormcloudVideoPlayer] Extracted ${mediaUrls.length} media URLs from VAST:`,
|
|
3646
|
+
mediaUrls
|
|
3647
|
+
);
|
|
3648
|
+
}
|
|
3649
|
+
} catch (error) {
|
|
3650
|
+
if (this.config.debugAdTiming) {
|
|
3651
|
+
console.warn(
|
|
3652
|
+
"[StormcloudVideoPlayer] Failed to parse VAST XML:",
|
|
3653
|
+
error
|
|
3654
|
+
);
|
|
3561
3655
|
}
|
|
3656
|
+
}
|
|
3657
|
+
return mediaUrls;
|
|
3658
|
+
}
|
|
3659
|
+
async preloadMediaFile(mediaUrl) {
|
|
3660
|
+
if (this.preloadedMediaUrls.has(mediaUrl)) {
|
|
3661
|
+
return;
|
|
3662
|
+
}
|
|
3663
|
+
if (this.preloadingMediaUrls.has(mediaUrl)) {
|
|
3664
|
+
return;
|
|
3665
|
+
}
|
|
3666
|
+
this.preloadingMediaUrls.add(mediaUrl);
|
|
3667
|
+
try {
|
|
3562
3668
|
if (this.config.debugAdTiming) {
|
|
3563
3669
|
console.log(
|
|
3564
|
-
`[StormcloudVideoPlayer]
|
|
3670
|
+
`[StormcloudVideoPlayer] Preloading video file: ${mediaUrl}`
|
|
3565
3671
|
);
|
|
3566
3672
|
}
|
|
3567
|
-
|
|
3568
|
-
|
|
3673
|
+
const response = await fetch(mediaUrl, {
|
|
3674
|
+
mode: "cors",
|
|
3675
|
+
method: "GET",
|
|
3676
|
+
headers: {
|
|
3677
|
+
Range: "bytes=0-1048576"
|
|
3678
|
+
}
|
|
3679
|
+
});
|
|
3680
|
+
if (response.ok || response.status === 206) {
|
|
3681
|
+
this.preloadedMediaUrls.add(mediaUrl);
|
|
3569
3682
|
if (this.config.debugAdTiming) {
|
|
3570
3683
|
console.log(
|
|
3571
|
-
`[StormcloudVideoPlayer]
|
|
3684
|
+
`[StormcloudVideoPlayer] Successfully preloaded video file: ${mediaUrl}`
|
|
3572
3685
|
);
|
|
3573
3686
|
}
|
|
3574
|
-
}
|
|
3687
|
+
}
|
|
3688
|
+
} catch (error) {
|
|
3689
|
+
if (this.config.debugAdTiming) {
|
|
3690
|
+
console.warn(
|
|
3691
|
+
`[StormcloudVideoPlayer] Failed to preload video file: ${mediaUrl}`,
|
|
3692
|
+
error
|
|
3693
|
+
);
|
|
3694
|
+
}
|
|
3695
|
+
} finally {
|
|
3696
|
+
this.preloadingMediaUrls.delete(mediaUrl);
|
|
3697
|
+
}
|
|
3698
|
+
}
|
|
3699
|
+
async preloadAllAdsInBackground() {
|
|
3700
|
+
if (this.adPodAllUrls.length === 0) {
|
|
3701
|
+
return;
|
|
3702
|
+
}
|
|
3703
|
+
if (this.config.debugAdTiming) {
|
|
3704
|
+
console.log(
|
|
3705
|
+
`[StormcloudVideoPlayer] Starting parallel preload of ${this.adPodAllUrls.length} ads`
|
|
3706
|
+
);
|
|
3707
|
+
}
|
|
3708
|
+
const preloadPromises = this.adPodAllUrls.map(
|
|
3709
|
+
(vastTagUrl) => this.preloadSingleAd(vastTagUrl).catch((error) => {
|
|
3575
3710
|
if (this.config.debugAdTiming) {
|
|
3576
3711
|
console.warn(
|
|
3577
|
-
`[StormcloudVideoPlayer]
|
|
3712
|
+
`[StormcloudVideoPlayer] Preload failed for ${vastTagUrl}:`,
|
|
3578
3713
|
error
|
|
3579
3714
|
);
|
|
3580
3715
|
}
|
|
3581
|
-
})
|
|
3582
|
-
|
|
3583
|
-
|
|
3716
|
+
})
|
|
3717
|
+
);
|
|
3718
|
+
await Promise.all(preloadPromises);
|
|
3719
|
+
if (this.config.debugAdTiming) {
|
|
3720
|
+
console.log(
|
|
3721
|
+
`[StormcloudVideoPlayer] Background preloading completed for all ads`
|
|
3722
|
+
);
|
|
3584
3723
|
}
|
|
3585
3724
|
}
|
|
3725
|
+
async preloadSingleAd(vastTagUrl) {
|
|
3726
|
+
if (!vastTagUrl) return;
|
|
3727
|
+
try {
|
|
3728
|
+
if (this.ima.preloadAds && !this.ima.hasPreloadedAd(vastTagUrl)) {
|
|
3729
|
+
if (!this.preloadingAdUrls.has(vastTagUrl)) {
|
|
3730
|
+
if (this.config.debugAdTiming) {
|
|
3731
|
+
console.log(
|
|
3732
|
+
`[StormcloudVideoPlayer] Preloading VAST: ${vastTagUrl}`
|
|
3733
|
+
);
|
|
3734
|
+
}
|
|
3735
|
+
this.preloadingAdUrls.add(vastTagUrl);
|
|
3736
|
+
await this.ima.preloadAds(vastTagUrl).then(() => {
|
|
3737
|
+
if (this.config.debugAdTiming) {
|
|
3738
|
+
console.log(
|
|
3739
|
+
`[StormcloudVideoPlayer] IMA VAST preload complete: ${vastTagUrl}`
|
|
3740
|
+
);
|
|
3741
|
+
}
|
|
3742
|
+
}).catch((error) => {
|
|
3743
|
+
if (this.config.debugAdTiming) {
|
|
3744
|
+
console.warn(
|
|
3745
|
+
`[StormcloudVideoPlayer] IMA VAST preload failed: ${vastTagUrl}`,
|
|
3746
|
+
error
|
|
3747
|
+
);
|
|
3748
|
+
}
|
|
3749
|
+
}).finally(() => {
|
|
3750
|
+
this.preloadingAdUrls.delete(vastTagUrl);
|
|
3751
|
+
});
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
let mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3755
|
+
if (!mediaUrls) {
|
|
3756
|
+
if (this.config.debugAdTiming) {
|
|
3757
|
+
console.log(
|
|
3758
|
+
`[StormcloudVideoPlayer] Fetching and parsing VAST to extract media URLs: ${vastTagUrl}`
|
|
3759
|
+
);
|
|
3760
|
+
}
|
|
3761
|
+
mediaUrls = await this.fetchAndParseVastXml(vastTagUrl);
|
|
3762
|
+
if (mediaUrls.length > 0) {
|
|
3763
|
+
this.vastToMediaUrlMap.set(vastTagUrl, mediaUrls);
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
if (mediaUrls && mediaUrls.length > 0) {
|
|
3767
|
+
const primaryMediaUrl = mediaUrls[0];
|
|
3768
|
+
if (primaryMediaUrl && !this.preloadedMediaUrls.has(primaryMediaUrl)) {
|
|
3769
|
+
await this.preloadMediaFile(primaryMediaUrl);
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3772
|
+
} catch (error) {
|
|
3773
|
+
if (this.config.debugAdTiming) {
|
|
3774
|
+
console.warn(
|
|
3775
|
+
`[StormcloudVideoPlayer] Failed to preload ad: ${vastTagUrl}`,
|
|
3776
|
+
error
|
|
3777
|
+
);
|
|
3778
|
+
}
|
|
3779
|
+
}
|
|
3780
|
+
}
|
|
3781
|
+
findNextPreloadedAd() {
|
|
3782
|
+
var _a, _b, _c;
|
|
3783
|
+
for (let i = 0; i < this.adPodQueue.length; i++) {
|
|
3784
|
+
const vastTagUrl = this.adPodQueue[i];
|
|
3785
|
+
if (!vastTagUrl) continue;
|
|
3786
|
+
const hasImaPreload = (_c = (_b = (_a = this.ima).hasPreloadedAd) == null ? void 0 : _b.call(_a, vastTagUrl)) != null ? _c : false;
|
|
3787
|
+
const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3788
|
+
const hasMediaPreload = mediaUrls && mediaUrls.length > 0 ? this.preloadedMediaUrls.has(mediaUrls[0]) : false;
|
|
3789
|
+
if (hasImaPreload || hasMediaPreload) {
|
|
3790
|
+
if (this.config.debugAdTiming) {
|
|
3791
|
+
console.log(
|
|
3792
|
+
`[StormcloudVideoPlayer] Found preloaded ad at index ${i}: ${vastTagUrl}`,
|
|
3793
|
+
{ hasImaPreload, hasMediaPreload }
|
|
3794
|
+
);
|
|
3795
|
+
}
|
|
3796
|
+
this.adPodQueue.splice(0, i + 1);
|
|
3797
|
+
return vastTagUrl;
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
if (this.config.debugAdTiming) {
|
|
3801
|
+
console.log(
|
|
3802
|
+
"[StormcloudVideoPlayer] No preloaded ads found in queue"
|
|
3803
|
+
);
|
|
3804
|
+
}
|
|
3805
|
+
return void 0;
|
|
3806
|
+
}
|
|
3586
3807
|
getRemainingAdMs() {
|
|
3587
3808
|
if (this.expectedAdBreakDurationMs == null || this.currentAdBreakStartWallClockMs == null)
|
|
3588
3809
|
return 0;
|
|
@@ -3751,6 +3972,9 @@ var StormcloudVideoPlayer = class {
|
|
|
3751
3972
|
(_b = this.ima) == null ? void 0 : _b.destroy();
|
|
3752
3973
|
this.releaseAdHoldState();
|
|
3753
3974
|
this.preloadingAdUrls.clear();
|
|
3975
|
+
this.vastToMediaUrlMap.clear();
|
|
3976
|
+
this.preloadedMediaUrls.clear();
|
|
3977
|
+
this.preloadingMediaUrls.clear();
|
|
3754
3978
|
this.adPodAllUrls = [];
|
|
3755
3979
|
}
|
|
3756
3980
|
};
|