senza-sdk 4.2.63 → 4.2.64-70c0747.0
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/bundle.js +1 -1
- package/package.json +15 -7
- package/src/api.js +183 -350
- package/src/{alarmManager.js → implementation/alarmManager.js} +15 -52
- package/src/implementation/api.js +367 -0
- package/src/{deviceManager.js → implementation/deviceManager.js} +4 -65
- package/src/{lifecycle.js → implementation/lifecycle.js} +5 -181
- package/src/{messageManager.js → implementation/messageManager.js} +6 -6
- package/src/{platformManager.js → implementation/platformManager.js} +5 -4
- package/src/{remotePlayer.js → implementation/remotePlayer.js} +2 -1
- package/src/{senzaShakaPlayer.js → implementation/senzaShakaPlayer.js} +18 -28
- package/src/{utils.js → implementation/utils.js} +15 -6
- package/src/interface/alarmManager.js +69 -0
- package/src/interface/api.js +8 -0
- package/src/interface/deviceManager.js +133 -0
- package/src/interface/lifecycle.js +278 -0
- package/src/interface/messageManager.js +46 -0
- package/src/interface/platformManager.js +35 -0
- package/src/interface/remotePlayer.js +441 -0
- package/src/interface/senzaShakaPlayer.js +171 -0
- package/src/interface/utils.js +45 -0
- /package/src/{SessionInfo.js → implementation/SessionInfo.js} +0 -0
- /package/src/{devHelper.js → implementation/devHelper.js} +0 -0
- /package/src/{eventListenersManager.js → implementation/eventListenersManager.js} +0 -0
- /package/src/{subtitlesUtils.js → implementation/subtitlesUtils.js} +0 -0
- /package/src/{devSequence.js → interface/devSequence.js} +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Lifecycle as LifecycleInterface } from "../interface/lifecycle";
|
|
2
|
+
import { getPlatformInfo } from "./api";
|
|
3
|
+
import { alarmManager } from "./alarmManager";
|
|
2
4
|
import {
|
|
3
5
|
getFCID,
|
|
4
6
|
isAudioSyncConfigured,
|
|
@@ -24,76 +26,7 @@ const DEFAULT_AUTO_BACKGROUND_ENABLED = false;
|
|
|
24
26
|
* @fires userinactivity
|
|
25
27
|
* @fires userdisconnected
|
|
26
28
|
*/
|
|
27
|
-
class Lifecycle extends
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @typedef {Object} ConnectReason - The reason the ui app has been loaded
|
|
31
|
-
* @property {string} UNKNOWN
|
|
32
|
-
* @property {string} INITIAL_CONNECTION - Indicates that ui app has been loaded for the first time
|
|
33
|
-
* @property {string} APPLICATION_RELOAD - Indicates that ui app has been reloaded (e.g. after HOME keypress)
|
|
34
|
-
* @property {string} UI_RELEASE - Indicates that ui app has been reloaded after ui release
|
|
35
|
-
* @property {string} UI_TERMINATION - Indicates that ui app has been reloaded due to ui termination
|
|
36
|
-
* @property {string} WEBRTC_ERROR - Indicates that ui app has been reloaded due to webrtc error
|
|
37
|
-
* @property {string} UI_WATCHDOG - Indicates that ui app has been reloaded due to ui watchdog not receiving ui frames
|
|
38
|
-
*/
|
|
39
|
-
ConnectReason = Object.freeze({
|
|
40
|
-
UNKNOWN: "unknown",
|
|
41
|
-
INITIAL_CONNECTION: "initial_connection",
|
|
42
|
-
APPLICATION_RELOAD: "reload_app",
|
|
43
|
-
UI_RELEASE: "ui_release",
|
|
44
|
-
UI_TERMINATION: "ui_termination",
|
|
45
|
-
WEBRTC_ERROR: "webrtc_error",
|
|
46
|
-
UI_WATCHDOG: "ui_watchdog"
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @typedef {Object} UiState - The ui lifecycle state
|
|
51
|
-
* @property {string} UNKNOWN - state is unknown at this time
|
|
52
|
-
* @property {string} FOREGROUND - ui is displayed
|
|
53
|
-
* @property {string} IN_TRANSITION_TO_FOREGROUND - ui is about to be displayed
|
|
54
|
-
* @property {string} BACKGROUND - remote player is playing (full screen playback is displayed)
|
|
55
|
-
* @property {string} IN_TRANSITION_TO_BACKGROUND - remote player is about to be playing
|
|
56
|
-
*/
|
|
57
|
-
UiState = Object.freeze({
|
|
58
|
-
UNKNOWN: "unknown",
|
|
59
|
-
FOREGROUND: "foreground",
|
|
60
|
-
IN_TRANSITION_TO_FOREGROUND: "inTransitionToForeground",
|
|
61
|
-
BACKGROUND: "background",
|
|
62
|
-
IN_TRANSITION_TO_BACKGROUND: "inTransitionToBackground"
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @event Lifecycle#onstatechange
|
|
67
|
-
* @description Fired after transition from one state to another.<br>
|
|
68
|
-
* The flow is: foreground --> inTransitionToBackground --> background --> inTransitionToForeground --> foreground
|
|
69
|
-
* @property {UiState} state - Indicates the new state.
|
|
70
|
-
* @example
|
|
71
|
-
* lifecycle.addEventListener("onstatechange", (e) => {
|
|
72
|
-
* console.log("new state is", e.state);
|
|
73
|
-
* });
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @event Lifecycle#userinactivity
|
|
78
|
-
* @description Fired after the ui has been inactive (i.e. no key presses) for a configurable number of seconds.<br>
|
|
79
|
-
* @property {number} timeout - the number of seconds after which the application will be unloaded.
|
|
80
|
-
* @example
|
|
81
|
-
* lifecycle.addEventListener("userinactivity", (e) => {
|
|
82
|
-
* console.log(`Application will be unloaded in ${e.timeout} seconds`);
|
|
83
|
-
* });
|
|
84
|
-
* @alpha API has not yet been released
|
|
85
|
-
*/
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* @event Lifecycle#userdisconnected
|
|
89
|
-
* @description Fired when the user session ends .
|
|
90
|
-
* This event is useful for cleaning up application state or saving data before the application closes. Event callback should return promise to ensure that the event is handled before the application is terminated
|
|
91
|
-
* @example
|
|
92
|
-
* lifecycle.addEventListener("userdisconnected", () => {
|
|
93
|
-
* console.log("User session ended, cleaning up application state");
|
|
94
|
-
* // Perform any necessary cleanup here
|
|
95
|
-
* });
|
|
96
|
-
*/
|
|
29
|
+
class Lifecycle extends LifecycleInterface {
|
|
97
30
|
constructor() {
|
|
98
31
|
super();
|
|
99
32
|
|
|
@@ -305,15 +238,6 @@ class Lifecycle extends EventTarget {
|
|
|
305
238
|
return this._autoBackgroundOnUIDelay;
|
|
306
239
|
}
|
|
307
240
|
|
|
308
|
-
/**
|
|
309
|
-
* Configure lifecycle settings
|
|
310
|
-
* @param {Object} config - Configuration object
|
|
311
|
-
* @param {Object} [config.autoBackground] - Auto background settings
|
|
312
|
-
* @param {boolean} [config.autoBackground.enabled] - Enable/disable auto background
|
|
313
|
-
* @param {Object} [config.autoBackground.timeout] - Timeout settings
|
|
314
|
-
* @param {number|false} [config.autoBackground.timeout.playing=30] - Timeout in seconds when video is playing, false to disable
|
|
315
|
-
* @param {number|false} [config.autoBackground.timeout.idle=false] - Timeout in seconds when in UI mode, false to disable
|
|
316
|
-
*/
|
|
317
241
|
configure(config) {
|
|
318
242
|
if (config?.autoBackground) {
|
|
319
243
|
const { enabled, timeout } = config.autoBackground;
|
|
@@ -353,15 +277,6 @@ class Lifecycle extends EventTarget {
|
|
|
353
277
|
}
|
|
354
278
|
}
|
|
355
279
|
|
|
356
|
-
/**
|
|
357
|
-
* Get the current configuration settings
|
|
358
|
-
* @returns {Object} The current configuration object
|
|
359
|
-
* @example
|
|
360
|
-
* const config = lifecycle.getConfiguration();
|
|
361
|
-
* console.log(config.autoBackground.enabled); // true/false
|
|
362
|
-
* console.log(config.autoBackground.timeout.playing); // 30
|
|
363
|
-
* console.log(config.autoBackground.timeout.idle); // false
|
|
364
|
-
*/
|
|
365
280
|
getConfiguration() {
|
|
366
281
|
return {
|
|
367
282
|
autoBackground: {
|
|
@@ -410,10 +325,6 @@ class Lifecycle extends EventTarget {
|
|
|
410
325
|
return Promise.resolve(true);
|
|
411
326
|
}
|
|
412
327
|
|
|
413
|
-
/**
|
|
414
|
-
* Getter for returning the ui lifecycle state
|
|
415
|
-
* @returns {UiState} the current application lifecycle state
|
|
416
|
-
*/
|
|
417
328
|
get state() {
|
|
418
329
|
if (!this._isInitialized) {
|
|
419
330
|
this._state = this.UiState.UNKNOWN;
|
|
@@ -421,10 +332,6 @@ class Lifecycle extends EventTarget {
|
|
|
421
332
|
return this._state;
|
|
422
333
|
}
|
|
423
334
|
|
|
424
|
-
/**
|
|
425
|
-
* Getter for returning the application connection reason
|
|
426
|
-
* @returns {ConnectReason} the application connection reason
|
|
427
|
-
*/
|
|
428
335
|
get connectReason() {
|
|
429
336
|
if (!this._isInitialized) {
|
|
430
337
|
this._connectReason = this.ConnectReason.UNKNOWN;
|
|
@@ -432,11 +339,6 @@ class Lifecycle extends EventTarget {
|
|
|
432
339
|
return this._connectReason;
|
|
433
340
|
}
|
|
434
341
|
|
|
435
|
-
/**
|
|
436
|
-
* Getter for returning the event that triggered the reloading of the ui after ui has been released
|
|
437
|
-
* @returns {Object} trigger event
|
|
438
|
-
* @property {string} type - the type of the trigger event (e.g. keyPressEvent, videoPlaybackEvent)
|
|
439
|
-
* @property {object} data - data of the event, dependent on its type (e.g. keyPressEvent has data of keyValue) */
|
|
440
342
|
get triggerEvent() {
|
|
441
343
|
if (!this._isInitialized) {
|
|
442
344
|
this._triggerEvent = {};
|
|
@@ -444,14 +346,6 @@ class Lifecycle extends EventTarget {
|
|
|
444
346
|
return this._triggerEvent;
|
|
445
347
|
}
|
|
446
348
|
|
|
447
|
-
/**
|
|
448
|
-
* @deprecated Use `lifecycle.configure()` instead.
|
|
449
|
-
* Controls the autoBackground feature.<br>
|
|
450
|
-
* When enabled, the application will automatically move to the background state after a configurable
|
|
451
|
-
* period of inactivity. Use the `configure` method to set timeouts for video playback and UI states.
|
|
452
|
-
* @type {boolean}
|
|
453
|
-
* @see {@link Lifecycle#configure}
|
|
454
|
-
*/
|
|
455
349
|
set autoBackground(enabled) {
|
|
456
350
|
this._autoBackground = enabled;
|
|
457
351
|
if (this._isAutoBackgroundEnabled()) {
|
|
@@ -465,14 +359,6 @@ class Lifecycle extends EventTarget {
|
|
|
465
359
|
return this._autoBackground;
|
|
466
360
|
}
|
|
467
361
|
|
|
468
|
-
/**
|
|
469
|
-
* @deprecated Use `lifecycle.configure()` instead.
|
|
470
|
-
* The number of seconds of user inactivity before the application moves to the background state while playing video.
|
|
471
|
-
* Use the `configure` method to set this timeout.
|
|
472
|
-
* @type {integer}
|
|
473
|
-
* @default 30
|
|
474
|
-
* @see {@link Lifecycle#configure}
|
|
475
|
-
*/
|
|
476
362
|
set autoBackgroundDelay(delay) {
|
|
477
363
|
this._autoBackgroundOnVideoDelay = delay;
|
|
478
364
|
if (this._isAutoBackgroundEnabled() && remotePlayer._isPlaying) {
|
|
@@ -484,14 +370,6 @@ class Lifecycle extends EventTarget {
|
|
|
484
370
|
return this._autoBackgroundOnVideoDelay;
|
|
485
371
|
}
|
|
486
372
|
|
|
487
|
-
/**
|
|
488
|
-
* @deprecated Use `lifecycle.configure()` instead.
|
|
489
|
-
* The number of seconds of user inactivity before the application moves to the background state while in the UI (not playing).
|
|
490
|
-
* Use the `configure` method to set this timeout.
|
|
491
|
-
* @type {integer}
|
|
492
|
-
* @default -1
|
|
493
|
-
* @see {@link Lifecycle#configure}
|
|
494
|
-
*/
|
|
495
373
|
set autoBackgroundOnUIDelay(delay) {
|
|
496
374
|
this._autoBackgroundOnUIDelay = delay;
|
|
497
375
|
if (this._isAutoBackgroundEnabled() && !remotePlayer._isPlaying) {
|
|
@@ -534,18 +412,6 @@ class Lifecycle extends EventTarget {
|
|
|
534
412
|
this._countdown = null;
|
|
535
413
|
}
|
|
536
414
|
|
|
537
|
-
/**
|
|
538
|
-
* @deprecated use lifecycle.state instead.
|
|
539
|
-
* Async function that returns the ui lifecycle state
|
|
540
|
-
* @returns {UiState} the current application lifecycle state
|
|
541
|
-
* @example
|
|
542
|
-
* try {
|
|
543
|
-
* const state = await lifecycle.getState();
|
|
544
|
-
* console.log("current state is", state);
|
|
545
|
-
* } catch (e) {
|
|
546
|
-
* console.error("getState failed", e);
|
|
547
|
-
* }
|
|
548
|
-
*/
|
|
549
415
|
getState() {
|
|
550
416
|
if (window.cefQuery) {
|
|
551
417
|
return new Promise((resolve, reject) => {
|
|
@@ -566,14 +432,6 @@ class Lifecycle extends EventTarget {
|
|
|
566
432
|
sdkLogger.warn("lifecycle getState is not supported if NOT running e2e");
|
|
567
433
|
}
|
|
568
434
|
|
|
569
|
-
/**
|
|
570
|
-
* Once playback starts on the remote player,
|
|
571
|
-
* the application is moved from foreground to inTransitionToBackground and eventually to background.
|
|
572
|
-
* The application will need to call moveToForeground when it receives an event that needs the UI to be displayed again,
|
|
573
|
-
* for example a key press, a playback end-of-file or a playback error.
|
|
574
|
-
* @return {Promise} Promise which is resolved when the moveToForeground command has been successfully processed.
|
|
575
|
-
* Failure to process the moveToForeground command will result in the promise being rejected.
|
|
576
|
-
*/
|
|
577
435
|
moveToForeground() {
|
|
578
436
|
if (window.cefQuery) {
|
|
579
437
|
if (this._inTransition || this._state === this.UiState.FOREGROUND || this._state === this.UiState.IN_TRANSITION_TO_FOREGROUND) {
|
|
@@ -735,17 +593,6 @@ class Lifecycle extends EventTarget {
|
|
|
735
593
|
return Promise.resolve(false);
|
|
736
594
|
}
|
|
737
595
|
|
|
738
|
-
/**
|
|
739
|
-
* This method moves the application to the background.
|
|
740
|
-
* It should be called after remotePlayer.play().
|
|
741
|
-
* As a consequence, remote player playback will be displayed in full screen.
|
|
742
|
-
* @example
|
|
743
|
-
* remotePlayer.load("https://example.com/video.mp4", 0);
|
|
744
|
-
* remotePlayer.play();
|
|
745
|
-
* lifecycle.moveToBackground();
|
|
746
|
-
* @return {Promise} Promise which is resolved when the moveToBackground command has been successfully processed.
|
|
747
|
-
* Failure to process the moveToBackground command will result in the promise being rejected.
|
|
748
|
-
*/
|
|
749
596
|
moveToBackground() {
|
|
750
597
|
if (window.cefQuery) {
|
|
751
598
|
if (this._inTransition || this._state === this.UiState.BACKGROUND || this._state === this.UiState.IN_TRANSITION_TO_BACKGROUND) {
|
|
@@ -769,13 +616,6 @@ class Lifecycle extends EventTarget {
|
|
|
769
616
|
return this._moveToBackground();
|
|
770
617
|
}
|
|
771
618
|
|
|
772
|
-
/**
|
|
773
|
-
* Use this api to switch to another tenant (other than the home tenant) which will launch the application associated with the tenantId. The tenantId must be configured in the
|
|
774
|
-
* Senza platform. Switching to the home tenant should use the exitApplication().
|
|
775
|
-
* @param {string} tenantId The tenantId to switch
|
|
776
|
-
* @return {Promise} Promise which is resolved when the switchTenant command has been successfully processed.
|
|
777
|
-
* Failure to process the switchTenant command will result in the promise being rejected.
|
|
778
|
-
*/
|
|
779
619
|
switchTenant(tenantId) {
|
|
780
620
|
if (tenantId && tenantId.length > 0) {
|
|
781
621
|
if (tenantId === getPlatformInfo().sessionInfo?.tenantId) {
|
|
@@ -821,11 +661,6 @@ class Lifecycle extends EventTarget {
|
|
|
821
661
|
return Promise.reject("SwitchTenant requires a valid tenantId string parameter");
|
|
822
662
|
}
|
|
823
663
|
|
|
824
|
-
/**
|
|
825
|
-
* Use this api to exit the application which will redirect the browser to the home tenant application.
|
|
826
|
-
* @return {Promise} Promise which is resolved when the exitApplication command has been successfully processed.
|
|
827
|
-
* Failure to process the exitApplication command will result in the promise being rejected.
|
|
828
|
-
*/
|
|
829
664
|
exitApplication() {
|
|
830
665
|
if (window.cefQuery) {
|
|
831
666
|
return new Promise((resolve, reject) => {
|
|
@@ -874,12 +709,6 @@ class Lifecycle extends EventTarget {
|
|
|
874
709
|
return Promise.reject("exitApplication is not supported if NOT running e2e");
|
|
875
710
|
}
|
|
876
711
|
|
|
877
|
-
/**
|
|
878
|
-
* Add event listener for lifecycle events
|
|
879
|
-
* @param {string} type - The event type to listen for
|
|
880
|
-
* @param {Function} listener - The callback function. Listeners for 'userdisconnected' events should return a promise to ensure the event is processed before the application exits.
|
|
881
|
-
* @param {Object} options - Event listener options
|
|
882
|
-
*/
|
|
883
712
|
addEventListener(type, listener, options) {
|
|
884
713
|
if (type === "userdisconnected") {
|
|
885
714
|
// Use the event manager for userdisconnected events
|
|
@@ -890,12 +719,7 @@ class Lifecycle extends EventTarget {
|
|
|
890
719
|
}
|
|
891
720
|
}
|
|
892
721
|
|
|
893
|
-
|
|
894
|
-
* Remove event listener
|
|
895
|
-
* @param {string} type - The event type
|
|
896
|
-
* @param {Function} listener - The callback function to remove
|
|
897
|
-
* @param {Object} options - Event listener options
|
|
898
|
-
*/
|
|
722
|
+
|
|
899
723
|
removeEventListener(type, listener, options) {
|
|
900
724
|
if (type === "userdisconnected") {
|
|
901
725
|
// Use the event manager for userdisconnected events
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
import {getFCID, sdkLogger} from "./utils";
|
|
1
|
+
import { MessageManager as MessageManagerInterface } from "../interface/messageManager";
|
|
2
|
+
import { getFCID, sdkLogger } from "./utils";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* MessageManager is a singleton class that manages the external messages received by the application. It fires custom events as "message" with the payload as the content
|
|
6
6
|
* @fires MessageManager#message
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
class MessageManager extends
|
|
9
|
+
class MessageManager extends MessageManagerInterface {
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @typedef {object} MessageDetails - object which contains the content of the message
|
|
@@ -34,7 +34,7 @@ class MessageManager extends EventTarget {
|
|
|
34
34
|
super();
|
|
35
35
|
typeof document !== "undefined" && document.addEventListener("hs/externalEvent", (e) => {
|
|
36
36
|
sdkLogger.log("Got hs/externalEvent", JSON.stringify(e.detail));
|
|
37
|
-
this.dispatchEvent(new CustomEvent("message", {detail: {eventName: e.detail.eventName, payload: e.detail.payload, fcid: e.detail.fcid } }));
|
|
37
|
+
this.dispatchEvent(new CustomEvent("message", { detail: { eventName: e.detail.eventName, payload: e.detail.payload, fcid: e.detail.fcid } }));
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -49,13 +49,13 @@ class MessageManager extends EventTarget {
|
|
|
49
49
|
return new Promise((resolve, reject) => {
|
|
50
50
|
if (window.cefQuery) {
|
|
51
51
|
const FCID = getFCID();
|
|
52
|
-
const logger = sdkLogger.withFields({FCID});
|
|
52
|
+
const logger = sdkLogger.withFields({ FCID });
|
|
53
53
|
const message = {
|
|
54
54
|
type: "registerGroupEvent",
|
|
55
55
|
fcid: FCID,
|
|
56
56
|
groups
|
|
57
57
|
};
|
|
58
|
-
const request = {target: "UI-Streamer", waitForResponse: false, message: JSON.stringify(message)};
|
|
58
|
+
const request = { target: "UI-Streamer", waitForResponse: false, message: JSON.stringify(message) };
|
|
59
59
|
window.cefQuery({
|
|
60
60
|
request: JSON.stringify(request),
|
|
61
61
|
persistent: false,
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { PlatformManager as PlatformManagerInterface } from "../interface/platformManager";
|
|
1
2
|
import { sdkLogger } from "./utils";
|
|
2
|
-
import {sessionInfo} from "./SessionInfo";
|
|
3
|
+
import { sessionInfo } from "./SessionInfo";
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* PlatformManager is a singleton class that manages the platform
|
|
7
8
|
*/
|
|
8
|
-
class PlatformManager extends
|
|
9
|
+
class PlatformManager extends PlatformManagerInterface {
|
|
9
10
|
|
|
10
11
|
constructor() {
|
|
11
12
|
super();
|
|
@@ -22,7 +23,7 @@ class PlatformManager extends EventTarget {
|
|
|
22
23
|
get appConfig() {
|
|
23
24
|
const sessionInfoObj = sessionInfo.sessionInfoObj;
|
|
24
25
|
const appConfig = sessionInfoObj.homeSessionInfo?.["appConfig"] || {};
|
|
25
|
-
sdkLogger.info("PlatformManager get appConfig: \n" + JSON.stringify(appConfig, null,2));
|
|
26
|
+
sdkLogger.info("PlatformManager get appConfig: \n" + JSON.stringify(appConfig, null, 2));
|
|
26
27
|
return appConfig;
|
|
27
28
|
}
|
|
28
29
|
|
|
@@ -35,7 +36,7 @@ class PlatformManager extends EventTarget {
|
|
|
35
36
|
*/
|
|
36
37
|
setTimezone(timezone) {
|
|
37
38
|
if (window.cefQuery) {
|
|
38
|
-
const request = {message: JSON.stringify({type: "setTimeZone", timezone}), waitForResponse: false, target: "UI-Streamer"};
|
|
39
|
+
const request = { message: JSON.stringify({ type: "setTimeZone", timezone }), waitForResponse: false, target: "UI-Streamer" };
|
|
39
40
|
window.cefQuery({
|
|
40
41
|
request: JSON.stringify(request),
|
|
41
42
|
persistent: false,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RemotePlayer as RemotePlayerInterface } from "../interface/remotePlayer";
|
|
1
2
|
import {
|
|
2
3
|
getFCID,
|
|
3
4
|
isAudioSyncConfigured,
|
|
@@ -82,7 +83,7 @@ function setPlaybackInfo(playbackInfo) {
|
|
|
82
83
|
* @fires seeked (Not implemented yet)
|
|
83
84
|
* @fires loadedmetadata (Not implemented yet)
|
|
84
85
|
*/
|
|
85
|
-
class RemotePlayer extends
|
|
86
|
+
class RemotePlayer extends RemotePlayerInterface {
|
|
86
87
|
constructor() {
|
|
87
88
|
super();
|
|
88
89
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { shaka } from "../interface/senzaShakaPlayer";
|
|
2
|
+
|
|
2
3
|
import { remotePlayer, lifecycle, getPlatformInfo } from "./api";
|
|
3
4
|
import { sdkLogger, iso6393to1 } from "./utils";
|
|
4
5
|
|
|
@@ -30,11 +31,6 @@ class SenzaError extends shaka.util.Error {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
// Copy the shaka module and replace the Player class with SenzaShakaPlayer
|
|
34
|
-
// if we don't Copy the shaka module, the Player class will be replaced for all the other modules that import shaka
|
|
35
|
-
const senzaShaka = { ...shaka };
|
|
36
|
-
|
|
37
|
-
|
|
38
34
|
/**
|
|
39
35
|
* SenzaShakaPlayer subclass of Shaka that handles both local and remote playback.
|
|
40
36
|
*
|
|
@@ -78,7 +74,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
78
74
|
* @description Timeout in milliseconds to wait for playing event
|
|
79
75
|
* @default 3000
|
|
80
76
|
*/
|
|
81
|
-
_playingTimeout =
|
|
77
|
+
_playingTimeout = 3000;
|
|
82
78
|
|
|
83
79
|
/**
|
|
84
80
|
* @private
|
|
@@ -93,7 +89,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
93
89
|
* @description Whether to stop remote player on error
|
|
94
90
|
* @default false
|
|
95
91
|
*/
|
|
96
|
-
|
|
92
|
+
_shouldStopRemotePlayerOnError = false;
|
|
97
93
|
|
|
98
94
|
/**
|
|
99
95
|
* @private
|
|
@@ -185,7 +181,7 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
185
181
|
originatesFromRemotePlayer: true
|
|
186
182
|
};
|
|
187
183
|
|
|
188
|
-
const response = await this.getNetworkingEngine().request(
|
|
184
|
+
const response = await this.getNetworkingEngine().request(shaka.net.NetworkingEngine.RequestType.LICENSE, request).promise;
|
|
189
185
|
|
|
190
186
|
let responseBody = response.data;
|
|
191
187
|
if (response.status < 200 || response.status >= 300) {
|
|
@@ -284,15 +280,13 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
284
280
|
|
|
285
281
|
|
|
286
282
|
/**
|
|
287
|
-
* Handles errors
|
|
288
|
-
* The promise returned to the call for video element play will be rejected.
|
|
283
|
+
* Handles errors for play promises and remote player events.
|
|
289
284
|
* @private
|
|
290
285
|
* @param {Error} error - The error object.
|
|
291
286
|
*/
|
|
292
287
|
_handlePlayPromiseError(error) {
|
|
293
288
|
|
|
294
289
|
sdkLogger.error("Error while waiting for playing event:", error);
|
|
295
|
-
|
|
296
290
|
if (this._playPromiseReject) {
|
|
297
291
|
this._playPromiseReject(error);
|
|
298
292
|
this._playPromiseResolve = null;
|
|
@@ -302,7 +296,6 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
302
296
|
clearTimeout(this._playTimeoutId);
|
|
303
297
|
this._playTimeoutId = null;
|
|
304
298
|
}
|
|
305
|
-
|
|
306
299
|
}
|
|
307
300
|
|
|
308
301
|
/**
|
|
@@ -563,12 +556,11 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
563
556
|
const isCritical = this._isErrorCritical(remotePlayerErrorCode);
|
|
564
557
|
const error = this._createSenzaError(remotePlayerErrorCode, message, isCritical);
|
|
565
558
|
const errorMap = new Map();
|
|
566
|
-
const shouldStopPlayback = this._shouldStopOnRemotePlayerError && this.videoElement && isCritical;
|
|
567
559
|
errorMap.set("detail", error);
|
|
568
560
|
|
|
569
561
|
// Check if we should stop playback - only for critical errors when configured
|
|
570
|
-
|
|
571
|
-
|
|
562
|
+
if (this._shouldStopRemotePlayerOnError &&
|
|
563
|
+
this.videoElement && isCritical) {
|
|
572
564
|
try {
|
|
573
565
|
sdkLogger.warn("Stopping local player playback due to critical error");
|
|
574
566
|
// Stop only local playback
|
|
@@ -576,11 +568,9 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
576
568
|
} catch (stopError) {
|
|
577
569
|
sdkLogger.error("Error while trying to stop video element playback:", stopError);
|
|
578
570
|
}
|
|
579
|
-
// Handle error while waiting for play event. If the error is not critical or the system is configured not to stop remote player on error,
|
|
580
|
-
// the playback timeout will start the local playback
|
|
581
|
-
this._handlePlayPromiseError(error);
|
|
582
571
|
}
|
|
583
|
-
|
|
572
|
+
// Handle error while waiting for play event
|
|
573
|
+
this._handlePlayPromiseError(error);
|
|
584
574
|
this.dispatchEvent(new shaka.util.FakeEvent("error", errorMap));
|
|
585
575
|
}
|
|
586
576
|
|
|
@@ -690,14 +680,14 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
690
680
|
/**
|
|
691
681
|
* Override the configure method to add custom configuration handling
|
|
692
682
|
* Supports the following additional configuration options:
|
|
693
|
-
* -
|
|
683
|
+
* - shouldStopRemotePlayerOnError: boolean - If true, remote player will be stopped on error
|
|
694
684
|
*
|
|
695
685
|
* @override
|
|
696
686
|
* @param {Object} config - Configuration object to be merged with existing config
|
|
697
|
-
* @param {boolean} [config.
|
|
687
|
+
* @param {boolean} [config.shouldStopRemotePlayerOnError=true] - Whether to stop remote player on error
|
|
698
688
|
* @example
|
|
699
689
|
* player.configure({
|
|
700
|
-
*
|
|
690
|
+
* shouldStopRemotePlayerOnError: false, // Don't stop remote player on error
|
|
701
691
|
* // ... other shaka configurations
|
|
702
692
|
* });
|
|
703
693
|
*/
|
|
@@ -705,12 +695,12 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
705
695
|
sdkLogger.log("configure player with: ", JSON.stringify(config));
|
|
706
696
|
|
|
707
697
|
// Handle custom configuration
|
|
708
|
-
if (config.
|
|
709
|
-
this.
|
|
698
|
+
if (config.shouldStopRemotePlayerOnError !== undefined) {
|
|
699
|
+
this._shouldStopRemotePlayerOnError = !!config.shouldStopRemotePlayerOnError;
|
|
710
700
|
// Remove our custom config so it doesn't get passed to parent
|
|
711
701
|
// Use rest operator without creating a named variable for the removed property
|
|
712
702
|
// eslint-disable-next-line no-unused-vars
|
|
713
|
-
const {
|
|
703
|
+
const { shouldStopRemotePlayerOnError, ...shakaConfig } = config;
|
|
714
704
|
config = shakaConfig;
|
|
715
705
|
}
|
|
716
706
|
|
|
@@ -810,5 +800,5 @@ export class SenzaShakaPlayer extends shaka.Player {
|
|
|
810
800
|
|
|
811
801
|
}
|
|
812
802
|
|
|
813
|
-
|
|
814
|
-
export {
|
|
803
|
+
shaka.Player = SenzaShakaPlayer;
|
|
804
|
+
export { shaka };
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { getPlatformInfo } from "./api";
|
|
2
|
-
import pack from "../package.json";
|
|
3
2
|
import { sessionInfo } from "./SessionInfo";
|
|
4
|
-
const { version } = pack;
|
|
5
3
|
|
|
6
4
|
const REST_RESPONSE_TIMEOUT_SECONDS = 5;
|
|
7
5
|
|
|
6
|
+
export function getVersion() {
|
|
7
|
+
return typeof IMPLEMENTATION_VERSION !== "undefined"
|
|
8
|
+
// eslint-disable-next-line no-undef
|
|
9
|
+
? IMPLEMENTATION_VERSION
|
|
10
|
+
: "unknown";
|
|
11
|
+
};
|
|
12
|
+
|
|
8
13
|
export function getFCID() {
|
|
9
14
|
return Math.round(Math.random() * 100000) + "-" + getPlatformInfo().sessionInfo?.connectionId;
|
|
10
15
|
}
|
|
@@ -42,7 +47,7 @@ class SdkLogger {
|
|
|
42
47
|
console.info(`[hs-sdk] [metrics] ${JSON.stringify(metricObj)}`);
|
|
43
48
|
}
|
|
44
49
|
withFields(logFields) {
|
|
45
|
-
return new SdkLogger({...this.logFields, ...logFields});
|
|
50
|
+
return new SdkLogger({ ...this.logFields, ...logFields });
|
|
46
51
|
}
|
|
47
52
|
formatLogString(data) {
|
|
48
53
|
let logString = "[hs-sdk] " + data.join(" ");
|
|
@@ -51,9 +56,13 @@ class SdkLogger {
|
|
|
51
56
|
}
|
|
52
57
|
return logString;
|
|
53
58
|
}
|
|
59
|
+
addfields(fields) {
|
|
60
|
+
this.logFields = { ...this.logFields, ...fields };
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
54
63
|
}
|
|
55
64
|
|
|
56
|
-
export const sdkLogger = new SdkLogger({sdkVersion:
|
|
65
|
+
export const sdkLogger = new SdkLogger({ sdkVersion: getVersion(), url: window?.location?.href ?? "" });
|
|
57
66
|
|
|
58
67
|
export async function getRestResponse(messageName) {
|
|
59
68
|
|
|
@@ -64,14 +73,14 @@ export async function getRestResponse(messageName) {
|
|
|
64
73
|
|
|
65
74
|
return new Promise((resolve, reject) => {
|
|
66
75
|
const FCID = getFCID();
|
|
67
|
-
const logger = sdkLogger.withFields({FCID});
|
|
76
|
+
const logger = sdkLogger.withFields({ FCID });
|
|
68
77
|
const message = {
|
|
69
78
|
type: "restRequest",
|
|
70
79
|
name: messageName,
|
|
71
80
|
method: "GET",
|
|
72
81
|
fcid: FCID
|
|
73
82
|
};
|
|
74
|
-
const request = {target: "TC", waitForResponse: true, message: JSON.stringify(message)};
|
|
83
|
+
const request = { target: "TC", waitForResponse: true, message: JSON.stringify(message) };
|
|
75
84
|
let timeoutHandler = 0;
|
|
76
85
|
const queryId = window.cefQuery({
|
|
77
86
|
request: JSON.stringify(request),
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { noop } from "./utils";
|
|
2
|
+
/**
|
|
3
|
+
* @class AlarmManager
|
|
4
|
+
* AlarmManager is a singleton class that manages the alarms in the application. It fires events whose types are the names of the alarms.
|
|
5
|
+
* @fires MyAlarm
|
|
6
|
+
*/
|
|
7
|
+
export class AlarmManager extends EventTarget {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* alarm event
|
|
11
|
+
*
|
|
12
|
+
* @event AlarmManager#MyAlarm
|
|
13
|
+
* @description Fired when time of 'MyAlarm' arrives. If this alarm triggers the application load and the application doesn't call
|
|
14
|
+
* lifecycle.moveToForeground() in the alarm callback (i.e. the application remains in the background after the callback is completed),
|
|
15
|
+
* the application will be unloaded.
|
|
16
|
+
* NOTE: If you perform async operations in the callback (without moving to foreground), you must wait for the async
|
|
17
|
+
* operation to finish before returning from the callback, otherwise the application will be unloaded before the async operation is finished.<br>
|
|
18
|
+
* @example
|
|
19
|
+
* alarmManager.addEventListener("MyAlarm", async (e) => {
|
|
20
|
+
* console.log("alarm MyAlarm arrived with data", e.detail);
|
|
21
|
+
* await fetch("http://www.example.com");
|
|
22
|
+
* });
|
|
23
|
+
* alarmManager.addAlarm("MyAlarm", Date.now() + 60*60*1000, "MyData");
|
|
24
|
+
*/
|
|
25
|
+
constructor() {
|
|
26
|
+
super();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
addEventListener(type, callback) {
|
|
30
|
+
noop("AlarmManager.addEventListener", type, callback);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
removeEventListener(type, callback) {
|
|
34
|
+
noop("AlarmManager.removeEventListener", type, callback);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Set alarm to be fired at the specified time, event when ui is released
|
|
38
|
+
* @param {string} alarmName unique name for the alarm
|
|
39
|
+
* @param {number} alarmTime target time for the alarm to be fired, represented by the number of milliseconds elapsed since the epoch
|
|
40
|
+
* @param {string} [data] data to be passed back when the alarm is fired
|
|
41
|
+
* */
|
|
42
|
+
addAlarm(alarmName, alarmTime, data = "", toleranceBefore = 0, toleranceAfter = 0) {
|
|
43
|
+
noop("AlarmManager.addAlarm", alarmName, alarmTime, data, toleranceBefore, toleranceAfter);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Delete the specified alarm
|
|
47
|
+
* @param {string} alarmName name of alarm to be deleted
|
|
48
|
+
*
|
|
49
|
+
* */
|
|
50
|
+
deleteAlarm(alarmName) {
|
|
51
|
+
noop("AlarmManager.deleteAlarm", alarmName);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Delete all alarms
|
|
55
|
+
*
|
|
56
|
+
* */
|
|
57
|
+
deleteAllAlarms() {
|
|
58
|
+
noop("AlarmManager.deleteAllAlarms");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Async function that asks for all active alarms
|
|
62
|
+
* @returns {Promise} when resolved, returns an array of objects containing alarmName and alarmTime fields
|
|
63
|
+
* @throws {string} error string in case of an error
|
|
64
|
+
*
|
|
65
|
+
* */
|
|
66
|
+
getActiveAlarms() {
|
|
67
|
+
return noop("AlarmManager.getActiveAlarms");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Lifecycle } from "./lifecycle.js";
|
|
2
|
+
export { DeviceManager } from "./deviceManager.js";
|
|
3
|
+
export { PlatformManager } from "./platformManager.js";
|
|
4
|
+
export { AlarmManager } from "./alarmManager.js";
|
|
5
|
+
export { MessageManager } from "./messageManager.js";
|
|
6
|
+
export { RemotePlayer } from "./remotePlayer.js";
|
|
7
|
+
export { SenzaShakaPlayer as ShakaPlayer, shaka } from "./senzaShakaPlayer.js";
|
|
8
|
+
export { showSequence, initSequence } from "./devSequence.js";
|