@livedesk/client 0.1.117 → 0.1.119

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.
@@ -0,0 +1,27 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { dirname, join, resolve } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ const packageRoot = resolve(__dirname, '..');
7
+
8
+ export function readClientPackageVersion() {
9
+ try {
10
+ const packageInfo = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'));
11
+ return String(packageInfo.version || '0.0.0');
12
+ } catch {
13
+ return '0.0.0';
14
+ }
15
+ }
16
+
17
+ export function formatClientVersionBanner(env = process.env) {
18
+ const clientPackage = `@livedesk/client@${readClientPackageVersion()}`;
19
+ const launcherName = String(env.LIVEDESK_NPM_LAUNCHER_NAME || '').trim();
20
+ const launcherVersion = String(env.LIVEDESK_NPM_LAUNCHER_VERSION || '').trim();
21
+
22
+ if (launcherName && launcherVersion) {
23
+ return `[LiveDesk Client] npm packages: ${launcherName}@${launcherVersion} -> ${clientPackage}`;
24
+ }
25
+
26
+ return `[LiveDesk Client] npm package: ${clientPackage}`;
27
+ }
@@ -8,6 +8,7 @@ import { createServer } from 'node:http';
8
8
  import { createRequire } from 'node:module';
9
9
  import net from 'node:net';
10
10
  import os from 'node:os';
11
+ import { formatClientVersionBanner, readClientPackageVersion } from './client-version.js';
11
12
 
12
13
  const __dirname = dirname(fileURLToPath(import.meta.url));
13
14
  const require = createRequire(import.meta.url);
@@ -74,12 +75,7 @@ Enable Windows auto-start from the connection page when this client signs in.
74
75
  }
75
76
 
76
77
  function readPackageVersion() {
77
- try {
78
- const packageInfo = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'));
79
- return packageInfo.version || '0.0.0';
80
- } catch {
81
- return '0.0.0';
82
- }
78
+ return readClientPackageVersion();
83
79
  }
84
80
 
85
81
  function isTruthy(value) {
@@ -2508,7 +2504,7 @@ function resolveBundledFfmpegPaths() {
2508
2504
  }
2509
2505
  };
2510
2506
 
2511
- if (process.platform === 'darwin') {
2507
+ if (process.platform === 'darwin' || process.platform === 'win32') {
2512
2508
  addFfmpegStatic();
2513
2509
  addFfmpegInstaller();
2514
2510
  } else {
@@ -2727,6 +2723,8 @@ async function main() {
2727
2723
  return;
2728
2724
  }
2729
2725
 
2726
+ console.log(formatClientVersionBanner());
2727
+
2730
2728
  let connectionPage = null;
2731
2729
  while (true) {
2732
2730
  const prepared = await prepareLoginConnection(parsed, connectionPage);
@@ -3,6 +3,7 @@ import CoreGraphics
3
3
  import CoreMedia
4
4
  import CoreVideo
5
5
  import Foundation
6
+ import IOSurface
6
7
  import ScreenCaptureKit
7
8
  import VideoToolbox
8
9
 
@@ -23,6 +24,7 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
23
24
  private var encodedCount: Int = 0
24
25
  private var encodedKeyCount: Int = 0
25
26
  private var encodedDeltaCount: Int = 0
27
+ private var loggedInputSurface = false
26
28
 
27
29
  init(displayIndex: Int, width: Int, height: Int, fps: Int, bitrateKbps: Int) {
28
30
  self.displayIndex = max(0, displayIndex)
@@ -56,7 +58,7 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
56
58
  configuration.width = width
57
59
  configuration.height = height
58
60
  configuration.minimumFrameInterval = CMTime(value: 1, timescale: CMTimeScale(fps))
59
- configuration.queueDepth = 8
61
+ configuration.queueDepth = 3
60
62
  configuration.showsCursor = false
61
63
  configuration.pixelFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
62
64
 
@@ -76,13 +78,20 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
76
78
  let encoderSpecification: [CFString: Any] = [
77
79
  kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder: true
78
80
  ]
81
+ let imageBufferAttributes: [CFString: Any] = [
82
+ kCVPixelBufferPixelFormatTypeKey: NSNumber(value: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),
83
+ kCVPixelBufferWidthKey: NSNumber(value: width),
84
+ kCVPixelBufferHeightKey: NSNumber(value: height),
85
+ kCVPixelBufferMetalCompatibilityKey: true,
86
+ kCVPixelBufferIOSurfacePropertiesKey: [:] as CFDictionary
87
+ ]
79
88
  let status = VTCompressionSessionCreate(
80
89
  allocator: kCFAllocatorDefault,
81
90
  width: Int32(width),
82
91
  height: Int32(height),
83
92
  codecType: kCMVideoCodecType_H264,
84
93
  encoderSpecification: encoderSpecification as CFDictionary,
85
- imageBufferAttributes: nil,
94
+ imageBufferAttributes: imageBufferAttributes as CFDictionary,
86
95
  compressedDataAllocator: nil,
87
96
  outputCallback: Self.compressionCallback,
88
97
  refcon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),
@@ -93,9 +102,10 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
93
102
  }
94
103
 
95
104
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_RealTime, value: kCFBooleanTrue)
105
+ VTSessionSetProperty(session, key: kVTCompressionPropertyKey_PrioritizeEncodingSpeedOverQuality, value: kCFBooleanTrue)
96
106
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowTemporalCompression, value: kCFBooleanTrue)
97
107
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowFrameReordering, value: kCFBooleanFalse)
98
- VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxFrameDelayCount, value: NSNumber(value: 1))
108
+ VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxFrameDelayCount, value: NSNumber(value: 0))
99
109
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ProfileLevel, value: kVTProfileLevel_H264_Baseline_AutoLevel)
100
110
  let recoveryKeyInterval = max(1, fps / 2)
