@livedesk/client 0.1.91 → 0.1.93
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/README.md +6 -3
- package/fast/linux-x64/livedesk-client-fast.dll +0 -0
- package/fast/linux-x64/livedesk-client-fast.pdb +0 -0
- package/fast/osx-arm64/MindExec.RemoteAgent.Fast/MacScreenCaptureKitH264.swift +18 -5
- package/fast/osx-arm64/livedesk-client-fast.dll +0 -0
- package/fast/osx-arm64/livedesk-client-fast.pdb +0 -0
- package/fast/osx-x64/MindExec.RemoteAgent.Fast/MacScreenCaptureKitH264.swift +18 -5
- package/fast/osx-x64/livedesk-client-fast.dll +0 -0
- package/fast/osx-x64/livedesk-client-fast.pdb +0 -0
- package/fast/win-x64/livedesk-client-fast.dll +0 -0
- package/fast/win-x64/livedesk-client-fast.pdb +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -39,8 +39,11 @@ the matching callback URL to Supabase Auth redirect URLs.
|
|
|
39
39
|
The client registers the device, sends status heartbeats, can return
|
|
40
40
|
Hub-requested thumbnails, can stream a focused view-only live screen, and
|
|
41
41
|
can receive safe task-only instructions. The C# RemoteFast engine also supports
|
|
42
|
-
keyboard/mouse control, file transfer, and
|
|
43
|
-
|
|
42
|
+
keyboard/mouse control on Windows, macOS, and Linux/X11, file transfer, and
|
|
43
|
+
Windows system-audio loopback playback. macOS control requires Accessibility
|
|
44
|
+
permission for the terminal app that started LiveDesk; screen streaming requires
|
|
45
|
+
Screen Recording permission. LiveDesk opens the matching System Settings page
|
|
46
|
+
only when that permission is first needed. When file transfer is enabled by the Hub, received files are saved
|
|
44
47
|
to `Desktop/LiveDeskFiles` unless the Hub sets another destination folder.
|
|
45
48
|
|
|
46
49
|
By default, the launcher uses the packaged C# RemoteFast engine when supported.
|
|
@@ -70,7 +73,7 @@ Frame pipeline roadmap:
|
|
|
70
73
|
|
|
71
74
|
- Mode 1: `mode1-jpeg` - current test path using screen capture, resize, and JPEG binary frames.
|
|
72
75
|
- Mode 2: `mode2-lz4` - Windows Fast path using raw BGRA frames compressed as an LZ4 block.
|
|
73
|
-
- Mode 3: `mode3-h264-hw` - OS-specific
|
|
76
|
+
- Mode 3: `mode3-h264-hw` - OS-specific hardware H.264 path. Windows tries Media Foundation/NVENC/QSV/AMF, macOS prefers ScreenCaptureKit plus VideoToolbox, and Linux tries NVENC/VAAPI/QSV. macOS emits one startup key frame and then an approximately one-second GOP. The launcher uses bundled ffmpeg for fallback paths unless `LIVEDESK_FFMPEG` points to a custom binary. On macOS, set `LIVEDESK_FFMPEG_AVFOUNDATION_INPUT` only when the ScreenCaptureKit helper is unavailable and the AVFoundation fallback input is not `1:none`.
|
|
74
77
|
|
|
75
78
|
Legacy mode names such as `remote-fast` and `remote-quality` are treated as
|
|
76
79
|
Mode 1 aliases.
|
|
Binary file
|
|
Binary file
|
|
@@ -37,7 +37,16 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
|
|
|
37
37
|
throw LiveDeskSCKError.noDisplays
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
let
|
|
40
|
+
let mainDisplayID = CGMainDisplayID()
|
|
41
|
+
let orderedDisplays = shareableContent.displays.sorted { left, right in
|
|
42
|
+
let leftIsMain = left.displayID == mainDisplayID
|
|
43
|
+
let rightIsMain = right.displayID == mainDisplayID
|
|
44
|
+
if leftIsMain != rightIsMain {
|
|
45
|
+
return leftIsMain
|
|
46
|
+
}
|
|
47
|
+
return left.displayID < right.displayID
|
|
48
|
+
}
|
|
49
|
+
let display = orderedDisplays[min(displayIndex, orderedDisplays.count - 1)]
|
|
41
50
|
let filter = SCContentFilter(display: display, excludingWindows: [])
|
|
42
51
|
let configuration = SCStreamConfiguration()
|
|
43
52
|
configuration.width = width
|
|
@@ -79,8 +88,8 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
|
|
|
79
88
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_RealTime, value: kCFBooleanTrue)
|
|
80
89
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowFrameReordering, value: kCFBooleanFalse)
|
|
81
90
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ProfileLevel, value: kVTProfileLevel_H264_Baseline_AutoLevel)
|
|
82
|
-
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameInterval, value: NSNumber(value:
|
|
83
|
-
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, value: NSNumber(value:
|
|
91
|
+
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameInterval, value: NSNumber(value: fps))
|
|
92
|
+
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, value: NSNumber(value: 1.0))
|
|
84
93
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ExpectedFrameRate, value: NSNumber(value: fps))
|
|
85
94
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AverageBitRate, value: NSNumber(value: bitrateKbps * 1000))
|
|
86
95
|
VTCompressionSessionPrepareToEncodeFrames(session)
|
|
@@ -111,8 +120,12 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
|
|
|
111
120
|
frameCount += 1
|
|
112
121
|
let pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
|
|
113
122
|
let duration = CMTime(value: 1, timescale: CMTimeScale(fps))
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
var frameProperties: CFDictionary?
|
|
124
|
+
if frameCount == 1 {
|
|
125
|
+
let properties = NSMutableDictionary()
|
|
126
|
+
properties[kVTEncodeFrameOptionKey_ForceKeyFrame] = kCFBooleanTrue
|
|
127
|
+
frameProperties = properties
|
|
128
|
+
}
|
|
116
129
|
|
|
117
130
|
let status = VTCompressionSessionEncodeFrame(
|
|
118
131
|
session,
|
|
Binary file
|
|
Binary file
|
|
@@ -37,7 +37,16 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
|
|
|
37
37
|
throw LiveDeskSCKError.noDisplays
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
let
|
|
40
|
+
let mainDisplayID = CGMainDisplayID()
|
|
41
|
+
let orderedDisplays = shareableContent.displays.sorted { left, right in
|
|
42
|
+
let leftIsMain = left.displayID == mainDisplayID
|
|
43
|
+
let rightIsMain = right.displayID == mainDisplayID
|
|
44
|
+
if leftIsMain != rightIsMain {
|
|
45
|
+
return leftIsMain
|
|
46
|
+
}
|
|
47
|
+
return left.displayID < right.displayID
|
|
48
|
+
}
|
|
49
|
+
let display = orderedDisplays[min(displayIndex, orderedDisplays.count - 1)]
|
|
41
50
|
let filter = SCContentFilter(display: display, excludingWindows: [])
|
|
42
51
|
let configuration = SCStreamConfiguration()
|
|
43
52
|
configuration.width = width
|
|
@@ -79,8 +88,8 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
|
|
|
79
88
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_RealTime, value: kCFBooleanTrue)
|
|
80
89
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AllowFrameReordering, value: kCFBooleanFalse)
|
|
81
90
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ProfileLevel, value: kVTProfileLevel_H264_Baseline_AutoLevel)
|
|
82
|
-
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameInterval, value: NSNumber(value:
|
|
83
|
-
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, value: NSNumber(value:
|
|
91
|
+
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameInterval, value: NSNumber(value: fps))
|
|
92
|
+
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_MaxKeyFrameIntervalDuration, value: NSNumber(value: 1.0))
|
|
84
93
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_ExpectedFrameRate, value: NSNumber(value: fps))
|
|
85
94
|
VTSessionSetProperty(session, key: kVTCompressionPropertyKey_AverageBitRate, value: NSNumber(value: bitrateKbps * 1000))
|
|
86
95
|
VTCompressionSessionPrepareToEncodeFrames(session)
|
|
@@ -111,8 +120,12 @@ final class LiveDeskScreenCaptureKitEncoder: NSObject, SCStreamOutput, SCStreamD
|
|
|
111
120
|
frameCount += 1
|
|
112
121
|
let pts = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
|
|
113
122
|
let duration = CMTime(value: 1, timescale: CMTimeScale(fps))
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
var frameProperties: CFDictionary?
|
|
124
|
+
if frameCount == 1 {
|
|
125
|
+
let properties = NSMutableDictionary()
|
|
126
|
+
properties[kVTEncodeFrameOptionKey_ForceKeyFrame] = kCFBooleanTrue
|
|
127
|
+
frameProperties = properties
|
|
128
|
+
}
|
|
116
129
|
|
|
117
130
|
let status = VTCompressionSessionEncodeFrame(
|
|
118
131
|
session,
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|