stormcloud-video-player 0.3.6 → 0.3.8
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 +26 -191
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +26 -191
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +26 -191
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +1 -0
- package/lib/players/HlsPlayer.cjs +26 -191
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +26 -191
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +6 -80
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +26 -191
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
|
@@ -222,7 +222,6 @@ function createImaController(video, options) {
|
|
|
222
222
|
video.muted = true;
|
|
223
223
|
video.volume = 0;
|
|
224
224
|
contentVideoHidden = true;
|
|
225
|
-
console.log("[DEBUG-LAYER] \u{1F534} Content video HIDDEN | muted=true, volume=0");
|
|
226
225
|
}
|
|
227
226
|
}
|
|
228
227
|
function showContentVideo() {
|
|
@@ -234,9 +233,6 @@ function createImaController(video, options) {
|
|
|
234
233
|
video.muted = originalMutedState;
|
|
235
234
|
video.volume = originalVolume;
|
|
236
235
|
contentVideoHidden = false;
|
|
237
|
-
console.log(
|
|
238
|
-
`[DEBUG-LAYER] \u{1F7E2} Content video RESTORED | muted=${originalMutedState}, volume=${originalVolume}`
|
|
239
|
-
);
|
|
240
236
|
}
|
|
241
237
|
}
|
|
242
238
|
function createAdVideoElement() {
|
|
@@ -257,13 +253,9 @@ function createImaController(video, options) {
|
|
|
257
253
|
"canplay",
|
|
258
254
|
() => {
|
|
259
255
|
adVideo.style.opacity = "1";
|
|
260
|
-
console.log("[DEBUG-LAYER] \u{1F4FA} Ad video element ready (canplay fired)");
|
|
261
256
|
},
|
|
262
257
|
{ once: true }
|
|
263
258
|
);
|
|
264
|
-
console.log(
|
|
265
|
-
`[DEBUG-AUDIO] \u{1F50A} Ad video created | volume=${adVideo.volume}, muted=${adVideo.muted}`
|
|
266
|
-
);
|
|
267
259
|
return adVideo;
|
|
268
260
|
}
|
|
269
261
|
function emit(event, payload) {
|
|
@@ -415,10 +407,8 @@ function createImaController(video, options) {
|
|
|
415
407
|
function destroyAdsManager() {
|
|
416
408
|
if (adsManager) {
|
|
417
409
|
try {
|
|
418
|
-
console.log("[IMA] Destroying existing ads manager");
|
|
419
410
|
adsManager.destroy();
|
|
420
|
-
} catch
|
|
421
|
-
console.warn("[IMA] Error destroying ads manager:", error);
|
|
411
|
+
} catch {
|
|
422
412
|
}
|
|
423
413
|
adsManager = void 0;
|
|
424
414
|
}
|
|
@@ -436,9 +426,6 @@ function createImaController(video, options) {
|
|
|
436
426
|
if (!adVideoElement) {
|
|
437
427
|
adVideoElement = createAdVideoElement();
|
|
438
428
|
adContainerEl.appendChild(adVideoElement);
|
|
439
|
-
console.log(
|
|
440
|
-
"[IMA] Dedicated ad video element added to container"
|
|
441
|
-
);
|
|
442
429
|
}
|
|
443
430
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
444
431
|
adContainerEl,
|
|
@@ -446,9 +433,6 @@ function createImaController(video, options) {
|
|
|
446
433
|
);
|
|
447
434
|
try {
|
|
448
435
|
(_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
|
|
449
|
-
console.log(
|
|
450
|
-
"[IMA] AdDisplayContainer initialized with dedicated ad video"
|
|
451
|
-
);
|
|
452
436
|
} catch {
|
|
453
437
|
}
|
|
454
438
|
}
|
|
@@ -456,9 +440,6 @@ function createImaController(video, options) {
|
|
|
456
440
|
});
|
|
457
441
|
},
|
|
458
442
|
async requestAds(vastTagUrl) {
|
|
459
|
-
console.log("[IMA] \u{1F4E1} === requestAds() called ===");
|
|
460
|
-
console.log("[IMA] VAST URL:", vastTagUrl);
|
|
461
|
-
console.log("[IMA] This will fetch the ad from the server - no visual change yet");
|
|
462
443
|
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
463
444
|
const error = new Error("VAST tag URL is empty or undefined");
|
|
464
445
|
console.warn("[IMA] \u274C", error.message);
|
|
@@ -501,7 +482,6 @@ function createImaController(video, options) {
|
|
|
501
482
|
lastAdTagUrl = vastTagUrl;
|
|
502
483
|
retryAttempts = 0;
|
|
503
484
|
if (!adDisplayContainer) {
|
|
504
|
-
console.log("[IMA] Creating ad display container");
|
|
505
485
|
const container = document.createElement("div");
|
|
506
486
|
container.style.position = "absolute";
|
|
507
487
|
container.style.left = "0";
|
|
@@ -524,25 +504,11 @@ function createImaController(video, options) {
|
|
|
524
504
|
if (!adVideoElement) {
|
|
525
505
|
adVideoElement = createAdVideoElement();
|
|
526
506
|
adContainerEl.appendChild(adVideoElement);
|
|
527
|
-
console.log(
|
|
528
|
-
"[IMA] Dedicated ad video element created and added to container"
|
|
529
|
-
);
|
|
530
507
|
}
|
|
531
508
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
532
509
|
container,
|
|
533
510
|
adVideoElement
|
|
534
511
|
);
|
|
535
|
-
try {
|
|
536
|
-
adDisplayContainer.initialize();
|
|
537
|
-
console.log(
|
|
538
|
-
"[IMA] Ad display container initialized with dedicated ad video"
|
|
539
|
-
);
|
|
540
|
-
} catch (error) {
|
|
541
|
-
console.warn(
|
|
542
|
-
"[IMA] Failed to initialize ad display container:",
|
|
543
|
-
error
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
512
|
}
|
|
547
513
|
const videoWidth = video.offsetWidth || video.clientWidth;
|
|
548
514
|
const videoHeight = video.offsetHeight || video.clientHeight;
|
|
@@ -557,29 +523,17 @@ function createImaController(video, options) {
|
|
|
557
523
|
return Promise.reject(error);
|
|
558
524
|
}
|
|
559
525
|
if (!adsLoader) {
|
|
560
|
-
console.log("[IMA] Creating ads loader");
|
|
561
526
|
const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);
|
|
562
527
|
adsLoader = adsLoaderCls;
|
|
563
528
|
adsLoader.addEventListener(
|
|
564
529
|
google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED,
|
|
565
530
|
(evt) => {
|
|
566
|
-
console.log("[DEBUG-FLOW] \u2705 ADS_MANAGER_LOADED - Setting up manager");
|
|
567
531
|
try {
|
|
568
532
|
const adsRenderingSettings = new google.ima.AdsRenderingSettings();
|
|
569
533
|
adsRenderingSettings.enablePreloading = true;
|
|
570
534
|
adsManager = evt.getAdsManager(video, adsRenderingSettings);
|
|
571
535
|
const AdEvent = google.ima.AdEvent.Type;
|
|
572
536
|
const AdErrorEvent = google.ima.AdErrorEvent.Type;
|
|
573
|
-
const keyEvents = ["STARTED", "COMPLETE", "CONTENT_PAUSE_REQUESTED", "CONTENT_RESUME_REQUESTED", "ALL_ADS_COMPLETED"];
|
|
574
|
-
keyEvents.forEach((eventType) => {
|
|
575
|
-
if (AdEvent[eventType]) {
|
|
576
|
-
adsManager.addEventListener(AdEvent[eventType], (e) => {
|
|
577
|
-
var _a, _b;
|
|
578
|
-
const ad = (_a = e.getAd) == null ? void 0 : _a.call(e);
|
|
579
|
-
console.log(`[DEBUG-FLOW] \u{1F3AC} ${eventType} | title=${((_b = ad == null ? void 0 : ad.getTitle) == null ? void 0 : _b.call(ad)) || "N/A"}`);
|
|
580
|
-
});
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
537
|
adsManager.addEventListener(
|
|
584
538
|
AdErrorEvent.AD_ERROR,
|
|
585
539
|
(errorEvent) => {
|
|
@@ -596,7 +550,6 @@ function createImaController(video, options) {
|
|
|
596
550
|
if (adContainerEl) {
|
|
597
551
|
adContainerEl.style.pointerEvents = "none";
|
|
598
552
|
adContainerEl.style.display = "none";
|
|
599
|
-
console.log("[DEBUG-LAYER] \u274C Ad container HIDDEN (error)");
|
|
600
553
|
}
|
|
601
554
|
}, 300);
|
|
602
555
|
}
|
|
@@ -628,7 +581,6 @@ function createImaController(video, options) {
|
|
|
628
581
|
adsManager.addEventListener(
|
|
629
582
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
630
583
|
() => {
|
|
631
|
-
console.log("[DEBUG-FLOW] \u{1F3AF} CONTENT_PAUSE_REQUESTED - Ad request accepted");
|
|
632
584
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
633
585
|
video.pause();
|
|
634
586
|
}
|
|
@@ -638,15 +590,11 @@ function createImaController(video, options) {
|
|
|
638
590
|
}
|
|
639
591
|
);
|
|
640
592
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
641
|
-
console.log("[DEBUG-FLOW] \u25B6\uFE0F STARTED - Ad playing now");
|
|
642
593
|
setAdPlayingFlag(true);
|
|
643
594
|
hideContentVideo();
|
|
644
595
|
if (adVideoElement) {
|
|
645
596
|
adVideoElement.volume = originalMutedState ? 0 : originalVolume;
|
|
646
597
|
adVideoElement.muted = originalMutedState;
|
|
647
|
-
console.log(
|
|
648
|
-
`[DEBUG-AUDIO] \u{1F50A} Ad audio set | volume=${adVideoElement.volume}, muted=${adVideoElement.muted}`
|
|
649
|
-
);
|
|
650
598
|
}
|
|
651
599
|
if (adContainerEl) {
|
|
652
600
|
adContainerEl.style.pointerEvents = "auto";
|
|
@@ -659,15 +607,12 @@ function createImaController(video, options) {
|
|
|
659
607
|
adsManager.addEventListener(
|
|
660
608
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
661
609
|
() => {
|
|
662
|
-
console.log("[DEBUG-FLOW] \u23F8\uFE0F CONTENT_RESUME - Single ad done");
|
|
663
610
|
adPlaying = false;
|
|
664
611
|
setAdPlayingFlag(false);
|
|
665
|
-
console.log("[DEBUG-LAYER] \u26A0\uFE0F Waiting for pod manager (more ads, placeholder, or done)");
|
|
666
612
|
emit("content_resume");
|
|
667
613
|
}
|
|
668
614
|
);
|
|
669
615
|
adsManager.addEventListener(AdEvent.ALL_ADS_COMPLETED, () => {
|
|
670
|
-
console.log("[DEBUG-FLOW] \u{1F3C1} ALL_ADS_COMPLETED - Pod finished");
|
|
671
616
|
adPlaying = false;
|
|
672
617
|
setAdPlayingFlag(false);
|
|
673
618
|
if (adContainerEl) {
|
|
@@ -677,19 +622,16 @@ function createImaController(video, options) {
|
|
|
677
622
|
if (adContainerEl) {
|
|
678
623
|
adContainerEl.style.pointerEvents = "none";
|
|
679
624
|
adContainerEl.style.display = "none";
|
|
680
|
-
console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (pod done)");
|
|
681
625
|
}
|
|
682
626
|
}, 300);
|
|
683
627
|
}
|
|
684
628
|
showContentVideo();
|
|
685
629
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds) && video.paused) {
|
|
686
|
-
video.play().catch((
|
|
687
|
-
console.warn("[DEBUG-ERROR] Failed to resume video:", e);
|
|
630
|
+
video.play().catch(() => {
|
|
688
631
|
});
|
|
689
632
|
}
|
|
690
633
|
emit("all_ads_completed");
|
|
691
634
|
});
|
|
692
|
-
console.log("[IMA] Ads manager event listeners attached");
|
|
693
635
|
if (adsLoadedResolve) {
|
|
694
636
|
adsLoadedResolve();
|
|
695
637
|
adsLoadedResolve = void 0;
|
|
@@ -784,9 +726,7 @@ function createImaController(video, options) {
|
|
|
784
726
|
}
|
|
785
727
|
const preloadPromise = fetchVastDocument(vastTagUrl).then((xml) => {
|
|
786
728
|
preloadedVast.set(vastTagUrl, xml);
|
|
787
|
-
|
|
788
|
-
}).catch((error) => {
|
|
789
|
-
console.warn("[IMA] Failed to preload VAST response:", error);
|
|
729
|
+
}).catch(() => {
|
|
790
730
|
preloadedVast.delete(vastTagUrl);
|
|
791
731
|
}).finally(() => {
|
|
792
732
|
preloadingVast.delete(vastTagUrl);
|
|
@@ -799,7 +739,6 @@ function createImaController(video, options) {
|
|
|
799
739
|
},
|
|
800
740
|
async play() {
|
|
801
741
|
var _a, _b;
|
|
802
|
-
console.log("[DEBUG-FLOW] \u25B6\uFE0F play() - Starting ad playback");
|
|
803
742
|
if (!((_a = window.google) == null ? void 0 : _a.ima) || !adDisplayContainer) {
|
|
804
743
|
return Promise.reject(new Error("IMA SDK not available"));
|
|
805
744
|
}
|
|
@@ -815,19 +754,15 @@ function createImaController(video, options) {
|
|
|
815
754
|
if (adVideoElement) {
|
|
816
755
|
adVideoElement.volume = adVolume;
|
|
817
756
|
adVideoElement.muted = originalMutedState;
|
|
818
|
-
console.log(
|
|
819
|
-
`[DEBUG-AUDIO] \u{1F50A} Pre-start ad audio | volume=${adVolume}, muted=${originalMutedState}`
|
|
820
|
-
);
|
|
821
757
|
}
|
|
822
758
|
try {
|
|
823
759
|
adsManager.setVolume(adVolume);
|
|
824
|
-
} catch
|
|
825
|
-
console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
|
|
760
|
+
} catch {
|
|
826
761
|
}
|
|
827
762
|
adsManager.start();
|
|
828
763
|
return Promise.resolve();
|
|
829
764
|
} catch (error) {
|
|
830
|
-
console.error("[
|
|
765
|
+
console.error("[IMA] \u274C Error starting ad:", error);
|
|
831
766
|
adPlaying = false;
|
|
832
767
|
setAdPlayingFlag(false);
|
|
833
768
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
@@ -839,7 +774,6 @@ function createImaController(video, options) {
|
|
|
839
774
|
},
|
|
840
775
|
async stop() {
|
|
841
776
|
var _a;
|
|
842
|
-
console.log("[DEBUG-FLOW] \u23F9\uFE0F stop() - Stopping ad playback");
|
|
843
777
|
adPlaying = false;
|
|
844
778
|
setAdPlayingFlag(false);
|
|
845
779
|
if (adContainerEl) {
|
|
@@ -849,7 +783,6 @@ function createImaController(video, options) {
|
|
|
849
783
|
if (adContainerEl) {
|
|
850
784
|
adContainerEl.style.pointerEvents = "none";
|
|
851
785
|
adContainerEl.style.display = "none";
|
|
852
|
-
console.log("[DEBUG-LAYER] \u26AB Ad container HIDDEN (stop)");
|
|
853
786
|
}
|
|
854
787
|
}, 300);
|
|
855
788
|
}
|
|
@@ -919,9 +852,6 @@ function createImaController(video, options) {
|
|
|
919
852
|
},
|
|
920
853
|
updateOriginalMutedState(muted, volume) {
|
|
921
854
|
const nextVolume = typeof volume === "number" && !Number.isNaN(volume) ? Math.max(0, Math.min(1, volume)) : originalVolume;
|
|
922
|
-
console.log(
|
|
923
|
-
`[DEBUG-AUDIO] \u{1F4BE} Saved original state | muted: ${originalMutedState}->${muted}, volume: ${originalVolume}->${nextVolume}`
|
|
924
|
-
);
|
|
925
855
|
originalMutedState = muted;
|
|
926
856
|
originalVolume = nextVolume;
|
|
927
857
|
},
|
|
@@ -936,15 +866,11 @@ function createImaController(video, options) {
|
|
|
936
866
|
if (adVideoElement && adPlaying) {
|
|
937
867
|
adVideoElement.volume = clampedVolume;
|
|
938
868
|
adVideoElement.muted = clampedVolume === 0;
|
|
939
|
-
console.log(
|
|
940
|
-
`[DEBUG-AUDIO] \u{1F50A} Ad volume changed | volume=${clampedVolume}, muted=${clampedVolume === 0}`
|
|
941
|
-
);
|
|
942
869
|
}
|
|
943
870
|
if (adsManager && adPlaying) {
|
|
944
871
|
try {
|
|
945
872
|
adsManager.setVolume(clampedVolume);
|
|
946
|
-
} catch
|
|
947
|
-
console.warn("[DEBUG-ERROR] Failed to set IMA manager volume:", error);
|
|
873
|
+
} catch {
|
|
948
874
|
}
|
|
949
875
|
}
|
|
950
876
|
},
|
|
@@ -2162,6 +2088,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2162
2088
|
this.fetchedAdDurations = /* @__PURE__ */ new Map();
|
|
2163
2089
|
this.targetAdBreakDurationMs = null;
|
|
2164
2090
|
this.isAdaptiveMode = false;
|
|
2091
|
+
this.failedVastUrls = /* @__PURE__ */ new Set();
|
|
2165
2092
|
initializePolyfills();
|
|
2166
2093
|
const browserOverrides = getBrowserConfigOverrides();
|
|
2167
2094
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -2434,51 +2361,37 @@ var StormcloudVideoPlayer = class {
|
|
|
2434
2361
|
});
|
|
2435
2362
|
this.ima.on("ad_error", (errorPayload) => {
|
|
2436
2363
|
const remaining = this.getRemainingAdMs();
|
|
2437
|
-
console.error(
|
|
2438
|
-
`[DEBUG-POD] \u274C ad_error event | inBreak=${this.inAdBreak}, queue=${this.adPodQueue.length}, remaining=${remaining}ms`,
|
|
2439
|
-
errorPayload ? `
|
|
2440
|
-
Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
2441
|
-
);
|
|
2364
|
+
console.error("[AD-ERROR] Ad playback failed", errorPayload || "");
|
|
2442
2365
|
if (this.inAdBreak) {
|
|
2443
2366
|
if (remaining > 500 && this.adPodQueue.length > 0) {
|
|
2444
2367
|
const nextPreloaded = this.findNextPreloadedAd();
|
|
2445
2368
|
if (nextPreloaded) {
|
|
2446
2369
|
this.currentAdIndex++;
|
|
2447
|
-
console.log(
|
|
2448
|
-
`[DEBUG-POD] \u27A1\uFE0F Trying next ad after error (${this.currentAdIndex}/${this.totalAdsInBreak})`
|
|
2449
|
-
);
|
|
2450
2370
|
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2451
2371
|
this.handleAdFailure();
|
|
2452
2372
|
});
|
|
2453
2373
|
} else {
|
|
2454
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No more preloaded ads - calling handleAdFailure");
|
|
2455
2374
|
this.handleAdFailure();
|
|
2456
2375
|
}
|
|
2457
2376
|
} else {
|
|
2458
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No more ads or time - calling handleAdFailure");
|
|
2459
2377
|
this.handleAdFailure();
|
|
2460
2378
|
}
|
|
2461
2379
|
} else {
|
|
2462
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F Error before ad break established");
|
|
2463
2380
|
this.handleAdFailure();
|
|
2464
2381
|
}
|
|
2465
2382
|
});
|
|
2466
2383
|
this.ima.on("content_pause", () => {
|
|
2467
|
-
console.log(`[DEBUG-POD] \u{1F3AF} content_pause (AD STARTING!) | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}`);
|
|
2468
2384
|
this.clearAdFailsafeTimer();
|
|
2469
2385
|
this.clearAdRequestWatchdog();
|
|
2470
2386
|
this.activeAdRequestToken = null;
|
|
2471
2387
|
this.showAds = true;
|
|
2472
|
-
console.log("[DEBUG-LAYER] \u{1F3AC} Layers: Main=hidden, Ad=visible, Placeholder=no");
|
|
2473
2388
|
});
|
|
2474
2389
|
this.ima.on("content_resume", () => {
|
|
2475
|
-
console.log(`[DEBUG-POD] \u23F8\uFE0F content_resume | ad ${this.currentAdIndex}/${this.totalAdsInBreak}, queue=${this.adPodQueue.length}, remaining=${this.getRemainingAdMs()}ms`);
|
|
2476
2390
|
this.clearAdFailsafeTimer();
|
|
2477
2391
|
this.clearAdRequestWatchdog();
|
|
2478
2392
|
this.activeAdRequestToken = null;
|
|
2479
2393
|
this.showAds = false;
|
|
2480
2394
|
if (!this.inAdBreak) {
|
|
2481
|
-
console.warn("[DEBUG-POD] \u26A0\uFE0F Not in ad break - shouldn't happen");
|
|
2482
2395
|
return;
|
|
2483
2396
|
}
|
|
2484
2397
|
const remaining = this.getRemainingAdMs();
|
|
@@ -2486,17 +2399,13 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2486
2399
|
const nextPreloaded = this.findNextPreloadedAd();
|
|
2487
2400
|
if (nextPreloaded) {
|
|
2488
2401
|
this.currentAdIndex++;
|
|
2489
|
-
console.log(`[DEBUG-POD] \u27A1\uFE0F Playing next ad ${this.currentAdIndex}/${this.totalAdsInBreak} (preloaded)`);
|
|
2490
2402
|
this.playSingleAd(nextPreloaded).catch(() => {
|
|
2491
|
-
console.error("[DEBUG-POD] \u274C Failed to play next ad");
|
|
2492
2403
|
this.handleAdPodComplete();
|
|
2493
2404
|
});
|
|
2494
2405
|
} else {
|
|
2495
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads - ending pod");
|
|
2496
2406
|
this.handleAdPodComplete();
|
|
2497
2407
|
}
|
|
2498
2408
|
} else {
|
|
2499
|
-
console.log("[DEBUG-POD] \u2705 Pod complete (no more ads or time expired)");
|
|
2500
2409
|
this.handleAdPodComplete();
|
|
2501
2410
|
}
|
|
2502
2411
|
});
|
|
@@ -2650,9 +2559,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2650
2559
|
}
|
|
2651
2560
|
if (marker.type === "start") {
|
|
2652
2561
|
if (this.inAdBreak) {
|
|
2653
|
-
console.log(
|
|
2654
|
-
`[DEBUG-POD] \u26A0\uFE0F SCTE-35 start marker ignored - already in ad break (currentTime: ${this.video.currentTime})`
|
|
2655
|
-
);
|
|
2656
2562
|
return;
|
|
2657
2563
|
}
|
|
2658
2564
|
this.inAdBreak = true;
|
|
@@ -2721,9 +2627,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2721
2627
|
return;
|
|
2722
2628
|
}
|
|
2723
2629
|
if (marker.type === "progress" && this.inAdBreak) {
|
|
2724
|
-
console.log(
|
|
2725
|
-
`[DEBUG-POD] \u{1F4CA} SCTE-35 progress marker (currentTime: ${this.video.currentTime})`
|
|
2726
|
-
);
|
|
2727
2630
|
if (marker.durationSeconds != null) {
|
|
2728
2631
|
this.expectedAdBreakDurationMs = marker.durationSeconds * 1e3;
|
|
2729
2632
|
}
|
|
@@ -2736,7 +2639,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2736
2639
|
this.scheduleAdStopCountdown(remainingMs);
|
|
2737
2640
|
}
|
|
2738
2641
|
if (!this.ima.isAdPlaying() && this.activeAdRequestToken === null) {
|
|
2739
|
-
console.log("[DEBUG-POD] \u{1F4CA} Progress marker: no ad playing, attempting to start");
|
|
2740
2642
|
const scheduled = this.findCurrentOrNextBreak(
|
|
2741
2643
|
this.video.currentTime * 1e3
|
|
2742
2644
|
);
|
|
@@ -2748,24 +2650,16 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
2748
2650
|
this.playSingleAd(first).catch(() => {
|
|
2749
2651
|
});
|
|
2750
2652
|
}
|
|
2751
|
-
} else {
|
|
2752
|
-
console.log(
|
|
2753
|
-
`[DEBUG-POD] \u{1F4CA} Progress marker: ad playing or request active (playing=${this.ima.isAdPlaying()}, token=${this.activeAdRequestToken})`
|
|
2754
|
-
);
|
|
2755
2653
|
}
|
|
2756
2654
|
return;
|
|
2757
2655
|
}
|
|
2758
2656
|
if (marker.type === "end") {
|
|
2759
|
-
console.log(
|
|
2760
|
-
`[DEBUG-POD] \u{1F3C1} SCTE-35 end marker received (currentTime: ${this.video.currentTime})`
|
|
2761
|
-
);
|
|
2762
2657
|
this.inAdBreak = false;
|
|
2763
2658
|
this.expectedAdBreakDurationMs = void 0;
|
|
2764
2659
|
this.currentAdBreakStartWallClockMs = void 0;
|
|
2765
2660
|
this.clearAdStartTimer();
|
|
2766
2661
|
this.clearAdStopTimer();
|
|
2767
2662
|
if (this.ima.isAdPlaying()) {
|
|
2768
|
-
console.log("[DEBUG-POD] \u{1F6D1} Stopping ad due to SCTE-35 end marker");
|
|
2769
2663
|
this.ima.stop().catch(() => {
|
|
2770
2664
|
});
|
|
2771
2665
|
}
|
|
@@ -3166,21 +3060,17 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3166
3060
|
} else if (tags && tags.length > 0) {
|
|
3167
3061
|
vastTagUrls = tags;
|
|
3168
3062
|
} else {
|
|
3169
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No VAST tag available");
|
|
3170
3063
|
return;
|
|
3171
3064
|
}
|
|
3172
3065
|
if (vastTagUrls.length > 0) {
|
|
3173
|
-
console.log(`[DEBUG-POD] \u{1F3AF} Starting ad break with ${vastTagUrls.length} ads`);
|
|
3174
3066
|
this.adPodAllUrls = [...vastTagUrls];
|
|
3175
3067
|
this.preloadingAdUrls.clear();
|
|
3176
3068
|
this.vastToMediaUrlMap.clear();
|
|
3177
3069
|
this.preloadedMediaUrls.clear();
|
|
3178
3070
|
this.preloadingMediaUrls.clear();
|
|
3071
|
+
this.failedVastUrls.clear();
|
|
3179
3072
|
const currentMuted = this.video.muted;
|
|
3180
3073
|
const currentVolume = this.video.volume;
|
|
3181
|
-
console.log(
|
|
3182
|
-
`[DEBUG-AUDIO] \u{1F4BE} Capturing ORIGINAL state (once) | muted=${currentMuted}, volume=${currentVolume}`
|
|
3183
|
-
);
|
|
3184
3074
|
this.ima.updateOriginalMutedState(currentMuted, currentVolume);
|
|
3185
3075
|
this.inAdBreak = true;
|
|
3186
3076
|
this.currentAdIndex = 0;
|
|
@@ -3241,40 +3131,27 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3241
3131
|
}
|
|
3242
3132
|
async playAdPod() {
|
|
3243
3133
|
if (this.adPodQueue.length === 0) {
|
|
3244
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No ads in pod");
|
|
3245
3134
|
return;
|
|
3246
3135
|
}
|
|
3247
3136
|
const waitTime = this.isAdaptiveMode ? 50 : 500;
|
|
3248
3137
|
await new Promise((resolve) => setTimeout(resolve, waitTime));
|
|
3249
|
-
if (this.config.debugAdTiming) {
|
|
3250
|
-
console.log(
|
|
3251
|
-
`[DEBUG-POD] \u{1F50D} Looking for preloaded ad in queue of ${this.adPodQueue.length} URLs`
|
|
3252
|
-
);
|
|
3253
|
-
}
|
|
3254
3138
|
const firstPreloaded = this.findNextPreloadedAd();
|
|
3255
3139
|
if (!firstPreloaded) {
|
|
3256
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F No preloaded ads found, trying first ad from queue");
|
|
3257
3140
|
const firstAd = this.adPodQueue.shift();
|
|
3258
3141
|
if (firstAd) {
|
|
3259
3142
|
this.currentAdIndex++;
|
|
3260
|
-
console.log(`[DEBUG-POD] \u{1F3AC} Attempting to play first ad (not preloaded): ${firstAd.substring(0, 60)}...`);
|
|
3261
3143
|
try {
|
|
3262
3144
|
await this.playSingleAd(firstAd);
|
|
3263
3145
|
} catch (error) {
|
|
3264
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F First ad failed, error handler will retry");
|
|
3265
3146
|
return;
|
|
3266
3147
|
}
|
|
3267
|
-
} else {
|
|
3268
|
-
console.log("[DEBUG-POD] \u274C No ads available in queue");
|
|
3269
3148
|
}
|
|
3270
3149
|
return;
|
|
3271
3150
|
}
|
|
3272
3151
|
this.currentAdIndex++;
|
|
3273
|
-
console.log(`[DEBUG-POD] \u{1F680} Starting pod with ad ${this.currentAdIndex}/${this.totalAdsInBreak}`);
|
|
3274
3152
|
try {
|
|
3275
3153
|
await this.playSingleAd(firstPreloaded);
|
|
3276
3154
|
} catch (error) {
|
|
3277
|
-
console.log("[DEBUG-POD] \u26A0\uFE0F First ad failed, error handler will retry");
|
|
3278
3155
|
}
|
|
3279
3156
|
}
|
|
3280
3157
|
findCurrentOrNextBreak(nowMs) {
|
|
@@ -3354,15 +3231,9 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3354
3231
|
const overrunMs = Math.max(0, elapsedSinceStartMs - expectedDurationMs);
|
|
3355
3232
|
const shouldExtendAdBreak = (adPlaying || pendingAds || this.showAds) && overrunMs < maxExtensionMs;
|
|
3356
3233
|
if (shouldExtendAdBreak) {
|
|
3357
|
-
console.log(
|
|
3358
|
-
`[DEBUG-POD] \u23F3 Extending ad break | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms, overrun=${overrunMs}ms`
|
|
3359
|
-
);
|
|
3360
3234
|
this.scheduleAdStopCountdown(checkIntervalMs);
|
|
3361
3235
|
return;
|
|
3362
3236
|
}
|
|
3363
|
-
console.log(
|
|
3364
|
-
`[DEBUG-POD] \u23F1\uFE0F Ad break duration expired | elapsed=${elapsedSinceStartMs}ms, expected=${expectedDurationMs}ms`
|
|
3365
|
-
);
|
|
3366
3237
|
if (adPlaying) {
|
|
3367
3238
|
this.ima.stop().catch(() => {
|
|
3368
3239
|
});
|
|
@@ -3395,42 +3266,29 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3395
3266
|
this.ptsDriftEmaMs = this.ptsDriftEmaMs * (1 - alpha) + sampleMs * alpha;
|
|
3396
3267
|
}
|
|
3397
3268
|
async playSingleAd(vastTagUrl) {
|
|
3398
|
-
console.log(`[DEBUG-POD] \u{1F3AC} playSingleAd | url=${vastTagUrl.substring(0, 60)}...`);
|
|
3399
3269
|
if (this.ima.isAdPlaying()) {
|
|
3400
|
-
|
|
3270
|
+
return;
|
|
3271
|
+
}
|
|
3272
|
+
if (this.failedVastUrls.has(vastTagUrl)) {
|
|
3273
|
+
console.warn("[AD-ERROR] Skipping already-failed VAST URL:", vastTagUrl.substring(0, 60));
|
|
3274
|
+
this.handleAdFailure();
|
|
3401
3275
|
return;
|
|
3402
3276
|
}
|
|
3403
3277
|
const requestToken = ++this.adRequestTokenCounter;
|
|
3404
|
-
const wasPreloaded = this.ima.hasPreloadedAd(vastTagUrl);
|
|
3405
3278
|
this.activeAdRequestToken = requestToken;
|
|
3406
|
-
console.log(`[DEBUG-POD] \u{1F4DD} Request token=${requestToken}, preloaded=${wasPreloaded}`);
|
|
3407
3279
|
this.startAdRequestWatchdog(requestToken);
|
|
3408
3280
|
try {
|
|
3409
|
-
console.log(`[DEBUG-POD] \u{1F4E1} Calling ima.requestAds() for token=${requestToken}...`);
|
|
3410
3281
|
await this.ima.requestAds(vastTagUrl);
|
|
3411
|
-
console.log(`[DEBUG-POD] \u2705 ima.requestAds() completed successfully`);
|
|
3412
3282
|
this.clearAdRequestWatchdog();
|
|
3413
3283
|
if (this.activeAdRequestToken !== requestToken) {
|
|
3414
|
-
console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after requestAds (stale request)`);
|
|
3415
3284
|
return;
|
|
3416
3285
|
}
|
|
3417
|
-
console.log(`[DEBUG-POD] \u{1F4FA} Calling ima.play() to start ad playback...`);
|
|
3418
|
-
console.log(`[DEBUG-POD] \u{1F4CA} Video element state: paused=${this.video.paused}, muted=${this.video.muted}, readyState=${this.video.readyState}`);
|
|
3419
3286
|
try {
|
|
3420
3287
|
this.startAdFailsafeTimer(requestToken);
|
|
3421
3288
|
await this.ima.play();
|
|
3422
|
-
if (this.activeAdRequestToken === requestToken) {
|
|
3423
|
-
console.log(`[DEBUG-POD] \u2705 Ad play initiated successfully (token=${requestToken})`);
|
|
3424
|
-
} else {
|
|
3425
|
-
console.warn(`[DEBUG-POD] \u26A0\uFE0F Token mismatch after play (stale request)`);
|
|
3426
|
-
}
|
|
3427
3289
|
} catch (playError) {
|
|
3428
|
-
console.error(
|
|
3429
|
-
|
|
3430
|
-
playError instanceof Error ? playError.message : playError,
|
|
3431
|
-
"\nFull error:",
|
|
3432
|
-
playError
|
|
3433
|
-
);
|
|
3290
|
+
console.error("[AD-ERROR] Failed to play ad:", playError);
|
|
3291
|
+
this.failedVastUrls.add(vastTagUrl);
|
|
3434
3292
|
this.clearAdFailsafeTimer();
|
|
3435
3293
|
if (this.activeAdRequestToken === requestToken) {
|
|
3436
3294
|
this.activeAdRequestToken = null;
|
|
@@ -3439,7 +3297,8 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3439
3297
|
return;
|
|
3440
3298
|
}
|
|
3441
3299
|
} catch (error) {
|
|
3442
|
-
console.error("[
|
|
3300
|
+
console.error("[AD-ERROR] Ad request failed:", error == null ? void 0 : error.message);
|
|
3301
|
+
this.failedVastUrls.add(vastTagUrl);
|
|
3443
3302
|
this.clearAdRequestWatchdog();
|
|
3444
3303
|
this.clearAdFailsafeTimer();
|
|
3445
3304
|
if (this.activeAdRequestToken === requestToken) {
|
|
@@ -3450,7 +3309,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3450
3309
|
}
|
|
3451
3310
|
handleAdPodComplete() {
|
|
3452
3311
|
var _a;
|
|
3453
|
-
console.log("[DEBUG-POD] \u{1F3C1} handleAdPodComplete - Ending ad break, restoring content");
|
|
3454
3312
|
this.clearAdRequestWatchdog();
|
|
3455
3313
|
this.clearAdFailsafeTimer();
|
|
3456
3314
|
this.activeAdRequestToken = null;
|
|
@@ -3472,10 +3330,6 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3472
3330
|
});
|
|
3473
3331
|
const restoredMuted = this.ima.getOriginalMutedState();
|
|
3474
3332
|
const restoredVolume = this.ima.getOriginalVolume();
|
|
3475
|
-
console.log(
|
|
3476
|
-
`[DEBUG-AUDIO] \u{1F50A} Audio restored by IMA | muted=${restoredMuted}, volume=${restoredVolume}`
|
|
3477
|
-
);
|
|
3478
|
-
console.log("[DEBUG-LAYER] \u{1F3AC} Layers: Main=visible, Ad=hidden, Placeholder=no");
|
|
3479
3333
|
if (this.video.muted !== restoredMuted) {
|
|
3480
3334
|
this.video.muted = restoredMuted;
|
|
3481
3335
|
}
|
|
@@ -3483,16 +3337,14 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3483
3337
|
this.video.volume = restoredVolume;
|
|
3484
3338
|
}
|
|
3485
3339
|
if (!this.shouldContinueLiveStreamDuringAds() && this.video.paused) {
|
|
3486
|
-
|
|
3487
|
-
(_a = this.video.play()) == null ? void 0 : _a.catch((error) => {
|
|
3488
|
-
console.error("[DEBUG-ERROR] Failed to resume video:", error);
|
|
3340
|
+
(_a = this.video.play()) == null ? void 0 : _a.catch(() => {
|
|
3489
3341
|
});
|
|
3490
3342
|
}
|
|
3491
3343
|
}
|
|
3492
3344
|
handleAdFailure() {
|
|
3493
|
-
console.log("[DEBUG-POD] \u274C handleAdFailure - skipping to next ad or ending break");
|
|
3494
3345
|
const remaining = this.getRemainingAdMs();
|
|
3495
|
-
|
|
3346
|
+
const availableAds = this.adPodQueue.filter((url) => !this.failedVastUrls.has(url)).length;
|
|
3347
|
+
if (remaining > 500 && availableAds > 0) {
|
|
3496
3348
|
if (this.isAdaptiveMode && this.currentAdIndex <= 1) {
|
|
3497
3349
|
console.log("[ADAPTIVE-POD] \u23F3 First ad failed, waiting for sequential preload to catch up...");
|
|
3498
3350
|
setTimeout(() => {
|
|
@@ -3503,14 +3355,13 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3503
3355
|
const nextPreloaded = this.findNextPreloadedAd();
|
|
3504
3356
|
if (nextPreloaded) {
|
|
3505
3357
|
this.currentAdIndex++;
|
|
3506
|
-
console.log(`[DEBUG-POD] \u27A1\uFE0F Trying next ad after failure (${this.currentAdIndex}/${this.totalAdsInBreak})`);
|
|
3507
3358
|
this.playSingleAd(nextPreloaded).catch(() => {
|
|
3508
3359
|
this.handleAdPodComplete();
|
|
3509
3360
|
});
|
|
3510
3361
|
return;
|
|
3511
3362
|
}
|
|
3512
3363
|
}
|
|
3513
|
-
console.
|
|
3364
|
+
console.error("[AD-ERROR] All ads failed or time expired. Failed URLs:", this.failedVastUrls.size);
|
|
3514
3365
|
this.handleAdPodComplete();
|
|
3515
3366
|
}
|
|
3516
3367
|
tryNextAdWithRetry(retryCount) {
|
|
@@ -3963,37 +3814,21 @@ Error details: ${JSON.stringify(errorPayload)}` : ""
|
|
|
3963
3814
|
}
|
|
3964
3815
|
findNextPreloadedAd() {
|
|
3965
3816
|
var _a, _b, _c;
|
|
3966
|
-
if (this.config.debugAdTiming) {
|
|
3967
|
-
console.log(
|
|
3968
|
-
`[DEBUG-POD] \u{1F50E} Searching for preloaded ad in queue (${this.adPodQueue.length} URLs, ${this.preloadedMediaUrls.size} media preloaded, ${this.vastToMediaUrlMap.size} VAST mappings)`
|
|
3969
|
-
);
|
|
3970
|
-
}
|
|
3971
3817
|
for (let i = 0; i < this.adPodQueue.length; i++) {
|
|
3972
3818
|
const vastTagUrl = this.adPodQueue[i];
|
|
3973
3819
|
if (!vastTagUrl) continue;
|
|
3820
|
+
if (this.failedVastUrls.has(vastTagUrl)) {
|
|
3821
|
+
console.warn("[AD-ERROR] Skipping failed URL in queue");
|
|
3822
|
+
continue;
|
|
3823
|
+
}
|
|
3974
3824
|
const hasImaPreload = (_c = (_b = (_a = this.ima).hasPreloadedAd) == null ? void 0 : _b.call(_a, vastTagUrl)) != null ? _c : false;
|
|
3975
3825
|
const mediaUrls = this.vastToMediaUrlMap.get(vastTagUrl);
|
|
3976
3826
|
const hasMediaPreload = mediaUrls && mediaUrls.length > 0 ? this.preloadedMediaUrls.has(mediaUrls[0]) : false;
|
|
3977
|
-
if (this.config.debugAdTiming) {
|
|
3978
|
-
console.log(
|
|
3979
|
-
`[DEBUG-POD] Ad ${i}: IMA=${hasImaPreload}, Media=${hasMediaPreload}, MediaURLs=${(mediaUrls == null ? void 0 : mediaUrls.length) || 0}, URL=${vastTagUrl.substring(0, 60)}...`
|
|
3980
|
-
);
|
|
3981
|
-
}
|
|
3982
3827
|
if (hasImaPreload || hasMediaPreload) {
|
|
3983
|
-
if (this.config.debugAdTiming) {
|
|
3984
|
-
console.log(
|
|
3985
|
-
`[DEBUG-POD] \u2705 Found preloaded ad at index ${i}`
|
|
3986
|
-
);
|
|
3987
|
-
}
|
|
3988
3828
|
this.adPodQueue.splice(0, i + 1);
|
|
3989
3829
|
return vastTagUrl;
|
|
3990
3830
|
}
|
|
3991
3831
|
}
|
|
3992
|
-
if (this.config.debugAdTiming) {
|
|
3993
|
-
console.log(
|
|
3994
|
-
`[DEBUG-POD] \u274C No preloaded ads found in queue`
|
|
3995
|
-
);
|
|
3996
|
-
}
|
|
3997
3832
|
return void 0;
|
|
3998
3833
|
}
|
|
3999
3834
|
getRemainingAdMs() {
|