101
111
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameInterval, value: NSNumber(value: recoveryKeyInterval))
@@ -134,6 +144,12 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
134
144
  }
135
145
 
136
146
  frameCount += 1
147
+ if !loggedInputSurface {
148
+ loggedInputSurface = true
149
+ let pixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer)
150
+ let hasIOSurface = CVPixelBufferGetIOSurface(imageBuffer) != nil
151
+ fputs("LiveDeskSCK input pixelFormat=\(pixelFormat) iosurface=\(hasIOSurface ? 1 : 0) queueDepth=3 zeroCopyCandidate=\(hasIOSurface ? 1 : 0)\n", stderr)
152
+ }
137
153
  let pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
138
154
  let duration = CMTime(value: 1, timescale: CMTimeScale(fps))
139
155
  var frameProperties: CFDictionary?
@@ -3,6 +3,7 @@ import CoreGraphics
3
3
  import CoreMedia
4
4
  import CoreVideo
5
5
  import Foundation
6
+ import IOSurface
6
7
  import ScreenCaptureKit
7
8
  import VideoToolbox
8
9
 
@@ -23,6 +24,7 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
23
24
  private var encodedCount: Int = 0
24
25
  private var encodedKeyCount: Int = 0
25
26
  private var encodedDeltaCount: Int = 0
27
+ private var loggedInputSurface = false
26
28
 
27
29
  init(displayIndex: Int, width: Int, height: Int, fps: Int, bitrateKbps: Int) {
28
30
  self.displayIndex = max(0, displayIndex)
@@ -56,7 +58,7 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
56
58
  configuration.width = width
57
59
  configuration.height = height
58
60
  configuration.minimumFrameInterval = CMTime(value: 1, timescale: CMTimeScale(fps))
59
- configuration.queueDepth = 8
61
+ configuration.queueDepth = 3
60
62
  configuration.showsCursor = false
61
63
  configuration.pixelFormat = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
62
64
 
@@ -76,13 +78,20 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
76
78
  let encoderSpecification: [CFString: Any] = [
77
79
  kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder: true
78
80
  ]
81
+ let imageBufferAttributes: [CFString: Any] = [
82
+ kCVPixelBufferPixelFormatTypeKey: NSNumber(value: kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange),
83
+ kCVPixelBufferWidthKey: NSNumber(value: width),
84
+ kCVPixelBufferHeightKey: NSNumber(value: height),
85
+ kCVPixelBufferMetalCompatibilityKey: true,
86
+ kCVPixelBufferIOSurfacePropertiesKey: [:] as CFDictionary
87
+ ]
79
88
  let status = VTCompressionSessionCreate(
80
89
  allocator: kCFAllocatorDefault,
81
90
  width: Int32(width),
82
91
  height: Int32(height),
83
92
  codecType: kCMVideoCodecType_H264,
84
93
  encoderSpecification: encoderSpecification as CFDictionary,
85
- imageBufferAttributes: nil,
94
+ imageBufferAttributes: imageBufferAttributes as CFDictionary,
86
95
  compressedDataAllocator: nil,
87
96
  outputCallback: Self.compressionCallback,
88
97
  refcon: UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),
@@ -93,9 +102,10 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
93
102
  }
94
103
 
95
104
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_RealTime, value: kCFBooleanTrue)
105
+ VTSessionSetProperty(session, key: kVTCompressionPropertyKey_PrioritizeEncodingSpeedOverQuality, value: kCFBooleanTrue)
96
106
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowTemporalCompression, value: kCFBooleanTrue)
97
107
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowFrameReordering, value: kCFBooleanFalse)
98
- VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxFrameDelayCount, value: NSNumber(value: 1))
108
+ VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxFrameDelayCount, value: NSNumber(value: 0))
99
109
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ProfileLevel, value: kVTProfileLevel_H264_Baseline_AutoLevel)
100
110
  let recoveryKeyInterval = max(1, fps / 2)
101
111
  VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameInterval, value: NSNumber(value: recoveryKeyInterval))
@@ -134,6 +144,12 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
134
144
  }
135
145
 
136
146
  frameCount += 1
147
+ if !loggedInputSurface {
148
+ loggedInputSurface = true
149
+ let pixelFormat = CVPixelBufferGetPixelFormatType(imageBuffer)
150
+ let hasIOSurface = CVPixelBufferGetIOSurface(imageBuffer) != nil
151
+ fputs("LiveDeskSCK input pixelFormat=\(pixelFormat) iosurface=\(hasIOSurface ? 1 : 0) queueDepth=3 zeroCopyCandidate=\(hasIOSurface ? 1 : 0)\n", stderr)
152
+ }
137
153
  let pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
138
154
  let duration = CMTime(value: 1, timescale: CMTimeScale(fps))
139
155
  var frameProperties: CFDictionary?
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@livedesk/client",
3
- "version": "0.1.117",
3
+ "version": "0.1.119",
4
4
  "description": "LiveDesk local remote client",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,8 @@
16
16
  "THIRD_PARTY_NOTICES.md"
17
17
  ],
18
18
  "scripts": {
19
- "check": "node --check bin/livedesk-client.js && node --check bin/livedesk-client-node.js && node --check bin/livedesk-client-fast.js",
19
+ "check": "node --check bin/client-version.js && node --check bin/livedesk-client.js && node --check bin/livedesk-client-node.js && node --check bin/livedesk-client-fast.js",
20
+ "test:version": "node --test tests/client-version.test.mjs",
20
21
  "pack:dry": "npm pack --dry-run"
21
22
  },
22
23
  "keywords": [