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.js CHANGED
@@ -196,11 +196,13 @@ function supportsFeature(feature) {
196
196
  // src/sdk/ima.ts
197
197
  function createImaController(video, options) {
198
198
  let adPlaying = false;
199
+ let contentVideoHidden = false;
199
200
  let originalMutedState = false;
200
201
  let originalVolume = typeof video.volume === "number" && !Number.isNaN(video.volume) ? Math.max(0, Math.min(1, video.volume)) : 1;
201
202
  const listeners = /* @__PURE__ */ new Map();
202
203
  const preloadedVast = /* @__PURE__ */ new Map();
203
204
  const preloadingVast = /* @__PURE__ */ new Map();
205
+ let adVideoElement;
204
206
  function setAdPlayingFlag(isPlaying) {
205
207
  if (isPlaying) {
206
208
  video.dataset.stormcloudAdPlaying = "true";
@@ -208,6 +210,53 @@ function createImaController(video, options) {
208
210
  delete video.dataset.stormcloudAdPlaying;
209
211
  }
210
212
  }
213
+ function hideContentVideo() {
214
+ if (!contentVideoHidden) {
215
+ video.style.visibility = "hidden";
216
+ video.muted = true;
217
+ video.volume = 0;
218
+ contentVideoHidden = true;
219
+ console.log("[IMA] Content video hidden and muted");
220
+ }
221
+ }
222
+ function showContentVideo() {
223
+ if (contentVideoHidden) {
224
+ video.style.visibility = "visible";
225
+ video.muted = originalMutedState;
226
+ video.volume = originalVolume;
227
+ contentVideoHidden = false;
228
+ console.log(
229
+ `[IMA] Content video restored (muted: ${originalMutedState}, volume: ${originalVolume})`
230
+ );
231
+ }
232
+ }
233
+ function createAdVideoElement() {
234
+ const adVideo = document.createElement("video");
235
+ adVideo.style.position = "absolute";
236
+ adVideo.style.top = "0";
237
+ adVideo.style.left = "0";
238
+ adVideo.style.width = "100%";
239
+ adVideo.style.height = "100%";
240
+ adVideo.style.objectFit = "contain";
241
+ adVideo.style.backgroundColor = "transparent";
242
+ adVideo.style.zIndex = "15";
243
+ adVideo.playsInline = true;
244
+ adVideo.muted = false;
245
+ adVideo.volume = originalMutedState ? 0 : originalVolume;
246
+ adVideo.style.opacity = "0";
247
+ adVideo.addEventListener(
248
+ "canplay",
249
+ () => {
250
+ adVideo.style.opacity = "1";
251
+ console.log("[IMA] Ad video ready to play");
252
+ },
253
+ { once: true }
254
+ );
255
+ console.log(
256
+ `[IMA] Created dedicated ad video element with volume: ${adVideo.volume}, muted: ${adVideo.muted}`
257
+ );
258
+ return adVideo;
259
+ }
211
260
  function emit(event, payload) {
212
261
  const set = listeners.get(event);
213
262
  if (!set) return;
@@ -366,6 +415,9 @@ function createImaController(video, options) {
366
415
  }
367
416
  adsManager = void 0;
368
417
  }
418
+ if (adVideoElement) {
419
+ adVideoElement.style.opacity = "0";
420
+ }
369
421
  }
370
422
  return {
371
423
  initialize() {
@@ -374,12 +426,22 @@ function createImaController(video, options) {
374
426
  const google = window.google;
375
427
  ensurePlaceholderContainer();
376
428
  if (!adDisplayContainer && adContainerEl) {
429
+ if (!adVideoElement) {
430
+ adVideoElement = createAdVideoElement();
431
+ adContainerEl.appendChild(adVideoElement);
432
+ console.log(
433
+ "[IMA] Dedicated ad video element added to container"
434
+ );
435
+ }
377
436
  adDisplayContainer = new google.ima.AdDisplayContainer(
378
437
  adContainerEl,
379
- video
438
+ adVideoElement
380
439
  );
381
440
  try {
382
441
  (_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
442
+ console.log(
443
+ "[IMA] AdDisplayContainer initialized with dedicated ad video"
444
+ );
383
445
  } catch {
384
446
  }
385
447
  }
@@ -448,13 +510,22 @@ function createImaController(video, options) {
448
510
  }
449
511
  video.parentElement.appendChild(container);
450
512
  adContainerEl = container;
513
+ if (!adVideoElement) {
514
+ adVideoElement = createAdVideoElement();
515
+ adContainerEl.appendChild(adVideoElement);
516
+ console.log(
517
+ "[IMA] Dedicated ad video element created and added to container"
518
+ );
519
+ }
451
520
  adDisplayContainer = new google.ima.AdDisplayContainer(
452
521
  container,
453
- video
522
+ adVideoElement
454
523
  );
455
524
  try {
456
525
  adDisplayContainer.initialize();
457
- console.log("[IMA] Ad display container initialized");
526
+ console.log(
527
+ "[IMA] Ad display container initialized with dedicated ad video"
528
+ );
458
529
  } catch (error) {
459
530
  console.warn(
460
531
  "[IMA] Failed to initialize ad display container:",
@@ -497,12 +568,8 @@ function createImaController(video, options) {
497
568
  console.error("[IMA] Ad error:", errorEvent.getError());
498
569
  destroyAdsManager();
499
570
  adPlaying = false;
500
- const previousMutedState = video.muted;
501
- video.muted = originalMutedState;
571
+ showContentVideo();
502
572
  setAdPlayingFlag(false);
503
- console.log(
504
- `[IMA] Restored mute state after ad error: ${previousMutedState} -> ${originalMutedState}`
505
- );
506
573
  if (adContainerEl) {
507
574
  adContainerEl.style.pointerEvents = "none";
508
575
  adContainerEl.style.display = "none";
@@ -544,37 +611,35 @@ function createImaController(video, options) {
544
611
  adsManager.addEventListener(
545
612
  AdEvent.CONTENT_PAUSE_REQUESTED,
546
613
  () => {
547
- console.log(
548
- "[IMA] Content pause requested - FORCE MUTING main video"
549
- );
614
+ console.log("[IMA] Content pause requested");
550
615
  if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
551
616
  video.pause();
552
- console.log("[IMA] Video paused (VOD mode)");
617
+ console.log("[IMA] Content video paused (VOD mode)");
553
618
  } else {
554
619
  console.log(
555
- "[IMA] Video continues playing but muted (Live mode)"
620
+ "[IMA] Content video continues in background (Live mode)"
556
621
  );
557
622
  }
558
- video.muted = true;
559
- video.volume = 0;
560
623
  adPlaying = true;
561
624
  setAdPlayingFlag(true);
562
625
  emit("content_pause");
563
626
  }
564
627
  );
565
628
  adsManager.addEventListener(AdEvent.STARTED, () => {
566
- console.log(
567
- "[IMA] Ad started playing - FORCE MUTING main video"
568
- );
629
+ console.log("[IMA] Ad started - showing ad video");
569
630
  setAdPlayingFlag(true);
570
- video.muted = true;
571
- video.volume = 0;
631
+ hideContentVideo();
632
+ if (adVideoElement) {
633
+ adVideoElement.volume = originalMutedState ? 0 : originalVolume;
634
+ adVideoElement.muted = originalMutedState;
635
+ console.log(
636
+ `[IMA] Ad video volume: ${adVideoElement.volume}, muted: ${adVideoElement.muted}`
637
+ );
638
+ }
572
639
  if (adContainerEl) {
573
640
  adContainerEl.style.pointerEvents = "auto";
574
641
  adContainerEl.style.display = "flex";
575
- console.log(
576
- "[IMA] Ad container visibility set to flex with pointer events enabled"
577
- );
642
+ console.log("[IMA] Ad container now visible");
578
643
  }
579
644
  });
580
645
  adsManager.addEventListener(
@@ -583,17 +648,19 @@ function createImaController(video, options) {
583
648
  console.log("[IMA] Content resume requested");
584
649
  adPlaying = false;
585
650
  setAdPlayingFlag(false);
651
+ showContentVideo();
586
652
  emit("content_resume");
587
653
  setTimeout(() => {
588
654
  const stillInPod = video.dataset.stormcloudAdPlaying === "true";
589
655
  if (stillInPod) {
590
656
  console.log(
591
- "[IMA] Still in ad pod - keeping ad container visible (black screen)"
657
+ "[IMA] Still in ad pod - keeping ad container visible"
592
658
  );
593
659
  if (adContainerEl) {
594
660
  adContainerEl.style.display = "flex";
595
661
  adContainerEl.style.pointerEvents = "auto";
596
662
  }
663
+ hideContentVideo();
597
664
  }
598
665
  }, 50);
599
666
  }
@@ -613,7 +680,7 @@ function createImaController(video, options) {
613
680
  } catch (e) {
614
681
  console.error("[IMA] Error setting up ads manager:", e);
615
682
  adPlaying = false;
616
- video.muted = originalMutedState;
683
+ showContentVideo();
617
684
  setAdPlayingFlag(false);
618
685
  if (adContainerEl) {
619
686
  adContainerEl.style.pointerEvents = "none";
@@ -644,12 +711,8 @@ function createImaController(video, options) {
644
711
  (adErrorEvent) => {
645
712
  console.error("[IMA] Ads loader error:", adErrorEvent.getError());
646
713
  adPlaying = false;
647
- const previousMutedState = video.muted;
648
- video.muted = originalMutedState;
714
+ showContentVideo();
649
715
  setAdPlayingFlag(false);
650
- console.log(
651
- `[IMA] Restored mute state: ${previousMutedState} -> ${originalMutedState}`
652
- );
653
716
  if (adContainerEl) {
654
717
  adContainerEl.style.pointerEvents = "none";
655
718
  adContainerEl.style.display = "none";
@@ -728,11 +791,18 @@ function createImaController(video, options) {
728
791
  adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
729
792
  adPlaying = true;
730
793
  const adVolume = originalMutedState ? 0 : originalVolume;
794
+ if (adVideoElement) {
795
+ adVideoElement.volume = adVolume;
796
+ adVideoElement.muted = originalMutedState;
797
+ console.log(
798
+ `[IMA] Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
799
+ );
800
+ }
731
801
  try {
732
802
  adsManager.setVolume(adVolume);
733
- console.log(`[IMA] Set ad volume to ${adVolume}`);
803
+ console.log(`[IMA] Set IMA manager volume to ${adVolume}`);
734
804
  } catch (error) {
735
- console.warn("[IMA] Failed to set ad volume:", error);
805
+ console.warn("[IMA] Failed to set IMA manager volume:", error);
736
806
  }
737
807
  console.log("[IMA] Starting ad playback");
738
808
  adsManager.start();
@@ -753,6 +823,7 @@ function createImaController(video, options) {
753
823
  console.log("[IMA] Stopping ad playback");
754
824
  adPlaying = false;
755
825
  setAdPlayingFlag(false);
826
+ showContentVideo();
756
827
  if (adContainerEl) {
757
828
  adContainerEl.style.pointerEvents = "none";
758
829
  adContainerEl.style.display = "none";
@@ -768,8 +839,7 @@ function createImaController(video, options) {
768
839
  var _a;
769
840
  destroyAdsManager();
770
841
  adPlaying = false;
771
- video.muted = originalMutedState;
772
- video.volume = originalVolume;
842
+ showContentVideo();
773
843
  setAdPlayingFlag(false);
774
844
  if (adContainerEl) {
775
845
  adContainerEl.style.pointerEvents = "none";
@@ -785,6 +855,8 @@ function createImaController(video, options) {
785
855
  adContainerEl = void 0;
786
856
  adDisplayContainer = void 0;
787
857
  adsLoader = void 0;
858
+ adVideoElement = void 0;
859
+ contentVideoHidden = false;
788
860
  preloadedVast.clear();
789
861
  preloadingVast.clear();
790
862
  },
@@ -829,15 +901,26 @@ function createImaController(video, options) {
829
901
  return originalVolume;
830
902
  },
831
903
  setAdVolume(volume) {
904
+ const clampedVolume = Math.max(0, Math.min(1, volume));
905
+ if (adVideoElement && adPlaying) {
906
+ adVideoElement.volume = clampedVolume;
907
+ adVideoElement.muted = clampedVolume === 0;
908
+ console.log(
909
+ `[IMA] Set dedicated ad video volume to ${clampedVolume}, muted: ${clampedVolume === 0}`
910
+ );
911
+ }
832
912
  if (adsManager && adPlaying) {
833
913
  try {
834
- adsManager.setVolume(Math.max(0, Math.min(1, volume)));
914
+ adsManager.setVolume(clampedVolume);
835
915
  } catch (error) {
836
- console.warn("[IMA] Failed to set ad volume:", error);
916
+ console.warn("[IMA] Failed to set IMA manager volume:", error);
837
917
  }
838
918
  }
839
919
  },
840
920
  getAdVolume() {
921
+ if (adVideoElement && adPlaying) {
922
+ return adVideoElement.volume;
923
+ }
841
924
  if (adsManager && adPlaying) {
842
925
  try {
843
926
  return adsManager.getVolume();
@@ -3454,11 +3537,6 @@ var StormcloudVideoPlayer = class {
3454
3537
  }
3455
3538
  return false;
3456
3539
  }
3457
- if (this.config.debugAdTiming) {
3458
- console.log(
3459
- `[StormcloudVideoPlayer] isMuted() no ad playing: video.muted=${this.video.muted}`
3460
- );
3461
- }
3462
3540
  return this.video.muted;
3463
3541
  }
3464
3542
  setMuted(muted) {