livedesk 0.1.166 → 0.1.168
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/hub/src/mode4-atlas-worker.js +3 -0
- package/hub/src/mode4-atlas.js +6 -1
- package/hub/src/remote-hub.js +27 -2
- package/hub/src/server.js +10 -2
- package/package.json +3 -3
- package/web/dist/assets/index-QM1XaPEc.js +10 -0
- package/web/dist/index.html +1 -1
- package/web/dist/assets/index-tI6DRcvp.js +0 -10
|
@@ -31,6 +31,7 @@ let encoder = null;
|
|
|
31
31
|
let encoderCandidateIndex = 0;
|
|
32
32
|
let encoderCandidates = [];
|
|
33
33
|
let encoderOutputSeen = false;
|
|
34
|
+
let encoderGeneration = 0;
|
|
34
35
|
let encoderRestartTimer = null;
|
|
35
36
|
let encoderStartupTimer = null;
|
|
36
37
|
let inputWaitTimer = null;
|
|
@@ -119,6 +120,7 @@ function startEncoder() {
|
|
|
119
120
|
return;
|
|
120
121
|
}
|
|
121
122
|
const candidate = encoderCandidates[encoderCandidateIndex++];
|
|
123
|
+
encoderGeneration += 1;
|
|
122
124
|
const args = [
|
|
123
125
|
'-hide_banner', '-loglevel', 'warning',
|
|
124
126
|
'-f', 'rawvideo', '-pixel_format', 'rgb24',
|
|
@@ -226,6 +228,7 @@ function emitEncodedUnit(payload) {
|
|
|
226
228
|
isKeyFrame,
|
|
227
229
|
chunkType: isKeyFrame ? 'key' : 'delta',
|
|
228
230
|
hardwareEncoder: encoder?.candidate?.name || '',
|
|
231
|
+
encoderGeneration,
|
|
229
232
|
layoutVersion,
|
|
230
233
|
composeMs: lastComposeMs,
|
|
231
234
|
poolStarved,
|
package/hub/src/mode4-atlas.js
CHANGED
|
@@ -16,11 +16,13 @@ export class Mode4AtlasSession {
|
|
|
16
16
|
this.restartTimer = null;
|
|
17
17
|
this.pendingFrames = new Map();
|
|
18
18
|
this.frameSendsInFlight = new Set();
|
|
19
|
+
this.workerGeneration = 0;
|
|
19
20
|
this.startWorker();
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
startWorker() {
|
|
23
24
|
if (this.closed || this.worker) return;
|
|
25
|
+
const workerGeneration = ++this.workerGeneration;
|
|
24
26
|
const worker = fork(workerPath, [], {
|
|
25
27
|
env: { ...process.env },
|
|
26
28
|
stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
|
|
@@ -30,7 +32,10 @@ export class Mode4AtlasSession {
|
|
|
30
32
|
this.worker = worker;
|
|
31
33
|
worker.on('message', message => {
|
|
32
34
|
if (message?.type === 'frame' && message.metadata && message.payload) {
|
|
33
|
-
this.onFrame({
|
|
35
|
+
this.onFrame({
|
|
36
|
+
metadata: { ...message.metadata, workerGeneration },
|
|
37
|
+
payload: Buffer.from(message.payload)
|
|
38
|
+
});
|
|
34
39
|
} else if (message?.type === 'layout') {
|
|
35
40
|
this.onLayout(message);
|
|
36
41
|
} else if (message?.type === 'status' || message?.type === 'log') {
|
package/hub/src/remote-hub.js
CHANGED
|
@@ -8,7 +8,7 @@ const DEFAULT_HEARTBEAT_MS = 5000;
|
|
|
8
8
|
const DEFAULT_AGENT_TASK_TIMEOUT_MS = 120000;
|
|
9
9
|
const MAX_LINE_CHARS = 4 * 1024 * 1024;
|
|
10
10
|
const MAX_THUMBNAIL_BASE64_CHARS = 3 * 1024 * 1024;
|
|
11
|
-
const MAX_STREAM_BASE64_CHARS =
|
|
11
|
+
const MAX_STREAM_BASE64_CHARS = Math.ceil(8 * 1024 * 1024 * 4 / 3);
|
|
12
12
|
const MAX_THUMBNAIL_BINARY_BYTES = Math.floor(MAX_THUMBNAIL_BASE64_CHARS * 3 / 4);
|
|
13
13
|
const MAX_STREAM_BINARY_BYTES = Math.floor(MAX_STREAM_BASE64_CHARS * 3 / 4);
|
|
14
14
|
const MAX_AUDIO_BASE64_CHARS = 1024 * 1024;
|
|
@@ -21,7 +21,7 @@ const RECENT_FRAME_CACHE_TTL_MS = 4000;
|
|
|
21
21
|
const RECENT_THUMBNAIL_FRAME_CACHE_LIMIT = 2;
|
|
22
22
|
const RECENT_LIVE_FRAME_CACHE_LIMIT = 1;
|
|
23
23
|
const RECENT_THUMBNAIL_FRAME_CACHE_MAX_BYTES = 2 * 1024 * 1024;
|
|
24
|
-
const RECENT_LIVE_FRAME_CACHE_MAX_BYTES =
|
|
24
|
+
const RECENT_LIVE_FRAME_CACHE_MAX_BYTES = 8 * 1024 * 1024;
|
|
25
25
|
const LIVE_STREAM_PENDING_REUSE_MS = 5000;
|
|
26
26
|
const LIVE_STREAM_MIN_FRESH_MS = 3000;
|
|
27
27
|
const LIVE_STREAM_MAX_FRESH_MS = 12000;
|
|
@@ -77,6 +77,17 @@ const REMOTE_FRAME_MODE_PROFILES = Object.freeze({
|
|
|
77
77
|
profile: 'mode3-h264-hardware-v1',
|
|
78
78
|
modeVersion: 3,
|
|
79
79
|
implemented: true
|
|
80
|
+
}),
|
|
81
|
+
'mode5-lzo-delta': Object.freeze({
|
|
82
|
+
mode: 'mode5-lzo-delta',
|
|
83
|
+
label: 'Mode 5 - RGB565 Tile Delta LZO',
|
|
84
|
+
transport: 'ws-binary',
|
|
85
|
+
encoding: 'image-delta',
|
|
86
|
+
codec: 'rgb565-delta',
|
|
87
|
+
compression: 'lzo1x',
|
|
88
|
+
profile: 'mode5-lzo-rgb565-delta-v1',
|
|
89
|
+
modeVersion: 5,
|
|
90
|
+
implemented: true
|
|
80
91
|
})
|
|
81
92
|
});
|
|
82
93
|
const REMOTE_FRAME_MODE_ALIASES = new Map([
|
|
@@ -117,6 +128,14 @@ const REMOTE_FRAME_MODE_ALIASES = new Map([
|
|
|
117
128
|
['h264-hw', 'mode3-h264-hw'],
|
|
118
129
|
['hardware', 'mode3-h264-hw'],
|
|
119
130
|
['hardware-h264', 'mode3-h264-hw'],
|
|
131
|
+
['5', 'mode5-lzo-delta'],
|
|
132
|
+
['mode5', 'mode5-lzo-delta'],
|
|
133
|
+
['mode-5', 'mode5-lzo-delta'],
|
|
134
|
+
['mode5-lzo', 'mode5-lzo-delta'],
|
|
135
|
+
['mode5-lzo-delta', 'mode5-lzo-delta'],
|
|
136
|
+
['lzo-delta', 'mode5-lzo-delta'],
|
|
137
|
+
['tile-delta', 'mode5-lzo-delta'],
|
|
138
|
+
['control-lzo', 'mode5-lzo-delta'],
|
|
120
139
|
['thumb', 'thumbnail'],
|
|
121
140
|
['thumbnail', 'thumbnail'],
|
|
122
141
|
['video', 'mode3-h264-hw'],
|
|
@@ -3111,6 +3130,9 @@ export function createRemoteHub(options = {}) {
|
|
|
3111
3130
|
captureStageMs: readFrameStageMs(message, 'captureStageMs'),
|
|
3112
3131
|
convertMs: readFrameStageMs(message, 'convertMs'),
|
|
3113
3132
|
compressMs: readFrameStageMs(message, 'compressMs'),
|
|
3133
|
+
deltaTileSize: Number.isFinite(Number(message.deltaTileSize)) ? Number(message.deltaTileSize) : 0,
|
|
3134
|
+
deltaTileCount: Number.isFinite(Number(message.deltaTileCount)) ? Number(message.deltaTileCount) : 0,
|
|
3135
|
+
deltaTotalTiles: Number.isFinite(Number(message.deltaTotalTiles)) ? Number(message.deltaTotalTiles) : 0,
|
|
3114
3136
|
sameContentStreak,
|
|
3115
3137
|
payload,
|
|
3116
3138
|
accessToken: createFrameAccessToken()
|
|
@@ -3306,6 +3328,9 @@ export function createRemoteHub(options = {}) {
|
|
|
3306
3328
|
captureStageMs: readFrameStageMs(message, 'captureStageMs'),
|
|
3307
3329
|
convertMs: readFrameStageMs(message, 'convertMs'),
|
|
3308
3330
|
compressMs: readFrameStageMs(message, 'compressMs'),
|
|
3331
|
+
deltaTileSize: Number.isFinite(Number(message.deltaTileSize)) ? Number(message.deltaTileSize) : 0,
|
|
3332
|
+
deltaTileCount: Number.isFinite(Number(message.deltaTileCount)) ? Number(message.deltaTileCount) : 0,
|
|
3333
|
+
deltaTotalTiles: Number.isFinite(Number(message.deltaTotalTiles)) ? Number(message.deltaTotalTiles) : 0,
|
|
3309
3334
|
sameContentStreak,
|
|
3310
3335
|
payload,
|
|
3311
3336
|
accessToken: createFrameAccessToken()
|
package/hub/src/server.js
CHANGED
|
@@ -793,6 +793,9 @@ function buildRemoteFrameBinaryPacket(frameEvent, diagnostics = {}) {
|
|
|
793
793
|
captureStageMs: Number(frame.captureStageMs || 0) || 0,
|
|
794
794
|
convertMs: Number(frame.convertMs || 0) || 0,
|
|
795
795
|
compressMs: Number(frame.compressMs || 0) || 0,
|
|
796
|
+
deltaTileSize: Number(frame.deltaTileSize || 0) || 0,
|
|
797
|
+
deltaTileCount: Number(frame.deltaTileCount || 0) || 0,
|
|
798
|
+
deltaTotalTiles: Number(frame.deltaTotalTiles || 0) || 0,
|
|
796
799
|
sameContentStreak: Number(frame.sameContentStreak || 0) || 0,
|
|
797
800
|
layoutVersion: Number(frame.layoutVersion || 0) || 0,
|
|
798
801
|
atlasComposeMs: Number(frame.atlasComposeMs || 0) || 0,
|
|
@@ -911,6 +914,9 @@ function sendMode4AtlasFrame(ws, output) {
|
|
|
911
914
|
const metadata = output.metadata || {};
|
|
912
915
|
const frameSeq = Number(metadata.frameSeq || 0) || 0;
|
|
913
916
|
const isKeyFrame = metadata.isKeyFrame === true;
|
|
917
|
+
const workerGeneration = Math.max(1, Number(metadata.workerGeneration || 1) || 1);
|
|
918
|
+
const encoderGeneration = Math.max(1, Number(metadata.encoderGeneration || 1) || 1);
|
|
919
|
+
const streamId = `${ws.liveDeskAtlasStreamId}-w${workerGeneration}-e${encoderGeneration}`;
|
|
914
920
|
const frameEvent = {
|
|
915
921
|
kind: 'live',
|
|
916
922
|
deviceId: '__livedesk_mode4_atlas__',
|
|
@@ -921,8 +927,8 @@ function sendMode4AtlasFrame(ws, output) {
|
|
|
921
927
|
deviceId: '__livedesk_mode4_atlas__',
|
|
922
928
|
frameSeq,
|
|
923
929
|
streamFrameSeq: Number(metadata.streamFrameSeq || frameSeq) || frameSeq,
|
|
924
|
-
streamId
|
|
925
|
-
commandId:
|
|
930
|
+
streamId,
|
|
931
|
+
commandId: streamId,
|
|
926
932
|
width: Number(metadata.width || 1920),
|
|
927
933
|
height: Number(metadata.height || 1080),
|
|
928
934
|
sourceWidth: Number(metadata.width || 1920),
|
|
@@ -944,6 +950,8 @@ function sendMode4AtlasFrame(ws, output) {
|
|
|
944
950
|
receivedAt: new Date().toISOString(),
|
|
945
951
|
hardwareEncoder: String(metadata.hardwareEncoder || ''),
|
|
946
952
|
platformProfile: 'mode4-hub-atlas-worker',
|
|
953
|
+
workerGeneration,
|
|
954
|
+
encoderGeneration,
|
|
947
955
|
layoutVersion: Number(metadata.layoutVersion || 0),
|
|
948
956
|
atlasComposeMs: Number(metadata.composeMs || 0),
|
|
949
957
|
atlasPoolStarved: Number(metadata.poolStarved || 0),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livedesk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.168",
|
|
4
4
|
"description": "LiveDesk Hub and client launcher",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"check": "node --check bin/livedesk.js && node --check scripts/sync-web-dist.js",
|
|
17
17
|
"build": "node scripts/sync-web-dist.js",
|
|
18
|
-
"prepack": "
|
|
18
|
+
"prepack": "node scripts/sync-web-dist.js",
|
|
19
19
|
"pack:dry": "npm pack --dry-run"
|
|
20
20
|
},
|
|
21
21
|
"keywords": [
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@ffmpeg-installer/ffmpeg": "^1.1.0",
|
|
34
|
-
"@livedesk/client": "0.1.
|
|
34
|
+
"@livedesk/client": "0.1.108",
|
|
35
35
|
"cors": "^2.8.5",
|
|
36
36
|
"express": "^4.21.2",
|
|
37
37
|
"ffmpeg-static": "^5.3.0",
|