livedesk 0.1.408 → 0.1.409

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/client",
3
- "version": "0.1.173",
3
+ "version": "0.1.174",
4
4
  "description": "LiveDesk local remote client",
5
5
  "type": "module",
6
6
  "bin": {
@@ -39,10 +39,10 @@
39
39
  "ws": "^8.18.3"
40
40
  },
41
41
  "optionalDependencies": {
42
- "@livedesk/fast-linux-x64": "0.1.379",
43
- "@livedesk/fast-osx-arm64": "0.1.379",
44
- "@livedesk/fast-osx-x64": "0.1.379",
45
- "@livedesk/fast-win-x64": "0.1.379"
42
+ "@livedesk/fast-linux-x64": "0.1.380",
43
+ "@livedesk/fast-osx-arm64": "0.1.380",
44
+ "@livedesk/fast-osx-x64": "0.1.380",
45
+ "@livedesk/fast-win-x64": "0.1.380"
46
46
  },
47
47
  "publishConfig": {
48
48
  "access": "public"
@@ -0,0 +1,32 @@
1
+ const TILE_PRESETS = Object.freeze([
2
+ Object.freeze({ width: 320, height: 180 }),
3
+ Object.freeze({ width: 480, height: 270 }),
4
+ Object.freeze({ width: 640, height: 360 })
5
+ ]);
6
+
7
+ export function resolveMode4AtlasTileSize(options = {}) {
8
+ const deviceCount = Math.max(1, Math.floor(Number(options.deviceCount) || 1));
9
+ const atlasWidth = Math.max(640, Math.floor(Number(options.atlasWidth) || 1920));
10
+ const atlasHeight = Math.max(360, Math.floor(Number(options.atlasHeight) || 1080));
11
+ const requestedWidth = Number(options.requestedWidth) || 320;
12
+ const requestedHeight = Number(options.requestedHeight) || 180;
13
+ const columns = Math.max(1, Math.ceil(Math.sqrt(deviceCount)));
14
+ const rows = Math.max(1, Math.ceil(deviceCount / columns));
15
+ const requestedPresetIndex = requestedWidth >= 640 || requestedHeight >= 360
16
+ ? 2
17
+ : requestedWidth >= 480 || requestedHeight >= 270
18
+ ? 1
19
+ : 0;
20
+ const supportedCandidates = TILE_PRESETS.slice(0, requestedPresetIndex + 1).reverse();
21
+ const selected = supportedCandidates.find(candidate => (
22
+ candidate.width * columns <= atlasWidth
23
+ && candidate.height * rows <= atlasHeight
24
+ )) || TILE_PRESETS[0];
25
+
26
+ return {
27
+ width: selected.width,
28
+ height: selected.height,
29
+ columns,
30
+ rows
31
+ };
32
+ }
@@ -4,6 +4,7 @@ import { spawn } from 'node:child_process';
4
4
  import { createRequire } from 'node:module';
5
5
  import { existsSync } from 'node:fs';
6
6
  import { decodeLzo1xBlock } from './lzo1x.js';
7
+ import { resolveMode4AtlasTileSize } from './mode4-atlas-sizing.js';
7
8
 
8
9
  const require = createRequire(import.meta.url);
9
10
  const DEFAULT_WIDTH = 1920;
@@ -11,8 +12,8 @@ const DEFAULT_HEIGHT = 1080;
11
12
  const DEFAULT_FPS = 20;
12
13
  const MAX_DEVICES = 100;
13
14
  const FRAME_POOL_SIZE = 3;
14
- const MAX_TILE_WIDTH = 480;
15
- const MAX_TILE_HEIGHT = 270;
15
+ const MAX_TILE_WIDTH = 640;
16
+ const MAX_TILE_HEIGHT = 360;
16
17
 
17
18
  const rgb565Red = new Uint8Array(65_536);
18
19
  const rgb565Green = new Uint8Array(65_536);
@@ -59,12 +60,18 @@ function normalizeConfig(value) {
59
60
  .map(item => String(item || '').trim()).filter(Boolean))].slice(0, MAX_DEVICES);
60
61
  const maxWidth = clamp(value?.width, 640, 3840, DEFAULT_WIDTH);
61
62
  const maxHeight = clamp(value?.height, 360, 2160, DEFAULT_HEIGHT);
62
- const sharpTiles = Number(value?.tileWidth) >= 480 || Number(value?.tileHeight) >= 270;
63
- const sourceTileWidth = sharpTiles ? 480 : 320;
64
- const sourceTileHeight = sharpTiles ? 270 : 180;
65
63
  const count = Math.max(1, deviceIds.length);
66
- const columns = Math.max(1, Math.ceil(Math.sqrt(count)));
67
- const rows = Math.max(1, Math.ceil(count / columns));
64
+ const tileSize = resolveMode4AtlasTileSize({
65
+ requestedWidth: value?.tileWidth,
66
+ requestedHeight: value?.tileHeight,
67
+ deviceCount: count,
68
+ atlasWidth: maxWidth,
69
+ atlasHeight: maxHeight
70
+ });
71
+ const columns = tileSize.columns;
72
+ const rows = tileSize.rows;
73
+ const sourceTileWidth = tileSize.width;
74
+ const sourceTileHeight = tileSize.height;
68
75
  const tileWidth = Math.max(2, Math.min(sourceTileWidth, Math.floor(maxWidth / columns))) & ~1;
