stormcloud-video-player 0.8.21 → 0.8.23
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 +140 -28
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +140 -28
- package/lib/index.js.map +1 -1
- package/lib/player/AdBreakOrchestrator.cjs +7 -0
- package/lib/player/AdBreakOrchestrator.cjs.map +1 -1
- package/lib/player/AdBreakOrchestrator.d.cts +1 -0
- package/lib/player/AdConfigManager.cjs +95 -14
- package/lib/player/AdConfigManager.cjs.map +1 -1
- package/lib/player/HlsEngine.cjs +12 -3
- package/lib/player/HlsEngine.cjs.map +1 -1
- package/lib/player/HlsEngine.d.cts +1 -0
- package/lib/player/StormcloudVideoPlayer.cjs +136 -27
- package/lib/player/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/players/HlsPlayer.cjs +137 -27
- package/lib/players/HlsPlayer.cjs.map +1 -1
- package/lib/players/index.cjs +137 -27
- package/lib/players/index.cjs.map +1 -1
- package/lib/ui/StormcloudVideoPlayer.cjs +138 -28
- package/lib/ui/StormcloudVideoPlayer.cjs.map +1 -1
- package/lib/utils/ctvVastSignals.cjs +88 -7
- package/lib/utils/ctvVastSignals.cjs.map +1 -1
- package/lib/utils/vastEnvironmentSignals.cjs +88 -7
- package/lib/utils/vastEnvironmentSignals.cjs.map +1 -1
- package/lib/utils/vastMacros.cjs.map +1 -1
- package/package.json +1 -1
|
@@ -2331,6 +2331,18 @@ var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
|
|
|
2331
2331
|
var AIRY_APP_NAME = "AiryTV Movies & TV";
|
|
2332
2332
|
var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
|
|
2333
2333
|
var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
|
|
2334
|
+
var LG_TEST_APP_ID = "com.hulu.plus";
|
|
2335
|
+
var LG_TEST_APP_NAME = "Hulu";
|
|
2336
|
+
var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
|
|
2337
|
+
var _lgTestDeviceId;
|
|
2338
|
+
function getLgTestDeviceId() {
|
|
2339
|
+
if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
|
|
2340
|
+
return _lgTestDeviceId;
|
|
2341
|
+
}
|
|
2342
|
+
function isLgWebOS() {
|
|
2343
|
+
if (typeof navigator === "undefined") return false;
|
|
2344
|
+
return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
|
|
2345
|
+
}
|
|
2334
2346
|
function getDefaultAppId() {
|
|
2335
2347
|
if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
|
|
2336
2348
|
var ua = navigator.userAgent;
|
|
@@ -2356,17 +2368,20 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
|
|
|
2356
2368
|
"adid"
|
|
2357
2369
|
]);
|
|
2358
2370
|
function resolveVastEnvironmentSignals(isCtv) {
|
|
2359
|
-
var _ref
|
|
2371
|
+
var _ref;
|
|
2360
2372
|
var bridgeSignals = readNativeBridgeSignals();
|
|
2361
|
-
var
|
|
2362
|
-
var
|
|
2363
|
-
var
|
|
2373
|
+
var platformDevice = readPlatformNativeDeviceId();
|
|
2374
|
+
var lg = isCtv && isLgWebOS();
|
|
2375
|
+
var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
|
|
2376
|
+
var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
|
|
2377
|
+
var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
|
|
2378
|
+
var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
|
|
2364
2379
|
if (isCtv) {
|
|
2365
2380
|
return _object_spread_props(_object_spread({
|
|
2366
2381
|
isCtv: true,
|
|
2367
|
-
contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || AIRY_DEFAULT_CONTENT_URL,
|
|
2368
|
-
appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || getDefaultAppId(),
|
|
2369
|
-
appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || AIRY_APP_NAME,
|
|
2382
|
+
contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
|
|
2383
|
+
appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
|
|
2384
|
+
appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
|
|
2370
2385
|
sessionId: getOrCreateCtvSessionId()
|
|
2371
2386
|
}, deviceId ? {
|
|
2372
2387
|
deviceId: deviceId
|
|
@@ -2431,6 +2446,72 @@ function createUuid() {
|
|
|
2431
2446
|
return nibble.toString(16);
|
|
2432
2447
|
});
|
|
2433
2448
|
}
|
|
2449
|
+
function readPlatformNativeDeviceId() {
|
|
2450
|
+
if (typeof window === "undefined") return {};
|
|
2451
|
+
try {
|
|
2452
|
+
var _window_webapis;
|
|
2453
|
+
var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
|
|
2454
|
+
if (adinfo) {
|
|
2455
|
+
var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
|
|
2456
|
+
if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
|
|
2457
|
+
var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
|
|
2458
|
+
return _object_spread({
|
|
2459
|
+
deviceId: tifa,
|
|
2460
|
+
deviceIdType: "tifa"
|
|
2461
|
+
}, typeof lat === "boolean" ? {
|
|
2462
|
+
limitAdTracking: lat
|
|
2463
|
+
} : {});
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2466
|
+
} catch (unused) {}
|
|
2467
|
+
try {
|
|
2468
|
+
var webOSDev = window.webOSDev;
|
|
2469
|
+
if (webOSDev) {
|
|
2470
|
+
var _webOSDev_lgudid;
|
|
2471
|
+
var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
|
|
2472
|
+
if (typeof lgudid === "string" && lgudid) {
|
|
2473
|
+
if (isZeroedAdId(lgudid)) {
|
|
2474
|
+
return {
|
|
2475
|
+
deviceIdType: "lgudid",
|
|
2476
|
+
limitAdTracking: true
|
|
2477
|
+
};
|
|
2478
|
+
}
|
|
2479
|
+
if (!isMacroPlaceholder(lgudid)) {
|
|
2480
|
+
return {
|
|
2481
|
+
deviceId: lgudid,
|
|
2482
|
+
deviceIdType: "lgudid",
|
|
2483
|
+
limitAdTracking: false
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
} catch (unused) {}
|
|
2489
|
+
try {
|
|
2490
|
+
var roku = window.Roku;
|
|
2491
|
+
if (roku) {
|
|
2492
|
+
var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
|
|
2493
|
+
if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
|
|
2494
|
+
return {
|
|
2495
|
+
deviceId: rida,
|
|
2496
|
+
deviceIdType: "rida",
|
|
2497
|
+
limitAdTracking: false
|
|
2498
|
+
};
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
} catch (unused) {}
|
|
2502
|
+
return {};
|
|
2503
|
+
}
|
|
2504
|
+
var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
|
|
2505
|
+
"38400000-8cf0-11bd-b23e-10b96e40000d",
|
|
2506
|
+
"00000000-0000-0000-0000-000000000000"
|
|
2507
|
+
]);
|
|
2508
|
+
function isMacroPlaceholder(value) {
|
|
2509
|
+
var t = value.trim();
|
|
2510
|
+
return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
|
|
2511
|
+
}
|
|
2512
|
+
function isZeroedAdId(value) {
|
|
2513
|
+
return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
|
|
2514
|
+
}
|
|
2434
2515
|
function readNativeBridgeSignals() {
|
|
2435
2516
|
if (typeof window === "undefined") {
|
|
2436
2517
|
return {};
|
|
@@ -2771,7 +2852,7 @@ var INLINE_DEVICE_MACRO_REPLACEMENTS = [
|
|
|
2771
2852
|
}
|
|
2772
2853
|
}
|
|
2773
2854
|
];
|
|
2774
|
-
function
|
|
2855
|
+
function isMacroPlaceholder2(value) {
|
|
2775
2856
|
if (value == null) return true;
|
|
2776
2857
|
var trimmed = value.trim();
|
|
2777
2858
|
if (!trimmed) return true;
|
|
@@ -2830,11 +2911,11 @@ function applyDeviceIdentityParams(params, ctx) {
|
|
|
2830
2911
|
if (runtimeId) {
|
|
2831
2912
|
params.set("rdid", runtimeId);
|
|
2832
2913
|
params.set("idtype", runtimeType || tagType || "aaid");
|
|
2833
|
-
params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue :
|
|
2914
|
+
params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : isMacroPlaceholder2(tagLat) ? "0" : tagLat);
|
|
2834
2915
|
return;
|
|
2835
2916
|
}
|
|
2836
|
-
var tagRdidValid = Boolean(tagRdid && !
|
|
2837
|
-
var tagTypeValid = Boolean(tagType && !
|
|
2917
|
+
var tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));
|
|
2918
|
+
var tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));
|
|
2838
2919
|
if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {
|
|
2839
2920
|
params.delete("rdid");
|
|
2840
2921
|
params.delete("idtype");
|
|
@@ -2842,10 +2923,10 @@ function applyDeviceIdentityParams(params, ctx) {
|
|
|
2842
2923
|
return;
|
|
2843
2924
|
}
|
|
2844
2925
|
if (tagRdidValid) {
|
|
2845
|
-
if (
|
|
2926
|
+
if (isMacroPlaceholder2(tagType) && runtimeType) {
|
|
2846
2927
|
params.set("idtype", runtimeType);
|
|
2847
2928
|
}
|
|
2848
|
-
if (
|
|
2929
|
+
if (isMacroPlaceholder2(tagLat)) {
|
|
2849
2930
|
params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : "0");
|
|
2850
2931
|
}
|
|
2851
2932
|
return;
|
|
@@ -3031,7 +3112,7 @@ function applyVastMacros(baseUrl, ctx) {
|
|
|
3031
3112
|
}
|
|
3032
3113
|
var staleKeys = [];
|
|
3033
3114
|
params.forEach(function(value, key) {
|
|
3034
|
-
if (
|
|
3115
|
+
if (isMacroPlaceholder2(value)) {
|
|
3035
3116
|
staleKeys.push(key);
|
|
3036
3117
|
}
|
|
3037
3118
|
});
|
|
@@ -5980,7 +6061,7 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
5980
6061
|
key: "setupNativeHls",
|
|
5981
6062
|
value: function setupNativeHls() {
|
|
5982
6063
|
return _async_to_generator(function() {
|
|
5983
|
-
var _this_config_isLiveStream, _this_config_lowLatencyMode, _this_video_play;
|
|
6064
|
+
var _this_config_isLiveStream, _this_config_lowLatencyMode, adBehavior, _this_video_play;
|
|
5984
6065
|
return _ts_generator(this, function(_state) {
|
|
5985
6066
|
switch(_state.label){
|
|
5986
6067
|
case 0:
|
|
@@ -5989,10 +6070,11 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
5989
6070
|
this.video.src = this.config.src;
|
|
5990
6071
|
this.isLiveStream = (_this_config_isLiveStream = this.config.isLiveStream) !== null && _this_config_isLiveStream !== void 0 ? _this_config_isLiveStream : (_this_config_lowLatencyMode = this.config.lowLatencyMode) !== null && _this_config_lowLatencyMode !== void 0 ? _this_config_lowLatencyMode : false;
|
|
5991
6072
|
if (this.debug) {
|
|
5992
|
-
|
|
6073
|
+
adBehavior = this.isLiveStream ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
|
|
6074
|
+
console.log("[StormcloudVideoPlayer] Using native HLS playback:", {
|
|
5993
6075
|
isLive: this.isLiveStream,
|
|
5994
6076
|
allowNativeHls: this.config.allowNativeHls,
|
|
5995
|
-
adBehavior:
|
|
6077
|
+
adBehavior: adBehavior
|
|
5996
6078
|
});
|
|
5997
6079
|
}
|
|
5998
6080
|
if (!this.config.autoplay) return [
|
|
@@ -6401,6 +6483,14 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
6401
6483
|
});
|
|
6402
6484
|
}
|
|
6403
6485
|
},
|
|
6486
|
+
{
|
|
6487
|
+
key: "getLiveSyncPosition",
|
|
6488
|
+
value: function getLiveSyncPosition() {
|
|
6489
|
+
var _this_hls;
|
|
6490
|
+
var pos = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.liveSyncPosition;
|
|
6491
|
+
return typeof pos === "number" && Number.isFinite(pos) ? pos : void 0;
|
|
6492
|
+
}
|
|
6493
|
+
},
|
|
6404
6494
|
{
|
|
6405
6495
|
key: "destroy",
|
|
6406
6496
|
value: function destroy() {
|
|
@@ -7975,6 +8065,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
7975
8065
|
this.host.video.volume = restoredVolume;
|
|
7976
8066
|
}
|
|
7977
8067
|
if (this.host.shouldContinueLiveStreamDuringAds()) {
|
|
8068
|
+
var liveSyncPos = this.host.getLiveSyncPosition();
|
|
8069
|
+
if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
|
|
8070
|
+
if (this.debug) {
|
|
8071
|
+
console.log("[StormcloudVideoPlayer] Live break end — snapping to live edge: ".concat(this.host.video.currentTime.toFixed(2), "s → ").concat(liveSyncPos.toFixed(2), "s"));
|
|
8072
|
+
}
|
|
8073
|
+
this.host.video.currentTime = liveSyncPos;
|
|
8074
|
+
}
|
|
7978
8075
|
if (this.host.video.paused) {
|
|
7979
8076
|
var _this_host_video_play;
|
|
7980
8077
|
if (this.debug) console.log("[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback");
|
|
@@ -8117,6 +8214,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8117
8214
|
shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
|
|
8118
8215
|
return _this.shouldContinueLiveStreamDuringAds();
|
|
8119
8216
|
},
|
|
8217
|
+
getLiveSyncPosition: function getLiveSyncPosition() {
|
|
8218
|
+
return _this.hlsEngine.getLiveSyncPosition();
|
|
8219
|
+
},
|
|
8120
8220
|
generateVastUrls: function generateVastUrls(base, count) {
|
|
8121
8221
|
return _this.generateVastUrls(base, count);
|
|
8122
8222
|
}
|
|
@@ -8158,7 +8258,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8158
8258
|
// ───────────────────────────────────────────────────────────────
|
|
8159
8259
|
function load() {
|
|
8160
8260
|
return _async_to_generator(function() {
|
|
8161
|
-
var _this, _this_config_lowLatencyMode, error;
|
|
8261
|
+
var _this, _this_config_lowLatencyMode, error, continueLiveStreamDuringAds;
|
|
8162
8262
|
return _ts_generator(this, function(_state) {
|
|
8163
8263
|
switch(_state.label){
|
|
8164
8264
|
case 0:
|
|
@@ -8212,15 +8312,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8212
8312
|
3,
|
|
8213
8313
|
6
|
|
8214
8314
|
];
|
|
8215
|
-
this.adPlayer.destroy();
|
|
8216
|
-
this.adPlayer = this.createAdPlayer(false);
|
|
8217
|
-
this.adPlayer.initialize();
|
|
8218
8315
|
return [
|
|
8219
8316
|
4,
|
|
8220
8317
|
this.hlsEngine.setupNativeHls()
|
|
8221
8318
|
];
|
|
8222
8319
|
case 5:
|
|
8223
8320
|
_state.sent();
|
|
8321
|
+
continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();
|
|
8322
|
+
if (this.debug) {
|
|
8323
|
+
console.log("[StormcloudVideoPlayer] Native HLS ad behavior:", {
|
|
8324
|
+
isLive: this.hlsEngine.isLiveStream,
|
|
8325
|
+
continueLiveStreamDuringAds: continueLiveStreamDuringAds
|
|
8326
|
+
});
|
|
8327
|
+
}
|
|
8328
|
+
this.adPlayer.destroy();
|
|
8329
|
+
this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);
|
|
8330
|
+
this.adPlayer.initialize();
|
|
8224
8331
|
return [
|
|
8225
8332
|
2
|
|
8226
8333
|
];
|
|
@@ -8328,9 +8435,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8328
8435
|
{
|
|
8329
8436
|
key: "shouldContinueLiveStreamDuringAds",
|
|
8330
8437
|
value: function shouldContinueLiveStreamDuringAds() {
|
|
8331
|
-
if (this.
|
|
8332
|
-
|
|
8333
|
-
|
|
8438
|
+
if (this.hlsEngine.isLiveStream) {
|
|
8439
|
+
return true;
|
|
8440
|
+
}
|
|
8441
|
+
var duration = this.video.duration;
|
|
8442
|
+
if (!Number.isFinite(duration) || duration === Infinity) {
|
|
8443
|
+
return true;
|
|
8444
|
+
}
|
|
8445
|
+
return false;
|
|
8334
8446
|
}
|
|
8335
8447
|
},
|
|
8336
8448
|
{
|
|
@@ -8628,9 +8740,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8628
8740
|
this.adBreak.showAds = true;
|
|
8629
8741
|
this.adBreak.inAdBreak = true;
|
|
8630
8742
|
this.timing.currentAdBreakStartWallClockMs = Date.now();
|
|
8631
|
-
if (!this.video.paused) {
|
|
8632
|
-
this.video.pause();
|
|
8633
|
-
}
|
|
8634
8743
|
_state.label = 1;
|
|
8635
8744
|
case 1:
|
|
8636
8745
|
_state.trys.push([
|
|
@@ -8891,6 +9000,7 @@ var HlsPlayer = /*#__PURE__*/ function(_import_react_Component) {
|
|
|
8891
9000
|
if (_this1.props.muted !== void 0) config.muted = _this1.props.muted;
|
|
8892
9001
|
if (_this1.props.lowLatencyMode !== void 0) config.lowLatencyMode = _this1.props.lowLatencyMode;
|
|
8893
9002
|
if (_this1.props.allowNativeHls !== void 0) config.allowNativeHls = _this1.props.allowNativeHls;
|
|
9003
|
+
if (_this1.props.isLiveStream !== void 0) config.isLiveStream = _this1.props.isLiveStream;
|
|
8894
9004
|
if (_this1.props.driftToleranceMs !== void 0) config.driftToleranceMs = _this1.props.driftToleranceMs;
|
|
8895
9005
|
if (_this1.props.immediateManifestAds !== void 0) config.immediateManifestAds = _this1.props.immediateManifestAds;
|
|
8896
9006
|
if (_this1.props.debugAdTiming !== void 0) config.debugAdTiming = _this1.props.debugAdTiming;
|