stormcloud-video-player 0.2.15 → 0.2.17
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 +388 -245
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +2 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +388 -245
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +90 -20
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +2 -0
- package/lib/players/FilePlayer.cjs +12 -1
- package/lib/players/FilePlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +103 -23
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +115 -24
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/ima.cjs +38 -2
- package/lib/sdk/ima.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +363 -241
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
package/lib/players/index.cjs
CHANGED
|
@@ -326,6 +326,14 @@ function createImaController(video, options) {
|
|
|
326
326
|
function makeAdsRequest(google, vastTagUrl) {
|
|
327
327
|
const adsRequest = new google.ima.AdsRequest();
|
|
328
328
|
adsRequest.adTagUrl = vastTagUrl;
|
|
329
|
+
const videoWidth = video.offsetWidth || video.clientWidth || 640;
|
|
330
|
+
const videoHeight = video.offsetHeight || video.clientHeight || 360;
|
|
331
|
+
adsRequest.linearAdSlotWidth = videoWidth;
|
|
332
|
+
adsRequest.linearAdSlotHeight = videoHeight;
|
|
333
|
+
adsRequest.nonLinearAdSlotWidth = videoWidth;
|
|
334
|
+
adsRequest.nonLinearAdSlotHeight = videoHeight;
|
|
335
|
+
adsRequest.vastLoadTimeout = 5e3;
|
|
336
|
+
console.log(`[IMA] Ads request dimensions: ${videoWidth}x${videoHeight}`);
|
|
329
337
|
adsLoader.requestAds(adsRequest);
|
|
330
338
|
}
|
|
331
339
|
function destroyAdsManager() {
|
|
@@ -372,6 +380,18 @@ function createImaController(video, options) {
|
|
|
372
380
|
},
|
|
373
381
|
async requestAds(vastTagUrl) {
|
|
374
382
|
console.log("[IMA] Requesting ads:", vastTagUrl);
|
|
383
|
+
if (!vastTagUrl || vastTagUrl.trim() === "") {
|
|
384
|
+
const error = new Error("VAST tag URL is empty or undefined");
|
|
385
|
+
console.warn("[IMA]", error.message);
|
|
386
|
+
return Promise.reject(error);
|
|
387
|
+
}
|
|
388
|
+
try {
|
|
389
|
+
new URL(vastTagUrl);
|
|
390
|
+
} catch (e) {
|
|
391
|
+
const error = new Error(`Invalid VAST tag URL format: ${vastTagUrl}`);
|
|
392
|
+
console.warn("[IMA]", error.message);
|
|
393
|
+
return Promise.reject(error);
|
|
394
|
+
}
|
|
375
395
|
if (adPlaying) {
|
|
376
396
|
console.warn(
|
|
377
397
|
"[IMA] Cannot request new ads while an ad is playing. Call stop() first."
|
|
@@ -433,6 +453,18 @@ function createImaController(video, options) {
|
|
|
433
453
|
);
|
|
434
454
|
}
|
|
435
455
|
}
|
|
456
|
+
const videoWidth = video.offsetWidth || video.clientWidth;
|
|
457
|
+
const videoHeight = video.offsetHeight || video.clientHeight;
|
|
458
|
+
if (!videoWidth || !videoHeight || videoWidth === 0 || videoHeight === 0) {
|
|
459
|
+
const error = new Error(
|
|
460
|
+
`Invalid video dimensions: ${videoWidth}x${videoHeight}. Cannot initialize ads.`
|
|
461
|
+
);
|
|
462
|
+
console.warn("[IMA]", error.message);
|
|
463
|
+
currentReject == null ? void 0 : currentReject(error);
|
|
464
|
+
adsLoadedReject = void 0;
|
|
465
|
+
adsLoadedResolve = void 0;
|
|
466
|
+
return Promise.reject(error);
|
|
467
|
+
}
|
|
436
468
|
if (!adsLoader) {
|
|
437
469
|
console.log("[IMA] Creating ads loader");
|
|
438
470
|
const adsLoaderCls = new google.ima.AdsLoader(adDisplayContainer);
|
|
@@ -481,7 +513,9 @@ function createImaController(video, options) {
|
|
|
481
513
|
emit("ad_error");
|
|
482
514
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
483
515
|
if (video.paused) {
|
|
484
|
-
console.log(
|
|
516
|
+
console.log(
|
|
517
|
+
"[IMA] Resuming paused video after ad error"
|
|
518
|
+
);
|
|
485
519
|
(_a = video.play()) == null ? void 0 : _a.catch(() => {
|
|
486
520
|
});
|
|
487
521
|
}
|
|
@@ -583,7 +617,9 @@ function createImaController(video, options) {
|
|
|
583
617
|
}
|
|
584
618
|
if (!(options == null ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
585
619
|
if (video.paused) {
|
|
586
|
-
console.log(
|
|
620
|
+
console.log(
|
|
621
|
+
"[IMA] Resuming paused video after setup error"
|
|
622
|
+
);
|
|
587
623
|
video.play().catch(() => {
|
|
588
624
|
});
|
|
589
625
|
}
|
|
@@ -1778,6 +1814,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1778
1814
|
this.totalAdsInBreak = 0;
|
|
1779
1815
|
this.showAds = false;
|
|
1780
1816
|
this.isLiveStream = false;
|
|
1817
|
+
this.nativeHlsMode = false;
|
|
1818
|
+
this.videoSrcProtection = null;
|
|
1781
1819
|
initializePolyfills();
|
|
1782
1820
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1783
1821
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -1798,7 +1836,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1798
1836
|
}
|
|
1799
1837
|
if (adPlayerType === "hls") {
|
|
1800
1838
|
if (this.config.debugAdTiming) {
|
|
1801
|
-
console.log(
|
|
1839
|
+
console.log(
|
|
1840
|
+
"[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)"
|
|
1841
|
+
);
|
|
1802
1842
|
}
|
|
1803
1843
|
return createHlsAdPlayer(this.video, {
|
|
1804
1844
|
continueLiveStreamDuringAds,
|
|
@@ -1807,7 +1847,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1807
1847
|
});
|
|
1808
1848
|
} else {
|
|
1809
1849
|
if (this.config.debugAdTiming) {
|
|
1810
|
-
console.log(
|
|
1850
|
+
console.log(
|
|
1851
|
+
"[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)"
|
|
1852
|
+
);
|
|
1811
1853
|
}
|
|
1812
1854
|
return createImaController(this.video, {
|
|
1813
1855
|
continueLiveStreamDuringAds
|
|
@@ -1831,11 +1873,13 @@ var StormcloudVideoPlayer = class {
|
|
|
1831
1873
|
}
|
|
1832
1874
|
this.initializeTracking();
|
|
1833
1875
|
if (this.shouldUseNativeHls()) {
|
|
1876
|
+
this.nativeHlsMode = true;
|
|
1877
|
+
this.videoSrcProtection = this.config.src;
|
|
1834
1878
|
this.video.src = this.config.src;
|
|
1835
1879
|
this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
|
|
1836
1880
|
if (this.config.debugAdTiming) {
|
|
1837
1881
|
console.log(
|
|
1838
|
-
"[StormcloudVideoPlayer]
|
|
1882
|
+
"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:",
|
|
1839
1883
|
{
|
|
1840
1884
|
isLive: this.isLiveStream,
|
|
1841
1885
|
allowNativeHls: this.config.allowNativeHls,
|
|
@@ -1983,7 +2027,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1983
2027
|
this.ima.initialize();
|
|
1984
2028
|
this.ima.on("all_ads_completed", () => {
|
|
1985
2029
|
if (this.config.debugAdTiming) {
|
|
1986
|
-
console.log(
|
|
2030
|
+
console.log(
|
|
2031
|
+
"[StormcloudVideoPlayer] IMA all_ads_completed event received"
|
|
2032
|
+
);
|
|
1987
2033
|
}
|
|
1988
2034
|
});
|
|
1989
2035
|
this.ima.on("ad_error", () => {
|
|
@@ -2048,13 +2094,31 @@ var StormcloudVideoPlayer = class {
|
|
|
2048
2094
|
this.video.addEventListener("timeupdate", () => {
|
|
2049
2095
|
this.onTimeUpdate(this.video.currentTime);
|
|
2050
2096
|
});
|
|
2097
|
+
this.video.addEventListener("emptied", () => {
|
|
2098
|
+
if (this.nativeHlsMode && this.videoSrcProtection && !this.ima.isAdPlaying()) {
|
|
2099
|
+
if (this.config.debugAdTiming) {
|
|
2100
|
+
console.log(
|
|
2101
|
+
"[StormcloudVideoPlayer] Video src was cleared, restoring:",
|
|
2102
|
+
this.videoSrcProtection
|
|
2103
|
+
);
|
|
2104
|
+
}
|
|
2105
|
+
const currentTime = this.video.currentTime;
|
|
2106
|
+
const wasPaused = this.video.paused;
|
|
2107
|
+
this.video.src = this.videoSrcProtection;
|
|
2108
|
+
this.video.currentTime = currentTime;
|
|
2109
|
+
if (!wasPaused) {
|
|
2110
|
+
this.video.play().catch(() => {
|
|
2111
|
+
});
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
});
|
|
2051
2115
|
}
|
|
2052
2116
|
shouldUseNativeHls() {
|
|
2053
2117
|
const streamType = this.getStreamType();
|
|
2054
2118
|
if (streamType === "other") {
|
|
2055
2119
|
return true;
|
|
2056
2120
|
}
|
|
2057
|
-
const canNative = this.video.canPlayType("application/vnd.apple.
|
|
2121
|
+
const canNative = this.video.canPlayType("application/vnd.apple.mpegurl");
|
|
2058
2122
|
return !!(this.config.allowNativeHls && canNative);
|
|
2059
2123
|
}
|
|
2060
2124
|
onId3Tag(tag) {
|
|
@@ -2481,10 +2545,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2481
2545
|
var _a, _b, _c;
|
|
2482
2546
|
const vastMode = this.config.vastMode || "default";
|
|
2483
2547
|
if (this.config.debugAdTiming) {
|
|
2484
|
-
console.log(
|
|
2485
|
-
"[StormcloudVideoPlayer] VAST mode:",
|
|
2486
|
-
vastMode
|
|
2487
|
-
);
|
|
2548
|
+
console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
|
|
2488
2549
|
}
|
|
2489
2550
|
if (vastMode === "adstorm") {
|
|
2490
2551
|
if (!this.config.licenseKey) {
|
|
@@ -2602,10 +2663,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2602
2663
|
this.currentAdIndex = 0;
|
|
2603
2664
|
this.totalAdsInBreak = 1;
|
|
2604
2665
|
if (this.config.debugAdTiming) {
|
|
2605
|
-
console.log(
|
|
2606
|
-
"[StormcloudVideoPlayer] Using VAST endpoint:",
|
|
2607
|
-
vastTagUrl
|
|
2608
|
-
);
|
|
2666
|
+
console.log("[StormcloudVideoPlayer] Using VAST endpoint:", vastTagUrl);
|
|
2609
2667
|
}
|
|
2610
2668
|
} else if (tags && tags.length > 0) {
|
|
2611
2669
|
vastTagUrl = tags[0];
|
|
@@ -2757,15 +2815,21 @@ var StormcloudVideoPlayer = class {
|
|
|
2757
2815
|
await this.ima.requestAds(vastTagUrl);
|
|
2758
2816
|
try {
|
|
2759
2817
|
if (this.config.debugAdTiming) {
|
|
2760
|
-
console.log(
|
|
2818
|
+
console.log(
|
|
2819
|
+
"[StormcloudVideoPlayer] Ad request completed, attempting playback"
|
|
2820
|
+
);
|
|
2761
2821
|
}
|
|
2762
2822
|
await this.ima.play();
|
|
2763
2823
|
if (this.config.debugAdTiming) {
|
|
2764
|
-
console.log(
|
|
2824
|
+
console.log(
|
|
2825
|
+
"[StormcloudVideoPlayer] Ad playback started successfully"
|
|
2826
|
+
);
|
|
2765
2827
|
}
|
|
2766
2828
|
} catch (playError) {
|
|
2767
2829
|
if (this.config.debugAdTiming) {
|
|
2768
|
-
console.log(
|
|
2830
|
+
console.log(
|
|
2831
|
+
"[StormcloudVideoPlayer] No ads available, skipping playback"
|
|
2832
|
+
);
|
|
2769
2833
|
}
|
|
2770
2834
|
this.handleAdFailure();
|
|
2771
2835
|
return;
|
|
@@ -2821,7 +2885,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2821
2885
|
});
|
|
2822
2886
|
} else {
|
|
2823
2887
|
if (this.config.debugAdTiming) {
|
|
2824
|
-
console.log(
|
|
2888
|
+
console.log(
|
|
2889
|
+
"[StormcloudVideoPlayer] Video is already playing, no resume needed"
|
|
2890
|
+
);
|
|
2825
2891
|
}
|
|
2826
2892
|
}
|
|
2827
2893
|
}
|
|
@@ -2840,7 +2906,11 @@ var StormcloudVideoPlayer = class {
|
|
|
2840
2906
|
if (this.config.debugAdTiming) {
|
|
2841
2907
|
console.warn(
|
|
2842
2908
|
"[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
|
|
2843
|
-
{
|
|
2909
|
+
{
|
|
2910
|
+
paused: this.video.paused,
|
|
2911
|
+
showAds: this.showAds,
|
|
2912
|
+
adPlaying: this.ima.isAdPlaying()
|
|
2913
|
+
}
|
|
2844
2914
|
);
|
|
2845
2915
|
}
|
|
2846
2916
|
this.handleAdFailure();
|
|
@@ -3033,10 +3103,20 @@ var HlsPlayer = class extends import_react2.Component {
|
|
|
3033
3103
|
}
|
|
3034
3104
|
};
|
|
3035
3105
|
this.play = () => {
|
|
3036
|
-
var _a, _b;
|
|
3106
|
+
var _a, _b, _c;
|
|
3037
3107
|
if (this.props.videoElement) {
|
|
3038
|
-
this.props.videoElement
|
|
3039
|
-
|
|
3108
|
+
const video = this.props.videoElement;
|
|
3109
|
+
const hasValidSource = video.src || video.currentSrc && video.currentSrc !== "" || video.readyState >= 1;
|
|
3110
|
+
if (hasValidSource) {
|
|
3111
|
+
(_a = video.play()) == null ? void 0 : _a.catch((error) => {
|
|
3112
|
+
var _a2, _b2;
|
|
3113
|
+
console.error("[HlsPlayer] Failed to play:", error);
|
|
3114
|
+
(_b2 = (_a2 = this.props).onError) == null ? void 0 : _b2.call(_a2, error);
|
|
3115
|
+
});
|
|
3116
|
+
(_c = (_b = this.props).onPlay) == null ? void 0 : _c.call(_b);
|
|
3117
|
+
} else {
|
|
3118
|
+
console.warn("[HlsPlayer] Cannot play: video has no valid source");
|
|
3119
|
+
}
|
|
3040
3120
|
}
|
|
3041
3121
|
};
|
|
3042
3122
|
this.pause = () => {
|
|
@@ -3205,8 +3285,19 @@ var FilePlayer = class extends import_react3.Component {
|
|
|
3205
3285
|
};
|
|
3206
3286
|
};
|
|
3207
3287
|
this.play = () => {
|
|
3288
|
+
var _a;
|
|
3208
3289
|
if (this.props.videoElement) {
|
|
3209
|
-
this.props.videoElement
|
|
3290
|
+
const video = this.props.videoElement;
|
|
3291
|
+
const hasValidSource = video.src || video.currentSrc && video.currentSrc !== "" || video.readyState >= 1;
|
|
3292
|
+
if (hasValidSource) {
|
|
3293
|
+
(_a = video.play()) == null ? void 0 : _a.catch((error) => {
|
|
3294
|
+
var _a2, _b;
|
|
3295
|
+
console.error("[FilePlayer] Failed to play:", error);
|
|
3296
|
+
(_b = (_a2 = this.props).onError) == null ? void 0 : _b.call(_a2, error);
|
|
3297
|
+
});
|
|
3298
|
+
} else {
|
|
3299
|
+
console.warn("[FilePlayer] Cannot play: video has no valid source");
|
|
3300
|
+
}
|
|
3210
3301
|
}
|
|
3211
3302
|
};
|
|
3212
3303
|
this.pause = () => {
|