senza-sdk 4.4.4 → 4.4.6
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/dist/implementation.bundle.js +1 -1
- package/package.json +8 -7
- package/src/implementation/api.js +2 -0
- package/src/implementation/backgroundRenderControl.js +113 -0
- package/src/implementation/lifecycle.js +367 -23
- package/src/interface/lifecycle.js +48 -5
- package/src/interface/version.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "senza-sdk",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.6",
|
|
4
4
|
"main": "./src/api.js",
|
|
5
5
|
"description": "API for Senza application",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,17 +23,18 @@
|
|
|
23
23
|
"version:output": "echo 'export const version = \"'$npm_package_version'\";' > src/interface/version.js"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@babel/cli": "^7.
|
|
27
|
-
"@babel/core": "7.
|
|
28
|
-
"@babel/plugin-transform-modules-commonjs": "^7.
|
|
29
|
-
"@babel/preset-env": "^7.
|
|
26
|
+
"@babel/cli": "^7.22.0",
|
|
27
|
+
"@babel/core": "^7.22.0",
|
|
28
|
+
"@babel/plugin-transform-modules-commonjs": "^7.22.0",
|
|
29
|
+
"@babel/preset-env": "^7.22.0",
|
|
30
30
|
"@eslint/eslintrc": "^3.3.0",
|
|
31
31
|
"@eslint/js": "^9.22.0",
|
|
32
|
-
"babel-jest": "^
|
|
32
|
+
"babel-jest": "^30.2.0",
|
|
33
33
|
"eslint": "^9.22.0",
|
|
34
34
|
"eslint-plugin-jest": "^28.11.0",
|
|
35
35
|
"globals": "^16.0.0",
|
|
36
|
-
"jest": "^
|
|
36
|
+
"jest": "^30.2.0",
|
|
37
|
+
"jest-environment-jsdom" : "^30.2.0",
|
|
37
38
|
"jsdoc-to-markdown": "^7.1.1",
|
|
38
39
|
"webpack": "^5.72.1",
|
|
39
40
|
"webpack-cli": "^5.1.4"
|
|
@@ -6,6 +6,7 @@ import { remotePlayer } from "./remotePlayer.js";
|
|
|
6
6
|
import { deviceManager } from "./deviceManager.js";
|
|
7
7
|
import { displayManager } from "./displayManager.js";
|
|
8
8
|
import { messageManager } from "./messageManager.js";
|
|
9
|
+
import { backgroundRenderControl } from "./backgroundRenderControl.js";
|
|
9
10
|
|
|
10
11
|
export { remotePlayer };
|
|
11
12
|
export { lifecycle };
|
|
@@ -141,6 +142,7 @@ export async function init(interfaceApiVersion, showSequenceFunc, initSequenceFu
|
|
|
141
142
|
await remotePlayer._init(sessionInfoObj, triggerEvent);
|
|
142
143
|
alarmManager._init();
|
|
143
144
|
messageManager._init();
|
|
145
|
+
backgroundRenderControl._init();
|
|
144
146
|
await displayManager._init();
|
|
145
147
|
sdkLogger.log("All submodules initialized");
|
|
146
148
|
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { lifecycle } from "./lifecycle.js";
|
|
2
|
+
import { sdkLogger } from "./utils.js";
|
|
3
|
+
import { sessionInfo } from "./SessionInfo";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Internal background render control.
|
|
7
|
+
* Listens to lifecycle state changes and disables animation / video rendering when in background mode.
|
|
8
|
+
* Specifically it pauses CSS animations and hides video elements to reduce CPU/GPU load
|
|
9
|
+
*
|
|
10
|
+
* For remote-gpu deployments this reduces the CPU use in background mode from 6 cores to 0.4 cores.
|
|
11
|
+
*
|
|
12
|
+
* Extra CPU can be saved by also overriding requestAnimationFrame and slowing down time.
|
|
13
|
+
* This has the effect of ensuring the segments are downloaded at a slower pace
|
|
14
|
+
* - or not at all if you actually pause video, but these may have more complicated state and audio sync issues.
|
|
15
|
+
* Either way if you slow the decoding speed then we save more CPU by not doing as much SW video decoding,
|
|
16
|
+
* but the bulk is saved by the hidden video elements.
|
|
17
|
+
* See comments on https://jira01.engit.synamedia.com/browse/HSDEV-16827 for more about a PoC / spike that did this.
|
|
18
|
+
*
|
|
19
|
+
* As it stands, the current implementation that gets us 0.4 cores in background mode for remote-gpu is a good compromise of complexity vs benefit.
|
|
20
|
+
* It also roughly matches GPU mode background CPU use (maybe slightly better).
|
|
21
|
+
* GPU mode with this feature enabled (from my testing) saves about 0.15 cores ~0.45 -> ~0.30 cores
|
|
22
|
+
*
|
|
23
|
+
* This module uses the following settings:
|
|
24
|
+
* {
|
|
25
|
+
* "ui-streamer": {
|
|
26
|
+
* "throttleRenderingInBackground": {
|
|
27
|
+
* "enabled": true, // enable or disable the feature
|
|
28
|
+
* }
|
|
29
|
+
* }
|
|
30
|
+
* }
|
|
31
|
+
*/
|
|
32
|
+
class BackgroundRenderControl {
|
|
33
|
+
|
|
34
|
+
/** initialised
|
|
35
|
+
* @type {boolean}
|
|
36
|
+
* @private
|
|
37
|
+
* Whether the instance has been initialized.
|
|
38
|
+
*/
|
|
39
|
+
_initialized = false;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @type {boolean}
|
|
43
|
+
* @private
|
|
44
|
+
* Whether render control is enabled.
|
|
45
|
+
*/
|
|
46
|
+
_enabled = false;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @type {boolean}
|
|
50
|
+
* @private
|
|
51
|
+
* Whether rendering is currently active.
|
|
52
|
+
*/
|
|
53
|
+
_active = true;
|
|
54
|
+
|
|
55
|
+
/** @type {string|null}
|
|
56
|
+
* @private
|
|
57
|
+
* Stores the last known lifecycle state.
|
|
58
|
+
*/
|
|
59
|
+
_lastState = null;
|
|
60
|
+
|
|
61
|
+
/** @type {Function}
|
|
62
|
+
* @private
|
|
63
|
+
* Event listener for lifecycle state changes.
|
|
64
|
+
*/
|
|
65
|
+
_listener = (e) => this._handleStateChange(e.state);
|
|
66
|
+
|
|
67
|
+
_init() {
|
|
68
|
+
if (this._initialized) return;
|
|
69
|
+
this._enabled = sessionInfo?.sessionInfoObj.settings?.["ui-streamer"]?.throttleRenderingInBackground?.enabled ?? false;
|
|
70
|
+
sdkLogger.log(`Initializing BackgroundRenderControl: enabled=${this._enabled}`);
|
|
71
|
+
if (!this._enabled) return;
|
|
72
|
+
this._lastState = lifecycle.state;
|
|
73
|
+
lifecycle.addEventListener("onstatechange", this._listener);
|
|
74
|
+
this._initialized = true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
_handleStateChange(state) {
|
|
78
|
+
if (!this._enabled) return;
|
|
79
|
+
if (state === this._lastState) return;
|
|
80
|
+
this._lastState = state;
|
|
81
|
+
try {
|
|
82
|
+
if (state === lifecycle.UiState.FOREGROUND) this._onForeground();
|
|
83
|
+
else if (state === lifecycle.UiState.BACKGROUND) this._onBackground();
|
|
84
|
+
} catch (err) {
|
|
85
|
+
sdkLogger.error("BackgroundRenderControl state handling error", err);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
_onForeground() {
|
|
90
|
+
if (this._active) return;
|
|
91
|
+
sdkLogger.log("BackgroundRenderControl resume rendering");
|
|
92
|
+
this._active = true;
|
|
93
|
+
const style = document.getElementById("hs-sdk-bg-render-styles");
|
|
94
|
+
if (style) style.remove();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_onBackground() {
|
|
98
|
+
if (!this._active) return;
|
|
99
|
+
sdkLogger.log("BackgroundRenderControl throttle rendering");
|
|
100
|
+
this._active = false;
|
|
101
|
+
if (!document.getElementById("hs-sdk-bg-render-styles")) {
|
|
102
|
+
const style = document.createElement("style");
|
|
103
|
+
style.id = "hs-sdk-bg-render-styles";
|
|
104
|
+
style.textContent = `
|
|
105
|
+
* { animation-play-state: paused !important; transition: none !important; scroll-behavior: auto !important; }
|
|
106
|
+
canvas, video, img { visibility: hidden !important; }
|
|
107
|
+
`;
|
|
108
|
+
document.head.appendChild(style);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export const backgroundRenderControl = new BackgroundRenderControl();
|