stormcloud-video-player 0.2.27 → 0.2.29

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/lib/index.cjs CHANGED
@@ -265,11 +265,13 @@ function supportsFeature(feature) {
265
265
  // src/sdk/ima.ts
266
266
  function createImaController(video, options) {
267
267
  let adPlaying = false;
268
+ let contentVideoHidden = false;
268
269
  let originalMutedState = false;
269
270
  let originalVolume = typeof video.volume === "number" && !Number.isNaN(video.volume) ? Math.max(0, Math.min(1, video.volume)) : 1;
270
271
  const listeners = /* @__PURE__ */ new Map();
271
272
  const preloadedVast = /* @__PURE__ */ new Map();
272
273
  const preloadingVast = /* @__PURE__ */ new Map();
274
+ let adVideoElement;
273
275
  function setAdPlayingFlag(isPlaying) {
274
276
  if (isPlaying) {
275
277
  video.dataset.stormcloudAdPlaying = "true";
@@ -277,6 +279,53 @@ function createImaController(video, options) {
277
279
  delete video.dataset.stormcloudAdPlaying;
278
280
  }
279
281
  }
282
+ function hideContentVideo() {
283
+ if (!contentVideoHidden) {
284
+ video.style.visibility = "hidden";
285
+ video.muted = true;
286
+ video.volume = 0;
287
+ contentVideoHidden = true;
288
+ console.log("[IMA] Content video hidden and muted");
289
+ }
290
+ }
291
+ function showContentVideo() {
292
+ if (contentVideoHidden) {
293
+ video.style.visibility = "visible";
294
+ video.muted = originalMutedState;
295
+ video.volume = originalVolume;
296
+ contentVideoHidden = false;
297
+ console.log(
298
+ `[IMA] Content video restored (muted: ${originalMutedState}, volume: ${originalVolume})`
299
+ );
300
+ }
301
+ }
302
+ function createAdVideoElement() {
303
+ const adVideo = document.createElement("video");
304
+ adVideo.style.position = "absolute";
305
+ adVideo.style.top = "0";
306
+ adVideo.style.left = "0";
307
+ adVideo.style.width = "100%";
308
+ adVideo.style.height = "100%";
309
+ adVideo.style.objectFit = "contain";
310
+ adVideo.style.backgroundColor = "transparent";
311
+ adVideo.style.zIndex = "15";
312
+ adVideo.playsInline = true;
313
+ adVideo.muted = false;
314
+ adVideo.volume = originalMutedState ? 0 : originalVolume;
315
+ adVideo.style.opacity = "0";
316
+ adVideo.addEventListener(
317
+ "canplay",
318
+ () => {
319
+ adVideo.style.opacity = "1";
320
+ console.log("[IMA] Ad video ready to play");
321
+ },
322
+ { once: true }
323
+ );
324
+ console.log(
325
+ `[IMA] Created dedicated ad video element with volume: ${adVideo.volume}, muted: ${adVideo.muted}`
326
+ );
327
+ return adVideo;
328
+ }
280
329
  function emit(event, payload) {
281
330
  const set = listeners.get(event);
282
331
  if (!set) return;
@@ -435,6 +484,9 @@ function createImaController(video, options) {
435
484
  }
436
485
  adsManager = void 0;
437
486
  }
487
+ if (adVideoElement) {
488
+ adVideoElement.style.opacity = "0";
489
+ }
438
490
  }
439
491
  return {
440
492
  initialize() {
@@ -443,12 +495,22 @@ function createImaController(video, options) {
443
495
  const google = window.google;
444
496
  ensurePlaceholderContainer();
445
497
  if (!adDisplayContainer && adContainerEl) {
498
+ if (!adVideoElement) {
499
+ adVideoElement = createAdVideoElement();
500
+ adContainerEl.appendChild(adVideoElement);
501
+ console.log(
502
+ "[IMA] Dedicated ad video element added to container"
503
+ );
504
+ }
446
505
  adDisplayContainer = new google.ima.AdDisplayContainer(
447
506
  adContainerEl,
448
- video
507
+ adVideoElement
449
508
  );
450
509
  try {
451
510
  (_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
511
+ console.log(
512
+ "[IMA] AdDisplayContainer initialized with dedicated ad video"
513
+ );
452
514
  } catch {
453
515
  }
454
516
  }
@@ -517,13 +579,22 @@ function createImaController(video, options) {
517
579
  }
518
580
  video.parentElement.appendChild(container);
519
581
  adContainerEl = container;
582
+ if (!adVideoElement) {
583
+ adVideoElement = createAdVideoElement();
584
+ adContainerEl.appendChild(adVideoElement);
585
+ console.log(
586
+ "[IMA] Dedicated ad video element created and added to container"
587
+ );
588
+ }
520
589
  adDisplayContainer = new google.ima.AdDisplayContainer(
521
590
  container,
522
- video
591
+ adVideoElement
523
592
  );
524
593
  try {
525
594
  adDisplayContainer.initialize();
526
- console.log("[IMA] Ad display container initialized");
595
+ console.log(
596
+ "[IMA] Ad display container initialized with dedicated ad video"
597
+ );
527
598
  } catch (error) {
528
599
  console.warn(
529
600
  "[IMA] Failed to initialize ad display container:",
@@ -566,12 +637,8 @@ function createImaController(video, options) {
566
637
  console.error("[IMA] Ad error:", errorEvent.getError());
567
638
  destroyAdsManager();
568
639
  adPlaying = false;
569
- const previousMutedState = video.muted;
570
- video.muted = originalMutedState;
640
+ showContentVideo();
571
641
  setAdPlayingFlag(false);
572
- console.log(
573
- `[IMA] Restored mute state after ad error: ${previousMutedState} -> ${originalMutedState}`
574
- );
575
642
  if (adContainerEl) {
576
643
  adContainerEl.style.pointerEvents = "none";
577
644
  adContainerEl.style.display = "none";
@@ -613,37 +680,35 @@ function createImaController(video, options) {
613
680
  adsManager.addEventListener(
614
681
  AdEvent.CONTENT_PAUSE_REQUESTED,
615
682
  () => {
616
- console.log(
617
- "[IMA] Content pause requested - FORCE MUTING main video"
618
- );
683
+ console.log("[IMA] Content pause requested");
619
684
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
620
685
  video.pause();
621
- console.log("[IMA] Video paused (VOD mode)");
686
+ console.log("[IMA] Content video paused (VOD mode)");
622
687
  } else {
623
688
  console.log(
624
- "[IMA] Video continues playing but muted (Live mode)"
689
+ "[IMA] Content video continues in background (Live mode)"
625
690
  );
626
691
  }
627
- video.muted = true;
628
- video.volume = 0;
629
692
  adPlaying = true;
630
693
  setAdPlayingFlag(true);
631
694
  emit("content_pause");
632
695
  }
633
696
  );
634
697
  adsManager.addEventListener(AdEvent.STARTED, () => {
635
- console.log(
636
- "[IMA] Ad started playing - FORCE MUTING main video"
637
- );
698
+ console.log("[IMA] Ad started - showing ad video");
638
699
  setAdPlayingFlag(true);
639
- video.muted = true;
640
- video.volume = 0;
700
+ hideContentVideo();
701
+ if (adVideoElement) {
702
+ adVideoElement.volume = originalMutedState ? 0 : originalVolume;
703
+ adVideoElement.muted = originalMutedState;
704
+ console.log(
705
+ `[IMA] Ad video volume: ${adVideoElement.volume}, muted: ${adVideoElement.muted}`
706
+ );
707
+ }
641
708
  if (adContainerEl) {
642
709
  adContainerEl.style.pointerEvents = "auto";
643
710
  adContainerEl.style.display = "flex";
644
- console.log(
645
- "[IMA] Ad container visibility set to flex with pointer events enabled"
646
- );
711
+ console.log("[IMA] Ad container now visible");
647
712
  }
648
713
  });
649
714
  adsManager.addEventListener(
@@ -652,17 +717,19 @@ function createImaController(video, options) {
652
717
  console.log("[IMA] Content resume requested");
653
718
  adPlaying = false;
654
719
  setAdPlayingFlag(false);
720
+ showContentVideo();
655
721
  emit("content_resume");
656
722
  setTimeout(() => {
657
723
  const stillInPod = video.dataset.stormcloudAdPlaying === "true";
658
724
  if (stillInPod) {
659
725
  console.log(
660
- "[IMA] Still in ad pod - keeping ad container visible (black screen)"
726
+ "[IMA] Still in ad pod - keeping ad container visible"
661
727
  );
662
728
  if (adContainerEl) {
663
729
  adContainerEl.style.display = "flex";
664
730
  adContainerEl.style.pointerEvents = "auto";
665
731
  }
732
+ hideContentVideo();
666
733
  }
667
734
  }, 50);
668
735
  }
@@ -682,7 +749,7 @@ function createImaController(video, options) {
682
749
  } catch (e) {
683
750
  console.error("[IMA] Error setting up ads manager:", e);
684
751
  adPlaying = false;
685
- video.muted = originalMutedState;
752
+ showContentVideo();
686
753
  setAdPlayingFlag(false);
687
754
  if (adContainerEl) {
688
755
  adContainerEl.style.pointerEvents = "none";
@@ -713,12 +780,8 @@ function createImaController(video, options) {
713
780
  (adErrorEvent) => {
714
781
  console.error("[IMA] Ads loader error:", adErrorEvent.getError());
715
782
  adPlaying = false;
716
- const previousMutedState = video.muted;
717
- video.muted = originalMutedState;
783
+ showContentVideo();
718
784
  setAdPlayingFlag(false);
719
- console.log(
720
- `[IMA] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
721
- );
722
785
  if (adContainerEl) {
723
786
  adContainerEl.style.pointerEvents = "none";
724
787
  adContainerEl.style.display = "none";
@@ -797,11 +860,18 @@ function createImaController(video, options) {
797
860
  adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
798
861
  adPlaying = true;
799
862
  const adVolume = originalMutedState ? 0 : originalVolume;
863
+ if (adVideoElement) {
864
+ adVideoElement.volume = adVolume;
865
+ adVideoElement.muted = originalMutedState;
866
+ console.log(
867
+ `[IMA] Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
868
+ );
869
+ }
800
870
  try {
801
871
  adsManager.setVolume(adVolume);
802
- console.log(`[IMA] Set ad volume to ${adVolume}`);
872
+ console.log(`[IMA] Set IMA manager volume to ${adVolume}`);
803
873
  } catch (error) {
804
- console.warn("[IMA] Failed to set ad volume:", error);
874
+ console.warn("[IMA] Failed to set IMA manager volume:", error);
805
875
  }
806
876
  console.log("[IMA] Starting ad playback");
807
877
  adsManager.start();
@@ -822,6 +892,7 @@ function createImaController(video, options) {
822
892
  console.log("[IMA] Stopping ad playback");
823
893
  adPlaying = false;
824
894
  setAdPlayingFlag(false);
895
+ showContentVideo();
825
896
  if (adContainerEl) {
826
897
  adContainerEl.style.pointerEvents = "none";
827
898
  adContainerEl.style.display = "none";
@@ -837,8 +908,7 @@ function createImaController(video, options) {
837
908
  var _a;
838
909
  destroyAdsManager();
839
910
  adPlaying = false;
840
- video.muted = originalMutedState;
841
- video.volume = originalVolume;
911
+ showContentVideo();
842
912
  setAdPlayingFlag(false);
843
913
  if (adContainerEl) {
844
914
  adContainerEl.style.pointerEvents = "none";
@@ -854,6 +924,8 @@ function createImaController(video, options) {
854
924
  adContainerEl = void 0;
855
925
  adDisplayContainer = void 0;
856
926
  adsLoader = void 0;
927
+ adVideoElement = void 0;
928
+ contentVideoHidden = false;
857
929
  preloadedVast.clear();
858
930
  preloadingVast.clear();
859
931
  },
@@ -898,15 +970,26 @@ function createImaController(video, options) {
898
970
  return originalVolume;
899
971
  },
900
972
  setAdVolume(volume) {
973
+ const clampedVolume = Math.max(0, Math.min(1, volume));
974
+ if (adVideoElement && adPlaying) {
975
+ adVideoElement.volume = clampedVolume;
976
+ adVideoElement.muted = clampedVolume === 0;
977
+ console.log(
978
+ `[IMA] Set dedicated ad video volume to ${clampedVolume}, muted: ${clampedVolume === 0}`
979
+ );
980
+ }
901
981
  if (adsManager && adPlaying) {
902
982
  try {
903
- adsManager.setVolume(Math.max(0, Math.min(1, volume)));
983
+ adsManager.setVolume(clampedVolume);
904
984
  } catch (error) {
905
- console.warn("[IMA] Failed to set ad volume:", error);
985
+ console.warn("[IMA] Failed to set IMA manager volume:", error);
906
986
  }
907
987
  }
908
988
  },
909
989
  getAdVolume() {
990
+ if (adVideoElement && adPlaying) {
991
+ return adVideoElement.volume;
992
+ }
910
993
  if (adsManager && adPlaying) {
911
994
  try {
912
995
  return adsManager.getVolume();
@@ -3523,11 +3606,6 @@ var StormcloudVideoPlayer = class {
3523
3606
  }
3524
3607
  return false;
3525
3608
  }
3526
- if (this.config.debugAdTiming) {
3527
- console.log(
3528
- `[StormcloudVideoPlayer] isMuted() no ad playing: video.muted=${this.video.muted}`
3529
- );
3530
- }
3531
3609
  return this.video.muted;
3532
3610
  }
3533
3611
  setMuted(muted) {