stormcloud-video-player 0.8.33 → 0.8.35
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 +143 -19
- 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 +143 -19
- package/lib/index.js.map +1 -1
- package/lib/player/AdBreakOrchestrator.cjs +36 -16
- package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
- package/lib/player/AdBreakOrchestrator.d.cts +3 -7
- package/lib/player/AdConfigManager.cjs +36 -1
- package/lib/player/AdConfigManager.cjs.map +1 -1
- package/lib/player/AdConfigManager.d.cts +1 -1
- package/lib/player/AdTimingService.d.cts +1 -1
- package/lib/player/HlsEngine.d.cts +1 -1
- package/lib/player/PlayerControls.d.cts +1 -1
- package/lib/player/Scte35CueManager.d.cts +1 -1
- package/lib/player/Scte35Parser.d.cts +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +143 -19
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/player/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/player/playerTypes.d.cts +1 -1
- package/lib/players/HlsPlayer.cjs +143 -19
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +143 -19
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +62 -0
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +1 -1
- package/lib/sdk/pal.cjs +38 -2
- package/lib/sdk/pal.cjs.map +1 -1
- package/lib/{types-CSHvCbhZ.d.cts → types-cTqIKw_D.d.cts} +1 -0
- package/lib/ui/StormcloudVideoPlayer.cjs +143 -19
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/utils/browserCompat.cjs +1 -0
- package/lib/utils/browserCompat.cjs.map +1 -1
- package/lib/utils/browserCompat.d.cts +1 -0
- package/lib/utils/devUrl.cjs +102 -0
- package/lib/utils/devUrl.cjs.map +1 -0
- package/lib/utils/devUrl.d.cts +4 -0
- package/lib/utils/tracking.d.cts +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Component } from 'react';
|
|
2
|
-
import { a as StormcloudVideoPlayerConfig } from '../types-
|
|
2
|
+
import { a as StormcloudVideoPlayerConfig } from '../types-cTqIKw_D.cjs';
|
|
3
3
|
|
|
4
4
|
interface HlsPlayerProps extends StormcloudVideoPlayerConfig {
|
|
5
5
|
onMount?: (player: any) => void;
|
package/lib/players/index.cjs
CHANGED
|
@@ -455,6 +455,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
455
455
|
var preloadingAds = /* @__PURE__ */ new Map();
|
|
456
456
|
var destroyed = false;
|
|
457
457
|
var pendingTimeouts = [];
|
|
458
|
+
var STALL_TIMEOUT_MS = 4e3;
|
|
459
|
+
var STALL_CHECK_INTERVAL_MS = 1e3;
|
|
460
|
+
var stallWatchdogId;
|
|
461
|
+
var lastAdProgressTime = 0;
|
|
462
|
+
var lastAdProgressPosition = 0;
|
|
458
463
|
var trackingFired = {
|
|
459
464
|
impression: false,
|
|
460
465
|
start: false,
|
|
@@ -1087,6 +1092,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1087
1092
|
if (!adVideoElement || !currentAd) return;
|
|
1088
1093
|
adVideoElement.addEventListener("timeupdate", function() {
|
|
1089
1094
|
if (!currentAd || !adVideoElement) return;
|
|
1095
|
+
noteAdProgress();
|
|
1090
1096
|
var progress = adVideoElement.currentTime / currentAd.duration;
|
|
1091
1097
|
if (progress >= 0.25 && !trackingFired.firstQuartile) {
|
|
1092
1098
|
trackingFired.firstQuartile = true;
|
|
@@ -1102,6 +1108,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1102
1108
|
}
|
|
1103
1109
|
});
|
|
1104
1110
|
adVideoElement.addEventListener("playing", function() {
|
|
1111
|
+
startStallWatchdog();
|
|
1105
1112
|
if (!currentAd || trackingFired.start) return;
|
|
1106
1113
|
trackingFired.start = true;
|
|
1107
1114
|
fireTrackingPixels(currentAd.trackingUrls.start);
|
|
@@ -1242,8 +1249,52 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1242
1249
|
return false;
|
|
1243
1250
|
}
|
|
1244
1251
|
}
|
|
1252
|
+
function clearStallWatchdog() {
|
|
1253
|
+
if (stallWatchdogId != null) {
|
|
1254
|
+
clearInterval(stallWatchdogId);
|
|
1255
|
+
stallWatchdogId = void 0;
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
function noteAdProgress() {
|
|
1259
|
+
lastAdProgressTime = Date.now();
|
|
1260
|
+
if (adVideoElement) {
|
|
1261
|
+
lastAdProgressPosition = adVideoElement.currentTime;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
function handleAdStall() {
|
|
1265
|
+
console.warn("[HlsAdPlayer] Ad playback stalled (no progress) - recovering to avoid a blank frame");
|
|
1266
|
+
clearStallWatchdog();
|
|
1267
|
+
if (currentAd) {
|
|
1268
|
+
fireTrackingPixels(currentAd.trackingUrls.error);
|
|
1269
|
+
}
|
|
1270
|
+
if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
|
|
1271
|
+
return;
|
|
1272
|
+
}
|
|
1273
|
+
handleAdError();
|
|
1274
|
+
}
|
|
1275
|
+
function startStallWatchdog() {
|
|
1276
|
+
clearStallWatchdog();
|
|
1277
|
+
noteAdProgress();
|
|
1278
|
+
stallWatchdogId = window.setInterval(function() {
|
|
1279
|
+
if (!adPlaying || !adVideoElement) {
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {
|
|
1283
|
+
noteAdProgress();
|
|
1284
|
+
return;
|
|
1285
|
+
}
|
|
1286
|
+
if (adVideoElement.paused) {
|
|
1287
|
+
noteAdProgress();
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
if (Date.now() - lastAdProgressTime >= STALL_TIMEOUT_MS) {
|
|
1291
|
+
handleAdStall();
|
|
1292
|
+
}
|
|
1293
|
+
}, STALL_CHECK_INTERVAL_MS);
|
|
1294
|
+
}
|
|
1245
1295
|
function handleAdComplete() {
|
|
1246
1296
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
1297
|
+
clearStallWatchdog();
|
|
1247
1298
|
adPlaying = false;
|
|
1248
1299
|
setAdPlayingFlag(false);
|
|
1249
1300
|
contentVideo.muted = true;
|
|
@@ -1251,6 +1302,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1251
1302
|
adContainerEl.style.display = "none";
|
|
1252
1303
|
adContainerEl.style.pointerEvents = "none";
|
|
1253
1304
|
}
|
|
1305
|
+
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1306
|
+
contentVideo.style.visibility = "visible";
|
|
1307
|
+
contentVideo.style.opacity = "1";
|
|
1308
|
+
}
|
|
1254
1309
|
if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
|
|
1255
1310
|
if (contentVideo.paused) {
|
|
1256
1311
|
console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback");
|
|
@@ -1263,6 +1318,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1263
1318
|
}
|
|
1264
1319
|
function handleAdError() {
|
|
1265
1320
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
1321
|
+
clearStallWatchdog();
|
|
1266
1322
|
adPlaying = false;
|
|
1267
1323
|
setAdPlayingFlag(false);
|
|
1268
1324
|
contentVideo.muted = true;
|
|
@@ -1270,6 +1326,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1270
1326
|
adContainerEl.style.display = "none";
|
|
1271
1327
|
adContainerEl.style.pointerEvents = "none";
|
|
1272
1328
|
}
|
|
1329
|
+
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1330
|
+
contentVideo.style.visibility = "visible";
|
|
1331
|
+
contentVideo.style.opacity = "1";
|
|
1332
|
+
}
|
|
1273
1333
|
emit("ad_error");
|
|
1274
1334
|
}
|
|
1275
1335
|
return {
|
|
@@ -1467,6 +1527,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1467
1527
|
var previousMutedState;
|
|
1468
1528
|
return _ts_generator(this, function(_state) {
|
|
1469
1529
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
1530
|
+
clearStallWatchdog();
|
|
1470
1531
|
adPlaying = false;
|
|
1471
1532
|
setAdPlayingFlag(false);
|
|
1472
1533
|
previousMutedState = contentVideo.muted;
|
|
@@ -1505,6 +1566,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1505
1566
|
destroy: function destroy() {
|
|
1506
1567
|
console.log("[HlsAdPlayer] Destroying");
|
|
1507
1568
|
destroyed = true;
|
|
1569
|
+
clearStallWatchdog();
|
|
1508
1570
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1509
1571
|
try {
|
|
1510
1572
|
for(var _iterator = pendingTimeouts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
@@ -1649,6 +1711,41 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1649
1711
|
}
|
|
1650
1712
|
};
|
|
1651
1713
|
}
|
|
1714
|
+
// src/utils/devUrl.ts
|
|
1715
|
+
var PRIVATE_HOST_PATTERNS = [
|
|
1716
|
+
/^localhost$/i,
|
|
1717
|
+
/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,
|
|
1718
|
+
/^0\.0\.0\.0$/,
|
|
1719
|
+
/^::1$/,
|
|
1720
|
+
/^10\.\d{1,3}\.\d{1,3}\.\d{1,3}$/,
|
|
1721
|
+
/^192\.168\.\d{1,3}\.\d{1,3}$/,
|
|
1722
|
+
/^172\.(1[6-9]|2\d|3[0-1])\.\d{1,3}\.\d{1,3}$/
|
|
1723
|
+
];
|
|
1724
|
+
function isLocalDevHost(hostname) {
|
|
1725
|
+
var host = hostname.replace(/^\[/, "").replace(/\]$/, "").toLowerCase();
|
|
1726
|
+
if (!host) return false;
|
|
1727
|
+
if (host.endsWith(".local") || host.endsWith(".localhost")) return true;
|
|
1728
|
+
return PRIVATE_HOST_PATTERNS.some(function(pattern) {
|
|
1729
|
+
return pattern.test(host);
|
|
1730
|
+
});
|
|
1731
|
+
}
|
|
1732
|
+
function toDevSafeUrl(rawUrl) {
|
|
1733
|
+
if (!rawUrl) return rawUrl !== null && rawUrl !== void 0 ? rawUrl : "";
|
|
1734
|
+
var url;
|
|
1735
|
+
try {
|
|
1736
|
+
url = new URL(rawUrl);
|
|
1737
|
+
} catch (unused) {
|
|
1738
|
+
return rawUrl;
|
|
1739
|
+
}
|
|
1740
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
1741
|
+
return rawUrl;
|
|
1742
|
+
}
|
|
1743
|
+
if (!isLocalDevHost(url.hostname)) {
|
|
1744
|
+
return rawUrl;
|
|
1745
|
+
}
|
|
1746
|
+
var cleanPath = url.pathname.replace(/\/{2,}/g, "/") || "/index.html";
|
|
1747
|
+
return "file://".concat(cleanPath);
|
|
1748
|
+
}
|
|
1652
1749
|
// src/sdk/pal.ts
|
|
1653
1750
|
var PAL_SDK_URL = "https://imasdk.googleapis.com/pal/sdkloader/pal.js";
|
|
1654
1751
|
var _nonceLoader;
|
|
@@ -1735,12 +1832,12 @@ function createPalNonceManager() {
|
|
|
1735
1832
|
request.adWillPlayMuted = (_options_adWillPlayMuted = options.adWillPlayMuted) !== null && _options_adWillPlayMuted !== void 0 ? _options_adWillPlayMuted : false;
|
|
1736
1833
|
request.playerVolume = (_options_playerVolume = options.playerVolume) !== null && _options_playerVolume !== void 0 ? _options_playerVolume : request.adWillPlayMuted ? 0 : 1;
|
|
1737
1834
|
request.continuousPlayback = (_options_continuousPlayback = options.continuousPlayback) !== null && _options_continuousPlayback !== void 0 ? _options_continuousPlayback : true;
|
|
1738
|
-
request.descriptionUrl = options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : "");
|
|
1835
|
+
request.descriptionUrl = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
|
|
1739
1836
|
request.iconsSupported = true;
|
|
1740
1837
|
request.playerType = "StormcloudVideoPlayer";
|
|
1741
1838
|
request.playerVersion = "1.0";
|
|
1742
1839
|
request.supportedApiFrameworks = "2,7,9";
|
|
1743
|
-
request.url = options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : "");
|
|
1840
|
+
request.url = toDevSafeUrl(options.descriptionUrl || (typeof window !== "undefined" ? window.location.href : ""));
|
|
1744
1841
|
request.videoWidth = options.videoWidth || 640;
|
|
1745
1842
|
request.videoHeight = options.videoHeight || 480;
|
|
1746
1843
|
if (options.ppid) request.ppid = options.ppid;
|
|
@@ -3861,6 +3958,7 @@ function getBrowserConfigOverrides() {
|
|
|
3861
3958
|
var overrides = {};
|
|
3862
3959
|
if (browser.isSmartTV) {
|
|
3863
3960
|
overrides.allowNativeHls = true;
|
|
3961
|
+
overrides.pauseContentDuringAds = true;
|
|
3864
3962
|
}
|
|
3865
3963
|
return overrides;
|
|
3866
3964
|
}
|
|
@@ -5359,7 +5457,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
5359
5457
|
podMaxDurationMs: podParams.maxDurationMs,
|
|
5360
5458
|
isCtv: envSignals.isCtv,
|
|
5361
5459
|
contentUrl: envSignals.contentUrl,
|
|
5362
|
-
pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? window.location.href : void 0,
|
|
5460
|
+
pageUrl: !envSignals.isCtv && typeof window !== "undefined" ? toDevSafeUrl(window.location.href) : void 0,
|
|
5363
5461
|
adWillPlayMuted: adWillPlayMuted,
|
|
5364
5462
|
adWillAutoPlay: !!this.config.autoplay,
|
|
5365
5463
|
appId: envSignals.appId,
|
|
@@ -6743,12 +6841,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
6743
6841
|
// ───────────────────────────────────────────────────────────────
|
|
6744
6842
|
// IMA event listeners
|
|
6745
6843
|
// ───────────────────────────────────────────────────────────────
|
|
6746
|
-
|
|
6747
|
-
* Produces the next pod ad-request URL for the current break. Every request
|
|
6748
|
-
* (initial and continuous-fetch top-up) carries pod macros (pmad/pmnd/pmxd,
|
|
6749
|
-
* no ppos); pmxd tracks the remaining break time so top-up pods only ask for
|
|
6750
|
-
* what still fits.
|
|
6751
|
-
*/ key: "nextAdRequestUrl",
|
|
6844
|
+
key: "nextAdRequestUrl",
|
|
6752
6845
|
value: function nextAdRequestUrl(baseVastUrl) {
|
|
6753
6846
|
var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
|
|
6754
6847
|
var breakDurationMs = remaining > 0 ? remaining : void 0;
|
|
@@ -7877,7 +7970,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7877
7970
|
if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {
|
|
7878
7971
|
this.host.video.volume = restoredVolume;
|
|
7879
7972
|
}
|
|
7880
|
-
|
|
7973
|
+
this.host.video.style.visibility = "visible";
|
|
7974
|
+
this.host.video.style.opacity = "1";
|
|
7975
|
+
if (this.host.isLiveStream()) {
|
|
7881
7976
|
var liveSyncPos = this.host.getLiveSyncPosition();
|
|
7882
7977
|
if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
|
|
7883
7978
|
if (this.debug) {
|
|
@@ -7885,16 +7980,39 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7885
7980
|
}
|
|
7886
7981
|
this.host.video.currentTime = liveSyncPos;
|
|
7887
7982
|
}
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7983
|
+
}
|
|
7984
|
+
this.resumeContentPlayback();
|
|
7985
|
+
}
|
|
7986
|
+
},
|
|
7987
|
+
{
|
|
7988
|
+
key: "resumeContentPlayback",
|
|
7989
|
+
value: function resumeContentPlayback() {
|
|
7990
|
+
var _this = this;
|
|
7991
|
+
var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
|
|
7992
|
+
var maxAttempts = 3;
|
|
7993
|
+
if (!this.host.video.paused) {
|
|
7994
|
+
if (this.debug && attempt === 0) {
|
|
7995
|
+
console.log("[StormcloudVideoPlayer] Content video already playing after ads");
|
|
7894
7996
|
}
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7997
|
+
return;
|
|
7998
|
+
}
|
|
7999
|
+
if (this.debug) {
|
|
8000
|
+
console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
|
|
8001
|
+
}
|
|
8002
|
+
var playResult = this.host.video.play();
|
|
8003
|
+
if (playResult && typeof playResult.catch === "function") {
|
|
8004
|
+
playResult.catch(function(error) {
|
|
8005
|
+
if (attempt + 1 >= maxAttempts) {
|
|
8006
|
+
if (_this.debug) {
|
|
8007
|
+
console.warn("[StormcloudVideoPlayer] Failed to resume content playback after ads:", error);
|
|
8008
|
+
}
|
|
8009
|
+
return;
|
|
8010
|
+
}
|
|
8011
|
+
var backoffMs = 250 * (attempt + 1);
|
|
8012
|
+
window.setTimeout(function() {
|
|
8013
|
+
_this.resumeContentPlayback(attempt + 1);
|
|
8014
|
+
}, backoffMs);
|
|
8015
|
+
});
|
|
7898
8016
|
}
|
|
7899
8017
|
}
|
|
7900
8018
|
},
|
|
@@ -8008,6 +8126,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8008
8126
|
shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
|
|
8009
8127
|
return _this.shouldContinueLiveStreamDuringAds();
|
|
8010
8128
|
},
|
|
8129
|
+
isLiveStream: function isLiveStream() {
|
|
8130
|
+
return _this.hlsEngine.isLiveStream;
|
|
8131
|
+
},
|
|
8011
8132
|
getLiveSyncPosition: function getLiveSyncPosition() {
|
|
8012
8133
|
return _this.hlsEngine.getLiveSyncPosition();
|
|
8013
8134
|
},
|
|
@@ -8230,6 +8351,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8230
8351
|
{
|
|
8231
8352
|
key: "shouldContinueLiveStreamDuringAds",
|
|
8232
8353
|
value: function shouldContinueLiveStreamDuringAds() {
|
|
8354
|
+
if (this.config.pauseContentDuringAds) {
|
|
8355
|
+
return false;
|
|
8356
|
+
}
|
|
8233
8357
|
if (this.hlsEngine.isLiveStream) {
|
|
8234
8358
|
return true;
|
|
8235
8359
|
}
|