stormcloud-video-player 0.8.50 → 0.8.51
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 +272 -223
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +272 -223
- package/lib/index.js.map +1 -1
- package/lib/player/AdBreakOrchestrator.d.cts +1 -1
- 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 +249 -200
- 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 +249 -200
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.d.cts +1 -1
- package/lib/players/index.cjs +249 -200
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +220 -28
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.d.cts +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +249 -200
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.d.cts +1 -1
- package/lib/utils/tracking.d.cts +1 -1
- package/package.json +1 -1
package/lib/sdk/hlsAdPlayer.cjs
CHANGED
|
@@ -198,6 +198,150 @@ __export(hlsAdPlayer_exports, {
|
|
|
198
198
|
});
|
|
199
199
|
module.exports = __toCommonJS(hlsAdPlayer_exports);
|
|
200
200
|
var import_hls = __toESM(require("hls.js"), 1);
|
|
201
|
+
// src/utils/browserCompat.ts
|
|
202
|
+
function getChromeVersion(ua) {
|
|
203
|
+
var match = ua.match(/Chrome\/(\d+)/);
|
|
204
|
+
return match && match[1] ? parseInt(match[1], 10) : 0;
|
|
205
|
+
}
|
|
206
|
+
function getWebKitVersion(ua) {
|
|
207
|
+
var match = ua.match(/AppleWebKit\/(\d+)/);
|
|
208
|
+
return match && match[1] ? parseInt(match[1], 10) : 0;
|
|
209
|
+
}
|
|
210
|
+
function getPlatform() {
|
|
211
|
+
var _navigator_userAgentData;
|
|
212
|
+
if ("userAgentData" in navigator && ((_navigator_userAgentData = navigator.userAgentData) === null || _navigator_userAgentData === void 0 ? void 0 : _navigator_userAgentData.platform)) {
|
|
213
|
+
return navigator.userAgentData.platform;
|
|
214
|
+
}
|
|
215
|
+
var ua = navigator.userAgent;
|
|
216
|
+
if (/Mac|iPhone|iPad|iPod/i.test(ua)) {
|
|
217
|
+
return /iPhone|iPad|iPod/i.test(ua) ? "iPhone" : "MacIntel";
|
|
218
|
+
}
|
|
219
|
+
if (/Win/i.test(ua)) {
|
|
220
|
+
return "Win32";
|
|
221
|
+
}
|
|
222
|
+
if (/Linux/i.test(ua)) {
|
|
223
|
+
return /Android/i.test(ua) ? "Linux armv8l" : "Linux x86_64";
|
|
224
|
+
}
|
|
225
|
+
if (/CrOS/i.test(ua)) {
|
|
226
|
+
return "CrOS";
|
|
227
|
+
}
|
|
228
|
+
return navigator.platform || "Unknown";
|
|
229
|
+
}
|
|
230
|
+
function detectBrowser() {
|
|
231
|
+
var ua = navigator.userAgent;
|
|
232
|
+
var platform = getPlatform();
|
|
233
|
+
var name = "Unknown";
|
|
234
|
+
var version = "0";
|
|
235
|
+
var majorVersion = 0;
|
|
236
|
+
var isSmartTV = false;
|
|
237
|
+
var isLegacyTV = false;
|
|
238
|
+
var supportsModernJS = true;
|
|
239
|
+
var webOSVersion;
|
|
240
|
+
var tizenVersion;
|
|
241
|
+
var chromeVersionNum;
|
|
242
|
+
var chromeVersion = getChromeVersion(ua);
|
|
243
|
+
var webkitVersion = getWebKitVersion(ua);
|
|
244
|
+
chromeVersionNum = chromeVersion > 0 ? chromeVersion : void 0;
|
|
245
|
+
if (/Web0S|webOS|LG Browser|LGSTB/i.test(ua)) {
|
|
246
|
+
name = "LG WebOS";
|
|
247
|
+
isSmartTV = true;
|
|
248
|
+
var match = ua.match(/Web0S[/\s]*([\d.]+)/i) || ua.match(/webOS[/\s]*([\d.]+)/i);
|
|
249
|
+
if (!match || !match[1]) {
|
|
250
|
+
match = ua.match(/webOSTV[/\s-]*([\d.]+)/i) || ua.match(/webOS\.TV[/\s-]*([\d.]+)/i);
|
|
251
|
+
}
|
|
252
|
+
if (match && match[1]) {
|
|
253
|
+
version = match[1];
|
|
254
|
+
var parts = version.split(".");
|
|
255
|
+
majorVersion = parts[0] ? parseInt(parts[0], 10) : 0;
|
|
256
|
+
webOSVersion = majorVersion;
|
|
257
|
+
} else if (chromeVersion > 0) {
|
|
258
|
+
if (chromeVersion >= 79) {
|
|
259
|
+
webOSVersion = 6;
|
|
260
|
+
version = "6.0";
|
|
261
|
+
majorVersion = 6;
|
|
262
|
+
} else if (chromeVersion >= 68) {
|
|
263
|
+
webOSVersion = 5;
|
|
264
|
+
version = "5.0";
|
|
265
|
+
majorVersion = 5;
|
|
266
|
+
} else if (chromeVersion >= 53) {
|
|
267
|
+
webOSVersion = 4;
|
|
268
|
+
version = "4.0";
|
|
269
|
+
majorVersion = 4;
|
|
270
|
+
} else if (chromeVersion >= 38) {
|
|
271
|
+
webOSVersion = 3;
|
|
272
|
+
version = "3.0";
|
|
273
|
+
majorVersion = 3;
|
|
274
|
+
} else {
|
|
275
|
+
webOSVersion = 2;
|
|
276
|
+
version = "2.0";
|
|
277
|
+
majorVersion = 2;
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
version = "Unknown";
|
|
281
|
+
webOSVersion = void 0;
|
|
282
|
+
}
|
|
283
|
+
isLegacyTV = webOSVersion !== void 0 && webOSVersion < 3;
|
|
284
|
+
} else if (/Tizen/i.test(ua)) {
|
|
285
|
+
name = "Samsung Tizen";
|
|
286
|
+
isSmartTV = true;
|
|
287
|
+
var match1 = ua.match(/Tizen[/\s]*([\d.]+)/i);
|
|
288
|
+
version = match1 && match1[1] ? match1[1] : "Unknown";
|
|
289
|
+
if (version !== "Unknown") {
|
|
290
|
+
var parts1 = version.split(".");
|
|
291
|
+
majorVersion = parts1[0] ? parseInt(parts1[0], 10) : 0;
|
|
292
|
+
tizenVersion = majorVersion;
|
|
293
|
+
}
|
|
294
|
+
isLegacyTV = tizenVersion !== void 0 && tizenVersion < 3;
|
|
295
|
+
} else if (/SMART-TV|SmartTV/i.test(ua)) {
|
|
296
|
+
name = "Smart TV";
|
|
297
|
+
isSmartTV = true;
|
|
298
|
+
isLegacyTV = chromeVersion > 0 && chromeVersion < 53;
|
|
299
|
+
} else if (/NetCast/i.test(ua)) {
|
|
300
|
+
name = "LG NetCast";
|
|
301
|
+
isSmartTV = true;
|
|
302
|
+
isLegacyTV = true;
|
|
303
|
+
} else if (/BRAVIA/i.test(ua)) {
|
|
304
|
+
name = "Sony BRAVIA";
|
|
305
|
+
isSmartTV = true;
|
|
306
|
+
isLegacyTV = chromeVersion > 0 && chromeVersion < 53;
|
|
307
|
+
} else {
|
|
308
|
+
if (chromeVersion > 0) {
|
|
309
|
+
name = "Chrome";
|
|
310
|
+
version = chromeVersion.toString();
|
|
311
|
+
majorVersion = chromeVersion;
|
|
312
|
+
if (chromeVersion < 50) {
|
|
313
|
+
supportsModernJS = false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (webkitVersion > 0 && webkitVersion < 600) {
|
|
317
|
+
supportsModernJS = false;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (typeof Promise === "undefined" || typeof Map === "undefined" || typeof Set === "undefined") {
|
|
321
|
+
supportsModernJS = false;
|
|
322
|
+
}
|
|
323
|
+
if (typeof URLSearchParams === "undefined") {
|
|
324
|
+
supportsModernJS = false;
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
name: name,
|
|
328
|
+
version: version,
|
|
329
|
+
majorVersion: majorVersion,
|
|
330
|
+
isSmartTV: isSmartTV,
|
|
331
|
+
isLegacyTV: isLegacyTV,
|
|
332
|
+
platform: platform,
|
|
333
|
+
supportsModernJS: supportsModernJS,
|
|
334
|
+
webOSVersion: webOSVersion,
|
|
335
|
+
tizenVersion: tizenVersion,
|
|
336
|
+
chromeVersion: chromeVersionNum
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
function requiresMediaPipelineResetAfterAds() {
|
|
340
|
+
var _browser_tizenVersion;
|
|
341
|
+
var browser = detectBrowser();
|
|
342
|
+
return browser.name === "Samsung Tizen" && ((_browser_tizenVersion = browser.tizenVersion) !== null && _browser_tizenVersion !== void 0 ? _browser_tizenVersion : 0) >= 5;
|
|
343
|
+
}
|
|
344
|
+
// src/sdk/hlsAdPlayer.ts
|
|
201
345
|
var MAX_VAST_WRAPPER_DEPTH = 5;
|
|
202
346
|
function createHlsAdPlayer(contentVideo, options) {
|
|
203
347
|
var _contentVideo_AD_VIDEO_PROP, _contentVideo_AD_CONTAINER_PROP;
|
|
@@ -230,6 +374,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
230
374
|
var lastAdProgressPosition = 0;
|
|
231
375
|
var sawDecodedVideoFrame = false;
|
|
232
376
|
var videoFrameCallbackHandle;
|
|
377
|
+
var pendingPlayPromise;
|
|
233
378
|
var trackingFired = {
|
|
234
379
|
impression: false,
|
|
235
380
|
start: false,
|
|
@@ -1033,6 +1178,60 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1033
1178
|
complete: false
|
|
1034
1179
|
};
|
|
1035
1180
|
}
|
|
1181
|
+
function isRvfcSupported(video) {
|
|
1182
|
+
return typeof video.requestVideoFrameCallback === "function";
|
|
1183
|
+
}
|
|
1184
|
+
function settlePendingPlay() {
|
|
1185
|
+
pendingPlayPromise = void 0;
|
|
1186
|
+
}
|
|
1187
|
+
function startAdPlayback(context) {
|
|
1188
|
+
if (!adVideoElement) return;
|
|
1189
|
+
var playPromise = adVideoElement.play();
|
|
1190
|
+
pendingPlayPromise = playPromise;
|
|
1191
|
+
playPromise.catch(function(error) {
|
|
1192
|
+
if (pendingPlayPromise !== playPromise) {
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
console.error("[HlsAdPlayer] Error starting ".concat(context, ":"), error);
|
|
1196
|
+
handleAdError();
|
|
1197
|
+
}).finally(function() {
|
|
1198
|
+
if (pendingPlayPromise === playPromise) {
|
|
1199
|
+
pendingPlayPromise = void 0;
|
|
1200
|
+
}
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
function prepareVideoElementForNewSource() {
|
|
1204
|
+
settlePendingPlay();
|
|
1205
|
+
if (adHls) {
|
|
1206
|
+
adHls.destroy();
|
|
1207
|
+
adHls = void 0;
|
|
1208
|
+
}
|
|
1209
|
+
if (!adVideoElement) return;
|
|
1210
|
+
try {
|
|
1211
|
+
adVideoElement.pause();
|
|
1212
|
+
adVideoElement.removeAttribute("src");
|
|
1213
|
+
adVideoElement.load();
|
|
1214
|
+
} catch (error) {
|
|
1215
|
+
console.warn("[HlsAdPlayer] Error preparing ad video for new source:", error);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
function recreateAdVideoElement() {
|
|
1219
|
+
console.log("[HlsAdPlayer] Recreating ad video element (single-decoder platform)");
|
|
1220
|
+
teardownAdEventListeners();
|
|
1221
|
+
prepareVideoElementForNewSource();
|
|
1222
|
+
if (adVideoElement) {
|
|
1223
|
+
try {
|
|
1224
|
+
adVideoElement.remove();
|
|
1225
|
+
} catch (error) {
|
|
1226
|
+
console.warn("[HlsAdPlayer] Error removing ad video element:", error);
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
adVideoElement = createAdVideoElement();
|
|
1230
|
+
adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.appendChild(adVideoElement);
|
|
1231
|
+
contentVideo[AD_VIDEO_PROP] = adVideoElement;
|
|
1232
|
+
adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));
|
|
1233
|
+
adVideoElement.muted = originalMutedState;
|
|
1234
|
+
}
|
|
1036
1235
|
function loadCurrentAdMedia() {
|
|
1037
1236
|
if (!adVideoElement || !currentAd) {
|
|
1038
1237
|
throw new Error("No ad video element or ad to load");
|
|
@@ -1055,10 +1254,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1055
1254
|
adHls.attachMedia(adVideoElement);
|
|
1056
1255
|
adHls.on(import_hls.default.Events.MANIFEST_PARSED, function() {
|
|
1057
1256
|
console.log("[HlsAdPlayer] HLS manifest parsed, starting playback");
|
|
1058
|
-
|
|
1059
|
-
console.error("[HlsAdPlayer] Error starting ad playback:", error);
|
|
1060
|
-
handleAdError();
|
|
1061
|
-
});
|
|
1257
|
+
startAdPlayback("HLS ad playback");
|
|
1062
1258
|
});
|
|
1063
1259
|
adHls.on(import_hls.default.Events.ERROR, function(_event, data) {
|
|
1064
1260
|
console.error("[HlsAdPlayer] HLS error:", data);
|
|
@@ -1068,10 +1264,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1068
1264
|
});
|
|
1069
1265
|
} else if (isHlsAd && adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
|
|
1070
1266
|
adVideoElement.src = mediaFile.url;
|
|
1071
|
-
|
|
1072
|
-
console.error("[HlsAdPlayer] Error starting ad playback:", error);
|
|
1073
|
-
handleAdError();
|
|
1074
|
-
});
|
|
1267
|
+
startAdPlayback("native HLS ad playback");
|
|
1075
1268
|
} else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {
|
|
1076
1269
|
if (adHls) {
|
|
1077
1270
|
adHls.destroy();
|
|
@@ -1079,10 +1272,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1079
1272
|
}
|
|
1080
1273
|
adVideoElement.src = mediaFile.url;
|
|
1081
1274
|
adVideoElement.load();
|
|
1082
|
-
|
|
1083
|
-
console.error("[HlsAdPlayer] Error starting progressive ad playback:", error);
|
|
1084
|
-
handleAdError();
|
|
1085
|
-
});
|
|
1275
|
+
startAdPlayback("progressive ad playback");
|
|
1086
1276
|
} else {
|
|
1087
1277
|
throw new Error("Unsupported ad media file type: ".concat(mediaFile.type));
|
|
1088
1278
|
}
|
|
@@ -1099,6 +1289,13 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1099
1289
|
trackingFired.impression = true;
|
|
1100
1290
|
console.log("[HlsAdPlayer] Advancing to next pod ad (".concat(podIndex + 1, "/").concat(podAds.length, "): ").concat(currentAd.title, ", duration: ").concat(currentAd.duration, "s"));
|
|
1101
1291
|
}
|
|
1292
|
+
clearStallWatchdog();
|
|
1293
|
+
if (requiresMediaPipelineResetAfterAds()) {
|
|
1294
|
+
recreateAdVideoElement();
|
|
1295
|
+
setupAdEventListeners();
|
|
1296
|
+
} else {
|
|
1297
|
+
prepareVideoElementForNewSource();
|
|
1298
|
+
}
|
|
1102
1299
|
try {
|
|
1103
1300
|
loadCurrentAdMedia();
|
|
1104
1301
|
emit("pod_ad_started", {
|
|
@@ -1210,9 +1407,16 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1210
1407
|
if (decodedFrames !== void 0 && decodedFrames > 0) {
|
|
1211
1408
|
sawDecodedVideoFrame = true;
|
|
1212
1409
|
markFrameCounterReliable();
|
|
1213
|
-
} else if (
|
|
1214
|
-
|
|
1215
|
-
|
|
1410
|
+
} else if (adVideoElement.currentTime >= BLACKFRAME_MIN_PLAYBACK_S) {
|
|
1411
|
+
var timeAdvancing = adVideoElement.currentTime > lastAdProgressPosition + 0.05;
|
|
1412
|
+
if (isRvfcSupported(adVideoElement) && timeAdvancing) {
|
|
1413
|
+
handleVideoDecodeFailure();
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
if (decodedFrames === 0 && timeAdvancing && isFrameCounterReliable()) {
|
|
1417
|
+
handleVideoDecodeFailure();
|
|
1418
|
+
return;
|
|
1419
|
+
}
|
|
1216
1420
|
}
|
|
1217
1421
|
}
|
|
1218
1422
|
if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {
|
|
@@ -1229,19 +1433,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1229
1433
|
}, STALL_CHECK_INTERVAL_MS);
|
|
1230
1434
|
}
|
|
1231
1435
|
function releaseAdDecoder() {
|
|
1232
|
-
|
|
1233
|
-
adHls.destroy();
|
|
1234
|
-
adHls = void 0;
|
|
1235
|
-
}
|
|
1236
|
-
if (adVideoElement) {
|
|
1237
|
-
try {
|
|
1238
|
-
adVideoElement.pause();
|
|
1239
|
-
adVideoElement.removeAttribute("src");
|
|
1240
|
-
adVideoElement.load();
|
|
1241
|
-
} catch (error) {
|
|
1242
|
-
console.warn("[HlsAdPlayer] Error releasing ad decoder:", error);
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1436
|
+
prepareVideoElementForNewSource();
|
|
1245
1437
|
if (adContainerEl) {
|
|
1246
1438
|
adContainerEl.style.display = "none";
|
|
1247
1439
|
adContainerEl.style.pointerEvents = "none";
|