livedesk 0.1.169 → 0.1.170
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
|
@@ -150,6 +150,7 @@ const DUPLICATE_DEVICE_ACTIVE_REJECT_MS = 15000;
|
|
|
150
150
|
const DUPLICATE_DEVICE_LOG_THROTTLE_MS = 60000;
|
|
151
151
|
const DUPLICATE_DEVICE_RETRY_AFTER_MS = 30000;
|
|
152
152
|
const AGENT_BINARY_INGRESS_QUEUE_PACKETS = 256;
|
|
153
|
+
const MODE5_AGENT_BINARY_INGRESS_QUEUE_PACKETS = 2;
|
|
153
154
|
const AGENT_BINARY_INGRESS_DRAIN_BUDGET_PACKETS = 64;
|
|
154
155
|
const SYNTHETIC_FRAME_DATA_URL = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAABCAYAAAD0In+KAAAADElEQVR42mP8z8AAAAMBAQDJ/pLvAAAAAElFTkSuQmCC';
|
|
155
156
|
const SYNTHETIC_FRAME_PAYLOAD = Buffer.from(SYNTHETIC_FRAME_DATA_URL.split(',')[1], 'base64');
|
|
@@ -3132,6 +3133,8 @@ export function createRemoteHub(options = {}) {
|
|
|
3132
3133
|
compressMs: readFrameStageMs(message, 'compressMs'),
|
|
3133
3134
|
deltaTileSize: Number.isFinite(Number(message.deltaTileSize)) ? Number(message.deltaTileSize) : 0,
|
|
3134
3135
|
deltaTileCount: Number.isFinite(Number(message.deltaTileCount)) ? Number(message.deltaTileCount) : 0,
|
|
3136
|
+
deltaVisualTileCount: Number.isFinite(Number(message.deltaVisualTileCount)) ? Number(message.deltaVisualTileCount) : 0,
|
|
3137
|
+
deltaRefreshTileCount: Number.isFinite(Number(message.deltaRefreshTileCount)) ? Number(message.deltaRefreshTileCount) : 0,
|
|
3135
3138
|
deltaTotalTiles: Number.isFinite(Number(message.deltaTotalTiles)) ? Number(message.deltaTotalTiles) : 0,
|
|
3136
3139
|
sameContentStreak,
|
|
3137
3140
|
payload,
|
|
@@ -3330,6 +3333,8 @@ export function createRemoteHub(options = {}) {
|
|
|
3330
3333
|
compressMs: readFrameStageMs(message, 'compressMs'),
|
|
3331
3334
|
deltaTileSize: Number.isFinite(Number(message.deltaTileSize)) ? Number(message.deltaTileSize) : 0,
|
|
3332
3335
|
deltaTileCount: Number.isFinite(Number(message.deltaTileCount)) ? Number(message.deltaTileCount) : 0,
|
|
3336
|
+
deltaVisualTileCount: Number.isFinite(Number(message.deltaVisualTileCount)) ? Number(message.deltaVisualTileCount) : 0,
|
|
3337
|
+
deltaRefreshTileCount: Number.isFinite(Number(message.deltaRefreshTileCount)) ? Number(message.deltaRefreshTileCount) : 0,
|
|
3333
3338
|
deltaTotalTiles: Number.isFinite(Number(message.deltaTotalTiles)) ? Number(message.deltaTotalTiles) : 0,
|
|
3334
3339
|
sameContentStreak,
|
|
3335
3340
|
payload,
|
|
@@ -3500,6 +3505,23 @@ export function createRemoteHub(options = {}) {
|
|
|
3500
3505
|
state.binaryQueueDrops = Number(state.binaryQueueDrops || 0) + 1;
|
|
3501
3506
|
}
|
|
3502
3507
|
|
|
3508
|
+
function isMode5BinaryHeader(header) {
|
|
3509
|
+
const mode = safeString(header?.frameMode || header?.mode, 40).toLowerCase();
|
|
3510
|
+
return mode === 'mode5-lzo-delta';
|
|
3511
|
+
}
|
|
3512
|
+
|
|
3513
|
+
function dropQueuedMode5AgentBinaryFrame(state, header) {
|
|
3514
|
+
const streamId = safeString(header?.streamId, 160);
|
|
3515
|
+
const dropIndex = state.binaryQueue.findIndex(item => isMode5BinaryHeader(item?.header)
|
|
3516
|
+
&& (!streamId || safeString(item?.header?.streamId, 160) === streamId));
|
|
3517
|
+
if (dropIndex < 0) {
|
|
3518
|
+
return false;
|
|
3519
|
+
}
|
|
3520
|
+
state.binaryQueue.splice(dropIndex, 1);
|
|
3521
|
+
state.binaryQueueDrops = Number(state.binaryQueueDrops || 0) + 1;
|
|
3522
|
+
return true;
|
|
3523
|
+
}
|
|
3524
|
+
|
|
3503
3525
|
function scheduleAgentBinaryIngress(socket, state) {
|
|
3504
3526
|
if (!state || state.closed || !socket || socket.destroyed) {
|
|
3505
3527
|
return;
|
|
@@ -3545,6 +3567,17 @@ export function createRemoteHub(options = {}) {
|
|
|
3545
3567
|
if (!Array.isArray(state.binaryQueue)) {
|
|
3546
3568
|
state.binaryQueue = [];
|
|
3547
3569
|
}
|
|
3570
|
+
if (isMode5BinaryHeader(header)) {
|
|
3571
|
+
const streamId = safeString(header?.streamId, 160);
|
|
3572
|
+
let queuedMode5Packets = state.binaryQueue.filter(item => isMode5BinaryHeader(item?.header)
|
|
3573
|
+
&& (!streamId || safeString(item?.header?.streamId, 160) === streamId)).length;
|
|
3574
|
+
while (queuedMode5Packets >= MODE5_AGENT_BINARY_INGRESS_QUEUE_PACKETS) {
|
|
3575
|
+
if (!dropQueuedMode5AgentBinaryFrame(state, header)) {
|
|
3576
|
+
break;
|
|
3577
|
+
}
|
|
3578
|
+
queuedMode5Packets -= 1;
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3548
3581
|
while (state.binaryQueue.length >= AGENT_BINARY_INGRESS_QUEUE_PACKETS) {
|
|
3549
3582
|
dropQueuedAgentBinaryFrame(state);
|
|
3550
3583
|
}
|
package/hub/src/server.js
CHANGED
|
@@ -24,6 +24,8 @@ const httpPort = Number(process.env.LIVEDESK_HUB_HTTP_PORT || process.env.PORT |
|
|
|
24
24
|
const frameBackpressureBytes = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_BACKPRESSURE_BYTES', 64 * 1024 * 1024);
|
|
25
25
|
const frameClientQueuePackets = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_QUEUE_PACKETS', 256);
|
|
26
26
|
const frameClientDrainBudgetPackets = readPositiveIntegerEnv('LIVEDESK_FRAME_WS_DRAIN_BUDGET_PACKETS', 64);
|
|
27
|
+
const mode5FrameBackpressureBytes = readPositiveIntegerEnv('LIVEDESK_MODE5_WS_BACKPRESSURE_BYTES', 2 * 1024 * 1024);
|
|
28
|
+
const mode5FrameQueuePackets = readPositiveIntegerEnv('LIVEDESK_MODE5_WS_QUEUE_PACKETS', 2);
|
|
27
29
|
const frameClients = new Set();
|
|
28
30
|
const frameClientsByDeviceId = new Map();
|
|
29
31
|
const frameWildcardClients = new Set();
|
|
@@ -538,6 +540,16 @@ function dropQueuedFrameForLane(lane) {
|
|
|
538
540
|
}
|
|
539
541
|
}
|
|
540
542
|
|
|
543
|
+
function dropQueuedMode5FrameForLane(lane, deviceId) {
|
|
544
|
+
const dropIndex = lane.queue.findIndex(item => item?.isMode5 && item.deviceId === deviceId);
|
|
545
|
+
if (dropIndex < 0) {
|
|
546
|
+
return false;
|
|
547
|
+
}
|
|
548
|
+
lane.queue.splice(dropIndex, 1);
|
|
549
|
+
lane.dropped += 1;
|
|
550
|
+
return true;
|
|
551
|
+
}
|
|
552
|
+
|
|
541
553
|
function drainFrameClientSendLane(ws) {
|
|
542
554
|
const lane = ws.liveDeskFrameSendLane;
|
|
543
555
|
if (!lane || lane.draining) {
|
|
@@ -584,7 +596,8 @@ function enqueueFramePacketForClient(ws, packet, meta) {
|
|
|
584
596
|
ws.liveDeskFrameBackpressureDrops = Number(ws.liveDeskFrameBackpressureDrops || 0) + 1;
|
|
585
597
|
return false;
|
|
586
598
|
}
|
|
587
|
-
|
|
599
|
+
const backpressureBytes = meta.isMode5 ? mode5FrameBackpressureBytes : frameBackpressureBytes;
|
|
600
|
+
if (ws.bufferedAmount > backpressureBytes) {
|
|
588
601
|
ws.liveDeskFrameBackpressured = true;
|
|
589
602
|
lane.dropped += 1;
|
|
590
603
|
if (meta.isH264 && meta.deviceId) {
|
|
@@ -593,6 +606,16 @@ function enqueueFramePacketForClient(ws, packet, meta) {
|
|
|
593
606
|
ws.liveDeskFrameBackpressureDrops = Number(ws.liveDeskFrameBackpressureDrops || 0) + 1;
|
|
594
607
|
return false;
|
|
595
608
|
}
|
|
609
|
+
if (meta.isMode5) {
|
|
610
|
+
let queuedMode5Packets = lane.queue.filter(item => item?.isMode5 && item.deviceId === meta.deviceId).length;
|
|
611
|
+
while (queuedMode5Packets >= mode5FrameQueuePackets) {
|
|
612
|
+
if (!dropQueuedMode5FrameForLane(lane, meta.deviceId)) {
|
|
613
|
+
break;
|
|
614
|
+
}
|
|
615
|
+
queuedMode5Packets -= 1;
|
|
616
|
+
ws.liveDeskFrameBackpressureDrops = Number(ws.liveDeskFrameBackpressureDrops || 0) + 1;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
596
619
|
while (lane.queue.length >= frameClientQueuePackets) {
|
|
597
620
|
dropQueuedFrameForLane(lane);
|
|
598
621
|
ws.liveDeskFrameBackpressureDrops = Number(ws.liveDeskFrameBackpressureDrops || 0) + 1;
|
|
@@ -602,6 +625,7 @@ function enqueueFramePacketForClient(ws, packet, meta) {
|
|
|
602
625
|
deviceId: meta.deviceId,
|
|
603
626
|
frameSeq: meta.frameSeq,
|
|
604
627
|
isH264: meta.isH264,
|
|
628
|
+
isMode5: meta.isMode5,
|
|
605
629
|
isKeyFrame: meta.isKeyFrame
|
|
606
630
|
});
|
|
607
631
|
drainFrameClientSendLane(ws);
|
|
@@ -795,6 +819,8 @@ function buildRemoteFrameBinaryPacket(frameEvent, diagnostics = {}) {
|
|
|
795
819
|
compressMs: Number(frame.compressMs || 0) || 0,
|
|
796
820
|
deltaTileSize: Number(frame.deltaTileSize || 0) || 0,
|
|
797
821
|
deltaTileCount: Number(frame.deltaTileCount || 0) || 0,
|
|
822
|
+
deltaVisualTileCount: Number(frame.deltaVisualTileCount || 0) || 0,
|
|
823
|
+
deltaRefreshTileCount: Number(frame.deltaRefreshTileCount || 0) || 0,
|
|
798
824
|
deltaTotalTiles: Number(frame.deltaTotalTiles || 0) || 0,
|
|
799
825
|
sameContentStreak: Number(frame.sameContentStreak || 0) || 0,
|
|
800
826
|
layoutVersion: Number(frame.layoutVersion || 0) || 0,
|
|
@@ -854,6 +880,7 @@ function broadcastRemoteBinaryFrame(frameEvent) {
|
|
|
854
880
|
const frame = frameEvent.frame || {};
|
|
855
881
|
const isH264 = String(frame.codec || frame.mimeType || frame.format || '').toLowerCase().includes('h264')
|
|
856
882
|
|| String(frame.frameMode || frame.mode || '').toLowerCase() === 'mode3-h264-hw';
|
|
883
|
+
const isMode5 = String(frame.frameMode || frame.mode || '').toLowerCase() === 'mode5-lzo-delta';
|
|
857
884
|
const isKeyFrame = frame.isKeyFrame === true || String(frame.chunkType || '').toLowerCase() === 'key';
|
|
858
885
|
const frameSeq = Number(frame.frameSeq || 0) || 0;
|
|
859
886
|
for (const client of targetClients) {
|
|
@@ -879,7 +906,7 @@ function broadcastRemoteBinaryFrame(frameEvent) {
|
|
|
879
906
|
if (!packet) {
|
|
880
907
|
continue;
|
|
881
908
|
}
|
|
882
|
-
enqueueFramePacketForClient(client, packet, { deviceId, frameSeq, isH264, isKeyFrame });
|
|
909
|
+
enqueueFramePacketForClient(client, packet, { deviceId, frameSeq, isH264, isMode5, isKeyFrame });
|
|
883
910
|
}
|
|
884
911
|
}
|
|
885
912
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livedesk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.170",
|
|
4
4
|
"description": "LiveDesk Hub and client launcher",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -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.110",
|
|
35
35
|
"cors": "^2.8.5",
|
|
36
36
|
"express": "^4.21.2",
|
|
37
37
|
"ffmpeg-static": "^5.3.0",
|