stormcloud-video-player 0.8.34 → 0.8.36
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 +120 -16
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +21 -19
- package/lib/index.d.ts +21 -19
- package/lib/index.js +120 -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.cjs +18 -0
- package/lib/player/AdConfigManager.cjs.map +1 -1
- package/lib/player/AdConfigManager.d.cts +2 -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 +123 -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 +123 -16
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +123 -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 +123 -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){
|
|
@@ -1844,6 +1906,9 @@ var DEFAULT_MQTT_CONFIG = {
|
|
|
1844
1906
|
qos: 1
|
|
1845
1907
|
};
|
|
1846
1908
|
var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
|
|
1909
|
+
function applyMQTTConfig(overrides) {
|
|
1910
|
+
Object.assign(mqttConfig, overrides);
|
|
1911
|
+
}
|
|
1847
1912
|
function isMQTTEnabled() {
|
|
1848
1913
|
return mqttConfig.enabled;
|
|
1849
1914
|
}
|
|
@@ -3860,6 +3925,7 @@ function getBrowserConfigOverrides() {
|
|
|
3860
3925
|
var overrides = {};
|
|
3861
3926
|
if (browser.isSmartTV) {
|
|
3862
3927
|
overrides.allowNativeHls = true;
|
|
3928
|
+
overrides.pauseContentDuringAds = true;
|
|
3863
3929
|
}
|
|
3864
3930
|
return overrides;
|
|
3865
3931
|
}
|
|
@@ -5014,6 +5080,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
5014
5080
|
];
|
|
5015
5081
|
case 4:
|
|
5016
5082
|
data = _state.sent();
|
|
5083
|
+
this.applyMqttConfigFromResponse(data);
|
|
5017
5084
|
imaPayload = (_data_response = data.response) === null || _data_response === void 0 ? void 0 : (_data_response_ima = _data_response.ima) === null || _data_response_ima === void 0 ? void 0 : (_data_response_ima_publisherdeskima = _data_response_ima["publisherdesk.ima"]) === null || _data_response_ima_publisherdeskima === void 0 ? void 0 : _data_response_ima_publisherdeskima.payload;
|
|
5018
5085
|
if (imaPayload) {
|
|
5019
5086
|
decodedPayload = imaPayload;
|
|
@@ -5047,6 +5114,20 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
5047
5114
|
}).call(this);
|
|
5048
5115
|
}
|
|
5049
5116
|
},
|
|
5117
|
+
{
|
|
5118
|
+
key: "applyMqttConfigFromResponse",
|
|
5119
|
+
value: function applyMqttConfigFromResponse(data) {
|
|
5120
|
+
var _data_response;
|
|
5121
|
+
var mqttConfig2 = (_data_response = data.response) === null || _data_response === void 0 ? void 0 : _data_response.mqtt_config;
|
|
5122
|
+
if (!mqttConfig2 || (typeof mqttConfig2 === "undefined" ? "undefined" : _type_of(mqttConfig2)) !== "object") {
|
|
5123
|
+
return;
|
|
5124
|
+
}
|
|
5125
|
+
applyMQTTConfig(mqttConfig2);
|
|
5126
|
+
if (this.debug) {
|
|
5127
|
+
console.log("[StormcloudVideoPlayer] Applied MQTT config from /ads/web:", mqttConfig2);
|
|
5128
|
+
}
|
|
5129
|
+
}
|
|
5130
|
+
},
|
|
5050
5131
|
{
|
|
5051
5132
|
key: "fetchAndParseVmap",
|
|
5052
5133
|
value: function fetchAndParseVmap(vmapUrl) {
|
|
@@ -6742,12 +6823,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
6742
6823
|
// ───────────────────────────────────────────────────────────────
|
|
6743
6824
|
// IMA event listeners
|
|
6744
6825
|
// ───────────────────────────────────────────────────────────────
|
|
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",
|
|
6826
|
+
key: "nextAdRequestUrl",
|
|
6751
6827
|
value: function nextAdRequestUrl(baseVastUrl) {
|
|
6752
6828
|
var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
|
|
6753
6829
|
var breakDurationMs = remaining > 0 ? remaining : void 0;
|
|
@@ -7876,7 +7952,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7876
7952
|
if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {
|
|
7877
7953
|
this.host.video.volume = restoredVolume;
|
|
7878
7954
|
}
|
|
7879
|
-
|
|
7955
|
+
this.host.video.style.visibility = "visible";
|
|
7956
|
+
this.host.video.style.opacity = "1";
|
|
7957
|
+
if (this.host.isLiveStream()) {
|
|
7880
7958
|
var liveSyncPos = this.host.getLiveSyncPosition();
|
|
7881
7959
|
if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
|
|
7882
7960
|
if (this.debug) {
|
|
@@ -7884,16 +7962,39 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7884
7962
|
}
|
|
7885
7963
|
this.host.video.currentTime = liveSyncPos;
|
|
7886
7964
|
}
|
|
7887
|
-
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7965
|
+
}
|
|
7966
|
+
this.resumeContentPlayback();
|
|
7967
|
+
}
|
|
7968
|
+
},
|
|
7969
|
+
{
|
|
7970
|
+
key: "resumeContentPlayback",
|
|
7971
|
+
value: function resumeContentPlayback() {
|
|
7972
|
+
var _this = this;
|
|
7973
|
+
var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
|
|
7974
|
+
var maxAttempts = 3;
|
|
7975
|
+
if (!this.host.video.paused) {
|
|
7976
|
+
if (this.debug && attempt === 0) {
|
|
7977
|
+
console.log("[StormcloudVideoPlayer] Content video already playing after ads");
|
|
7893
7978
|
}
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7979
|
+
return;
|
|
7980
|
+
}
|
|
7981
|
+
if (this.debug) {
|
|
7982
|
+
console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
|
|
7983
|
+
}
|
|
7984
|
+
var playResult = this.host.video.play();
|
|
7985
|
+
if (playResult && typeof playResult.catch === "function") {
|
|
7986
|
+
playResult.catch(function(error) {
|
|
7987
|
+
if (attempt + 1 >= maxAttempts) {
|
|
7988
|
+
if (_this.debug) {
|
|
7989
|
+
console.warn("[StormcloudVideoPlayer] Failed to resume content playback after ads:", error);
|
|
7990
|
+
}
|
|
7991
|
+
return;
|
|
7992
|
+
}
|
|
7993
|
+
var backoffMs = 250 * (attempt + 1);
|
|
7994
|
+
window.setTimeout(function() {
|
|
7995
|
+
_this.resumeContentPlayback(attempt + 1);
|
|
7996
|
+
}, backoffMs);
|
|
7997
|
+
});
|
|
7897
7998
|
}
|
|
7898
7999
|
}
|
|
7899
8000
|
},
|
|
@@ -8007,6 +8108,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8007
8108
|
shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
|
|
8008
8109
|
return _this.shouldContinueLiveStreamDuringAds();
|
|
8009
8110
|
},
|
|
8111
|
+
isLiveStream: function isLiveStream() {
|
|
8112
|
+
return _this.hlsEngine.isLiveStream;
|
|
8113
|
+
},
|
|
8010
8114
|
getLiveSyncPosition: function getLiveSyncPosition() {
|
|
8011
8115
|
return _this.hlsEngine.getLiveSyncPosition();
|
|
8012
8116
|
},
|
|
@@ -8229,6 +8333,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8229
8333
|
{
|
|
8230
8334
|
key: "shouldContinueLiveStreamDuringAds",
|
|
8231
8335
|
value: function shouldContinueLiveStreamDuringAds() {
|
|
8336
|
+
if (this.config.pauseContentDuringAds) {
|
|
8337
|
+
return false;
|
|
8338
|
+
}
|
|
8232
8339
|
if (this.hlsEngine.isLiveStream) {
|
|
8233
8340
|
return true;
|
|
8234
8341
|
}
|