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
package/lib/players/index.cjs
CHANGED
|
@@ -2367,6 +2367,18 @@ var AIRY_ROKU_APP_ID = "com.freeairytv.roku";
|
|
|
2367
2367
|
var AIRY_APP_NAME = "AiryTV Movies & TV";
|
|
2368
2368
|
var AIRY_DEFAULT_CONTENT_URL = "https://live.airy.tv";
|
|
2369
2369
|
var CTV_SESSION_STORAGE_KEY = "stormcloud.ctv.sid";
|
|
2370
|
+
var LG_TEST_APP_ID = "com.hulu.plus";
|
|
2371
|
+
var LG_TEST_APP_NAME = "Hulu";
|
|
2372
|
+
var LG_TEST_CONTENT_URL = "https://www.hulu.com/live-tv";
|
|
2373
|
+
var _lgTestDeviceId;
|
|
2374
|
+
function getLgTestDeviceId() {
|
|
2375
|
+
if (!_lgTestDeviceId) _lgTestDeviceId = createUuid();
|
|
2376
|
+
return _lgTestDeviceId;
|
|
2377
|
+
}
|
|
2378
|
+
function isLgWebOS() {
|
|
2379
|
+
if (typeof navigator === "undefined") return false;
|
|
2380
|
+
return /Web0S|webOS|LG Browser|LGSTB|LGE/i.test(navigator.userAgent);
|
|
2381
|
+
}
|
|
2370
2382
|
function getDefaultAppId() {
|
|
2371
2383
|
if (typeof navigator === "undefined") return AIRY_ANDROID_APP_ID;
|
|
2372
2384
|
var ua = navigator.userAgent;
|
|
@@ -2392,17 +2404,20 @@ var ANDROID_ID_TYPES = /* @__PURE__ */ new Set([
|
|
|
2392
2404
|
"adid"
|
|
2393
2405
|
]);
|
|
2394
2406
|
function resolveVastEnvironmentSignals(isCtv) {
|
|
2395
|
-
var _ref
|
|
2407
|
+
var _ref;
|
|
2396
2408
|
var bridgeSignals = readNativeBridgeSignals();
|
|
2397
|
-
var
|
|
2398
|
-
var
|
|
2399
|
-
var
|
|
2409
|
+
var platformDevice = readPlatformNativeDeviceId();
|
|
2410
|
+
var lg = isCtv && isLgWebOS();
|
|
2411
|
+
var deviceId = bridgeSignals.deviceId || readStoredDeviceId() || platformDevice.deviceId || (lg && platformDevice.limitAdTracking !== true ? getLgTestDeviceId() : void 0);
|
|
2412
|
+
var deviceIdType = bridgeSignals.deviceIdType || readStoredString("deviceIdType") || readStoredString("idtype") || platformDevice.deviceIdType || inferDeviceIdType() || (lg ? "lgudid" : void 0);
|
|
2413
|
+
var platformLat = bridgeSignals.deviceId ? bridgeSignals.limitAdTracking : platformDevice.limitAdTracking;
|
|
2414
|
+
var limitAdTracking = deviceId != null ? (_ref = platformLat !== null && platformLat !== void 0 ? platformLat : readStoredLimitAdTracking()) !== null && _ref !== void 0 ? _ref : false : void 0;
|
|
2400
2415
|
if (isCtv) {
|
|
2401
2416
|
return _object_spread_props(_object_spread({
|
|
2402
2417
|
isCtv: true,
|
|
2403
|
-
contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || AIRY_DEFAULT_CONTENT_URL,
|
|
2404
|
-
appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || getDefaultAppId(),
|
|
2405
|
-
appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || AIRY_APP_NAME,
|
|
2418
|
+
contentUrl: bridgeSignals.contentUrl || readStoredString("contentUrl") || (lg ? LG_TEST_CONTENT_URL : AIRY_DEFAULT_CONTENT_URL),
|
|
2419
|
+
appId: bridgeSignals.appId || readStoredString("appId") || readStoredString("msid") || (lg ? LG_TEST_APP_ID : getDefaultAppId()),
|
|
2420
|
+
appName: bridgeSignals.appName || readStoredString("appName") || readStoredString("an") || (lg ? LG_TEST_APP_NAME : AIRY_APP_NAME),
|
|
2406
2421
|
sessionId: getOrCreateCtvSessionId()
|
|
2407
2422
|
}, deviceId ? {
|
|
2408
2423
|
deviceId: deviceId
|
|
@@ -2467,6 +2482,72 @@ function createUuid() {
|
|
|
2467
2482
|
return nibble.toString(16);
|
|
2468
2483
|
});
|
|
2469
2484
|
}
|
|
2485
|
+
function readPlatformNativeDeviceId() {
|
|
2486
|
+
if (typeof window === "undefined") return {};
|
|
2487
|
+
try {
|
|
2488
|
+
var _window_webapis;
|
|
2489
|
+
var adinfo = (_window_webapis = window.webapis) === null || _window_webapis === void 0 ? void 0 : _window_webapis.adinfo;
|
|
2490
|
+
if (adinfo) {
|
|
2491
|
+
var tifa = typeof adinfo.getTIFA === "function" ? adinfo.getTIFA() : adinfo.tifa;
|
|
2492
|
+
if (typeof tifa === "string" && tifa && !isMacroPlaceholder(tifa)) {
|
|
2493
|
+
var lat = typeof adinfo.isLATEnabled === "function" ? adinfo.isLATEnabled() : void 0;
|
|
2494
|
+
return _object_spread({
|
|
2495
|
+
deviceId: tifa,
|
|
2496
|
+
deviceIdType: "tifa"
|
|
2497
|
+
}, typeof lat === "boolean" ? {
|
|
2498
|
+
limitAdTracking: lat
|
|
2499
|
+
} : {});
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
} catch (unused) {}
|
|
2503
|
+
try {
|
|
2504
|
+
var webOSDev = window.webOSDev;
|
|
2505
|
+
if (webOSDev) {
|
|
2506
|
+
var _webOSDev_lgudid;
|
|
2507
|
+
var lgudid = typeof webOSDev.LGUDID === "function" ? webOSDev.LGUDID() : (_webOSDev_lgudid = webOSDev.lgudid) !== null && _webOSDev_lgudid !== void 0 ? _webOSDev_lgudid : webOSDev.LGUDID;
|
|
2508
|
+
if (typeof lgudid === "string" && lgudid) {
|
|
2509
|
+
if (isZeroedAdId(lgudid)) {
|
|
2510
|
+
return {
|
|
2511
|
+
deviceIdType: "lgudid",
|
|
2512
|
+
limitAdTracking: true
|
|
2513
|
+
};
|
|
2514
|
+
}
|
|
2515
|
+
if (!isMacroPlaceholder(lgudid)) {
|
|
2516
|
+
return {
|
|
2517
|
+
deviceId: lgudid,
|
|
2518
|
+
deviceIdType: "lgudid",
|
|
2519
|
+
limitAdTracking: false
|
|
2520
|
+
};
|
|
2521
|
+
}
|
|
2522
|
+
}
|
|
2523
|
+
}
|
|
2524
|
+
} catch (unused) {}
|
|
2525
|
+
try {
|
|
2526
|
+
var roku = window.Roku;
|
|
2527
|
+
if (roku) {
|
|
2528
|
+
var rida = typeof roku.getPublisherUniqueId === "function" ? roku.getPublisherUniqueId() : roku.rida;
|
|
2529
|
+
if (typeof rida === "string" && rida && !isMacroPlaceholder(rida)) {
|
|
2530
|
+
return {
|
|
2531
|
+
deviceId: rida,
|
|
2532
|
+
deviceIdType: "rida",
|
|
2533
|
+
limitAdTracking: false
|
|
2534
|
+
};
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
} catch (unused) {}
|
|
2538
|
+
return {};
|
|
2539
|
+
}
|
|
2540
|
+
var ZEROED_AD_ID_PATTERNS = /* @__PURE__ */ new Set([
|
|
2541
|
+
"38400000-8cf0-11bd-b23e-10b96e40000d",
|
|
2542
|
+
"00000000-0000-0000-0000-000000000000"
|
|
2543
|
+
]);
|
|
2544
|
+
function isMacroPlaceholder(value) {
|
|
2545
|
+
var t = value.trim();
|
|
2546
|
+
return !t || /^(\[[^\]]*\]|\{[^}]*\}|%%[^%]*%%)$/.test(t) || /^(unknown|null|undefined|none|n\/a|\$\{[^}]+\})$/i.test(t) || ZEROED_AD_ID_PATTERNS.has(t.toLowerCase());
|
|
2547
|
+
}
|
|
2548
|
+
function isZeroedAdId(value) {
|
|
2549
|
+
return ZEROED_AD_ID_PATTERNS.has(value.trim().toLowerCase());
|
|
2550
|
+
}
|
|
2470
2551
|
function readNativeBridgeSignals() {
|
|
2471
2552
|
if (typeof window === "undefined") {
|
|
2472
2553
|
return {};
|
|
@@ -2807,7 +2888,7 @@ var INLINE_DEVICE_MACRO_REPLACEMENTS = [
|
|
|
2807
2888
|
}
|
|
2808
2889
|
}
|
|
2809
2890
|
];
|
|
2810
|
-
function
|
|
2891
|
+
function isMacroPlaceholder2(value) {
|
|
2811
2892
|
if (value == null) return true;
|
|
2812
2893
|
var trimmed = value.trim();
|
|
2813
2894
|
if (!trimmed) return true;
|
|
@@ -2866,11 +2947,11 @@ function applyDeviceIdentityParams(params, ctx) {
|
|
|
2866
2947
|
if (runtimeId) {
|
|
2867
2948
|
params.set("rdid", runtimeId);
|
|
2868
2949
|
params.set("idtype", runtimeType || tagType || "aaid");
|
|
2869
|
-
params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue :
|
|
2950
|
+
params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : isMacroPlaceholder2(tagLat) ? "0" : tagLat);
|
|
2870
2951
|
return;
|
|
2871
2952
|
}
|
|
2872
|
-
var tagRdidValid = Boolean(tagRdid && !
|
|
2873
|
-
var tagTypeValid = Boolean(tagType && !
|
|
2953
|
+
var tagRdidValid = Boolean(tagRdid && !isMacroPlaceholder2(tagRdid));
|
|
2954
|
+
var tagTypeValid = Boolean(tagType && !isMacroPlaceholder2(tagType));
|
|
2874
2955
|
if (tagRdidValid && tagTypeValid && runtimeType && !isEquivalentDeviceIdType(tagType, runtimeType)) {
|
|
2875
2956
|
params.delete("rdid");
|
|
2876
2957
|
params.delete("idtype");
|
|
@@ -2878,10 +2959,10 @@ function applyDeviceIdentityParams(params, ctx) {
|
|
|
2878
2959
|
return;
|
|
2879
2960
|
}
|
|
2880
2961
|
if (tagRdidValid) {
|
|
2881
|
-
if (
|
|
2962
|
+
if (isMacroPlaceholder2(tagType) && runtimeType) {
|
|
2882
2963
|
params.set("idtype", runtimeType);
|
|
2883
2964
|
}
|
|
2884
|
-
if (
|
|
2965
|
+
if (isMacroPlaceholder2(tagLat)) {
|
|
2885
2966
|
params.set("is_lat", latValue !== null && latValue !== void 0 ? latValue : "0");
|
|
2886
2967
|
}
|
|
2887
2968
|
return;
|
|
@@ -3067,7 +3148,7 @@ function applyVastMacros(baseUrl, ctx) {
|
|
|
3067
3148
|
}
|
|
3068
3149
|
var staleKeys = [];
|
|
3069
3150
|
params.forEach(function(value, key) {
|
|
3070
|
-
if (
|
|
3151
|
+
if (isMacroPlaceholder2(value)) {
|
|
3071
3152
|
staleKeys.push(key);
|
|
3072
3153
|
}
|
|
3073
3154
|
});
|
|
@@ -6016,7 +6097,7 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
6016
6097
|
key: "setupNativeHls",
|
|
6017
6098
|
value: function setupNativeHls() {
|
|
6018
6099
|
return _async_to_generator(function() {
|
|
6019
|
-
var _this_config_isLiveStream, _this_config_lowLatencyMode, _this_video_play;
|
|
6100
|
+
var _this_config_isLiveStream, _this_config_lowLatencyMode, adBehavior, _this_video_play;
|
|
6020
6101
|
return _ts_generator(this, function(_state) {
|
|
6021
6102
|
switch(_state.label){
|
|
6022
6103
|
case 0:
|
|
@@ -6025,10 +6106,11 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
6025
6106
|
this.video.src = this.config.src;
|
|
6026
6107
|
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;
|
|
6027
6108
|
if (this.debug) {
|
|
6028
|
-
|
|
6109
|
+
adBehavior = this.isLiveStream ? "live (main video continues muted during ads)" : "vod (main video pauses during ads)";
|
|
6110
|
+
console.log("[StormcloudVideoPlayer] Using native HLS playback:", {
|
|
6029
6111
|
isLive: this.isLiveStream,
|
|
6030
6112
|
allowNativeHls: this.config.allowNativeHls,
|
|
6031
|
-
adBehavior:
|
|
6113
|
+
adBehavior: adBehavior
|
|
6032
6114
|
});
|
|
6033
6115
|
}
|
|
6034
6116
|
if (!this.config.autoplay) return [
|
|
@@ -6437,6 +6519,14 @@ var HlsEngine = /*#__PURE__*/ function() {
|
|
|
6437
6519
|
});
|
|
6438
6520
|
}
|
|
6439
6521
|
},
|
|
6522
|
+
{
|
|
6523
|
+
key: "getLiveSyncPosition",
|
|
6524
|
+
value: function getLiveSyncPosition() {
|
|
6525
|
+
var _this_hls;
|
|
6526
|
+
var pos = (_this_hls = this.hls) === null || _this_hls === void 0 ? void 0 : _this_hls.liveSyncPosition;
|
|
6527
|
+
return typeof pos === "number" && Number.isFinite(pos) ? pos : void 0;
|
|
6528
|
+
}
|
|
6529
|
+
},
|
|
6440
6530
|
{
|
|
6441
6531
|
key: "destroy",
|
|
6442
6532
|
value: function destroy() {
|
|
@@ -8011,6 +8101,13 @@ var AdBreakOrchestrator = /*#__PURE__*/ function() {
|
|
|
8011
8101
|
this.host.video.volume = restoredVolume;
|
|
8012
8102
|
}
|
|
8013
8103
|
if (this.host.shouldContinueLiveStreamDuringAds()) {
|
|
8104
|
+
var liveSyncPos = this.host.getLiveSyncPosition();
|
|
8105
|
+
if (liveSyncPos != null && liveSyncPos > this.host.video.currentTime) {
|
|
8106
|
+
if (this.debug) {
|
|
8107
|
+
console.log("[StormcloudVideoPlayer] Live break end — snapping to live edge: ".concat(this.host.video.currentTime.toFixed(2), "s → ").concat(liveSyncPos.toFixed(2), "s"));
|
|
8108
|
+
}
|
|
8109
|
+
this.host.video.currentTime = liveSyncPos;
|
|
8110
|
+
}
|
|
8014
8111
|
if (this.host.video.paused) {
|
|
8015
8112
|
var _this_host_video_play;
|
|
8016
8113
|
if (this.debug) console.log("[StormcloudVideoPlayer] Content video paused in live mode after ads, resuming playback");
|
|
@@ -8153,6 +8250,9 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8153
8250
|
shouldContinueLiveStreamDuringAds: function shouldContinueLiveStreamDuringAds() {
|
|
8154
8251
|
return _this.shouldContinueLiveStreamDuringAds();
|
|
8155
8252
|
},
|
|
8253
|
+
getLiveSyncPosition: function getLiveSyncPosition() {
|
|
8254
|
+
return _this.hlsEngine.getLiveSyncPosition();
|
|
8255
|
+
},
|
|
8156
8256
|
generateVastUrls: function generateVastUrls(base, count) {
|
|
8157
8257
|
return _this.generateVastUrls(base, count);
|
|
8158
8258
|
}
|
|
@@ -8194,7 +8294,7 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8194
8294
|
// ───────────────────────────────────────────────────────────────
|
|
8195
8295
|
function load() {
|
|
8196
8296
|
return _async_to_generator(function() {
|
|
8197
|
-
var _this, _this_config_lowLatencyMode, error;
|
|
8297
|
+
var _this, _this_config_lowLatencyMode, error, continueLiveStreamDuringAds;
|
|
8198
8298
|
return _ts_generator(this, function(_state) {
|
|
8199
8299
|
switch(_state.label){
|
|
8200
8300
|
case 0:
|
|
@@ -8248,15 +8348,22 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8248
8348
|
3,
|
|
8249
8349
|
6
|
|
8250
8350
|
];
|
|
8251
|
-
this.adPlayer.destroy();
|
|
8252
|
-
this.adPlayer = this.createAdPlayer(false);
|
|
8253
|
-
this.adPlayer.initialize();
|
|
8254
8351
|
return [
|
|
8255
8352
|
4,
|
|
8256
8353
|
this.hlsEngine.setupNativeHls()
|
|
8257
8354
|
];
|
|
8258
8355
|
case 5:
|
|
8259
8356
|
_state.sent();
|
|
8357
|
+
continueLiveStreamDuringAds = this.shouldContinueLiveStreamDuringAds();
|
|
8358
|
+
if (this.debug) {
|
|
8359
|
+
console.log("[StormcloudVideoPlayer] Native HLS ad behavior:", {
|
|
8360
|
+
isLive: this.hlsEngine.isLiveStream,
|
|
8361
|
+
continueLiveStreamDuringAds: continueLiveStreamDuringAds
|
|
8362
|
+
});
|
|
8363
|
+
}
|
|
8364
|
+
this.adPlayer.destroy();
|
|
8365
|
+
this.adPlayer = this.createAdPlayer(continueLiveStreamDuringAds);
|
|
8366
|
+
this.adPlayer.initialize();
|
|
8260
8367
|
return [
|
|
8261
8368
|
2
|
|
8262
8369
|
];
|
|
@@ -8364,9 +8471,14 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8364
8471
|
{
|
|
8365
8472
|
key: "shouldContinueLiveStreamDuringAds",
|
|
8366
8473
|
value: function shouldContinueLiveStreamDuringAds() {
|
|
8367
|
-
if (this.
|
|
8368
|
-
|
|
8369
|
-
|
|
8474
|
+
if (this.hlsEngine.isLiveStream) {
|
|
8475
|
+
return true;
|
|
8476
|
+
}
|
|
8477
|
+
var duration = this.video.duration;
|
|
8478
|
+
if (!Number.isFinite(duration) || duration === Infinity) {
|
|
8479
|
+
return true;
|
|
8480
|
+
}
|
|
8481
|
+
return false;
|
|
8370
8482
|
}
|
|
8371
8483
|
},
|
|
8372
8484
|
{
|
|
@@ -8664,9 +8776,6 @@ var StormcloudVideoPlayer = /*#__PURE__*/ function() {
|
|
|
8664
8776
|
this.adBreak.showAds = true;
|
|
8665
8777
|
this.adBreak.inAdBreak = true;
|
|
8666
8778
|
this.timing.currentAdBreakStartWallClockMs = Date.now();
|
|
8667
|
-
if (!this.video.paused) {
|
|
8668
|
-
this.video.pause();
|
|
8669
|
-
}
|
|
8670
8779
|
_state.label = 1;
|
|
8671
8780
|
case 1:
|
|
8672
8781
|
_state.trys.push([
|
|
@@ -8899,6 +9008,7 @@ var HlsPlayer = /*#__PURE__*/ function(_import_react2_Component) {
|
|
|
8899
9008
|
if (_this1.props.muted !== void 0) config.muted = _this1.props.muted;
|
|
8900
9009
|
if (_this1.props.lowLatencyMode !== void 0) config.lowLatencyMode = _this1.props.lowLatencyMode;
|
|
8901
9010
|
if (_this1.props.allowNativeHls !== void 0) config.allowNativeHls = _this1.props.allowNativeHls;
|
|
9011
|
+
if (_this1.props.isLiveStream !== void 0) config.isLiveStream = _this1.props.isLiveStream;
|
|
8902
9012
|
if (_this1.props.driftToleranceMs !== void 0) config.driftToleranceMs = _this1.props.driftToleranceMs;
|
|
8903
9013
|
if (_this1.props.immediateManifestAds !== void 0) config.immediateManifestAds = _this1.props.immediateManifestAds;
|
|
8904
9014
|
if (_this1.props.debugAdTiming !== void 0) config.debugAdTiming = _this1.props.debugAdTiming;
|