stormcloud-video-player 0.2.14 → 0.2.16
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/README.md +92 -11
- package/dist/stormcloud-vp.min.js +2 -2
- package/lib/index.cjs +397 -256
- 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 +397 -256
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +91 -30
- 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 +104 -33
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +116 -34
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +27 -8
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +372 -252
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
|
@@ -850,7 +850,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
850
850
|
const xmlDoc = parser.parseFromString(xmlString, "text/xml");
|
|
851
851
|
const parserError = xmlDoc.querySelector("parsererror");
|
|
852
852
|
if (parserError) {
|
|
853
|
-
console.error("[HlsAdPlayer] XML parsing error:", parserError.textContent);
|
|
853
|
+
console.error("[HlsAdPlayer] XML parsing error (malformed VAST XML):", parserError.textContent);
|
|
854
854
|
return null;
|
|
855
855
|
}
|
|
856
856
|
const adElement = xmlDoc.querySelector("Ad");
|
|
@@ -860,28 +860,45 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
860
860
|
}
|
|
861
861
|
const adId = adElement.getAttribute("id") || "unknown";
|
|
862
862
|
const title = ((_a = xmlDoc.querySelector("AdTitle")) == null ? void 0 : _a.textContent) || "Ad";
|
|
863
|
+
const isNoAdAvailable = adId === "empty" || title.toLowerCase().includes("no ad available") || title.toLowerCase() === "no ad available";
|
|
863
864
|
const durationText = ((_b = xmlDoc.querySelector("Duration")) == null ? void 0 : _b.textContent) || "00:00:30";
|
|
864
865
|
const durationParts = durationText.split(":");
|
|
865
866
|
const duration = parseInt(durationParts[0] || "0", 10) * 3600 + parseInt(durationParts[1] || "0", 10) * 60 + parseInt(durationParts[2] || "0", 10);
|
|
866
867
|
const mediaFileElements = xmlDoc.querySelectorAll("MediaFile");
|
|
867
868
|
const mediaFiles = [];
|
|
868
|
-
mediaFileElements.
|
|
869
|
+
console.log(`[HlsAdPlayer] Found ${mediaFileElements.length} MediaFile element(s) in VAST XML`);
|
|
870
|
+
mediaFileElements.forEach((mf, index) => {
|
|
869
871
|
var _a2;
|
|
870
872
|
const type = mf.getAttribute("type") || "";
|
|
873
|
+
const url = ((_a2 = mf.textContent) == null ? void 0 : _a2.trim()) || "";
|
|
874
|
+
const width = mf.getAttribute("width") || "";
|
|
875
|
+
const height = mf.getAttribute("height") || "";
|
|
876
|
+
console.log(`[HlsAdPlayer] MediaFile ${index}: type="${type}", url="${url}", width="${width}", height="${height}"`);
|
|
871
877
|
if (type === "application/x-mpegURL" || type.includes("m3u8")) {
|
|
878
|
+
if (!url) {
|
|
879
|
+
console.warn(`[HlsAdPlayer] MediaFile ${index} has HLS type but empty URL`);
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
872
882
|
const bitrateAttr = mf.getAttribute("bitrate");
|
|
873
883
|
const bitrateValue = bitrateAttr ? parseInt(bitrateAttr, 10) : void 0;
|
|
874
884
|
mediaFiles.push({
|
|
875
|
-
url
|
|
885
|
+
url,
|
|
876
886
|
type,
|
|
877
|
-
width: parseInt(
|
|
878
|
-
height: parseInt(
|
|
887
|
+
width: parseInt(width || "1920", 10),
|
|
888
|
+
height: parseInt(height || "1080", 10),
|
|
879
889
|
bitrate: bitrateValue && bitrateValue > 0 ? bitrateValue : void 0
|
|
880
890
|
});
|
|
891
|
+
console.log(`[HlsAdPlayer] Added HLS MediaFile: ${url}`);
|
|
892
|
+
} else {
|
|
893
|
+
console.log(`[HlsAdPlayer] MediaFile ${index} ignored (type="${type}" is not HLS)`);
|
|
881
894
|
}
|
|
882
895
|
});
|
|
883
896
|
if (mediaFiles.length === 0) {
|
|
884
|
-
|
|
897
|
+
if (isNoAdAvailable) {
|
|
898
|
+
console.warn("[HlsAdPlayer] No ads available (VAST response indicates no ads)");
|
|
899
|
+
} else {
|
|
900
|
+
console.warn("[HlsAdPlayer] No HLS media files found in VAST XML");
|
|
901
|
+
}
|
|
885
902
|
return null;
|
|
886
903
|
}
|
|
887
904
|
const trackingUrls = {
|
|
@@ -1069,9 +1086,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1069
1086
|
}
|
|
1070
1087
|
const vastXml = await response.text();
|
|
1071
1088
|
console.log("[HlsAdPlayer] VAST XML received");
|
|
1089
|
+
console.log("[HlsAdPlayer] VAST XML content (first 2000 chars):", vastXml.substring(0, 2e3));
|
|
1072
1090
|
const ad = parseVastXml(vastXml);
|
|
1073
1091
|
if (!ad) {
|
|
1074
|
-
|
|
1092
|
+
console.warn("[HlsAdPlayer] No ads available from VAST response");
|
|
1093
|
+
return Promise.resolve();
|
|
1075
1094
|
}
|
|
1076
1095
|
currentAd = ad;
|
|
1077
1096
|
console.log(`[HlsAdPlayer] Ad parsed: ${ad.title}, duration: ${ad.duration}s`);
|
|
@@ -1086,7 +1105,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1086
1105
|
},
|
|
1087
1106
|
async play() {
|
|
1088
1107
|
if (!currentAd) {
|
|
1089
|
-
console.warn("[HlsAdPlayer] Cannot play: No ad loaded");
|
|
1108
|
+
console.warn("[HlsAdPlayer] Cannot play: No ad loaded (no ads available)");
|
|
1090
1109
|
return Promise.reject(new Error("No ad loaded"));
|
|
1091
1110
|
}
|
|
1092
1111
|
console.log("[HlsAdPlayer] Starting ad playback");
|
|
@@ -1717,6 +1736,8 @@ var StormcloudVideoPlayer = class {
|
|
|
1717
1736
|
this.totalAdsInBreak = 0;
|
|
1718
1737
|
this.showAds = false;
|
|
1719
1738
|
this.isLiveStream = false;
|
|
1739
|
+
this.nativeHlsMode = false;
|
|
1740
|
+
this.videoSrcProtection = null;
|
|
1720
1741
|
initializePolyfills();
|
|
1721
1742
|
const browserOverrides = getBrowserConfigOverrides();
|
|
1722
1743
|
this.config = { ...config, ...browserOverrides };
|
|
@@ -1737,7 +1758,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1737
1758
|
}
|
|
1738
1759
|
if (adPlayerType === "hls") {
|
|
1739
1760
|
if (this.config.debugAdTiming) {
|
|
1740
|
-
console.log(
|
|
1761
|
+
console.log(
|
|
1762
|
+
"[StormcloudVideoPlayer] Creating HLS ad player (AdStorm mode)"
|
|
1763
|
+
);
|
|
1741
1764
|
}
|
|
1742
1765
|
return createHlsAdPlayer(this.video, {
|
|
1743
1766
|
continueLiveStreamDuringAds,
|
|
@@ -1746,7 +1769,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1746
1769
|
});
|
|
1747
1770
|
} else {
|
|
1748
1771
|
if (this.config.debugAdTiming) {
|
|
1749
|
-
console.log(
|
|
1772
|
+
console.log(
|
|
1773
|
+
"[StormcloudVideoPlayer] Creating Google IMA ad player (Default mode)"
|
|
1774
|
+
);
|
|
1750
1775
|
}
|
|
1751
1776
|
return createImaController(this.video, {
|
|
1752
1777
|
continueLiveStreamDuringAds
|
|
@@ -1770,11 +1795,13 @@ var StormcloudVideoPlayer = class {
|
|
|
1770
1795
|
}
|
|
1771
1796
|
this.initializeTracking();
|
|
1772
1797
|
if (this.shouldUseNativeHls()) {
|
|
1798
|
+
this.nativeHlsMode = true;
|
|
1799
|
+
this.videoSrcProtection = this.config.src;
|
|
1773
1800
|
this.video.src = this.config.src;
|
|
1774
1801
|
this.isLiveStream = (_a = this.config.lowLatencyMode) != null ? _a : false;
|
|
1775
1802
|
if (this.config.debugAdTiming) {
|
|
1776
1803
|
console.log(
|
|
1777
|
-
"[StormcloudVideoPlayer]
|
|
1804
|
+
"[StormcloudVideoPlayer] Using native HLS playback - VOD mode:",
|
|
1778
1805
|
{
|
|
1779
1806
|
isLive: this.isLiveStream,
|
|
1780
1807
|
allowNativeHls: this.config.allowNativeHls,
|
|
@@ -1922,7 +1949,9 @@ var StormcloudVideoPlayer = class {
|
|
|
1922
1949
|
this.ima.initialize();
|
|
1923
1950
|
this.ima.on("all_ads_completed", () => {
|
|
1924
1951
|
if (this.config.debugAdTiming) {
|
|
1925
|
-
console.log(
|
|
1952
|
+
console.log(
|
|
1953
|
+
"[StormcloudVideoPlayer] IMA all_ads_completed event received"
|
|
1954
|
+
);
|
|
1926
1955
|
}
|
|
1927
1956
|
});
|
|
1928
1957
|
this.ima.on("ad_error", () => {
|
|
@@ -1987,13 +2016,31 @@ var StormcloudVideoPlayer = class {
|
|
|
1987
2016
|
this.video.addEventListener("timeupdate", () => {
|
|
1988
2017
|
this.onTimeUpdate(this.video.currentTime);
|
|
1989
2018
|
});
|
|
2019
|
+
this.video.addEventListener("emptied", () => {
|
|
2020
|
+
if (this.nativeHlsMode && this.videoSrcProtection && !this.ima.isAdPlaying()) {
|
|
2021
|
+
if (this.config.debugAdTiming) {
|
|
2022
|
+
console.log(
|
|
2023
|
+
"[StormcloudVideoPlayer] Video src was cleared, restoring:",
|
|
2024
|
+
this.videoSrcProtection
|
|
2025
|
+
);
|
|
2026
|
+
}
|
|
2027
|
+
const currentTime = this.video.currentTime;
|
|
2028
|
+
const wasPaused = this.video.paused;
|
|
2029
|
+
this.video.src = this.videoSrcProtection;
|
|
2030
|
+
this.video.currentTime = currentTime;
|
|
2031
|
+
if (!wasPaused) {
|
|
2032
|
+
this.video.play().catch(() => {
|
|
2033
|
+
});
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
});
|
|
1990
2037
|
}
|
|
1991
2038
|
shouldUseNativeHls() {
|
|
1992
2039
|
const streamType = this.getStreamType();
|
|
1993
2040
|
if (streamType === "other") {
|
|
1994
2041
|
return true;
|
|
1995
2042
|
}
|
|
1996
|
-
const canNative = this.video.canPlayType("application/vnd.apple.
|
|
2043
|
+
const canNative = this.video.canPlayType("application/vnd.apple.mpegurl");
|
|
1997
2044
|
return !!(this.config.allowNativeHls && canNative);
|
|
1998
2045
|
}
|
|
1999
2046
|
onId3Tag(tag) {
|
|
@@ -2420,10 +2467,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2420
2467
|
var _a, _b, _c;
|
|
2421
2468
|
const vastMode = this.config.vastMode || "default";
|
|
2422
2469
|
if (this.config.debugAdTiming) {
|
|
2423
|
-
console.log(
|
|
2424
|
-
"[StormcloudVideoPlayer] VAST mode:",
|
|
2425
|
-
vastMode
|
|
2426
|
-
);
|
|
2470
|
+
console.log("[StormcloudVideoPlayer] VAST mode:", vastMode);
|
|
2427
2471
|
}
|
|
2428
2472
|
if (vastMode === "adstorm") {
|
|
2429
2473
|
if (!this.config.licenseKey) {
|
|
@@ -2438,7 +2482,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2438
2482
|
this.apiVastTagUrl = vastEndpoint;
|
|
2439
2483
|
if (this.config.debugAdTiming) {
|
|
2440
2484
|
console.log(
|
|
2441
|
-
"[StormcloudVideoPlayer] Using AdStorm VAST endpoint:",
|
|
2485
|
+
"[StormcloudVideoPlayer] Using AdStorm VAST endpoint (adstorm mode):",
|
|
2442
2486
|
vastEndpoint
|
|
2443
2487
|
);
|
|
2444
2488
|
}
|
|
@@ -2541,10 +2585,7 @@ var StormcloudVideoPlayer = class {
|
|
|
2541
2585
|
this.currentAdIndex = 0;
|
|
2542
2586
|
this.totalAdsInBreak = 1;
|
|
2543
2587
|
if (this.config.debugAdTiming) {
|
|
2544
|
-
console.log(
|
|
2545
|
-
"[StormcloudVideoPlayer] Using VAST endpoint:",
|
|
2546
|
-
vastTagUrl
|
|
2547
|
-
);
|
|
2588
|
+
console.log("[StormcloudVideoPlayer] Using VAST endpoint:", vastTagUrl);
|
|
2548
2589
|
}
|
|
2549
2590
|
} else if (tags && tags.length > 0) {
|
|
2550
2591
|
vastTagUrl = tags[0];
|
|
@@ -2694,12 +2735,26 @@ var StormcloudVideoPlayer = class {
|
|
|
2694
2735
|
this.startAdFailsafeTimer();
|
|
2695
2736
|
try {
|
|
2696
2737
|
await this.ima.requestAds(vastTagUrl);
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2738
|
+
try {
|
|
2739
|
+
if (this.config.debugAdTiming) {
|
|
2740
|
+
console.log(
|
|
2741
|
+
"[StormcloudVideoPlayer] Ad request completed, attempting playback"
|
|
2742
|
+
);
|
|
2743
|
+
}
|
|
2744
|
+
await this.ima.play();
|
|
2745
|
+
if (this.config.debugAdTiming) {
|
|
2746
|
+
console.log(
|
|
2747
|
+
"[StormcloudVideoPlayer] Ad playback started successfully"
|
|
2748
|
+
);
|
|
2749
|
+
}
|
|
2750
|
+
} catch (playError) {
|
|
2751
|
+
if (this.config.debugAdTiming) {
|
|
2752
|
+
console.log(
|
|
2753
|
+
"[StormcloudVideoPlayer] No ads available, skipping playback"
|
|
2754
|
+
);
|
|
2755
|
+
}
|
|
2756
|
+
this.handleAdFailure();
|
|
2757
|
+
return;
|
|
2703
2758
|
}
|
|
2704
2759
|
} catch (error) {
|
|
2705
2760
|
if (this.config.debugAdTiming) {
|
|
@@ -2752,7 +2807,9 @@ var StormcloudVideoPlayer = class {
|
|
|
2752
2807
|
});
|
|
2753
2808
|
} else {
|
|
2754
2809
|
if (this.config.debugAdTiming) {
|
|
2755
|
-
console.log(
|
|
2810
|
+
console.log(
|
|
2811
|
+
"[StormcloudVideoPlayer] Video is already playing, no resume needed"
|
|
2812
|
+
);
|
|
2756
2813
|
}
|
|
2757
2814
|
}
|
|
2758
2815
|
}
|
|
@@ -2771,7 +2828,11 @@ var StormcloudVideoPlayer = class {
|
|
|
2771
2828
|
if (this.config.debugAdTiming) {
|
|
2772
2829
|
console.warn(
|
|
2773
2830
|
"[StormcloudVideoPlayer] Failsafe timer triggered - forcing video resume",
|
|
2774
|
-
{
|
|
2831
|
+
{
|
|
2832
|
+
paused: this.video.paused,
|
|
2833
|
+
showAds: this.showAds,
|
|
2834
|
+
adPlaying: this.ima.isAdPlaying()
|
|
2835
|
+
}
|
|
2775
2836
|
);
|
|
2776
2837
|
}
|
|
2777
2838
|
this.handleAdFailure();
|