stormcloud-video-player 0.2.26 → 0.2.28

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.
@@ -203,6 +203,7 @@ function createImaController(video, options) {
203
203
  const listeners = /* @__PURE__ */ new Map();
204
204
  const preloadedVast = /* @__PURE__ */ new Map();
205
205
  const preloadingVast = /* @__PURE__ */ new Map();
206
+ let adVideoElement;
206
207
  function setAdPlayingFlag(isPlaying) {
207
208
  if (isPlaying) {
208
209
  video.dataset.stormcloudAdPlaying = "true";
@@ -210,6 +211,24 @@ function createImaController(video, options) {
210
211
  delete video.dataset.stormcloudAdPlaying;
211
212
  }
212
213
  }
214
+ function createAdVideoElement() {
215
+ const adVideo = document.createElement("video");
216
+ adVideo.style.position = "absolute";
217
+ adVideo.style.top = "0";
218
+ adVideo.style.left = "0";
219
+ adVideo.style.width = "100%";
220
+ adVideo.style.height = "100%";
221
+ adVideo.style.objectFit = "contain";
222
+ adVideo.style.backgroundColor = "#000";
223
+ adVideo.style.zIndex = "15";
224
+ adVideo.playsInline = true;
225
+ adVideo.muted = false;
226
+ adVideo.volume = originalMutedState ? 0 : originalVolume;
227
+ console.log(
228
+ `[IMA] Created dedicated ad video element with volume: ${adVideo.volume}, muted: ${adVideo.muted}`
229
+ );
230
+ return adVideo;
231
+ }
213
232
  function emit(event, payload) {
214
233
  const set = listeners.get(event);
215
234
  if (!set) return;
@@ -376,12 +395,22 @@ function createImaController(video, options) {
376
395
  const google = window.google;
377
396
  ensurePlaceholderContainer();
378
397
  if (!adDisplayContainer && adContainerEl) {
398
+ if (!adVideoElement) {
399
+ adVideoElement = createAdVideoElement();
400
+ adContainerEl.appendChild(adVideoElement);
401
+ console.log(
402
+ "[IMA] Dedicated ad video element added to container"
403
+ );
404
+ }
379
405
  adDisplayContainer = new google.ima.AdDisplayContainer(
380
406
  adContainerEl,
381
- video
407
+ adVideoElement
382
408
  );
383
409
  try {
384
410
  (_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
411
+ console.log(
412
+ "[IMA] AdDisplayContainer initialized with dedicated ad video"
413
+ );
385
414
  } catch {
386
415
  }
387
416
  }
@@ -450,13 +479,22 @@ function createImaController(video, options) {
450
479
  }
451
480
  video.parentElement.appendChild(container);
452
481
  adContainerEl = container;
482
+ if (!adVideoElement) {
483
+ adVideoElement = createAdVideoElement();
484
+ adContainerEl.appendChild(adVideoElement);
485
+ console.log(
486
+ "[IMA] Dedicated ad video element created and added to container"
487
+ );
488
+ }
453
489
  adDisplayContainer = new google.ima.AdDisplayContainer(
454
490
  container,
455
- video
491
+ adVideoElement
456
492
  );
457
493
  try {
458
494
  adDisplayContainer.initialize();
459
- console.log("[IMA] Ad display container initialized");
495
+ console.log(
496
+ "[IMA] Ad display container initialized with dedicated ad video"
497
+ );
460
498
  } catch (error) {
461
499
  console.warn(
462
500
  "[IMA] Failed to initialize ad display container:",
@@ -499,11 +537,10 @@ function createImaController(video, options) {
499
537
  console.error("[IMA] Ad error:", errorEvent.getError());
500
538
  destroyAdsManager();
501
539
  adPlaying = false;
502
- const previousMutedState = video.muted;
503
- video.muted = originalMutedState;
540
+ video.style.visibility = "visible";
504
541
  setAdPlayingFlag(false);
505
542
  console.log(
506
- `[IMA] Restored mute state after ad error: ${previousMutedState} -> ${originalMutedState}`
543
+ "[IMA] Restored main video visibility after ad error"
507
544
  );
508
545
  if (adContainerEl) {
509
546
  adContainerEl.style.pointerEvents = "none";
@@ -547,18 +584,17 @@ function createImaController(video, options) {
547
584
  AdEvent.CONTENT_PAUSE_REQUESTED,
548
585
  () => {
549
586
  console.log(
550
- "[IMA] Content pause requested - FORCE MUTING main video"
587
+ "[IMA] Content pause requested - hiding main video, showing ad video"
551
588
  );
552
589
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
553
590
  video.pause();
554
- console.log("[IMA] Video paused (VOD mode)");
591
+ console.log("[IMA] Content video paused (VOD mode)");
555
592
  } else {
556
593
  console.log(
557
- "[IMA] Video continues playing but muted (Live mode)"
594
+ "[IMA] Content video continues playing in background (Live mode)"
558
595
  );
559
596
  }
560
- video.muted = true;
561
- video.volume = 0;
597
+ video.style.visibility = "hidden";
562
598
  adPlaying = true;
563
599
  setAdPlayingFlag(true);
564
600
  emit("content_pause");
@@ -566,36 +602,46 @@ function createImaController(video, options) {
566
602
  );
567
603
  adsManager.addEventListener(AdEvent.STARTED, () => {
568
604
  console.log(
569
- "[IMA] Ad started playing - FORCE MUTING main video"
605
+ "[IMA] Ad started playing - showing dedicated ad video"
570
606
  );
571
607
  setAdPlayingFlag(true);
572
- video.muted = true;
573
- video.volume = 0;
608
+ video.style.visibility = "hidden";
609
+ if (adVideoElement) {
610
+ adVideoElement.volume = originalMutedState ? 0 : originalVolume;
611
+ adVideoElement.muted = originalMutedState;
612
+ console.log(
613
+ `[IMA] Ad video volume: ${adVideoElement.volume}, muted: ${adVideoElement.muted}`
614
+ );
615
+ }
574
616
  if (adContainerEl) {
575
617
  adContainerEl.style.pointerEvents = "auto";
576
618
  adContainerEl.style.display = "flex";
577
619
  console.log(
578
- "[IMA] Ad container visibility set to flex with pointer events enabled"
620
+ "[IMA] Ad container visible with dedicated ad video"
579
621
  );
580
622
  }
581
623
  });
582
624
  adsManager.addEventListener(
583
625
  AdEvent.CONTENT_RESUME_REQUESTED,
584
626
  () => {
585
- console.log("[IMA] Content resume requested");
627
+ console.log(
628
+ "[IMA] Content resume requested - showing main video"
629
+ );
586
630
  adPlaying = false;
587
631
  setAdPlayingFlag(false);
632
+ video.style.visibility = "visible";
588
633
  emit("content_resume");
589
634
  setTimeout(() => {
590
635
  const stillInPod = video.dataset.stormcloudAdPlaying === "true";
591
636
  if (stillInPod) {
592
637
  console.log(
593
- "[IMA] Still in ad pod - keeping ad container visible (black screen)"
638
+ "[IMA] Still in ad pod - keeping ad video visible"
594
639
  );
595
640
  if (adContainerEl) {
596
641
  adContainerEl.style.display = "flex";
597
642
  adContainerEl.style.pointerEvents = "auto";
598
643
  }
644
+ video.style.visibility = "hidden";
599
645
  }
600
646
  }, 50);
601
647
  }
@@ -615,7 +661,7 @@ function createImaController(video, options) {
615
661
  } catch (e) {
616
662
  console.error("[IMA] Error setting up ads manager:", e);
617
663
  adPlaying = false;
618
- video.muted = originalMutedState;
664
+ video.style.visibility = "visible";
619
665
  setAdPlayingFlag(false);
620
666
  if (adContainerEl) {
621
667
  adContainerEl.style.pointerEvents = "none";
@@ -646,11 +692,10 @@ function createImaController(video, options) {
646
692
  (adErrorEvent) => {
647
693
  console.error("[IMA] Ads loader error:", adErrorEvent.getError());
648
694
  adPlaying = false;
649
- const previousMutedState = video.muted;
650
- video.muted = originalMutedState;
695
+ video.style.visibility = "visible";
651
696
  setAdPlayingFlag(false);
652
697
  console.log(
653
- `[IMA] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
698
+ "[IMA] Restored main video visibility after loader error"
654
699
  );
655
700
  if (adContainerEl) {
656
701
  adContainerEl.style.pointerEvents = "none";
@@ -730,11 +775,18 @@ function createImaController(video, options) {
730
775
  adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
731
776
  adPlaying = true;
732
777
  const adVolume = originalMutedState ? 0 : originalVolume;
778
+ if (adVideoElement) {
779
+ adVideoElement.volume = adVolume;
780
+ adVideoElement.muted = originalMutedState;
781
+ console.log(
782
+ `[IMA] Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
783
+ );
784
+ }
733
785
  try {
734
786
  adsManager.setVolume(adVolume);
735
- console.log(`[IMA] Set ad volume to ${adVolume}`);
787
+ console.log(`[IMA] Set IMA manager volume to ${adVolume}`);
736
788
  } catch (error) {
737
- console.warn("[IMA] Failed to set ad volume:", error);
789
+ console.warn("[IMA] Failed to set IMA manager volume:", error);
738
790
  }
739
791
  console.log("[IMA] Starting ad playback");
740
792
  adsManager.start();
@@ -755,6 +807,7 @@ function createImaController(video, options) {
755
807
  console.log("[IMA] Stopping ad playback");
756
808
  adPlaying = false;
757
809
  setAdPlayingFlag(false);
810
+ video.style.visibility = "visible";
758
811
  if (adContainerEl) {
759
812
  adContainerEl.style.pointerEvents = "none";
760
813
  adContainerEl.style.display = "none";
@@ -770,8 +823,7 @@ function createImaController(video, options) {
770
823
  var _a;
771
824
  destroyAdsManager();
772
825
  adPlaying = false;
773
- video.muted = originalMutedState;
774
- video.volume = originalVolume;
826
+ video.style.visibility = "visible";
775
827
  setAdPlayingFlag(false);
776
828
  if (adContainerEl) {
777
829
  adContainerEl.style.pointerEvents = "none";
@@ -787,6 +839,7 @@ function createImaController(video, options) {
787
839
  adContainerEl = void 0;
788
840
  adDisplayContainer = void 0;
789
841
  adsLoader = void 0;
842
+ adVideoElement = void 0;
790
843
  preloadedVast.clear();
791
844
  preloadingVast.clear();
792
845
  },
@@ -831,15 +884,26 @@ function createImaController(video, options) {
831
884
  return originalVolume;
832
885
  },
833
886
  setAdVolume(volume) {
887
+ const clampedVolume = Math.max(0, Math.min(1, volume));
888
+ if (adVideoElement && adPlaying) {
889
+ adVideoElement.volume = clampedVolume;
890
+ adVideoElement.muted = clampedVolume === 0;
891
+ console.log(
892
+ `[IMA] Set dedicated ad video volume to ${clampedVolume}, muted: ${clampedVolume === 0}`
893
+ );
894
+ }
834
895
  if (adsManager && adPlaying) {
835
896
  try {
836
- adsManager.setVolume(Math.max(0, Math.min(1, volume)));
897
+ adsManager.setVolume(clampedVolume);
837
898
  } catch (error) {
838
- console.warn("[IMA] Failed to set ad volume:", error);
899
+ console.warn("[IMA] Failed to set IMA manager volume:", error);
839
900
  }
840
901
  }
841
902
  },
842
903
  getAdVolume() {
904
+ if (adVideoElement && adPlaying) {
905
+ return adVideoElement.volume;
906
+ }
843
907
  if (adsManager && adPlaying) {
844
908
  try {
845
909
  return adsManager.getVolume();
@@ -3456,11 +3520,6 @@ var StormcloudVideoPlayer = class {
3456
3520
  }
3457
3521
  return false;
3458
3522
  }
3459
- if (this.config.debugAdTiming) {
3460
- console.log(
3461
- `[StormcloudVideoPlayer] isMuted() no ad playing: video.muted=${this.video.muted}`
3462
- );
3463
- }
3464
3523
  return this.video.muted;
3465
3524
  }
3466
3525
  setMuted(muted) {
@@ -3490,6 +3549,26 @@ var StormcloudVideoPlayer = class {
3490
3549
  console.log("[StormcloudVideoPlayer] setMuted called:", muted);
3491
3550
  }
3492
3551
  }
3552
+ setVolume(volume) {
3553
+ const clampedVolume = Math.max(0, Math.min(1, volume));
3554
+ const adPlaying = this.ima.isAdPlaying();
3555
+ if (adPlaying) {
3556
+ this.ima.setAdVolume(clampedVolume);
3557
+ this.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);
3558
+ if (this.config.debugAdTiming) {
3559
+ console.log("[StormcloudVideoPlayer] setVolume applied during ad", {
3560
+ volume: clampedVolume
3561
+ });
3562
+ }
3563
+ } else {
3564
+ this.video.volume = clampedVolume;
3565
+ this.video.muted = clampedVolume === 0;
3566
+ this.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);
3567
+ if (this.config.debugAdTiming) {
3568
+ console.log("[StormcloudVideoPlayer] setVolume called:", clampedVolume);
3569
+ }
3570
+ }
3571
+ }
3493
3572
  isFullscreen() {
3494
3573
  return !!document.fullscreenElement;
3495
3574
  }