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
|
@@ -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){
|
|
@@ -1880,6 +1942,9 @@ var DEFAULT_MQTT_CONFIG = {
|
|
|
1880
1942
|
qos: 1
|
|
1881
1943
|
};
|
|
1882
1944
|
var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
|
|
1945
|
+
function applyMQTTConfig(overrides) {
|
|
1946
|
+
Object.assign(mqttConfig, overrides);
|
|
1947
|
+
}
|
|
1883
1948
|
function isMQTTEnabled() {
|
|
1884
1949
|
return mqttConfig.enabled;
|
|
1885
1950
|
}
|
|
@@ -3896,6 +3961,7 @@ function getBrowserConfigOverrides() {
|
|
|
3896
3961
|
var overrides = {};
|
|
3897
3962
|
if (browser.isSmartTV) {
|
|
3898
3963
|
overrides.allowNativeHls = true;
|
|
3964
|
+
overrides.pauseContentDuringAds = true;
|
|
3899
3965
|
}
|
|
3900
3966
|
return overrides;
|
|
3901
3967
|
}
|
|
@@ -5050,6 +5116,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
5050
5116
|
];
|
|
5051
5117
|
case 4:
|
|
5052
5118
|
data = _state.sent();
|
|
5119
|
+
this.applyMqttConfigFromResponse(data);
|
|
5053
5120
|
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;
|
|
5054
5121
|
if (imaPayload) {
|
|
5055
5122
|
decodedPayload = imaPayload;
|
|
@@ -5083,6 +5150,20 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
5083
5150
|
}).call(this);
|
|
5084
5151
|
}
|
|
5085
5152
|
},
|
|
5153
|
+
{
|
|
5154
|
+
key: "applyMqttConfigFromResponse",
|
|
5155
|
+
value: function applyMqttConfigFromResponse(data) {
|
|
5156
|
+
var _data_response;
|
|
5157
|
+
var mqttConfig2 = (_data_response = data.response) === null || _data_response === void 0 ? void 0 : _data_response.mqtt_config;
|
|
5158
|
+
if (!mqttConfig2 || (typeof mqttConfig2 === "undefined" ? "undefined" : _type_of(mqttConfig2)) !== "object") {
|
|
5159
|
+
return;
|
|
5160
|
+
}
|
|
5161
|
+
applyMQTTConfig(mqttConfig2);
|
|
5162
|
+
if (this.debug) {
|
|
5163
|
+
console.log("[StormcloudVideoPlayer] Applied MQTT config from /ads/web:", mqttConfig2);
|
|
5164
|
+
}
|
|
5165
|
+
}
|
|
5166
|
+
},
|
|
5086
5167
|
{
|
|
5087
5168
|
key: "fetchAndParseVmap",
|
|
5088
5169
|
value: function fetchAndParseVmap(vmapUrl) {
|
|
@@ -6778,12 +6859,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
6778
6859
|
// ───────────────────────────────────────────────────────────────
|
|
6779
6860
|
// IMA event listeners
|
|
6780
6861
|
// ───────────────────────────────────────────────────────────────
|
|
6781
|
-
|
|
6782
|
-
* Produces the next pod ad-request URL for the current break. Every request
|
|
6783
|
-
* (initial and continuous-fetch top-up) carries pod macros (pmad/pmnd/pmxd,
|
|
6784
|
-
* no ppos); pmxd tracks the remaining break time so top-up pods only ask for
|
|
6785
|
-
* what still fits.
|
|
6786
|
-
*/ key: "nextAdRequestUrl",
|
|
6862
|
+
key: "nextAdRequestUrl",
|
|
6787
6863
|
value: function nextAdRequestUrl(baseVastUrl) {
|
|
6788
6864
|
var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
|
|
6789
6865
|
var breakDurationMs = remaining > 0 ? remaining : void 0;
|
|
@@ -7912,7 +7988,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7912
7988
|
if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {
|
|
7913
7989
|
this.host.video.volume = restoredVolume;
|
|
7914
7990
|
}
|
|
7915
|
-
|
|
7991
|
+
this.host.video.style.visibility = "visible";
|
|
7992
|
+
this.host.video.style.opacity = "1";
|
|
7993
|
+
if (this.host.isLiveStream()) {
|
|
7916
7994
|
var liveSyncPos = this.host.getLiveSyncPosition();
|
|
7917
7995
|
if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
|
|
7918
7996
|
if (this.debug) {
|
|
@@ -7920,16 +7998,39 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7920
7998
|
}
|
|
7921
7999
|
this.host.video.currentTime = liveSyncPos;
|
|
7922
8000
|
}
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
8001
|
+
}
|
|
8002
|
+
this.resumeContentPlayback();
|
|
8003
|
+
}
|
|
8004
|
+
},
|
|
8005
|
+
{
|
|
8006
|
+
key: "resumeContentPlayback",
|
|
8007
|
+
value: function resumeContentPlayback() {
|
|
8008
|
+
var _this = this;
|
|
8009
|
+
var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
|
|
8010
|
+
var maxAttempts = 3;
|
|
8011
|
+
if (!this.host.video.paused) {
|
|
8012
|
+
if (this.debug && attempt === 0) {
|
|
8013
|
+
console.log("[StormcloudVideoPlayer] Content video already playing after ads");
|
|
7929
8014
|
}
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
8015
|
+
return;
|
|
8016
|
+
}
|
|
8017
|
+
if (this.debug) {
|
|
8018
|
+
console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
|
|
8019
|
+
}
|
|
8020
|
+
var playResult = this.host.video.play();
|
|
8021
|
+
if (playResult && typeof playResult.catch === "function") {
|
|
8022
|
+
playResult.catch(function(error) {
|
|
8023
|
+
if (attempt + 1 >= maxAttempts) {
|
|
8024
|
+
if (_this.debug) {
|
|
8025
|
+
console.warn("[StormcloudVideoPlayer] Failed to resume content playback after ads:", error);
|
|
8026
|
+
}
|
|
8027
|
+
return;
|
|
8028
|
+
}
|
|
8029
|
+
var backoffMs = 250 * (attempt + 1);
|
|
8030
|
+
window.setTimeout(function() {
|
|
8031
|
+
_this.resumeContentPlayback(attempt + 1);
|
|
8032
|
+
}, backoffMs);
|
|
8033
|
+
});
|
|
7933
8034
|
}
|
|
7934
8035
|
}
|
|
7935
8036
|
},
|
|
@@ -8043,6 +8144,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8043
8144
|
shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
|
|
8044
8145
|
return _this.shouldContinueLiveStreamDuringAds();
|
|
8045
8146
|
},
|
|
8147
|
+
isLiveStream: function isLiveStream() {
|
|
8148
|
+
return _this.hlsEngine.isLiveStream;
|
|
8149
|
+
},
|
|
8046
8150
|
getLiveSyncPosition: function getLiveSyncPosition() {
|
|
8047
8151
|
return _this.hlsEngine.getLiveSyncPosition();
|
|
8048
8152
|
},
|
|
@@ -8265,6 +8369,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8265
8369
|
{
|
|
8266
8370
|
key: "shouldContinueLiveStreamDuringAds",
|
|
8267
8371
|
value: function shouldContinueLiveStreamDuringAds() {
|
|
8372
|
+
if (this.config.pauseContentDuringAds) {
|
|
8373
|
+
return false;
|
|
8374
|
+
}
|
|
8268
8375
|
if (this.hlsEngine.isLiveStream) {
|
|
8269
8376
|
return true;
|
|
8270
8377
|
}
|