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,4 +1,4 @@
|
|
|
1
|
-
import { b as AdBreak, a as StormcloudVideoPlayerConfig, A as AdController } from '../types-
|
|
1
|
+
import { b as AdBreak, a as StormcloudVideoPlayerConfig, A as AdController } from '../types-cTqIKw_D.cjs';
|
|
2
2
|
import { PalNonceManager } from '../sdk/pal.cjs';
|
|
3
3
|
import { VastConsentSignals } from '../utils/vastMacros.cjs';
|
|
4
4
|
|
|
@@ -20,6 +20,7 @@ declare class AdConfigManager {
|
|
|
20
20
|
get debug(): boolean;
|
|
21
21
|
isVmapEnabled(): boolean;
|
|
22
22
|
fetchAdConfiguration(): Promise<void>;
|
|
23
|
+
private applyMqttConfigFromResponse;
|
|
23
24
|
private fetchAndParseVmap;
|
|
24
25
|
private parseVmapToBreaks;
|
|
25
26
|
private parseVmapTimeOffsetToMs;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as StormcloudVideoPlayerConfig, S as Scte35Marker, A as AdController } from '../types-
|
|
1
|
+
import { a as StormcloudVideoPlayerConfig, S as Scte35Marker, A as AdController } from '../types-cTqIKw_D.cjs';
|
|
2
2
|
|
|
3
3
|
interface AdTimingCallbacks {
|
|
4
4
|
onAdStopTimerFired(): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Hls from 'hls.js';
|
|
2
|
-
import { a as StormcloudVideoPlayerConfig, S as Scte35Marker } from '../types-
|
|
2
|
+
import { a as StormcloudVideoPlayerConfig, S as Scte35Marker } from '../types-cTqIKw_D.cjs';
|
|
3
3
|
import { Scte35CueContext } from './playerTypes.cjs';
|
|
4
4
|
import { Scte35CueManager } from './Scte35CueManager.cjs';
|
|
5
5
|
import { AdTimingService } from './AdTimingService.cjs';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AdController } from '../types-
|
|
1
|
+
import { A as AdController } from '../types-cTqIKw_D.cjs';
|
|
2
2
|
|
|
3
3
|
declare function getAdAudioVolume(adPlayer: AdController): number;
|
|
4
4
|
declare function toggleMute(video: HTMLVideoElement, adPlayer: AdController, debug: boolean): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as Scte35Marker, I as Id3TagInfo } from '../types-
|
|
1
|
+
import { S as Scte35Marker, I as Id3TagInfo } from '../types-cTqIKw_D.cjs';
|
|
2
2
|
|
|
3
3
|
declare function parseCueOutDuration(value: string): number | undefined;
|
|
4
4
|
declare function parseCueOutCont(value: string): {
|
|
@@ -368,6 +368,11 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
368
368
|
var preloadingAds = /* @__PURE__ */ new Map();
|
|
369
369
|
var destroyed = false;
|
|
370
370
|
var pendingTimeouts = [];
|
|
371
|
+
var STALL_TIMEOUT_MS = 4e3;
|
|
372
|
+
var STALL_CHECK_INTERVAL_MS = 1e3;
|
|
373
|
+
var stallWatchdogId;
|
|
374
|
+
var lastAdProgressTime = 0;
|
|
375
|
+
var lastAdProgressPosition = 0;
|
|
371
376
|
var trackingFired = {
|
|
372
377
|
impression: false,
|
|
373
378
|
start: false,
|
|
@@ -1000,6 +1005,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1000
1005
|
if (!adVideoElement || !currentAd) return;
|
|
1001
1006
|
adVideoElement.addEventListener("timeupdate", function() {
|
|
1002
1007
|
if (!currentAd || !adVideoElement) return;
|
|
1008
|
+
noteAdProgress();
|
|
1003
1009
|
var progress = adVideoElement.currentTime / currentAd.duration;
|
|
1004
1010
|
if (progress >= 0.25 && !trackingFired.firstQuartile) {
|
|
1005
1011
|
trackingFired.firstQuartile = true;
|
|
@@ -1015,6 +1021,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1015
1021
|
}
|
|
1016
1022
|
});
|
|
1017
1023
|
adVideoElement.addEventListener("playing", function() {
|
|
1024
|
+
startStallWatchdog();
|
|
1018
1025
|
if (!currentAd || trackingFired.start) return;
|
|
1019
1026
|
trackingFired.start = true;
|
|
1020
1027
|
fireTrackingPixels(currentAd.trackingUrls.start);
|
|
@@ -1155,8 +1162,52 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1155
1162
|
return false;
|
|
1156
1163
|
}
|
|
1157
1164
|
}
|
|
1165
|
+
function clearStallWatchdog() {
|
|
1166
|
+
if (stallWatchdogId != null) {
|
|
1167
|
+
clearInterval(stallWatchdogId);
|
|
1168
|
+
stallWatchdogId = void 0;
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
function noteAdProgress() {
|
|
1172
|
+
lastAdProgressTime = Date.now();
|
|
1173
|
+
if (adVideoElement) {
|
|
1174
|
+
lastAdProgressPosition = adVideoElement.currentTime;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
function handleAdStall() {
|
|
1178
|
+
console.warn("[HlsAdPlayer] Ad playback stalled (no progress) - recovering to avoid a blank frame");
|
|
1179
|
+
clearStallWatchdog();
|
|
1180
|
+
if (currentAd) {
|
|
1181
|
+
fireTrackingPixels(currentAd.trackingUrls.error);
|
|
1182
|
+
}
|
|
1183
|
+
if (podIndex < podAds.length - 1 && advanceToNextPodAd()) {
|
|
1184
|
+
return;
|
|
1185
|
+
}
|
|
1186
|
+
handleAdError();
|
|
1187
|
+
}
|
|
1188
|
+
function startStallWatchdog() {
|
|
1189
|
+
clearStallWatchdog();
|
|
1190
|
+
noteAdProgress();
|
|
1191
|
+
stallWatchdogId = window.setInterval(function() {
|
|
1192
|
+
if (!adPlaying || !adVideoElement) {
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {
|
|
1196
|
+
noteAdProgress();
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1199
|
+
if (adVideoElement.paused) {
|
|
1200
|
+
noteAdProgress();
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
if (Date.now() - lastAdProgressTime >= STALL_TIMEOUT_MS) {
|
|
1204
|
+
handleAdStall();
|
|
1205
|
+
}
|
|
1206
|
+
}, STALL_CHECK_INTERVAL_MS);
|
|
1207
|
+
}
|
|
1158
1208
|
function handleAdComplete() {
|
|
1159
1209
|
console.log("[HlsAdPlayer] Handling ad completion");
|
|
1210
|
+
clearStallWatchdog();
|
|
1160
1211
|
adPlaying = false;
|
|
1161
1212
|
setAdPlayingFlag(false);
|
|
1162
1213
|
contentVideo.muted = true;
|
|
@@ -1164,6 +1215,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1164
1215
|
adContainerEl.style.display = "none";
|
|
1165
1216
|
adContainerEl.style.pointerEvents = "none";
|
|
1166
1217
|
}
|
|
1218
|
+
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1219
|
+
contentVideo.style.visibility = "visible";
|
|
1220
|
+
contentVideo.style.opacity = "1";
|
|
1221
|
+
}
|
|
1167
1222
|
if (options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds) {
|
|
1168
1223
|
if (contentVideo.paused) {
|
|
1169
1224
|
console.log("[HlsAdPlayer] Content video paused in live mode, resuming playback");
|
|
@@ -1176,6 +1231,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1176
1231
|
}
|
|
1177
1232
|
function handleAdError() {
|
|
1178
1233
|
console.log("[HlsAdPlayer] Handling ad error");
|
|
1234
|
+
clearStallWatchdog();
|
|
1179
1235
|
adPlaying = false;
|
|
1180
1236
|
setAdPlayingFlag(false);
|
|
1181
1237
|
contentVideo.muted = true;
|
|
@@ -1183,6 +1239,10 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1183
1239
|
adContainerEl.style.display = "none";
|
|
1184
1240
|
adContainerEl.style.pointerEvents = "none";
|
|
1185
1241
|
}
|
|
1242
|
+
if (!(options === null || options === void 0 ? void 0 : options.continueLiveStreamDuringAds)) {
|
|
1243
|
+
contentVideo.style.visibility = "visible";
|
|
1244
|
+
contentVideo.style.opacity = "1";
|
|
1245
|
+
}
|
|
1186
1246
|
emit("ad_error");
|
|
1187
1247
|
}
|
|
1188
1248
|
return {
|
|
@@ -1380,6 +1440,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1380
1440
|
var previousMutedState;
|
|
1381
1441
|
return _ts_generator(this, function(_state) {
|
|
1382
1442
|
console.log("[HlsAdPlayer] Stopping ad");
|
|
1443
|
+
clearStallWatchdog();
|
|
1383
1444
|
adPlaying = false;
|
|
1384
1445
|
setAdPlayingFlag(false);
|
|
1385
1446
|
previousMutedState = contentVideo.muted;
|
|
@@ -1418,6 +1479,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1418
1479
|
destroy: function destroy() {
|
|
1419
1480
|
console.log("[HlsAdPlayer] Destroying");
|
|
1420
1481
|
destroyed = true;
|
|
1482
|
+
clearStallWatchdog();
|
|
1421
1483
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1422
1484
|
try {
|
|
1423
1485
|
for(var _iterator = pendingTimeouts[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
@@ -1793,6 +1855,9 @@ var DEFAULT_MQTT_CONFIG = {
|
|
|
1793
1855
|
qos: 1
|
|
1794
1856
|
};
|
|
1795
1857
|
var mqttConfig = _object_spread({}, DEFAULT_MQTT_CONFIG);
|
|
1858
|
+
function applyMQTTConfig(overrides) {
|
|
1859
|
+
Object.assign(mqttConfig, overrides);
|
|
1860
|
+
}
|
|
1796
1861
|
function isMQTTEnabled() {
|
|
1797
1862
|
return mqttConfig.enabled;
|
|
1798
1863
|
}
|
|
@@ -3809,6 +3874,7 @@ function getBrowserConfigOverrides() {
|
|
|
3809
3874
|
var overrides = {};
|
|
3810
3875
|
if (browser.isSmartTV) {
|
|
3811
3876
|
overrides.allowNativeHls = true;
|
|
3877
|
+
overrides.pauseContentDuringAds = true;
|
|
3812
3878
|
}
|
|
3813
3879
|
return overrides;
|
|
3814
3880
|
}
|
|
@@ -4963,6 +5029,7 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
4963
5029
|
];
|
|
4964
5030
|
case 4:
|
|
4965
5031
|
data = _state.sent();
|
|
5032
|
+
this.applyMqttConfigFromResponse(data);
|
|
4966
5033
|
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;
|
|
4967
5034
|
if (imaPayload) {
|
|
4968
5035
|
decodedPayload = imaPayload;
|
|
@@ -4996,6 +5063,20 @@ var AdConfigManager = /*#__PURE__*/ function() {
|
|
|
4996
5063
|
}).call(this);
|
|
4997
5064
|
}
|
|
4998
5065
|
},
|
|
5066
|
+
{
|
|
5067
|
+
key: "applyMqttConfigFromResponse",
|
|
5068
|
+
value: function applyMqttConfigFromResponse(data) {
|
|
5069
|
+
var _data_response;
|
|
5070
|
+
var mqttConfig2 = (_data_response = data.response) === null || _data_response === void 0 ? void 0 : _data_response.mqtt_config;
|
|
5071
|
+
if (!mqttConfig2 || (typeof mqttConfig2 === "undefined" ? "undefined" : _type_of(mqttConfig2)) !== "object") {
|
|
5072
|
+
return;
|
|
5073
|
+
}
|
|
5074
|
+
applyMQTTConfig(mqttConfig2);
|
|
5075
|
+
if (this.debug) {
|
|
5076
|
+
console.log("[StormcloudVideoPlayer] Applied MQTT config from /ads/web:", mqttConfig2);
|
|
5077
|
+
}
|
|
5078
|
+
}
|
|
5079
|
+
},
|
|
4999
5080
|
{
|
|
5000
5081
|
key: "fetchAndParseVmap",
|
|
5001
5082
|
value: function fetchAndParseVmap(vmapUrl) {
|
|
@@ -6691,12 +6772,7 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
6691
6772
|
// ───────────────────────────────────────────────────────────────
|
|
6692
6773
|
// IMA event listeners
|
|
6693
6774
|
// ───────────────────────────────────────────────────────────────
|
|
6694
|
-
|
|
6695
|
-
* Produces the next pod ad-request URL for the current break. Every request
|
|
6696
|
-
* (initial and continuous-fetch top-up) carries pod macros (pmad/pmnd/pmxd,
|
|
6697
|
-
* no ppos); pmxd tracks the remaining break time so top-up pods only ask for
|
|
6698
|
-
* what still fits.
|
|
6699
|
-
*/ key: "nextAdRequestUrl",
|
|
6775
|
+
key: "nextAdRequestUrl",
|
|
6700
6776
|
value: function nextAdRequestUrl(baseVastUrl) {
|
|
6701
6777
|
var remaining = Math.min(this.timing.getWallClockRemainingAdMs(), this.timing.getDurationBudgetRemainingMs());
|
|
6702
6778
|
var breakDurationMs = remaining > 0 ? remaining : void 0;
|
|
@@ -7825,7 +7901,9 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7825
7901
|
if (Math.abs(this.host.video.volume - restoredVolume) > 0.01) {
|
|
7826
7902
|
this.host.video.volume = restoredVolume;
|
|
7827
7903
|
}
|
|
7828
|
-
|
|
7904
|
+
this.host.video.style.visibility = "visible";
|
|
7905
|
+
this.host.video.style.opacity = "1";
|
|
7906
|
+
if (this.host.isLiveStream()) {
|
|
7829
7907
|
var liveSyncPos = this.host.getLiveSyncPosition();
|
|
7830
7908
|
if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
|
|
7831
7909
|
if (this.debug) {
|
|
@@ -7833,16 +7911,39 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7833
7911
|
}
|
|
7834
7912
|
this.host.video.currentTime = liveSyncPos;
|
|
7835
7913
|
}
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7914
|
+
}
|
|
7915
|
+
this.resumeContentPlayback();
|
|
7916
|
+
}
|
|
7917
|
+
},
|
|
7918
|
+
{
|
|
7919
|
+
key: "resumeContentPlayback",
|
|
7920
|
+
value: function resumeContentPlayback() {
|
|
7921
|
+
var _this = this;
|
|
7922
|
+
var attempt = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 0;
|
|
7923
|
+
var maxAttempts = 3;
|
|
7924
|
+
if (!this.host.video.paused) {
|
|
7925
|
+
if (this.debug && attempt === 0) {
|
|
7926
|
+
console.log("[StormcloudVideoPlayer] Content video already playing after ads");
|
|
7842
7927
|
}
|
|
7843
|
-
|
|
7844
|
-
|
|
7845
|
-
|
|
7928
|
+
return;
|
|
7929
|
+
}
|
|
7930
|
+
if (this.debug) {
|
|
7931
|
+
console.log("[StormcloudVideoPlayer] Resuming content playback after ads (attempt ".concat(attempt + 1, "/").concat(maxAttempts, ")"));
|
|
7932
|
+
}
|
|
7933
|
+
var playResult = this.host.video.play();
|
|
7934
|
+
if (playResult && typeof playResult.catch === "function") {
|
|
7935
|
+
playResult.catch(function(error) {
|
|
7936
|
+
if (attempt + 1 >= maxAttempts) {
|
|
7937
|
+
if (_this.debug) {
|
|
7938
|
+
console.warn("[StormcloudVideoPlayer] Failed to resume content playback after ads:", error);
|
|
7939
|
+
}
|
|
7940
|
+
return;
|
|
7941
|
+
}
|
|
7942
|
+
var backoffMs = 250 * (attempt + 1);
|
|
7943
|
+
window.setTimeout(function() {
|
|
7944
|
+
_this.resumeContentPlayback(attempt + 1);
|
|
7945
|
+
}, backoffMs);
|
|
7946
|
+
});
|
|
7846
7947
|
}
|
|
7847
7948
|
}
|
|
7848
7949
|
},
|
|
@@ -7956,6 +8057,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
7956
8057
|
shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
|
|
7957
8058
|
return _this.shouldContinueLiveStreamDuringAds();
|
|
7958
8059
|
},
|
|
8060
|
+
isLiveStream: function isLiveStream() {
|
|
8061
|
+
return _this.hlsEngine.isLiveStream;
|
|
8062
|
+
},
|
|
7959
8063
|
getLiveSyncPosition: function getLiveSyncPosition() {
|
|
7960
8064
|
return _this.hlsEngine.getLiveSyncPosition();
|
|
7961
8065
|
},
|
|
@@ -8178,6 +8282,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8178
8282
|
{
|
|
8179
8283
|
key: "shouldContinueLiveStreamDuringAds",
|
|
8180
8284
|
value: function shouldContinueLiveStreamDuringAds() {
|
|
8285
|
+
if (this.config.pauseContentDuringAds) {
|
|
8286
|
+
return false;
|
|
8287
|
+
}
|
|
8181
8288
|
if (this.hlsEngine.isLiveStream) {
|
|
8182
8289
|
return true;
|
|
8183
8290
|
}
|