69
76
  const tileHeight = Math.max(2, Math.min(sourceTileHeight, Math.floor(maxHeight / rows))) & ~1;
70
77
  return {
package/hub/src/server.js CHANGED
@@ -8,8 +8,9 @@ import { dirname, resolve } from 'node:path';
8
8
  import { fileURLToPath } from 'node:url';
9
9
  import os from 'node:os';
10
10
  import { WebSocketServer } from 'ws';
11
- import { createRemoteHub } from './remote-hub.js';
11
+ import { createRemoteHub } from './remote-hub.js';
12
12
  import { buildMode4AtlasSessionKey, Mode4AtlasPool, planMode4AtlasInputTransitions } from './mode4-atlas-pool.js';
13
+ import { resolveMode4AtlasTileSize } from './mode4-atlas-sizing.js';
13
14
  import { createHubFilesystem } from './filesystem/hub-filesystem.js';
14
15
  import { createHubTransferJobs } from './filesystem/transfer-jobs.js';
15
16
  import { createHubSharedFolders } from './filesystem/shared-folders.js';
@@ -2287,13 +2288,21 @@ function sendMode4AtlasFrame(ws, output) {
2287
2288
  }
2288
2289
 
2289
2290
  function configureMode4Atlas(ws, payload = {}) {
2290
- const deviceIds = normalizeDeviceIds(payload.deviceIds ?? payload.devices ?? payload.deviceId).slice(0, 100);
2291
- const captureDeviceIds = normalizeDeviceIds(payload.captureDeviceIds ?? payload.inputDeviceIds ?? deviceIds)
2292
- .filter(deviceId => deviceIds.includes(deviceId));
2293
- const monitorSelections = normalizeMonitorSelections(payload.monitorSelections);
2294
- const sharpTiles = Number(payload.tileWidth) >= 480 || Number(payload.tileHeight) >= 270;
2295
- const tileWidth = sharpTiles ? 480 : 320;
2296
- const tileHeight = sharpTiles ? 270 : 180;
2291
+ const deviceIds = normalizeDeviceIds(payload.deviceIds ?? payload.devices ?? payload.deviceId).slice(0, 100);
2292
+ const captureDeviceIds = normalizeDeviceIds(payload.captureDeviceIds ?? payload.inputDeviceIds ?? deviceIds)
2293
+ .filter(deviceId => deviceIds.includes(deviceId));
2294
+ const monitorSelections = normalizeMonitorSelections(payload.monitorSelections);
2295
+ const width = clampNumber(payload.width, 640, 3840, 1920);
2296
+ const height = clampNumber(payload.height, 360, 2160, 1080);
2297
+ const tileSize = resolveMode4AtlasTileSize({
2298
+ requestedWidth: payload.tileWidth,
2299
+ requestedHeight: payload.tileHeight,
2300
+ deviceCount: deviceIds.length,
2301
+ atlasWidth: width,
2302
+ atlasHeight: height
2303
+ });
2304
+ const tileWidth = tileSize.width;
2305
+ const tileHeight = tileSize.height;
2297
2306
  const previousInputDeviceIds = ws.liveDeskAtlasInputDeviceIds instanceof Set
2298
2307
  ? new Set(ws.liveDeskAtlasInputDeviceIds)
2299
2308
  : new Set();
@@ -2304,8 +2313,8 @@ function configureMode4Atlas(ws, payload = {}) {
2304
2313
  // every layout device ingestible lets a paused/reused input retain its
2305
2314
  // latest tile while only the changed device restarts capture.
2306
2315
  inputDeviceIds: deviceIds,
2307
- width: clampNumber(payload.width, 640, 3840, 1920),
2308
- height: clampNumber(payload.height, 360, 2160, 1080),
2316
+ width,
2317
+ height,
2309
2318
  tileWidth,
2310
2319
  tileHeight,
2311
2320
  fps: clampNumber(payload.fps, 1, 30, 20),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "livedesk",
3
- "version": "0.1.408",
4
- "livedeskClientVersion": "0.1.173",
3
+ "version": "0.1.409",
4
+ "livedeskClientVersion": "0.1.174",
5
5
  "buildFlavor": "production",
6
6
  "description": "LiveDesk Hub and client launcher",
7
7
  "type": "module",
@@ -49,10 +49,10 @@
49
49
  "ws": "^8.18.3"
50
50
  },
51
51
  "optionalDependencies": {
52
- "@livedesk/fast-linux-x64": "0.1.379",
53
- "@livedesk/fast-osx-arm64": "0.1.379",
54
- "@livedesk/fast-osx-x64": "0.1.379",
55
- "@livedesk/fast-win-x64": "0.1.379"
52
+ "@livedesk/fast-linux-x64": "0.1.380",
53
+ "@livedesk/fast-osx-arm64": "0.1.380",
54
+ "@livedesk/fast-osx-x64": "0.1.380",
55
+ "@livedesk/fast-win-x64": "0.1.380"
56
56
  },
57
57
  "publishConfig": {
58
58
  "access": "public"