stormcloud-video-player 0.8.34 → 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 +105 -16
- 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 +105 -16
- 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.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 +105 -16
- 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 +105 -16
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +105 -16
- 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/{types-CSHvCbhZ.d.cts → types-cTqIKw_D.d.cts} +1 -0
- package/lib/ui/StormcloudVideoPlayer.cjs +105 -16
- 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/tracking.d.cts +1 -1
- package/package.json +1 -1
|
@@ -419,6 +419,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
419
419
|
var preloadingAds = /* @__PURE__ */ new Map();
|
|
420
420
|
var destroyed = false;
|
|
421
421
|
var pendingTimeouts = [];
|
|
422
|
+
var STALL_TIMEOUT_MS = 4e3;
|
|
423
|
+
var STALL_CHECK_INTERVAL_MS = 1e3;
|
|
424
|
+
var stallWatchdogId;
|
|
425
|
+
var lastAdProgressTime = 0;
|
|
426
|
+
var lastAdProgressPosition = 0;
|
|
422
427
|
var trackingFired = {
|
|
423
428
|
impression: false,
|
|
424
429
|
start: false,
|
|
@@ -1051,6 +1056,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1051
1056
|
if (!adVideoElement || !currentAd) return;
|
|
1052
1057
|
adVideoElement.addEventListener("timeupdate", function() {
|
|
1053
1058
|
if (!currentAd || !adVideoElement) return;
|
|
1059
|
+
noteAdProgress();
|
|
1054
1060
|
var progress = adVideoElement.currentTime / currentAd.duration;
|
|
1055
1061
|
if (progress >= 0.25 && !trackingFired.firstQuartile) {
|
|
1056
1062
|
trackingFired.firstQuartile = true;
|
|
@@ -1066,6 +1072,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1066
1072
|
}
|
|
1067
1073
|
});
|
|
1068
1074
|
adVideoElement.addEventListener("playing", function() {
|
|
1075
|
+
startStallWatchdog();
|
|
1069
1076
|
if (!currentAd || trackingFired.start) return;
|
|
1070
1077
|
trackingFired.start = true;
|
|
1071
1078
|
fireTrackingPixels(currentAd.trackingUrls.start);
|
|
@@ -1206,8 +1213,52 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1206
1213
|
return false;
|
|
1207
1214
|
}
|
|
1208
1215
|
}
|
|
1216
|
+
function clearStallWatchdog() {
|
|
1217
|
+
if (stallWatchdogId != null) {
|
|
1218
|
+
clearInterval(stallWatchdogId);
|
|
1219
|
+
stallWatchdogId = void 0;
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1222
|
+
function noteAdProgress() {
|
|
1223
|
+
lastAdProgressTime = Date.now();
|
|
1224
|
+
if (adVideoElement) {
|
|
1225
|
+
lastAdProgressPosition = adVideoElement.currentTime;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
function handleAdStall() {
|
|
1229
|
+
console.warn("[HlsAdPlayer] Ad playback stalled (no progress) - recovering to avoid a blank frame");
|
|
1230
|
+
clearStallWatchdog();
|
|
1231
|
+
if (currentAd) {
|
|
1232
|
+
fireTrackingPixels(currentAd.trackingUrls.error);
|
|
1233
|
+
}
|
|
1234
|
+
if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
handleAdError();
|
|
1238
|
+
}
|
|
1239
|
+
function startStallWatchdog() {
|
|
1240
|
+
clearStallWatchdog();
|
|
1241
|
+
noteAdProgress();
|
|
1242
|
+
stallWatchdogId = window.setInterval(function() {
|
|
1243
|
+
if (!adPlaying || !adVideoElement) {
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {
|
|
1247
|
+
noteAdProgress();
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1250
|
+
if (adVideoElement.paused) {
|
|
1251
|
+
noteAdProgress();
|
|
1252
|
+
return;
|
|
1253
|
+
}
|
|
1254
|
+
if (Date.now() - lastAdProgressTime >= STALL_TIMEOUT_MS) {
|
|
1255
|
+
handleAdStall();
|
|
1256
|
+
}
|
|
1257
|
+
}, STALL_CHECK_INTERVAL_MS);
|
|
1258
|
+
}
|
|
1209
1259
|
function handleAdComplete() {
|
|
1210
1260
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
1261
|
+
clearStallWatchdog();
|
|
1211
1262
|
adPlaying = false;
|
|
1212
1263
|
setAdPlayingFlag(false);
|
|
1213
1264
|
contentVideo.muted = true;
|
|
@@ -1215,6 +1266,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1215
1266
|
adContainerEl.style.display = "none";
|
|
1216
1267
|
adContainerEl.style.pointerEvents = "none";
|
|
1217
1268
|
}
|
|
1269
|
+
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1270
|
+
contentVideo.style.visibility = "visible";
|
|
1271
|
+
contentVideo.style.opacity = "1";
|
|
1272
|
+
}
|
|
1218
1273
|
if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
|
|
1219
1274
|
if (contentVideo.paused) {
|
|
1220
1275
|
console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback");
|
|
@@ -1227,6 +1282,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1227
1282
|
}
|
|
1228
1283
|
function handleAdError() {
|
|
1229
1284
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
1285
|
+
clearStallWatchdog();
|
|
1230
1286
|
adPlaying = false;
|
|
1231
1287
|
setAdPlayingFlag(false);
|
|
1232
1288
|
contentVideo.muted = true;
|
|
@@ -1234,6 +1290,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1234
1290
|
adContainerEl.style.display = "none";
|
|
1235
1291
|
adContainerEl.style.pointerEvents = "none";
|
|
1236
1292
|
}
|
|
1293
|
+
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1294
|
+
contentVideo.style.visibility = "visible";
|
|
1295
|
+
contentVideo.style.opacity = "1";
|
|
1296
|
+
}
|
|
1237
1297
|
emit("ad_error");
|
|
1238
1298
|
}
|
|
1239
1299
|
return {
|
|
@@ -1431,6 +1491,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1431
1491
|
var previousMutedState;
|
|
1432
1492
|
return _ts_generator(this, function(_state) {
|
|
1433
1493
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
1494
|
+
clearStallWatchdog();
|
|
1434
1495
|
adPlaying = false;
|
|
1435
1496
|
setAdPlayingFlag(false);
|
|
1436
1497
|
previousMutedState = contentVideo.muted;
|
|
@@ -1469,6 +1530,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1469
1530
|
destroy: function destroy() {
|
|
1470
1531
|
console.log("[HlsAdPlayer] Destroying");
|
|
1471
1532
|
destroyed = true;
|
|
1533
|
+
clearStallWatchdog();
|
|
1472
1534
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1473
1535
|
try {
|
|
1474
1536
|
for(var _iterator = pendingTimeouts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
@@ -3860,6 +3922,7 @@ function getBrowserConfigOverrides() {
|
|
|
3860
3922
|
var overrides = {};
|
|
3861
3923
|
if (browser.isSmartTV) {
|
|
3862
3924
|
overrides.allowNativeHls = true;
|
|
3925
|
+
overrides.pauseContentDuringAds = true;
|
|
3863
3926
|
}
|
|
3864
3927
|
return overrides;
|
|
3865
3928
|
}
|
|
@@ -6742,12 +6805,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
6742
6805
|
// ───────────────────────────────────────────────────────────────
|
|
6743
6806
|
// IMA event listeners
|
|
6744
6807
|
// ───────────────────────────────────────────────────────────────
|
|
6745
|
-
|
|
6746
|
-
* Produces the next pod ad-request URL for the current break. Every request
|
|
6747
|
-
* (initial and continuous-fetch top-up) carries pod macros (pmad/pmnd/pmxd,
|
|
6748
|
-
* no ppos); pmxd tracks the remaining break time so top-up pods only ask for
|
|
6749
|
-
* what still fits.
|
|
6750
|
-
*/ key: "nextAdRequestUrl",
|
|
6808
|
+
key: "nextAdRequestUrl",
|
|
6751
6809
|
value: function nextAdRequestUrl(baseVastUrl) {
|
|
6752
6810
|
var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
|
|
6753
6811
|
var breakDurationMs = remaining > 0 ? remaining : void 0;
|
|
@@ -7876,7 +7934,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7876
7934
|
if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {
|
|
7877
7935
|
this.host.video.volume = restoredVolume;
|
|
7878
7936
|
}
|
|
7879
|
-
|
|
7937
|
+
this.host.video.style.visibility = "visible";
|
|
7938
|
+
this.host.video.style.opacity = "1";
|
|
7939
|
+
if (this.host.isLiveStream()) {
|
|
7880
7940
|
var liveSyncPos = this.host.getLiveSyncPosition();
|
|
7881
7941
|
if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
|
|
7882
7942
|
if (this.debug) {
|
|
@@ -7884,16 +7944,39 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7884
7944
|
}
|
|
7885
7945
|
this.host.video.currentTime = liveSyncPos;
|
|
7886
7946
|
}
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7947
|
+
}
|
|
7948
|
+
this.resumeContentPlayback();
|
|
7949
|
+
}
|
|
7950
|
+
},
|
|
7951
|
+
{
|
|
7952
|
+
key: "resumeContentPlayback",
|
|
7953
|
+
value: function resumeContentPlayback() {
|
|
7954
|
+
var _this = this;
|
|
7955
|
+
var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
|
|
7956
|
+
var maxAttempts = 3;
|
|
7957
|
+
if (!this.host.video.paused) {
|
|
7958
|
+
if (this.debug && attempt === 0) {
|
|
7959
|
+
console.log("[StormcloudVideoPlayer] Content video already playing after ads");
|
|
7893
7960
|
}
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7961
|
+
return;
|
|
7962
|
+
}
|
|
7963
|
+
if (this.debug) {
|
|
7964
|
+
console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
|
|
7965
|
+
}
|
|
7966
|
+
var playResult = this.host.video.play();
|
|
7967
|
+
if (playResult && typeof playResult.catch === "function") {
|
|
7968
|
+
playResult.catch(function(error) {
|
|
7969
|
+
if (attempt + 1 >= maxAttempts) {
|
|
7970
|
+
if (_this.debug) {
|
|
7971
|
+
console.warn("[StormcloudVideoPlayer] Failed to resume content playback after ads:", error);
|
|
7972
|
+
}
|
|
7973
|
+
return;
|
|
7974
|
+
}
|
|
7975
|
+
var backoffMs = 250 * (attempt + 1);
|
|
7976
|
+
window.setTimeout(function() {
|
|
7977
|
+
_this.resumeContentPlayback(attempt + 1);
|
|
7978
|
+
}, backoffMs);
|
|
7979
|
+
});
|
|
7897
7980
|
}
|
|
7898
7981
|
}
|
|
7899
7982
|
},
|
|
@@ -8007,6 +8090,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8007
8090
|
shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
|
|
8008
8091
|
return _this.shouldContinueLiveStreamDuringAds();
|
|
8009
8092
|
},
|
|
8093
|
+
isLiveStream: function isLiveStream() {
|
|
8094
|
+
return _this.hlsEngine.isLiveStream;
|
|
8095
|
+
},
|
|
8010
8096
|
getLiveSyncPosition: function getLiveSyncPosition() {
|
|
8011
8097
|
return _this.hlsEngine.getLiveSyncPosition();
|
|
8012
8098
|
},
|
|
@@ -8229,6 +8315,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8229
8315
|
{
|
|
8230
8316
|
key: "shouldContinueLiveStreamDuringAds",
|
|
8231
8317
|
value: function shouldContinueLiveStreamDuringAds() {
|
|
8318
|
+
if (this.config.pauseContentDuringAds) {
|
|
8319
|
+
return false;
|
|
8320
|
+
}
|
|
8232
8321
|
if (this.hlsEngine.isLiveStream) {
|
|
8233
8322
|
return true;
|
|
8234
8323
|
}
|