livedesk 0.1.19 → 0.1.21
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/remote-hub.js
CHANGED
|
@@ -27,7 +27,7 @@ const REMOTE_AGENT_PROTOCOL = 'mindexec.remote.agent';
|
|
|
27
27
|
const REMOTE_FRAME_PROTOCOL = 'mindexec.remote.frame.v2';
|
|
28
28
|
const REMOTE_FRAME_PROTOCOL_VERSION = 2;
|
|
29
29
|
const REMOTE_FRAME_HANDSHAKE = 'smartview-request-open-frame';
|
|
30
|
-
const DEFAULT_REMOTE_FRAME_MODE = '
|
|
30
|
+
const DEFAULT_REMOTE_FRAME_MODE = 'mode1-jpeg';
|
|
31
31
|
const REMOTE_FRAME_MODE_PROFILES = Object.freeze({
|
|
32
32
|
thumbnail: Object.freeze({
|
|
33
33
|
mode: 'thumbnail',
|
|
@@ -40,54 +40,77 @@ const REMOTE_FRAME_MODE_PROFILES = Object.freeze({
|
|
|
40
40
|
modeVersion: 1,
|
|
41
41
|
implemented: true
|
|
42
42
|
}),
|
|
43
|
-
'
|
|
44
|
-
mode: '
|
|
45
|
-
label: '
|
|
43
|
+
'mode1-jpeg': Object.freeze({
|
|
44
|
+
mode: 'mode1-jpeg',
|
|
45
|
+
label: 'Mode 1 - Test JPEG Binary',
|
|
46
46
|
transport: 'ws-binary',
|
|
47
47
|
encoding: 'image',
|
|
48
48
|
codec: 'jpeg',
|
|
49
49
|
compression: 'image/jpeg',
|
|
50
|
-
profile: 'jpeg-binary-v1',
|
|
50
|
+
profile: 'mode1-jpeg-binary-v1',
|
|
51
51
|
modeVersion: 1,
|
|
52
52
|
implemented: true
|
|
53
53
|
}),
|
|
54
|
-
'
|
|
55
|
-
mode: '
|
|
56
|
-
label: '
|
|
54
|
+
'mode2-lz4': Object.freeze({
|
|
55
|
+
mode: 'mode2-lz4',
|
|
56
|
+
label: 'Mode 2 - Raw BGRA LZ4',
|
|
57
57
|
transport: 'ws-binary',
|
|
58
|
-
encoding: 'image',
|
|
59
|
-
codec: '
|
|
60
|
-
compression: '
|
|
61
|
-
profile: '
|
|
62
|
-
modeVersion:
|
|
58
|
+
encoding: 'image-raw',
|
|
59
|
+
codec: 'bgra32',
|
|
60
|
+
compression: 'lz4',
|
|
61
|
+
profile: 'mode2-lz4-bgra-v1',
|
|
62
|
+
modeVersion: 2,
|
|
63
63
|
implemented: true
|
|
64
64
|
}),
|
|
65
|
-
'
|
|
66
|
-
mode: '
|
|
67
|
-
label: '
|
|
65
|
+
'mode3-h264-hw': Object.freeze({
|
|
66
|
+
mode: 'mode3-h264-hw',
|
|
67
|
+
label: 'Mode 3 - Hardware H.264',
|
|
68
68
|
transport: 'ws-binary',
|
|
69
69
|
encoding: 'video',
|
|
70
|
-
codec: '
|
|
71
|
-
compression: 'video
|
|
72
|
-
profile: '
|
|
73
|
-
modeVersion:
|
|
70
|
+
codec: 'h264',
|
|
71
|
+
compression: 'video/h264',
|
|
72
|
+
profile: 'mode3-h264-hardware-v1',
|
|
73
|
+
modeVersion: 3,
|
|
74
74
|
implemented: false
|
|
75
75
|
})
|
|
76
76
|
});
|
|
77
77
|
const REMOTE_FRAME_MODE_ALIASES = new Map([
|
|
78
|
-
['
|
|
79
|
-
['
|
|
80
|
-
['
|
|
81
|
-
['
|
|
82
|
-
['
|
|
83
|
-
['
|
|
84
|
-
['
|
|
85
|
-
['
|
|
78
|
+
['1', 'mode1-jpeg'],
|
|
79
|
+
['mode1', 'mode1-jpeg'],
|
|
80
|
+
['mode-1', 'mode1-jpeg'],
|
|
81
|
+
['mode1-jpeg', 'mode1-jpeg'],
|
|
82
|
+
['jpeg', 'mode1-jpeg'],
|
|
83
|
+
['jpg', 'mode1-jpeg'],
|
|
84
|
+
['test', 'mode1-jpeg'],
|
|
85
|
+
['fast', 'mode1-jpeg'],
|
|
86
|
+
['remotefast', 'mode1-jpeg'],
|
|
87
|
+
['remote_fast', 'mode1-jpeg'],
|
|
88
|
+
['remote-fast', 'mode1-jpeg'],
|
|
89
|
+
['quality', 'mode1-jpeg'],
|
|
90
|
+
['remotequality', 'mode1-jpeg'],
|
|
91
|
+
['remote_quality', 'mode1-jpeg'],
|
|
92
|
+
['remote-quality', 'mode1-jpeg'],
|
|
93
|
+
['2', 'mode2-lz4'],
|
|
94
|
+
['mode2', 'mode2-lz4'],
|
|
95
|
+
['mode-2', 'mode2-lz4'],
|
|
96
|
+
['mode2-lz4', 'mode2-lz4'],
|
|
97
|
+
['lz4', 'mode2-lz4'],
|
|
98
|
+
['tile-lz4', 'mode2-lz4'],
|
|
99
|
+
['tiles-lz4', 'mode2-lz4'],
|
|
100
|
+
['3', 'mode3-h264-hw'],
|
|
101
|
+
['mode3', 'mode3-h264-hw'],
|
|
102
|
+
['mode-3', 'mode3-h264-hw'],
|
|
103
|
+
['mode3-h264', 'mode3-h264-hw'],
|
|
104
|
+
['mode3-h264-hw', 'mode3-h264-hw'],
|
|
105
|
+
['h264', 'mode3-h264-hw'],
|
|
106
|
+
['h264-hw', 'mode3-h264-hw'],
|
|
107
|
+
['hardware', 'mode3-h264-hw'],
|
|
108
|
+
['hardware-h264', 'mode3-h264-hw'],
|
|
86
109
|
['thumb', 'thumbnail'],
|
|
87
110
|
['thumbnail', 'thumbnail'],
|
|
88
|
-
['video', '
|
|
89
|
-
['codec', '
|
|
90
|
-
['video-codec', '
|
|
111
|
+
['video', 'mode3-h264-hw'],
|
|
112
|
+
['codec', 'mode3-h264-hw'],
|
|
113
|
+
['video-codec', 'mode3-h264-hw']
|
|
91
114
|
]);
|
|
92
115
|
const MAX_SYNTHETIC_DEVICES = 1000;
|
|
93
116
|
const DEFAULT_HOST_TARGET_LEASE_MS = 30000;
|
|
@@ -134,7 +157,7 @@ function safeString(value, maxLength = 200) {
|
|
|
134
157
|
return String(value ?? '').replace(/[\r\n\t]/g, ' ').trim().slice(0, maxLength);
|
|
135
158
|
}
|
|
136
159
|
|
|
137
|
-
function normalizeRemoteFrameMode(value, fallback = DEFAULT_REMOTE_FRAME_MODE) {
|
|
160
|
+
function normalizeRemoteFrameMode(value, fallback = DEFAULT_REMOTE_FRAME_MODE, { allowUnimplemented = false } = {}) {
|
|
138
161
|
const requested = safeString(value, 80).toLowerCase();
|
|
139
162
|
const fallbackMode = REMOTE_FRAME_MODE_PROFILES[fallback] ? fallback : DEFAULT_REMOTE_FRAME_MODE;
|
|
140
163
|
if (!requested) {
|
|
@@ -143,7 +166,7 @@ function normalizeRemoteFrameMode(value, fallback = DEFAULT_REMOTE_FRAME_MODE) {
|
|
|
143
166
|
|
|
144
167
|
const normalized = REMOTE_FRAME_MODE_ALIASES.get(requested) || requested;
|
|
145
168
|
const profile = REMOTE_FRAME_MODE_PROFILES[normalized];
|
|
146
|
-
if (!profile || profile.implemented !== true) {
|
|
169
|
+
if (!profile || (!allowUnimplemented && profile.implemented !== true)) {
|
|
147
170
|
return fallbackMode;
|
|
148
171
|
}
|
|
149
172
|
|
|
@@ -164,14 +187,13 @@ function serializeRemoteFrameModeProfile(profile) {
|
|
|
164
187
|
};
|
|
165
188
|
}
|
|
166
189
|
|
|
167
|
-
function getRemoteFrameModeProfile(value, fallback = DEFAULT_REMOTE_FRAME_MODE) {
|
|
168
|
-
const mode = normalizeRemoteFrameMode(value, fallback);
|
|
190
|
+
function getRemoteFrameModeProfile(value, fallback = DEFAULT_REMOTE_FRAME_MODE, options = {}) {
|
|
191
|
+
const mode = normalizeRemoteFrameMode(value, fallback, options);
|
|
169
192
|
return serializeRemoteFrameModeProfile(REMOTE_FRAME_MODE_PROFILES[mode]);
|
|
170
193
|
}
|
|
171
194
|
|
|
172
195
|
function getSupportedRemoteFrameModeProfiles() {
|
|
173
196
|
return Object.values(REMOTE_FRAME_MODE_PROFILES)
|
|
174
|
-
.filter(profile => profile.implemented === true)
|
|
175
197
|
.map(serializeRemoteFrameModeProfile);
|
|
176
198
|
}
|
|
177
199
|
|
|
@@ -222,14 +244,14 @@ function normalizeIncomingFrameModeProfile(value) {
|
|
|
222
244
|
}
|
|
223
245
|
|
|
224
246
|
if (typeof value === 'string') {
|
|
225
|
-
return getRemoteFrameModeProfile(value);
|
|
247
|
+
return getRemoteFrameModeProfile(value, DEFAULT_REMOTE_FRAME_MODE, { allowUnimplemented: true });
|
|
226
248
|
}
|
|
227
249
|
|
|
228
250
|
if (typeof value !== 'object') {
|
|
229
251
|
return null;
|
|
230
252
|
}
|
|
231
253
|
|
|
232
|
-
const profile =
|
|
254
|
+
const profile = getRemoteFrameModeProfile(value.mode || value.frameMode || value.profile, DEFAULT_REMOTE_FRAME_MODE, { allowUnimplemented: true });
|
|
233
255
|
return {
|
|
234
256
|
mode: profile.mode,
|
|
235
257
|
label: safeString(value.label, 80) || profile.mode,
|
|
@@ -1593,8 +1615,8 @@ export function createRemoteHub(options = {}) {
|
|
|
1593
1615
|
streamId: safeString(streamId, 128) || `${mode}-${Date.now()}`,
|
|
1594
1616
|
frameSeq,
|
|
1595
1617
|
commandId: safeString(options.commandId, 128),
|
|
1596
|
-
width: clampNumber(options.width, 2, 2560, mode === '
|
|
1597
|
-
height: clampNumber(options.height, 1, 1440, mode === '
|
|
1618
|
+
width: clampNumber(options.width, 2, 2560, mode === 'thumbnail' ? 360 : 640),
|
|
1619
|
+
height: clampNumber(options.height, 1, 1440, mode === 'thumbnail' ? 220 : 360),
|
|
1598
1620
|
mimeType: 'image/png',
|
|
1599
1621
|
format: 'image/png',
|
|
1600
1622
|
mode,
|
|
@@ -1606,7 +1628,7 @@ export function createRemoteHub(options = {}) {
|
|
|
1606
1628
|
transferProtocol: descriptor.transferProtocol,
|
|
1607
1629
|
transferProtocolVersion: descriptor.transferProtocolVersion,
|
|
1608
1630
|
handshake: descriptor.handshake,
|
|
1609
|
-
fps: clampNumber(options.fps, 1, 24, mode === '
|
|
1631
|
+
fps: clampNumber(options.fps, 1, 24, mode === 'thumbnail' ? 1 : 2),
|
|
1610
1632
|
capturedAt: now,
|
|
1611
1633
|
receivedAt: now,
|
|
1612
1634
|
byteLength: 68,
|
|
@@ -2579,6 +2601,9 @@ export function createRemoteHub(options = {}) {
|
|
|
2579
2601
|
encoding: transfer.encoding,
|
|
2580
2602
|
codec: transfer.codec,
|
|
2581
2603
|
compression: transfer.compression || mimeType,
|
|
2604
|
+
pixelFormat: safeString(message.pixelFormat, 40),
|
|
2605
|
+
bytesPerPixel: Number.isFinite(Number(message.bytesPerPixel)) ? Number(message.bytesPerPixel) : 0,
|
|
2606
|
+
uncompressedByteLength: Number.isFinite(Number(message.uncompressedByteLength)) ? Number(message.uncompressedByteLength) : 0,
|
|
2582
2607
|
transferProtocol: transfer.transferProtocol,
|
|
2583
2608
|
transferProtocolVersion: transfer.transferProtocolVersion,
|
|
2584
2609
|
handshake: transfer.handshake,
|
|
@@ -2714,6 +2739,9 @@ export function createRemoteHub(options = {}) {
|
|
|
2714
2739
|
encoding: transfer.encoding,
|
|
2715
2740
|
codec: transfer.codec,
|
|
2716
2741
|
compression: transfer.compression || mimeType,
|
|
2742
|
+
pixelFormat: safeString(message.pixelFormat, 40),
|
|
2743
|
+
bytesPerPixel: Number.isFinite(Number(message.bytesPerPixel)) ? Number(message.bytesPerPixel) : 0,
|
|
2744
|
+
uncompressedByteLength: Number.isFinite(Number(message.uncompressedByteLength)) ? Number(message.uncompressedByteLength) : 0,
|
|
2717
2745
|
transferProtocol: transfer.transferProtocol,
|
|
2718
2746
|
transferProtocolVersion: transfer.transferProtocolVersion,
|
|
2719
2747
|
handshake: transfer.handshake,
|
package/hub/src/server.js
CHANGED
|
@@ -134,7 +134,7 @@ function normalizeTransferFiles(value) {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
function normalizeLiveOptions(payload = {}) {
|
|
137
|
-
const mode = String(payload.frameMode || payload.mode || '
|
|
137
|
+
const mode = String(payload.frameMode || payload.mode || 'mode2-lz4').trim() || 'mode2-lz4';
|
|
138
138
|
return {
|
|
139
139
|
fps: clampNumber(payload.fps, 1, 24, 2),
|
|
140
140
|
maxWidth: clampNumber(payload.maxWidth, 320, 2560, 640),
|
|
@@ -230,6 +230,9 @@ function buildRemoteFrameBinaryPacket(frameEvent) {
|
|
|
230
230
|
encoding: frame.encoding || '',
|
|
231
231
|
codec: frame.codec || '',
|
|
232
232
|
compression: frame.compression || frame.mimeType || frame.format || '',
|
|
233
|
+
pixelFormat: frame.pixelFormat || '',
|
|
234
|
+
bytesPerPixel: Number(frame.bytesPerPixel || 0) || 0,
|
|
235
|
+
uncompressedByteLength: Number(frame.uncompressedByteLength || 0) || 0,
|
|
233
236
|
fps: Number(frame.fps || 0) || 0,
|
|
234
237
|
capturedAt: frame.capturedAt || '',
|
|
235
238
|
receivedAt: frame.receivedAt || '',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livedesk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "LiveDesk Hub and client launcher",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"node": ">=20"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@livedesk/client": "0.1.
|
|
33
|
+
"@livedesk/client": "0.1.27",
|
|
34
34
|
"cors": "^2.8.5",
|
|
35
35
|
"express": "^4.21.2",
|
|
36
36
|
"ws": "^8.18.3"
|