stormcloud-video-player 0.8.50 → 0.8.52
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 +283 -225
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +283 -225
- package/lib/index.js.map +1 -1
- package/lib/player/StormcloudVideoPlayer.cjs +260 -202
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +260 -202
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +260 -202
- package/lib/players/index.cjs.map +1 -1
- package/lib/sdk/hlsAdPlayer.cjs +231 -30
- package/lib/sdk/hlsAdPlayer.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +260 -202
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/package.json +1 -1
- package/lib/types-iDjS8f_7.d.cts +0 -133
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;
|
|
@@ -210,6 +354,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
210
354
|
var AD_CONTAINER_PROP = "__stormcloudAdContainer";
|
|
211
355
|
var AD_VIDEO_PROP = "__stormcloudAdVideo";
|
|
212
356
|
var FRAME_COUNTER_RELIABLE_PROP = "__stormcloudFrameCounterReliable";
|
|
357
|
+
var RVFC_RELIABLE_PROP = "__stormcloudRvfcReliable";
|
|
213
358
|
var adVideoElement = (_contentVideo_AD_VIDEO_PROP = contentVideo[AD_VIDEO_PROP]) !== null && _contentVideo_AD_VIDEO_PROP !== void 0 ? _contentVideo_AD_VIDEO_PROP : void 0;
|
|
214
359
|
var adHls;
|
|
215
360
|
var adContainerEl = (_contentVideo_AD_CONTAINER_PROP = contentVideo[AD_CONTAINER_PROP]) !== null && _contentVideo_AD_CONTAINER_PROP !== void 0 ? _contentVideo_AD_CONTAINER_PROP : void 0;
|
|
@@ -230,6 +375,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
230
375
|
var lastAdProgressPosition = 0;
|
|
231
376
|
var sawDecodedVideoFrame = false;
|
|
232
377
|
var videoFrameCallbackHandle;
|
|
378
|
+
var pendingPlayPromise;
|
|
233
379
|
var trackingFired = {
|
|
234
380
|
impression: false,
|
|
235
381
|
start: false,
|
|
@@ -1033,6 +1179,60 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1033
1179
|
complete: false
|
|
1034
1180
|
};
|
|
1035
1181
|
}
|
|
1182
|
+
function isRvfcSupported(video) {
|
|
1183
|
+
return typeof video.requestVideoFrameCallback === "function";
|
|
1184
|
+
}
|
|
1185
|
+
function settlePendingPlay() {
|
|
1186
|
+
pendingPlayPromise = void 0;
|
|
1187
|
+
}
|
|
1188
|
+
function startAdPlayback(context) {
|
|
1189
|
+
if (!adVideoElement) return;
|
|
1190
|
+
var playPromise = adVideoElement.play();
|
|
1191
|
+
pendingPlayPromise = playPromise;
|
|
1192
|
+
playPromise.catch(function(error) {
|
|
1193
|
+
if (pendingPlayPromise !== playPromise) {
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
console.error("[HlsAdPlayer] Error starting ".concat(context, ":"), error);
|
|
1197
|
+
handleAdError();
|
|
1198
|
+
}).finally(function() {
|
|
1199
|
+
if (pendingPlayPromise === playPromise) {
|
|
1200
|
+
pendingPlayPromise = void 0;
|
|
1201
|
+
}
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
function prepareVideoElementForNewSource() {
|
|
1205
|
+
settlePendingPlay();
|
|
1206
|
+
if (adHls) {
|
|
1207
|
+
adHls.destroy();
|
|
1208
|
+
adHls = void 0;
|
|
1209
|
+
}
|
|
1210
|
+
if (!adVideoElement) return;
|
|
1211
|
+
try {
|
|
1212
|
+
adVideoElement.pause();
|
|
1213
|
+
adVideoElement.removeAttribute("src");
|
|
1214
|
+
adVideoElement.load();
|
|
1215
|
+
} catch (error) {
|
|
1216
|
+
console.warn("[HlsAdPlayer] Error preparing ad video for new source:", error);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
function recreateAdVideoElement() {
|
|
1220
|
+
console.log("[HlsAdPlayer] Recreating ad video element (single-decoder platform)");
|
|
1221
|
+
teardownAdEventListeners();
|
|
1222
|
+
prepareVideoElementForNewSource();
|
|
1223
|
+
if (adVideoElement) {
|
|
1224
|
+
try {
|
|
1225
|
+
adVideoElement.remove();
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
console.warn("[HlsAdPlayer] Error removing ad video element:", error);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
adVideoElement = createAdVideoElement();
|
|
1231
|
+
adContainerEl === null || adContainerEl === void 0 ? void 0 : adContainerEl.appendChild(adVideoElement);
|
|
1232
|
+
contentVideo[AD_VIDEO_PROP] = adVideoElement;
|
|
1233
|
+
adVideoElement.volume = Math.max(0, Math.min(1, originalVolume));
|
|
1234
|
+
adVideoElement.muted = originalMutedState;
|
|
1235
|
+
}
|
|
1036
1236
|
function loadCurrentAdMedia() {
|
|
1037
1237
|
if (!adVideoElement || !currentAd) {
|
|
1038
1238
|
throw new Error("No ad video element or ad to load");
|
|
@@ -1055,10 +1255,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1055
1255
|
adHls.attachMedia(adVideoElement);
|
|
1056
1256
|
adHls.on(import_hls.default.Events.MANIFEST_PARSED, function() {
|
|
1057
1257
|
console.log("[HlsAdPlayer] HLS manifest parsed, starting playback");
|
|
1058
|
-
|
|
1059
|
-
console.error("[HlsAdPlayer] Error starting ad playback:", error);
|
|
1060
|
-
handleAdError();
|
|
1061
|
-
});
|
|
1258
|
+
startAdPlayback("HLS ad playback");
|
|
1062
1259
|
});
|
|
1063
1260
|
adHls.on(import_hls.default.Events.ERROR, function(_event, data) {
|
|
1064
1261
|
console.error("[HlsAdPlayer] HLS error:", data);
|
|
@@ -1068,10 +1265,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1068
1265
|
});
|
|
1069
1266
|
} else if (isHlsAd && adVideoElement.canPlayType("application/vnd.apple.mpegurl")) {
|
|
1070
1267
|
adVideoElement.src = mediaFile.url;
|
|
1071
|
-
|
|
1072
|
-
console.error("[HlsAdPlayer] Error starting ad playback:", error);
|
|
1073
|
-
handleAdError();
|
|
1074
|
-
});
|
|
1268
|
+
startAdPlayback("native HLS ad playback");
|
|
1075
1269
|
} else if (!isHlsAd && isProgressiveMediaFile(mediaFile)) {
|
|
1076
1270
|
if (adHls) {
|
|
1077
1271
|
adHls.destroy();
|
|
@@ -1079,10 +1273,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1079
1273
|
}
|
|
1080
1274
|
adVideoElement.src = mediaFile.url;
|
|
1081
1275
|
adVideoElement.load();
|
|
1082
|
-
|
|
1083
|
-
console.error("[HlsAdPlayer] Error starting progressive ad playback:", error);
|
|
1084
|
-
handleAdError();
|
|
1085
|
-
});
|
|
1276
|
+
startAdPlayback("progressive ad playback");
|
|
1086
1277
|
} else {
|
|
1087
1278
|
throw new Error("Unsupported ad media file type: ".concat(mediaFile.type));
|
|
1088
1279
|
}
|
|
@@ -1099,6 +1290,13 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1099
1290
|
trackingFired.impression = true;
|
|
1100
1291
|
console.log("[HlsAdPlayer] Advancing to next pod ad (".concat(podIndex + 1, "/").concat(podAds.length, "): ").concat(currentAd.title, ", duration: ").concat(currentAd.duration, "s"));
|
|
1101
1292
|
}
|
|
1293
|
+
clearStallWatchdog();
|
|
1294
|
+
if (requiresMediaPipelineResetAfterAds()) {
|
|
1295
|
+
recreateAdVideoElement();
|
|
1296
|
+
setupAdEventListeners();
|
|
1297
|
+
} else {
|
|
1298
|
+
prepareVideoElementForNewSource();
|
|
1299
|
+
}
|
|
1102
1300
|
try {
|
|
1103
1301
|
loadCurrentAdMedia();
|
|
1104
1302
|
emit("pod_ad_started", {
|
|
@@ -1158,6 +1356,12 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1158
1356
|
function markFrameCounterReliable() {
|
|
1159
1357
|
contentVideo[FRAME_COUNTER_RELIABLE_PROP] = true;
|
|
1160
1358
|
}
|
|
1359
|
+
function isRvfcReliable() {
|
|
1360
|
+
return contentVideo[RVFC_RELIABLE_PROP] === true;
|
|
1361
|
+
}
|
|
1362
|
+
function markRvfcReliable() {
|
|
1363
|
+
contentVideo[RVFC_RELIABLE_PROP] = true;
|
|
1364
|
+
}
|
|
1161
1365
|
function cancelVideoFrameProbe() {
|
|
1162
1366
|
if (videoFrameCallbackHandle != null && adVideoElement && typeof adVideoElement.cancelVideoFrameCallback === "function") {
|
|
1163
1367
|
try {
|
|
@@ -1177,6 +1381,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1177
1381
|
videoFrameCallbackHandle = void 0;
|
|
1178
1382
|
if (!adPlaying) return;
|
|
1179
1383
|
sawDecodedVideoFrame = true;
|
|
1384
|
+
markRvfcReliable();
|
|
1180
1385
|
};
|
|
1181
1386
|
try {
|
|
1182
1387
|
videoFrameCallbackHandle = rvfc.call(adVideoElement, onPresentedFrame);
|
|
@@ -1201,18 +1406,26 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1201
1406
|
noteAdProgress();
|
|
1202
1407
|
sawDecodedVideoFrame = false;
|
|
1203
1408
|
startVideoFrameProbe();
|
|
1409
|
+
var blackFrameDetectionEnabled = !requiresMediaPipelineResetAfterAds();
|
|
1204
1410
|
stallWatchdogId = window.setInterval(function() {
|
|
1205
1411
|
if (!adPlaying || !adVideoElement) {
|
|
1206
1412
|
return;
|
|
1207
1413
|
}
|
|
1208
|
-
if (!sawDecodedVideoFrame && !adVideoElement.paused) {
|
|
1414
|
+
if (blackFrameDetectionEnabled && !sawDecodedVideoFrame && !adVideoElement.paused) {
|
|
1209
1415
|
var decodedFrames = getDecodedVideoFrameCount(adVideoElement);
|
|
1210
1416
|
if (decodedFrames !== void 0 && decodedFrames > 0) {
|
|
1211
1417
|
sawDecodedVideoFrame = true;
|
|
1212
1418
|
markFrameCounterReliable();
|
|
1213
|
-
} else if (
|
|
1214
|
-
|
|
1215
|
-
|
|
1419
|
+
} else if (adVideoElement.currentTime >= BLACKFRAME_MIN_PLAYBACK_S) {
|
|
1420
|
+
var timeAdvancing = adVideoElement.currentTime > lastAdProgressPosition + 0.05;
|
|
1421
|
+
if (isRvfcSupported(adVideoElement) && timeAdvancing && isRvfcReliable()) {
|
|
1422
|
+
handleVideoDecodeFailure();
|
|
1423
|
+
return;
|
|
1424
|
+
}
|
|
1425
|
+
if (decodedFrames === 0 && timeAdvancing && isFrameCounterReliable()) {
|
|
1426
|
+
handleVideoDecodeFailure();
|
|
1427
|
+
return;
|
|
1428
|
+
}
|
|
1216
1429
|
}
|
|
1217
1430
|
}
|
|
1218
1431
|
if (adVideoElement.currentTime > lastAdProgressPosition + 0.05) {
|
|
@@ -1229,19 +1442,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1229
1442
|
}, STALL_CHECK_INTERVAL_MS);
|
|
1230
1443
|
}
|
|
1231
1444
|
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
|
-
}
|
|
1445
|
+
prepareVideoElementForNewSource();
|
|
1245
1446
|
if (adContainerEl) {
|
|
1246
1447
|
adContainerEl.style.display = "none";
|
|
1247
1448
|
adContainerEl.style.pointerEvents = "none";
|
|
@@ -1618,7 +1819,7 @@ function createHlsAdPlayer(contentVideo, options) {
|
|
|
1618
1819
|
}
|
|
1619
1820
|
},
|
|
1620
1821
|
hidePlaceholder: function hidePlaceholder() {
|
|
1621
|
-
if (adContainerEl) {
|
|
1822
|
+
if (adContainerEl && !adPlaying) {
|
|
1622
1823
|
adContainerEl.style.display = "none";
|
|
1623
1824
|
adContainerEl.style.pointerEvents = "none";
|
|
1624
1825
|
}
|