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
|
@@ -405,6 +405,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
405
405
|
var preloadingAds = /* @__PURE__ */ new Map();
|
|
406
406
|
var destroyed = false;
|
|
407
407
|
var pendingTimeouts = [];
|
|
408
|
+
var STALL_TIMEOUT_MS = 4e3;
|
|
409
|
+
var STALL_CHECK_INTERVAL_MS = 1e3;
|
|
410
|
+
var stallWatchdogId;
|
|
411
|
+
var lastAdProgressTime = 0;
|
|
412
|
+
var lastAdProgressPosition = 0;
|
|
408
413
|
var trackingFired = {
|
|
409
414
|
impression: false,
|
|
410
415
|
start: false,
|
|
@@ -1037,6 +1042,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1037
1042
|
if (!adVideoElement || !currentAd) return;
|
|
1038
1043
|
adVideoElement.addEventListener("timeupdate", function() {
|
|
1039
1044
|
if (!currentAd || !adVideoElement) return;
|
|
1045
|
+
noteAdProgress();
|
|
1040
1046
|
var progress = adVideoElement.currentTime / currentAd.duration;
|
|
1041
1047
|
if (progress >= 0.25 && !trackingFired.firstQuartile) {
|
|
1042
1048
|
trackingFired.firstQuartile = true;
|
|
@@ -1052,6 +1058,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1052
1058
|
}
|
|
1053
1059
|
});
|
|
1054
1060
|
adVideoElement.addEventListener("playing", function() {
|
|
1061
|
+
startStallWatchdog();
|
|
1055
1062
|
if (!currentAd || trackingFired.start) return;
|
|
1056
1063
|
trackingFired.start = true;
|
|
1057
1064
|
fireTrackingPixels(currentAd.trackingUrls.start);
|
|
@@ -1192,8 +1199,52 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1192
1199
|
return false;
|
|
1193
1200
|
}
|
|
1194
1201
|
}
|
|
1202
|
+
function clearStallWatchdog() {
|
|
1203
|
+
if (stallWatchdogId != null) {
|
|
1204
|
+
clearInterval(stallWatchdogId);
|
|
1205
|
+
stallWatchdogId = void 0;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
function noteAdProgress() {
|
|
1209
|
+
lastAdProgressTime = Date.now();
|
|
1210
|
+
if (adVideoElement) {
|
|
1211
|
+
lastAdProgressPosition = adVideoElement.currentTime;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
function handleAdStall() {
|
|
1215
|
+
console.warn("[HlsAdPlayer] Ad playback stalled (no progress) - recovering to avoid a blank frame");
|
|
1216
|
+
clearStallWatchdog();
|
|
1217
|
+
if (currentAd) {
|
|
1218
|
+
fireTrackingPixels(currentAd.trackingUrls.error);
|
|
1219
|
+
}
|
|
1220
|
+
if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
handleAdError();
|
|
1224
|
+
}
|
|
1225
|
+
function startStallWatchdog() {
|
|
1226
|
+
clearStallWatchdog();
|
|
1227
|
+
noteAdProgress();
|
|
1228
|
+
stallWatchdogId = window.setInterval(function() {
|
|
1229
|
+
if (!adPlaying || !adVideoElement) {
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {
|
|
1233
|
+
noteAdProgress();
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
if (adVideoElement.paused) {
|
|
1237
|
+
noteAdProgress();
|
|
1238
|
+
return;
|
|
1239
|
+
}
|
|
1240
|
+
if (Date.now() - lastAdProgressTime >= STALL_TIMEOUT_MS) {
|
|
1241
|
+
handleAdStall();
|
|
1242
|
+
}
|
|
1243
|
+
}, STALL_CHECK_INTERVAL_MS);
|
|
1244
|
+
}
|
|
1195
1245
|
function handleAdComplete() {
|
|
1196
1246
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
1247
|
+
clearStallWatchdog();
|
|
1197
1248
|
adPlaying = false;
|
|
1198
1249
|
setAdPlayingFlag(false);
|
|
1199
1250
|
contentVideo.muted = true;
|
|
@@ -1201,6 +1252,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1201
1252
|
adContainerEl.style.display = "none";
|
|
1202
1253
|
adContainerEl.style.pointerEvents = "none";
|
|
1203
1254
|
}
|
|
1255
|
+
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1256
|
+
contentVideo.style.visibility = "visible";
|
|
1257
|
+
contentVideo.style.opacity = "1";
|
|
1258
|
+
}
|
|
1204
1259
|
if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
|
|
1205
1260
|
if (contentVideo.paused) {
|
|
1206
1261
|
console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback");
|
|
@@ -1213,6 +1268,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1213
1268
|
}
|
|
1214
1269
|
function handleAdError() {
|
|
1215
1270
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
1271
|
+
clearStallWatchdog();
|
|
1216
1272
|
adPlaying = false;
|
|
1217
1273
|
setAdPlayingFlag(false);
|
|
1218
1274
|
contentVideo.muted = true;
|
|
@@ -1220,6 +1276,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1220
1276
|
adContainerEl.style.display = "none";
|
|
1221
1277
|
adContainerEl.style.pointerEvents = "none";
|
|
1222
1278
|
}
|
|
1279
|
+
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1280
|
+
contentVideo.style.visibility = "visible";
|
|
1281
|
+
contentVideo.style.opacity = "1";
|
|
1282
|
+
}
|
|
1223
1283
|
emit("ad_error");
|
|
1224
1284
|
}
|
|
1225
1285
|
return {
|
|
@@ -1417,6 +1477,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1417
1477
|
var previousMutedState;
|
|
1418
1478
|
return _ts_generator(this, function(_state) {
|
|
1419
1479
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
1480
|
+
clearStallWatchdog();
|
|
1420
1481
|
adPlaying = false;
|
|
1421
1482
|
setAdPlayingFlag(false);
|
|
1422
1483
|
previousMutedState = contentVideo.muted;
|
|
@@ -1455,6 +1516,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1455
1516
|
destroy: function destroy() {
|
|
1456
1517
|
console.log("[HlsAdPlayer] Destroying");
|
|
1457
1518
|
destroyed = true;
|
|
1519
|
+
clearStallWatchdog();
|
|
1458
1520
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1459
1521
|
try {
|
|
1460
1522
|
for(var _iterator = pendingTimeouts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
@@ -1830,6 +1892,9 @@ var DEFAULT_MQTT_CONFIG = {
|
|
|
1830
1892
|
qos: 1
|
|
1831
1893
|
};
|
|
1832
1894
|
var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
|
|
1895
|
+
function applyMQTTConfig(overrides) {
|
|
1896
|
+
Object.assign(mqttConfig, overrides);
|
|
1897
|
+
}
|
|
1833
1898
|
function isMQTTEnabled() {
|
|
1834
1899
|
return mqttConfig.enabled;
|
|
1835
1900
|
}
|
|
@@ -3846,6 +3911,7 @@ function getBrowserConfigOverrides() {
|
|
|
3846
3911
|
var overrides = {};
|
|
3847
3912
|
if (browser.isSmartTV) {
|
|
3848
3913
|
overrides.allowNativeHls = true;
|
|
3914
|
+
overrides.pauseContentDuringAds = true;
|
|
3849
3915
|
}
|
|
3850
3916
|
return overrides;
|
|
3851
3917
|
}
|
|
@@ -5000,6 +5066,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
5000
5066
|
];
|
|
5001
5067
|
case 4:
|
|
5002
5068
|
data = _state.sent();
|
|
5069
|
+
this.applyMqttConfigFromResponse(data);
|
|
5003
5070
|
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;
|
|
5004
5071
|
if (imaPayload) {
|
|
5005
5072
|
decodedPayload = imaPayload;
|
|
@@ -5033,6 +5100,20 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
5033
5100
|
}).call(this);
|
|
5034
5101
|
}
|
|
5035
5102
|
},
|
|
5103
|
+
{
|
|
5104
|
+
key: "applyMqttConfigFromResponse",
|
|
5105
|
+
value: function applyMqttConfigFromResponse(data) {
|
|
5106
|
+
var _data_response;
|
|
5107
|
+
var mqttConfig2 = (_data_response = data.response) === null || _data_response === void 0 ? void 0 : _data_response.mqtt_config;
|
|
5108
|
+
if (!mqttConfig2 || (typeof mqttConfig2 === "undefined" ? "undefined" : _type_of(mqttConfig2)) !== "object") {
|
|
5109
|
+
return;
|
|
5110
|
+
}
|
|
5111
|
+
applyMQTTConfig(mqttConfig2);
|
|
5112
|
+
if (this.debug) {
|
|
5113
|
+
console.log("[StormcloudVideoPlayer] Applied MQTT config from /ads/web:", mqttConfig2);
|
|
5114
|
+
}
|
|
5115
|
+
}
|
|
5116
|
+
},
|
|
5036
5117
|
{
|
|
5037
5118
|
key: "fetchAndParseVmap",
|
|
5038
5119
|
value: function fetchAndParseVmap(vmapUrl) {
|
|
@@ -6728,12 +6809,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
6728
6809
|
// ───────────────────────────────────────────────────────────────
|
|
6729
6810
|
// IMA event listeners
|
|
6730
6811
|
// ───────────────────────────────────────────────────────────────
|
|
6731
|
-
|
|
6732
|
-
* Produces the next pod ad-request URL for the current break. Every request
|
|
6733
|
-
* (initial and continuous-fetch top-up) carries pod macros (pmad/pmnd/pmxd,
|
|
6734
|
-
* no ppos); pmxd tracks the remaining break time so top-up pods only ask for
|
|
6735
|
-
* what still fits.
|
|
6736
|
-
*/ key: "nextAdRequestUrl",
|
|
6812
|
+
key: "nextAdRequestUrl",
|
|
6737
6813
|
value: function nextAdRequestUrl(baseVastUrl) {
|
|
6738
6814
|
var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
|
|
6739
6815
|
var breakDurationMs = remaining > 0 ? remaining : void 0;
|
|
@@ -7862,7 +7938,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7862
7938
|
if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {
|
|
7863
7939
|
this.host.video.volume = restoredVolume;
|
|
7864
7940
|
}
|
|
7865
|
-
|
|
7941
|
+
this.host.video.style.visibility = "visible";
|
|
7942
|
+
this.host.video.style.opacity = "1";
|
|
7943
|
+
if (this.host.isLiveStream()) {
|
|
7866
7944
|
var liveSyncPos = this.host.getLiveSyncPosition();
|
|
7867
7945
|
if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
|
|
7868
7946
|
if (this.debug) {
|
|
@@ -7870,16 +7948,39 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7870
7948
|
}
|
|
7871
7949
|
this.host.video.currentTime = liveSyncPos;
|
|
7872
7950
|
}
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
|
|
7878
|
-
|
|
7951
|
+
}
|
|
7952
|
+
this.resumeContentPlayback();
|
|
7953
|
+
}
|
|
7954
|
+
},
|
|
7955
|
+
{
|
|
7956
|
+
key: "resumeContentPlayback",
|
|
7957
|
+
value: function resumeContentPlayback() {
|
|
7958
|
+
var _this = this;
|
|
7959
|
+
var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
|
|
7960
|
+
var maxAttempts = 3;
|
|
7961
|
+
if (!this.host.video.paused) {
|
|
7962
|
+
if (this.debug && attempt === 0) {
|
|
7963
|
+
console.log("[StormcloudVideoPlayer] Content video already playing after ads");
|
|
7879
7964
|
}
|
|
7880
|
-
|
|
7881
|
-
|
|
7882
|
-
|
|
7965
|
+
return;
|
|
7966
|
+
}
|
|
7967
|
+
if (this.debug) {
|
|
7968
|
+
console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
|
|
7969
|
+
}
|
|
7970
|
+
var playResult = this.host.video.play();
|
|
7971
|
+
if (playResult && typeof playResult.catch === "function") {
|
|
7972
|
+
playResult.catch(function(error) {
|
|
7973
|
+
if (attempt + 1 >= maxAttempts) {
|
|
7974
|
+
if (_this.debug) {
|
|
7975
|
+
console.warn("[StormcloudVideoPlayer] Failed to resume content playback after ads:", error);
|
|
7976
|
+
}
|
|
7977
|
+
return;
|
|
7978
|
+
}
|
|
7979
|
+
var backoffMs = 250 * (attempt + 1);
|
|
7980
|
+
window.setTimeout(function() {
|
|
7981
|
+
_this.resumeContentPlayback(attempt + 1);
|
|
7982
|
+
}, backoffMs);
|
|
7983
|
+
});
|
|
7883
7984
|
}
|
|
7884
7985
|
}
|
|
7885
7986
|
},
|
|
@@ -7993,6 +8094,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
7993
8094
|
shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
|
|
7994
8095
|
return _this.shouldContinueLiveStreamDuringAds();
|
|
7995
8096
|
},
|
|
8097
|
+
isLiveStream: function isLiveStream() {
|
|
8098
|
+
return _this.hlsEngine.isLiveStream;
|
|
8099
|
+
},
|
|
7996
8100
|
getLiveSyncPosition: function getLiveSyncPosition() {
|
|
7997
8101
|
return _this.hlsEngine.getLiveSyncPosition();
|
|
7998
8102
|
},
|
|
@@ -8215,6 +8319,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8215
8319
|
{
|
|
8216
8320
|
key: "shouldContinueLiveStreamDuringAds",
|
|
8217
8321
|
value: function shouldContinueLiveStreamDuringAds() {
|
|
8322
|
+
if (this.config.pauseContentDuringAds) {
|
|
8323
|
+
return false;
|
|
8324
|
+
}
|
|
8218
8325
|
if (this.hlsEngine.isLiveStream) {
|
|
8219
8326
|
return true;
|
|
8220
8327
|
}
|