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.
- package/dist/stormcloud-vp.min.js +1 -1
- package/lib/index.cjs +114 -36
- 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 +114 -36
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +111 -32
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +1 -0
- package/lib/players/HlsPlayer.cjs +111 -32
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +111 -32
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +91 -27
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +114 -36
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
package/lib/index.d.cts
CHANGED
|
@@ -181,6 +181,7 @@ declare class StormcloudVideoPlayer {
|
|
|
181
181
|
toggleFullscreen(): Promise<void>;
|
|
182
182
|
isMuted(): boolean;
|
|
183
183
|
setMuted(muted: boolean): void;
|
|
184
|
+
setVolume(volume: number): void;
|
|
184
185
|
isFullscreen(): boolean;
|
|
185
186
|
isLive(): boolean;
|
|
186
187
|
get videoElement(): HTMLVideoElement;
|
package/lib/index.d.ts
CHANGED
|
@@ -181,6 +181,7 @@ declare class StormcloudVideoPlayer {
|
|
|
181
181
|
toggleFullscreen(): Promise<void>;
|
|
182
182
|
isMuted(): boolean;
|
|
183
183
|
setMuted(muted: boolean): void;
|
|
184
|
+
setVolume(volume: number): void;
|
|
184
185
|
isFullscreen(): boolean;
|
|
185
186
|
isLive(): boolean;
|
|
186
187
|
get videoElement(): HTMLVideoElement;
|
package/lib/index.js
CHANGED
|
@@ -201,6 +201,7 @@ function createImaController(video, options) {
|
|
|
201
201
|
const listeners = /* @__PURE__ */ new Map();
|
|
202
202
|
const preloadedVast = /* @__PURE__ */ new Map();
|
|
203
203
|
const preloadingVast = /* @__PURE__ */ new Map();
|
|
204
|
+
let adVideoElement;
|
|
204
205
|
function setAdPlayingFlag(isPlaying) {
|
|
205
206
|
if (isPlaying) {
|
|
206
207
|
video.dataset.stormcloudAdPlaying = "true";
|
|
@@ -208,6 +209,24 @@ function createImaController(video, options) {
|
|
|
208
209
|
delete video.dataset.stormcloudAdPlaying;
|
|
209
210
|
}
|
|
210
211
|
}
|
|
212
|
+
function createAdVideoElement() {
|
|
213
|
+
const adVideo = document.createElement("video");
|
|
214
|
+
adVideo.style.position = "absolute";
|
|
215
|
+
adVideo.style.top = "0";
|
|
216
|
+
adVideo.style.left = "0";
|
|
217
|
+
adVideo.style.width = "100%";
|
|
218
|
+
adVideo.style.height = "100%";
|
|
219
|
+
adVideo.style.objectFit = "contain";
|
|
220
|
+
adVideo.style.backgroundColor = "#000";
|
|
221
|
+
adVideo.style.zIndex = "15";
|
|
222
|
+
adVideo.playsInline = true;
|
|
223
|
+
adVideo.muted = false;
|
|
224
|
+
adVideo.volume = originalMutedState ? 0 : originalVolume;
|
|
225
|
+
console.log(
|
|
226
|
+
`[IMA] Created dedicated ad video element with volume: ${adVideo.volume}, muted: ${adVideo.muted}`
|
|
227
|
+
);
|
|
228
|
+
return adVideo;
|
|
229
|
+
}
|
|
211
230
|
function emit(event, payload) {
|
|
212
231
|
const set = listeners.get(event);
|
|
213
232
|
if (!set) return;
|
|
@@ -374,12 +393,22 @@ function createImaController(video, options) {
|
|
|
374
393
|
const google = window.google;
|
|
375
394
|
ensurePlaceholderContainer();
|
|
376
395
|
if (!adDisplayContainer && adContainerEl) {
|
|
396
|
+
if (!adVideoElement) {
|
|
397
|
+
adVideoElement = createAdVideoElement();
|
|
398
|
+
adContainerEl.appendChild(adVideoElement);
|
|
399
|
+
console.log(
|
|
400
|
+
"[IMA] Dedicated ad video element added to container"
|
|
401
|
+
);
|
|
402
|
+
}
|
|
377
403
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
378
404
|
adContainerEl,
|
|
379
|
-
|
|
405
|
+
adVideoElement
|
|
380
406
|
);
|
|
381
407
|
try {
|
|
382
408
|
(_a = adDisplayContainer.initialize) == null ? void 0 : _a.call(adDisplayContainer);
|
|
409
|
+
console.log(
|
|
410
|
+
"[IMA] AdDisplayContainer initialized with dedicated ad video"
|
|
411
|
+
);
|
|
383
412
|
} catch {
|
|
384
413
|
}
|
|
385
414
|
}
|
|
@@ -448,13 +477,22 @@ function createImaController(video, options) {
|
|
|
448
477
|
}
|
|
449
478
|
video.parentElement.appendChild(container);
|
|
450
479
|
adContainerEl = container;
|
|
480
|
+
if (!adVideoElement) {
|
|
481
|
+
adVideoElement = createAdVideoElement();
|
|
482
|
+
adContainerEl.appendChild(adVideoElement);
|
|
483
|
+
console.log(
|
|
484
|
+
"[IMA] Dedicated ad video element created and added to container"
|
|
485
|
+
);
|
|
486
|
+
}
|
|
451
487
|
adDisplayContainer = new google.ima.AdDisplayContainer(
|
|
452
488
|
container,
|
|
453
|
-
|
|
489
|
+
adVideoElement
|
|
454
490
|
);
|
|
455
491
|
try {
|
|
456
492
|
adDisplayContainer.initialize();
|
|
457
|
-
console.log(
|
|
493
|
+
console.log(
|
|
494
|
+
"[IMA] Ad display container initialized with dedicated ad video"
|
|
495
|
+
);
|
|
458
496
|
} catch (error) {
|
|
459
497
|
console.warn(
|
|
460
498
|
"[IMA] Failed to initialize ad display container:",
|
|
@@ -497,11 +535,10 @@ function createImaController(video, options) {
|
|
|
497
535
|
console.error("[IMA] Ad error:", errorEvent.getError());
|
|
498
536
|
destroyAdsManager();
|
|
499
537
|
adPlaying = false;
|
|
500
|
-
|
|
501
|
-
video.muted = originalMutedState;
|
|
538
|
+
video.style.visibility = "visible";
|
|
502
539
|
setAdPlayingFlag(false);
|
|
503
540
|
console.log(
|
|
504
|
-
|
|
541
|
+
"[IMA] Restored main video visibility after ad error"
|
|
505
542
|
);
|
|
506
543
|
if (adContainerEl) {
|
|
507
544
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -545,18 +582,17 @@ function createImaController(video, options) {
|
|
|
545
582
|
AdEvent.CONTENT_PAUSE_REQUESTED,
|
|
546
583
|
() => {
|
|
547
584
|
console.log(
|
|
548
|
-
"[IMA] Content pause requested -
|
|
585
|
+
"[IMA] Content pause requested - hiding main video, showing ad video"
|
|
549
586
|
);
|
|
550
587
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
551
588
|
video.pause();
|
|
552
|
-
console.log("[IMA]
|
|
589
|
+
console.log("[IMA] Content video paused (VOD mode)");
|
|
553
590
|
} else {
|
|
554
591
|
console.log(
|
|
555
|
-
"[IMA]
|
|
592
|
+
"[IMA] Content video continues playing in background (Live mode)"
|
|
556
593
|
);
|
|
557
594
|
}
|
|
558
|
-
video.
|
|
559
|
-
video.volume = 0;
|
|
595
|
+
video.style.visibility = "hidden";
|
|
560
596
|
adPlaying = true;
|
|
561
597
|
setAdPlayingFlag(true);
|
|
562
598
|
emit("content_pause");
|
|
@@ -564,36 +600,46 @@ function createImaController(video, options) {
|
|
|
564
600
|
);
|
|
565
601
|
adsManager.addEventListener(AdEvent.STARTED, () => {
|
|
566
602
|
console.log(
|
|
567
|
-
"[IMA] Ad started playing -
|
|
603
|
+
"[IMA] Ad started playing - showing dedicated ad video"
|
|
568
604
|
);
|
|
569
605
|
setAdPlayingFlag(true);
|
|
570
|
-
video.
|
|
571
|
-
|
|
606
|
+
video.style.visibility = "hidden";
|
|
607
|
+
if (adVideoElement) {
|
|
608
|
+
adVideoElement.volume = originalMutedState ? 0 : originalVolume;
|
|
609
|
+
adVideoElement.muted = originalMutedState;
|
|
610
|
+
console.log(
|
|
611
|
+
`[IMA] Ad video volume: ${adVideoElement.volume}, muted: ${adVideoElement.muted}`
|
|
612
|
+
);
|
|
613
|
+
}
|
|
572
614
|
if (adContainerEl) {
|
|
573
615
|
adContainerEl.style.pointerEvents = "auto";
|
|
574
616
|
adContainerEl.style.display = "flex";
|
|
575
617
|
console.log(
|
|
576
|
-
"[IMA] Ad container
|
|
618
|
+
"[IMA] Ad container visible with dedicated ad video"
|
|
577
619
|
);
|
|
578
620
|
}
|
|
579
621
|
});
|
|
580
622
|
adsManager.addEventListener(
|
|
581
623
|
AdEvent.CONTENT_RESUME_REQUESTED,
|
|
582
624
|
() => {
|
|
583
|
-
console.log(
|
|
625
|
+
console.log(
|
|
626
|
+
"[IMA] Content resume requested - showing main video"
|
|
627
|
+
);
|
|
584
628
|
adPlaying = false;
|
|
585
629
|
setAdPlayingFlag(false);
|
|
630
|
+
video.style.visibility = "visible";
|
|
586
631
|
emit("content_resume");
|
|
587
632
|
setTimeout(() => {
|
|
588
633
|
const stillInPod = video.dataset.stormcloudAdPlaying === "true";
|
|
589
634
|
if (stillInPod) {
|
|
590
635
|
console.log(
|
|
591
|
-
"[IMA] Still in ad pod - keeping ad
|
|
636
|
+
"[IMA] Still in ad pod - keeping ad video visible"
|
|
592
637
|
);
|
|
593
638
|
if (adContainerEl) {
|
|
594
639
|
adContainerEl.style.display = "flex";
|
|
595
640
|
adContainerEl.style.pointerEvents = "auto";
|
|
596
641
|
}
|
|
642
|
+
video.style.visibility = "hidden";
|
|
597
643
|
}
|
|
598
644
|
}, 50);
|
|
599
645
|
}
|
|
@@ -613,7 +659,7 @@ function createImaController(video, options) {
|
|
|
613
659
|
} catch (e) {
|
|
614
660
|
console.error("[IMA] Error setting up ads manager:", e);
|
|
615
661
|
adPlaying = false;
|
|
616
|
-
video.
|
|
662
|
+
video.style.visibility = "visible";
|
|
617
663
|
setAdPlayingFlag(false);
|
|
618
664
|
if (adContainerEl) {
|
|
619
665
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -644,11 +690,10 @@ function createImaController(video, options) {
|
|
|
644
690
|
(adErrorEvent) => {
|
|
645
691
|
console.error("[IMA] Ads loader error:", adErrorEvent.getError());
|
|
646
692
|
adPlaying = false;
|
|
647
|
-
|
|
648
|
-
video.muted = originalMutedState;
|
|
693
|
+
video.style.visibility = "visible";
|
|
649
694
|
setAdPlayingFlag(false);
|
|
650
695
|
console.log(
|
|
651
|
-
|
|
696
|
+
"[IMA] Restored main video visibility after loader error"
|
|
652
697
|
);
|
|
653
698
|
if (adContainerEl) {
|
|
654
699
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -728,11 +773,18 @@ function createImaController(video, options) {
|
|
|
728
773
|
adsManager.init(width, height, window.google.ima.ViewMode.NORMAL);
|
|
729
774
|
adPlaying = true;
|
|
730
775
|
const adVolume = originalMutedState ? 0 : originalVolume;
|
|
776
|
+
if (adVideoElement) {
|
|
777
|
+
adVideoElement.volume = adVolume;
|
|
778
|
+
adVideoElement.muted = originalMutedState;
|
|
779
|
+
console.log(
|
|
780
|
+
`[IMA] Set dedicated ad video volume to ${adVolume}, muted: ${originalMutedState}`
|
|
781
|
+
);
|
|
782
|
+
}
|
|
731
783
|
try {
|
|
732
784
|
adsManager.setVolume(adVolume);
|
|
733
|
-
console.log(`[IMA] Set
|
|
785
|
+
console.log(`[IMA] Set IMA manager volume to ${adVolume}`);
|
|
734
786
|
} catch (error) {
|
|
735
|
-
console.warn("[IMA] Failed to set
|
|
787
|
+
console.warn("[IMA] Failed to set IMA manager volume:", error);
|
|
736
788
|
}
|
|
737
789
|
console.log("[IMA] Starting ad playback");
|
|
738
790
|
adsManager.start();
|
|
@@ -753,6 +805,7 @@ function createImaController(video, options) {
|
|
|
753
805
|
console.log("[IMA] Stopping ad playback");
|
|
754
806
|
adPlaying = false;
|
|
755
807
|
setAdPlayingFlag(false);
|
|
808
|
+
video.style.visibility = "visible";
|
|
756
809
|
if (adContainerEl) {
|
|
757
810
|
adContainerEl.style.pointerEvents = "none";
|
|
758
811
|
adContainerEl.style.display = "none";
|
|
@@ -768,8 +821,7 @@ function createImaController(video, options) {
|
|
|
768
821
|
var _a;
|
|
769
822
|
destroyAdsManager();
|
|
770
823
|
adPlaying = false;
|
|
771
|
-
video.
|
|
772
|
-
video.volume = originalVolume;
|
|
824
|
+
video.style.visibility = "visible";
|
|
773
825
|
setAdPlayingFlag(false);
|
|
774
826
|
if (adContainerEl) {
|
|
775
827
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -785,6 +837,7 @@ function createImaController(video, options) {
|
|
|
785
837
|
adContainerEl = void 0;
|
|
786
838
|
adDisplayContainer = void 0;
|
|
787
839
|
adsLoader = void 0;
|
|
840
|
+
adVideoElement = void 0;
|
|
788
841
|
preloadedVast.clear();
|
|
789
842
|
preloadingVast.clear();
|
|
790
843
|
},
|
|
@@ -829,15 +882,26 @@ function createImaController(video, options) {
|
|
|
829
882
|
return originalVolume;
|
|
830
883
|
},
|
|
831
884
|
setAdVolume(volume) {
|
|
885
|
+
const clampedVolume = Math.max(0, Math.min(1, volume));
|
|
886
|
+
if (adVideoElement && adPlaying) {
|
|
887
|
+
adVideoElement.volume = clampedVolume;
|
|
888
|
+
adVideoElement.muted = clampedVolume === 0;
|
|
889
|
+
console.log(
|
|
890
|
+
`[IMA] Set dedicated ad video volume to ${clampedVolume}, muted: ${clampedVolume === 0}`
|
|
891
|
+
);
|
|
892
|
+
}
|
|
832
893
|
if (adsManager && adPlaying) {
|
|
833
894
|
try {
|
|
834
|
-
adsManager.setVolume(
|
|
895
|
+
adsManager.setVolume(clampedVolume);
|
|
835
896
|
} catch (error) {
|
|
836
|
-
console.warn("[IMA] Failed to set
|
|
897
|
+
console.warn("[IMA] Failed to set IMA manager volume:", error);
|
|
837
898
|
}
|
|
838
899
|
}
|
|
839
900
|
},
|
|
840
901
|
getAdVolume() {
|
|
902
|
+
if (adVideoElement && adPlaying) {
|
|
903
|
+
return adVideoElement.volume;
|
|
904
|
+
}
|
|
841
905
|
if (adsManager && adPlaying) {
|
|
842
906
|
try {
|
|
843
907
|
return adsManager.getVolume();
|
|
@@ -3454,11 +3518,6 @@ var StormcloudVideoPlayer = class {
|
|
|
3454
3518
|
}
|
|
3455
3519
|
return false;
|
|
3456
3520
|
}
|
|
3457
|
-
if (this.config.debugAdTiming) {
|
|
3458
|
-
console.log(
|
|
3459
|
-
`[StormcloudVideoPlayer] isMuted() no ad playing: video.muted=${this.video.muted}`
|
|
3460
|
-
);
|
|
3461
|
-
}
|
|
3462
3521
|
return this.video.muted;
|
|
3463
3522
|
}
|
|
3464
3523
|
setMuted(muted) {
|
|
@@ -3488,6 +3547,26 @@ var StormcloudVideoPlayer = class {
|
|
|
3488
3547
|
console.log("[StormcloudVideoPlayer] setMuted called:", muted);
|
|
3489
3548
|
}
|
|
3490
3549
|
}
|
|
3550
|
+
setVolume(volume) {
|
|
3551
|
+
const clampedVolume = Math.max(0, Math.min(1, volume));
|
|
3552
|
+
const adPlaying = this.ima.isAdPlaying();
|
|
3553
|
+
if (adPlaying) {
|
|
3554
|
+
this.ima.setAdVolume(clampedVolume);
|
|
3555
|
+
this.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);
|
|
3556
|
+
if (this.config.debugAdTiming) {
|
|
3557
|
+
console.log("[StormcloudVideoPlayer] setVolume applied during ad", {
|
|
3558
|
+
volume: clampedVolume
|
|
3559
|
+
});
|
|
3560
|
+
}
|
|
3561
|
+
} else {
|
|
3562
|
+
this.video.volume = clampedVolume;
|
|
3563
|
+
this.video.muted = clampedVolume === 0;
|
|
3564
|
+
this.ima.updateOriginalMutedState(clampedVolume === 0, clampedVolume);
|
|
3565
|
+
if (this.config.debugAdTiming) {
|
|
3566
|
+
console.log("[StormcloudVideoPlayer] setVolume called:", clampedVolume);
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3491
3570
|
isFullscreen() {
|
|
3492
3571
|
return !!document.fullscreenElement;
|
|
3493
3572
|
}
|
|
@@ -3668,10 +3747,9 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3668
3747
|
}
|
|
3669
3748
|
};
|
|
3670
3749
|
const handleVolumeChange = (newVolume) => {
|
|
3671
|
-
if (
|
|
3750
|
+
if (playerRef.current && isFinite(newVolume)) {
|
|
3672
3751
|
const clampedVolume = Math.max(0, Math.min(1, newVolume));
|
|
3673
|
-
|
|
3674
|
-
videoRef.current.muted = clampedVolume === 0;
|
|
3752
|
+
playerRef.current.setVolume(clampedVolume);
|
|
3675
3753
|
}
|
|
3676
3754
|
};
|
|
3677
3755
|
const handlePlaybackRateChange = (rate) => {
|
|
@@ -3773,7 +3851,7 @@ var StormcloudVideoPlayerComponent = React.memo(
|
|
|
3773
3851
|
if (autoplay !== void 0 && playerRef.current.videoElement) {
|
|
3774
3852
|
playerRef.current.videoElement.autoplay = autoplay;
|
|
3775
3853
|
}
|
|
3776
|
-
if (muted !== void 0) {
|
|
3854
|
+
if (muted !== void 0 && !playerRef.current.isShowingAds()) {
|
|
3777
3855
|
playerRef.current.setMuted(muted);
|
|
3778
3856
|
}
|
|
3779
3857
|
} catch (error) {
|