livedesk 0.1.441 → 0.1.442
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/bin/livedesk.js +40 -13
- package/bootstrap/client-process-identity.js +23 -2
- package/client/bin/livedesk-client.js +6 -0
- package/client/package.json +5 -5
- package/client/src/runtime/agent-process-lifecycle.js +100 -8
- package/hub/package.json +1 -1
- package/hub/src/remote-hub.js +6 -0
- package/hub/src/server.js +3 -0
- package/hub/src/transport/udp-rendezvous.js +402 -78
- package/package.json +6 -6
- package/web/dist/assets/index-D3VhnrP6.js +25 -0
- package/web/dist/index.html +1 -1
- package/web/dist/assets/index-BjLnf_H4.js +0 -25
package/bin/livedesk.js
CHANGED
|
@@ -13,7 +13,10 @@ import { acquireRuntimeLock } from '../bootstrap/runtime-lock.js';
|
|
|
13
13
|
import { migrateLegacyClientState } from '../bootstrap/state-migration.js';
|
|
14
14
|
import { createRoleBootstrapServer } from '../bootstrap/role-bootstrap-server.js';
|
|
15
15
|
import { parseLsofPids } from '../bootstrap/port-inspection.js';
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
isKnownLiveDeskCaptureHelperProcess,
|
|
18
|
+
isKnownLiveDeskClientAgentProcess
|
|
19
|
+
} from '../bootstrap/client-process-identity.js';
|
|
17
20
|
import { runLegacyClientUpdateSupervisorCli } from '../bootstrap/legacy-client-update.js';
|
|
18
21
|
import { transferSavedClientSessionToHub } from '../bootstrap/hub-auth-handoff.js';
|
|
19
22
|
|
|
@@ -569,11 +572,11 @@ function runQuiet(command, args) {
|
|
|
569
572
|
}
|
|
570
573
|
|
|
571
574
|
function isKnownLiveDeskLauncherProcess(processName, commandLine) {
|
|
572
|
-
const normalizedName = String(processName || '').trim();
|
|
575
|
+
const normalizedName = String(processName || '').trim().replaceAll('\\', '/').split('/').pop() || '';
|
|
573
576
|
const normalizedCommandLine = String(commandLine || '').replaceAll('\\', '/');
|
|
574
577
|
return /^(?:node|node\.exe)$/i.test(normalizedName)
|
|
575
|
-
&& /livedesk/i
|
|
576
|
-
|
|
578
|
+
&& /(?:^|\/)(?:node_modules\/livedesk\/bin\/livedesk\.js|packages\/livedesk\/bin\/livedesk\.js|node_modules\/\.bin\/livedesk)(?:\s|["']|$)/i
|
|
579
|
+
.test(normalizedCommandLine);
|
|
577
580
|
}
|
|
578
581
|
|
|
579
582
|
function existingRuntimeProbePorts() {
|
|
@@ -595,7 +598,7 @@ async function probeExistingRuntimeIdentity(existing) {
|
|
|
595
598
|
|
|
596
599
|
for (const port of existingRuntimeProbePorts()) {
|
|
597
600
|
const controller = new AbortController();
|
|
598
|
-
const timer = setTimeout(() => controller.abort(),
|
|
601
|
+
const timer = setTimeout(() => controller.abort(), 2500);
|
|
599
602
|
try {
|
|
600
603
|
const baseUrl = `http://127.0.0.1:${port}`;
|
|
601
604
|
const [healthResponse, statusResponse] = await Promise.all([
|
|
@@ -707,7 +710,19 @@ async function stopExistingRuntime(existing) {
|
|
|
707
710
|
if (error?.code !== 'ESRCH') throw error;
|
|
708
711
|
}
|
|
709
712
|
}
|
|
710
|
-
|
|
713
|
+
try {
|
|
714
|
+
await waitForProcessExit(processId);
|
|
715
|
+
} catch (error) {
|
|
716
|
+
if (os.platform() === 'win32') throw error;
|
|
717
|
+
console.warn(
|
|
718
|
+
`[LiveDesk] Confirmed launcher pid ${processId} did not finish graceful Client cleanup; `
|
|
719
|
+
+ 'force-stopping that launcher only. Verified orphan agents/helpers will be audited before restart.'
|
|
720
|
+
);
|
|
721
|
+
try { process.kill(processId, 'SIGKILL'); } catch (killError) {
|
|
722
|
+
if (killError?.code !== 'ESRCH') throw killError;
|
|
723
|
+
}
|
|
724
|
+
await waitForProcessExit(processId, 2000);
|
|
725
|
+
}
|
|
711
726
|
return runtimeProof;
|
|
712
727
|
}
|
|
713
728
|
|
|
@@ -881,7 +896,7 @@ async function stopUnixProcessesOnPorts(ports) {
|
|
|
881
896
|
async function stopStaleUnixClientAgents() {
|
|
882
897
|
if (os.platform() === 'win32') return;
|
|
883
898
|
const candidatePids = new Set();
|
|
884
|
-
for (const pattern of ['livedesk-client-fast', 'livedesk-client-node.js']) {
|
|
899
|
+
for (const pattern of ['livedesk-client-fast', 'livedesk-client-node.js', 'livedesk-sck-h264']) {
|
|
885
900
|
const result = await runQuiet('pgrep', ['-f', pattern]);
|
|
886
901
|
if (result.error?.code === 'ENOENT') return;
|
|
887
902
|
for (const pid of parseLsofPids(result.stdout)) {
|
|
@@ -889,22 +904,29 @@ async function stopStaleUnixClientAgents() {
|
|
|
889
904
|
}
|
|
890
905
|
}
|
|
891
906
|
|
|
892
|
-
const
|
|
907
|
+
const staleProcesses = [];
|
|
893
908
|
for (const pid of candidatePids) {
|
|
894
909
|
const details = await getProcessDetails(pid);
|
|
895
910
|
if (details && isKnownLiveDeskClientAgentProcess(details.processName, details.commandLine)) {
|
|
896
|
-
|
|
911
|
+
staleProcesses.push({ pid, type: 'agent' });
|
|
912
|
+
} else if (details && isKnownLiveDeskCaptureHelperProcess(details.processName, details.commandLine)) {
|
|
913
|
+
staleProcesses.push({ pid, type: 'capture-helper' });
|
|
897
914
|
}
|
|
898
915
|
}
|
|
899
|
-
if (
|
|
916
|
+
if (staleProcesses.length === 0) {
|
|
917
|
+
if (process.env.LIVEDESK_DEBUG === '1') {
|
|
918
|
+
console.log('[LiveDesk] Client lifecycle audit: verified stale agents=0 capture-helpers=0.');
|
|
919
|
+
}
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
900
922
|
|
|
901
|
-
for (const pid of
|
|
923
|
+
for (const { pid } of staleProcesses) {
|
|
902
924
|
try { process.kill(pid, 'SIGTERM'); } catch (error) {
|
|
903
925
|
if (error?.code !== 'ESRCH') throw error;
|
|
904
926
|
}
|
|
905
927
|
}
|
|
906
928
|
await waitMilliseconds(500);
|
|
907
|
-
for (const pid of
|
|
929
|
+
for (const { pid } of staleProcesses) {
|
|
908
930
|
try {
|
|
909
931
|
process.kill(pid, 0);
|
|
910
932
|
process.kill(pid, 'SIGKILL');
|
|
@@ -912,7 +934,12 @@ async function stopStaleUnixClientAgents() {
|
|
|
912
934
|
if (error?.code !== 'ESRCH') throw error;
|
|
913
935
|
}
|
|
914
936
|
}
|
|
915
|
-
|
|
937
|
+
const agentPids = staleProcesses.filter(item => item.type === 'agent').map(item => item.pid);
|
|
938
|
+
const helperPids = staleProcesses.filter(item => item.type === 'capture-helper').map(item => item.pid);
|
|
939
|
+
console.log(
|
|
940
|
+
`[LiveDesk] Client lifecycle audit: verified stale agents=${agentPids.length} `
|
|
941
|
+
+ `capture-helpers=${helperPids.length}; stopped pids=${staleProcesses.map(item => item.pid).join(', ')}.`
|
|
942
|
+
);
|
|
916
943
|
}
|
|
917
944
|
|
|
918
945
|
async function stopProcessesOnPorts(ports) {
|
|
@@ -2,8 +2,29 @@ export function isKnownLiveDeskClientAgentProcess(processName, commandLine) {
|
|
|
2
2
|
const normalizedName = String(processName || '').trim().replaceAll('\\', '/').split('/').pop() || '';
|
|
3
3
|
const normalizedCommandLine = String(commandLine || '').replaceAll('\\', '/');
|
|
4
4
|
const isNode = /^(?:node|node\.exe)$/i.test(normalizedName);
|
|
5
|
+
const isDotnet = /^(?:dotnet|dotnet\.exe)$/i.test(normalizedName);
|
|
5
6
|
const isFast = /^livedesk-client-fast(?:\.exe)?$/i.test(normalizedName);
|
|
6
7
|
const isKnownNodeAgent = /(?:node_modules\/(?:livedesk\/client|@livedesk\/client)|packages\/(?:livedesk\/client|client))\/bin\/livedesk-client-node\.js(?:\s|["']|$)/i.test(normalizedCommandLine);
|
|
7
|
-
const
|
|
8
|
-
|
|
8
|
+
const bundledFastRoot = '(?:node_modules/(?:livedesk/client|@livedesk/client)|packages/(?:livedesk/client|client))/fast/[^/\\s]+';
|
|
9
|
+
const optionalFastRoot = 'node_modules/@livedesk/fast-(?:linux-x64|osx-arm64|osx-x64|win-x64)/fast';
|
|
10
|
+
const fastRoot = `(?:${bundledFastRoot}|${optionalFastRoot})`;
|
|
11
|
+
const isKnownFastExecutable = new RegExp(
|
|
12
|
+
`${fastRoot}/livedesk-client-fast(?:\\.exe)?(?:\\s|["']|$)`,
|
|
13
|
+
'i'
|
|
14
|
+
).test(normalizedCommandLine);
|
|
15
|
+
const isKnownFastDll = new RegExp(
|
|
16
|
+
`${fastRoot}/livedesk-client-fast\\.dll(?:\\s|["']|$)`,
|
|
17
|
+
'i'
|
|
18
|
+
).test(normalizedCommandLine);
|
|
19
|
+
return (isNode && isKnownNodeAgent)
|
|
20
|
+
|| (isFast && isKnownFastExecutable)
|
|
21
|
+
|| (isDotnet && isKnownFastDll);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isKnownLiveDeskCaptureHelperProcess(processName, commandLine) {
|
|
25
|
+
const normalizedName = String(processName || '').trim().replaceAll('\\', '/').split('/').pop() || '';
|
|
26
|
+
const normalizedCommandLine = String(commandLine || '').replaceAll('\\', '/');
|
|
27
|
+
return /^livedesk-sck-h264$/i.test(normalizedName)
|
|
28
|
+
&& /(?:^|\/)\.livedesk\/helpers\/macos-sck-h264\/livedesk-sck-h264(?:\s|["']|$)/i
|
|
29
|
+
.test(normalizedCommandLine);
|
|
9
30
|
}
|
|
@@ -4102,11 +4102,17 @@ function spawnAgent(command, args, env = process.env, onStart = null) {
|
|
|
4102
4102
|
agentPid: 0,
|
|
4103
4103
|
restartVerified: false
|
|
4104
4104
|
});
|
|
4105
|
+
const ownsProcessGroup = process.platform !== 'win32';
|
|
4105
4106
|
const child = spawn(command, args, {
|
|
4106
4107
|
env,
|
|
4107
4108
|
stdio: 'inherit',
|
|
4109
|
+
// A dedicated Unix process group lets Ctrl+C, replacement startup, and
|
|
4110
|
+
// forced shutdown terminate RemoteFast together with its SCK/FFmpeg
|
|
4111
|
+
// descendants without touching npm, the terminal, or unrelated jobs.
|
|
4112
|
+
detached: ownsProcessGroup,
|
|
4108
4113
|
windowsHide: true
|
|
4109
4114
|
});
|
|
4115
|
+
child.livedeskOwnsProcessGroup = ownsProcessGroup;
|
|
4110
4116
|
activeAgentProcess = child;
|
|
4111
4117
|
if (typeof onStart === 'function') {
|
|
4112
4118
|
onStart(child);
|
package/client/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livedesk/client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.197",
|
|
4
4
|
"description": "LiveDesk local remote client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
"ws": "^8.18.3"
|
|
42
42
|
},
|
|
43
43
|
"optionalDependencies": {
|
|
44
|
-
"@livedesk/fast-linux-x64": "0.1.
|
|
45
|
-
"@livedesk/fast-osx-arm64": "0.1.
|
|
46
|
-
"@livedesk/fast-osx-x64": "0.1.
|
|
47
|
-
"@livedesk/fast-win-x64": "0.1.
|
|
44
|
+
"@livedesk/fast-linux-x64": "0.1.404",
|
|
45
|
+
"@livedesk/fast-osx-arm64": "0.1.404",
|
|
46
|
+
"@livedesk/fast-osx-x64": "0.1.404",
|
|
47
|
+
"@livedesk/fast-win-x64": "0.1.404"
|
|
48
48
|
},
|
|
49
49
|
"publishConfig": {
|
|
50
50
|
"access": "public"
|
|
@@ -1,9 +1,61 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
|
|
1
3
|
const SIGNAL_EXIT_CODES = Object.freeze({ SIGINT: 130, SIGTERM: 143 });
|
|
2
4
|
|
|
5
|
+
function terminateWindowsProcessTree(processId) {
|
|
6
|
+
return new Promise(resolve => {
|
|
7
|
+
execFile(
|
|
8
|
+
'taskkill.exe',
|
|
9
|
+
['/PID', String(processId), '/T', '/F'],
|
|
10
|
+
{
|
|
11
|
+
windowsHide: true,
|
|
12
|
+
timeout: 10000,
|
|
13
|
+
killSignal: 'SIGKILL'
|
|
14
|
+
},
|
|
15
|
+
error => resolve({ ok: !error, error: error || null })
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isOwnedUnixProcessGroupAlive(child, platform, signalProcess) {
|
|
21
|
+
const processId = Number(child?.pid || 0);
|
|
22
|
+
if (platform === 'win32'
|
|
23
|
+
|| child?.livedeskOwnsProcessGroup !== true
|
|
24
|
+
|| !Number.isInteger(processId)
|
|
25
|
+
|| processId <= 1) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
signalProcess(-processId, 0);
|
|
30
|
+
return true;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
return error?.code === 'EPERM';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function signalAgentTree(child, signal, platform, signalProcess) {
|
|
37
|
+
const processId = Number(child?.pid || 0);
|
|
38
|
+
if (platform !== 'win32'
|
|
39
|
+
&& child?.livedeskOwnsProcessGroup === true
|
|
40
|
+
&& Number.isInteger(processId)
|
|
41
|
+
&& processId > 1) {
|
|
42
|
+
try {
|
|
43
|
+
signalProcess(-processId, signal);
|
|
44
|
+
return;
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (error?.code !== 'ESRCH') throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
child.kill(signal);
|
|
50
|
+
}
|
|
51
|
+
|
|
3
52
|
export function installAgentTerminationHandlers({
|
|
4
53
|
hostProcess = process,
|
|
5
54
|
getAgentProcess,
|
|
6
|
-
shutdownTimeoutMs =
|
|
55
|
+
shutdownTimeoutMs = 8000,
|
|
56
|
+
platform = process.platform,
|
|
57
|
+
signalProcess = (pid, signal) => process.kill(pid, signal),
|
|
58
|
+
terminateWindowsTree = terminateWindowsProcessTree,
|
|
7
59
|
exitProcess = code => hostProcess.exit(code)
|
|
8
60
|
} = {}) {
|
|
9
61
|
if (typeof getAgentProcess !== 'function') {
|
|
@@ -18,32 +70,72 @@ export function installAgentTerminationHandlers({
|
|
|
18
70
|
terminating = true;
|
|
19
71
|
const exitCode = SIGNAL_EXIT_CODES[signal] || 1;
|
|
20
72
|
const child = getAgentProcess();
|
|
21
|
-
if (!child || child.exitCode !== null
|
|
73
|
+
if (!child || child.exitCode !== null) {
|
|
22
74
|
exitProcess(exitCode);
|
|
23
75
|
return;
|
|
24
76
|
}
|
|
25
77
|
|
|
26
78
|
let finished = false;
|
|
79
|
+
let poll = null;
|
|
80
|
+
let timeout = null;
|
|
81
|
+
let hardStop = null;
|
|
27
82
|
const finish = () => {
|
|
28
83
|
if (finished) return;
|
|
29
84
|
finished = true;
|
|
85
|
+
if (poll) clearInterval(poll);
|
|
86
|
+
if (timeout) clearTimeout(timeout);
|
|
87
|
+
if (hardStop) clearTimeout(hardStop);
|
|
30
88
|
exitProcess(exitCode);
|
|
31
89
|
};
|
|
32
|
-
child
|
|
90
|
+
const processId = Number(child?.pid || 0);
|
|
91
|
+
if (platform === 'win32') {
|
|
92
|
+
if (!Number.isInteger(processId) || processId <= 1) {
|
|
93
|
+
finish();
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// On Windows child.kill() only gives us the Agent leader's
|
|
97
|
+
// lifecycle. It does not provide an authoritative contract
|
|
98
|
+
// that FFmpeg descendants have stopped. Keep the launcher
|
|
99
|
+
// alive until taskkill has completed against this exact,
|
|
100
|
+
// launcher-owned process tree. Never search for or terminate
|
|
101
|
+
// unrelated ffmpeg.exe processes globally.
|
|
102
|
+
let treeTermination;
|
|
103
|
+
try {
|
|
104
|
+
treeTermination = terminateWindowsTree(processId);
|
|
105
|
+
} catch {
|
|
106
|
+
finish();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
Promise.resolve(treeTermination)
|
|
110
|
+
.catch(() => null)
|
|
111
|
+
.finally(finish);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const finishWhenTreeStops = () => {
|
|
115
|
+
const ownsUnixGroup = child?.livedeskOwnsProcessGroup === true
|
|
116
|
+
&& Number(child?.pid || 0) > 1;
|
|
117
|
+
const childAlive = child.exitCode === null && child.signalCode == null;
|
|
118
|
+
const groupAlive = ownsUnixGroup
|
|
119
|
+
&& isOwnedUnixProcessGroupAlive(child, platform, signalProcess);
|
|
120
|
+
if (!childAlive && !groupAlive) {
|
|
121
|
+
finish();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
child.once('exit', finishWhenTreeStops);
|
|
33
125
|
try {
|
|
34
|
-
child
|
|
126
|
+
signalAgentTree(child, signal, platform, signalProcess);
|
|
35
127
|
} catch {
|
|
36
128
|
finish();
|
|
37
129
|
return;
|
|
38
130
|
}
|
|
39
|
-
|
|
131
|
+
poll = setInterval(finishWhenTreeStops, 50);
|
|
132
|
+
timeout = setTimeout(() => {
|
|
40
133
|
try {
|
|
41
|
-
|
|
134
|
+
signalAgentTree(child, 'SIGKILL', platform, signalProcess);
|
|
42
135
|
} catch {
|
|
43
136
|
}
|
|
44
|
-
finish
|
|
137
|
+
hardStop = setTimeout(finish, 250);
|
|
45
138
|
}, Math.max(100, Number(shutdownTimeoutMs) || 3000));
|
|
46
|
-
timeout.unref?.();
|
|
47
139
|
};
|
|
48
140
|
handlers.set(signal, handler);
|
|
49
141
|
hostProcess.once(signal, handler);
|
package/hub/package.json
CHANGED
package/hub/src/remote-hub.js
CHANGED
|
@@ -3881,6 +3881,9 @@ export function createRemoteHub(options = {}) {
|
|
|
3881
3881
|
nativeEncodableFrameCount: Number.isFinite(Number(message.nativeEncodableFrameCount)) ? Number(message.nativeEncodableFrameCount) : 0,
|
|
3882
3882
|
nativeSkippedFrameCount: Number.isFinite(Number(message.nativeSkippedFrameCount)) ? Number(message.nativeSkippedFrameCount) : 0,
|
|
3883
3883
|
nativeEncodedFrameCount: Number.isFinite(Number(message.nativeEncodedFrameCount)) ? Number(message.nativeEncodedFrameCount) : 0,
|
|
3884
|
+
nativeEncodeFramesInFlight: Number.isFinite(Number(message.nativeEncodeFramesInFlight)) ? Number(message.nativeEncodeFramesInFlight) : 0,
|
|
3885
|
+
nativeBackpressureSkippedFrameCount: Number.isFinite(Number(message.nativeBackpressureSkippedFrameCount)) ? Number(message.nativeBackpressureSkippedFrameCount) : 0,
|
|
3886
|
+
nativeIdleSkippedFrameCount: Number.isFinite(Number(message.nativeIdleSkippedFrameCount)) ? Number(message.nativeIdleSkippedFrameCount) : 0,
|
|
3884
3887
|
nativeCaptureTelemetryAt: safeString(message.nativeCaptureTelemetryAt, 80),
|
|
3885
3888
|
droppedByAgent: Number.isFinite(Number(message.droppedByAgent)) ? Number(message.droppedByAgent) : 0,
|
|
3886
3889
|
hardwareEncoder: safeString(message.hardwareEncoder, 80),
|
|
@@ -4258,6 +4261,9 @@ export function createRemoteHub(options = {}) {
|
|
|
4258
4261
|
nativeEncodableFrameCount: Number.isFinite(Number(message.nativeEncodableFrameCount)) ? Number(message.nativeEncodableFrameCount) : 0,
|
|
4259
4262
|
nativeSkippedFrameCount: Number.isFinite(Number(message.nativeSkippedFrameCount)) ? Number(message.nativeSkippedFrameCount) : 0,
|
|
4260
4263
|
nativeEncodedFrameCount: Number.isFinite(Number(message.nativeEncodedFrameCount)) ? Number(message.nativeEncodedFrameCount) : 0,
|
|
4264
|
+
nativeEncodeFramesInFlight: Number.isFinite(Number(message.nativeEncodeFramesInFlight)) ? Number(message.nativeEncodeFramesInFlight) : 0,
|
|
4265
|
+
nativeBackpressureSkippedFrameCount: Number.isFinite(Number(message.nativeBackpressureSkippedFrameCount)) ? Number(message.nativeBackpressureSkippedFrameCount) : 0,
|
|
4266
|
+
nativeIdleSkippedFrameCount: Number.isFinite(Number(message.nativeIdleSkippedFrameCount)) ? Number(message.nativeIdleSkippedFrameCount) : 0,
|
|
4261
4267
|
nativeCaptureTelemetryAt: safeString(message.nativeCaptureTelemetryAt, 80),
|
|
4262
4268
|
droppedByAgent: Number.isFinite(Number(message.droppedByAgent)) ? Number(message.droppedByAgent) : 0,
|
|
4263
4269
|
hubIngressDropped: Number.isFinite(Number(message.hubIngressDropped)) ? Number(message.hubIngressDropped) : 0,
|
package/hub/src/server.js
CHANGED
|
@@ -2070,6 +2070,9 @@ function buildRemoteFrameBinaryPacket(frameEvent, diagnostics = {}) {
|
|
|
2070
2070
|
nativeEncodableFrameCount: Number(frame.nativeEncodableFrameCount || 0) || 0,
|
|
2071
2071
|
nativeSkippedFrameCount: Number(frame.nativeSkippedFrameCount || 0) || 0,
|
|
2072
2072
|
nativeEncodedFrameCount: Number(frame.nativeEncodedFrameCount || 0) || 0,
|
|
2073
|
+
nativeEncodeFramesInFlight: Number(frame.nativeEncodeFramesInFlight || 0) || 0,
|
|
2074
|
+
nativeBackpressureSkippedFrameCount: Number(frame.nativeBackpressureSkippedFrameCount || 0) || 0,
|
|
2075
|
+
nativeIdleSkippedFrameCount: Number(frame.nativeIdleSkippedFrameCount || 0) || 0,
|
|
2073
2076
|
nativeCaptureTelemetryAt: frame.nativeCaptureTelemetryAt || '',
|
|
2074
2077
|
droppedByAgent: Number(frame.droppedByAgent || 0) || 0,
|
|
2075
2078
|
hubIngressDropped: Number(frame.hubIngressDropped || 0) || 0,
|