node-mac-recorder 2.20.0 → 2.20.1
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/.claude/settings.local.json +2 -9
- package/index.js +22 -158
- package/package.json +1 -1
- package/src/cursor_tracker.mm +253 -109
- package/src/mac_recorder.mm +7 -58
- package/src/screen_capture_kit.mm +14 -23
- package/temp_cursor_1758662416766.json +0 -1
- package/temp_cursor_1758662420113.json +0 -1
- package/temp_cursor_1758662423166.json +0 -1
- package/temp_cursor_1758662426222.json +0 -1
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"permissions": {
|
|
3
3
|
"allow": [
|
|
4
|
-
"Bash(
|
|
5
|
-
"Bash(node:*)"
|
|
6
|
-
"Bash(npm install)",
|
|
7
|
-
"Bash(npm run clean:*)",
|
|
8
|
-
"Bash(npm run build:*)",
|
|
9
|
-
"Bash(npm run rebuild:*)",
|
|
10
|
-
"Bash(system_profiler:*)",
|
|
11
|
-
"Bash(sw_vers)",
|
|
12
|
-
"Bash(find:*)"
|
|
4
|
+
"Bash(node-gyp:*)",
|
|
5
|
+
"Bash(node:*)"
|
|
13
6
|
],
|
|
14
7
|
"deny": [],
|
|
15
8
|
"ask": []
|
package/index.js
CHANGED
|
@@ -87,11 +87,7 @@ class MacRecorder extends EventEmitter {
|
|
|
87
87
|
x: display.x,
|
|
88
88
|
y: display.y,
|
|
89
89
|
isPrimary: display.isPrimary,
|
|
90
|
-
scaleFactor: display.scaleFactor || 1.0,
|
|
91
|
-
physicalWidth: display.physicalWidth || display.width,
|
|
92
|
-
physicalHeight: display.physicalHeight || display.height,
|
|
93
90
|
resolution: `${display.width}x${display.height}`,
|
|
94
|
-
physicalResolution: `${display.physicalWidth || display.width}x${display.physicalHeight || display.height}`,
|
|
95
91
|
}));
|
|
96
92
|
}
|
|
97
93
|
|
|
@@ -775,31 +771,24 @@ class MacRecorder extends EventEmitter {
|
|
|
775
771
|
// JavaScript interval ile polling yap (daha sık - mouse event'leri yakalamak için)
|
|
776
772
|
this.cursorCaptureInterval = setInterval(() => {
|
|
777
773
|
try {
|
|
778
|
-
|
|
779
|
-
const cursorData = this.getCursorPosition();
|
|
774
|
+
const position = nativeBinding.getCursorPosition();
|
|
780
775
|
const timestamp = Date.now() - this.cursorCaptureStartTime;
|
|
781
776
|
|
|
782
|
-
//
|
|
783
|
-
let x =
|
|
784
|
-
let y =
|
|
785
|
-
let coordinateSystem = "
|
|
777
|
+
// Video-relative coordinate transformation for all recording types
|
|
778
|
+
let x = position.x;
|
|
779
|
+
let y = position.y;
|
|
780
|
+
let coordinateSystem = "global";
|
|
786
781
|
|
|
787
|
-
// Apply video-relative transformation for
|
|
782
|
+
// Apply video-relative transformation for all recording types
|
|
788
783
|
if (this.cursorDisplayInfo && this.cursorDisplayInfo.videoRelative) {
|
|
789
|
-
//
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
const scaledOffsetY = this.cursorDisplayInfo.videoOffsetY * recordingScaleY;
|
|
798
|
-
|
|
799
|
-
x = x - scaledOffsetX;
|
|
800
|
-
y = y - scaledOffsetY;
|
|
801
|
-
coordinateSystem = "video-relative";
|
|
802
|
-
}
|
|
784
|
+
// Step 1: Transform global → display-relative coordinates
|
|
785
|
+
const displayRelativeX = position.x - this.cursorDisplayInfo.displayX;
|
|
786
|
+
const displayRelativeY = position.y - this.cursorDisplayInfo.displayY;
|
|
787
|
+
|
|
788
|
+
// Step 2: Transform display-relative → video-relative coordinates
|
|
789
|
+
x = displayRelativeX - this.cursorDisplayInfo.videoOffsetX;
|
|
790
|
+
y = displayRelativeY - this.cursorDisplayInfo.videoOffsetY;
|
|
791
|
+
coordinateSystem = "video-relative";
|
|
803
792
|
|
|
804
793
|
// Bounds check for video area (don't skip, just note if outside)
|
|
805
794
|
const outsideVideo = x < 0 || y < 0 ||
|
|
@@ -812,30 +801,16 @@ class MacRecorder extends EventEmitter {
|
|
|
812
801
|
}
|
|
813
802
|
}
|
|
814
803
|
|
|
815
|
-
const
|
|
804
|
+
const cursorData = {
|
|
816
805
|
x: x,
|
|
817
806
|
y: y,
|
|
818
807
|
timestamp: timestamp,
|
|
819
808
|
unixTimeMs: Date.now(),
|
|
820
|
-
cursorType:
|
|
821
|
-
type:
|
|
809
|
+
cursorType: position.cursorType,
|
|
810
|
+
type: position.eventType || "move",
|
|
822
811
|
coordinateSystem: coordinateSystem,
|
|
823
|
-
//
|
|
812
|
+
// Video-relative metadata for all recording types
|
|
824
813
|
recordingType: this.cursorDisplayInfo?.recordingType || "display",
|
|
825
|
-
recordingInfo: {
|
|
826
|
-
// Logical coordinates for backward compatibility
|
|
827
|
-
logicalX: cursorData.x,
|
|
828
|
-
logicalY: cursorData.y,
|
|
829
|
-
// Recording coordinates for video overlay
|
|
830
|
-
recordingX: x,
|
|
831
|
-
recordingY: y,
|
|
832
|
-
// Recording resolution
|
|
833
|
-
recordingWidth: cursorData.recordingWidth,
|
|
834
|
-
recordingHeight: cursorData.recordingHeight,
|
|
835
|
-
// Scale factors
|
|
836
|
-
scaleX: cursorData.scaleX || 1,
|
|
837
|
-
scaleY: cursorData.scaleY || 1
|
|
838
|
-
},
|
|
839
814
|
videoInfo: this.cursorDisplayInfo ? {
|
|
840
815
|
width: this.cursorDisplayInfo.videoWidth,
|
|
841
816
|
height: this.cursorDisplayInfo.videoHeight,
|
|
@@ -850,9 +825,9 @@ class MacRecorder extends EventEmitter {
|
|
|
850
825
|
};
|
|
851
826
|
|
|
852
827
|
// Sadece eventType değiştiğinde veya pozisyon değiştiğinde kaydet
|
|
853
|
-
if (this.shouldCaptureEvent(
|
|
828
|
+
if (this.shouldCaptureEvent(cursorData)) {
|
|
854
829
|
// Dosyaya ekle
|
|
855
|
-
const jsonString = JSON.stringify(
|
|
830
|
+
const jsonString = JSON.stringify(cursorData);
|
|
856
831
|
|
|
857
832
|
if (this.cursorCaptureFirstWrite) {
|
|
858
833
|
fs.appendFileSync(filepath, jsonString);
|
|
@@ -862,7 +837,7 @@ class MacRecorder extends EventEmitter {
|
|
|
862
837
|
}
|
|
863
838
|
|
|
864
839
|
// Son pozisyonu sakla
|
|
865
|
-
this.lastCapturedData = { ...
|
|
840
|
+
this.lastCapturedData = { ...cursorData };
|
|
866
841
|
}
|
|
867
842
|
} catch (error) {
|
|
868
843
|
console.error("Cursor capture error:", error);
|
|
@@ -921,123 +896,12 @@ class MacRecorder extends EventEmitter {
|
|
|
921
896
|
const position = nativeBinding.getCursorPosition();
|
|
922
897
|
|
|
923
898
|
// Cursor hangi display'de ise o display'e relative döndür
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
// Add recording coordinates for video overlay alignment
|
|
927
|
-
const recordingCoordinates = this.calculateRecordingCoordinates(displayRelativePosition);
|
|
928
|
-
|
|
929
|
-
return {
|
|
930
|
-
...displayRelativePosition,
|
|
931
|
-
// Recording coordinates for video overlay (matches actual video resolution)
|
|
932
|
-
recordingX: recordingCoordinates.x,
|
|
933
|
-
recordingY: recordingCoordinates.y,
|
|
934
|
-
recordingWidth: recordingCoordinates.width,
|
|
935
|
-
recordingHeight: recordingCoordinates.height,
|
|
936
|
-
// Scale factors for reference
|
|
937
|
-
scaleX: recordingCoordinates.scaleX,
|
|
938
|
-
scaleY: recordingCoordinates.scaleY,
|
|
939
|
-
// Original coordinates for backward compatibility
|
|
940
|
-
x: displayRelativePosition.x,
|
|
941
|
-
y: displayRelativePosition.y
|
|
942
|
-
};
|
|
899
|
+
return this.getDisplayRelativePositionSync(position);
|
|
943
900
|
} catch (error) {
|
|
944
901
|
throw new Error("Failed to get cursor position: " + error.message);
|
|
945
902
|
}
|
|
946
903
|
}
|
|
947
904
|
|
|
948
|
-
/**
|
|
949
|
-
* Calculate cursor coordinates for recording video overlay alignment
|
|
950
|
-
* Converts logical display coordinates to actual video recording coordinates
|
|
951
|
-
*/
|
|
952
|
-
calculateRecordingCoordinates(displayPosition) {
|
|
953
|
-
try {
|
|
954
|
-
// Get current display information
|
|
955
|
-
if (!this.cachedDisplays) {
|
|
956
|
-
this.refreshDisplayCache();
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
// If still null, use native binding directly
|
|
960
|
-
if (!this.cachedDisplays) {
|
|
961
|
-
try {
|
|
962
|
-
const nativeDisplays = nativeBinding.getDisplays();
|
|
963
|
-
this.cachedDisplays = nativeDisplays.map((display, index) => ({
|
|
964
|
-
id: display.id,
|
|
965
|
-
name: display.name,
|
|
966
|
-
width: display.width,
|
|
967
|
-
height: display.height,
|
|
968
|
-
x: display.x,
|
|
969
|
-
y: display.y,
|
|
970
|
-
isPrimary: display.isPrimary,
|
|
971
|
-
scaleFactor: display.scaleFactor || 1.0,
|
|
972
|
-
physicalWidth: display.physicalWidth || display.width,
|
|
973
|
-
physicalHeight: display.physicalHeight || display.height,
|
|
974
|
-
resolution: `${display.width}x${display.height}`,
|
|
975
|
-
}));
|
|
976
|
-
} catch (e) {
|
|
977
|
-
console.warn('Failed to get displays from native binding:', e.message);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
// Find the target display
|
|
982
|
-
let targetDisplay = null;
|
|
983
|
-
if (displayPosition.displayId) {
|
|
984
|
-
targetDisplay = this.cachedDisplays.find(d => d.id === displayPosition.displayId);
|
|
985
|
-
}
|
|
986
|
-
if (!targetDisplay) {
|
|
987
|
-
targetDisplay = this.cachedDisplays.find(d => d.isPrimary) || this.cachedDisplays[0];
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
if (!targetDisplay) {
|
|
991
|
-
// Fallback: assume 1:1 mapping
|
|
992
|
-
return {
|
|
993
|
-
x: displayPosition.x,
|
|
994
|
-
y: displayPosition.y,
|
|
995
|
-
width: displayPosition.x,
|
|
996
|
-
height: displayPosition.y
|
|
997
|
-
};
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// Parse display dimensions
|
|
1001
|
-
const logicalWidth = parseInt(targetDisplay.resolution.split("x")[0]);
|
|
1002
|
-
const logicalHeight = parseInt(targetDisplay.resolution.split("x")[1]);
|
|
1003
|
-
|
|
1004
|
-
// Get physical recording dimensions
|
|
1005
|
-
// On Retina displays, recording is done at physical resolution (2x logical)
|
|
1006
|
-
const physicalWidth = targetDisplay.physicalWidth || (logicalWidth * (targetDisplay.scaleFactor || 1));
|
|
1007
|
-
const physicalHeight = targetDisplay.physicalHeight || (logicalHeight * (targetDisplay.scaleFactor || 1));
|
|
1008
|
-
|
|
1009
|
-
// Calculate scale factors for coordinate conversion
|
|
1010
|
-
const scaleX = physicalWidth / logicalWidth;
|
|
1011
|
-
const scaleY = physicalHeight / logicalHeight;
|
|
1012
|
-
|
|
1013
|
-
// Convert logical cursor coordinates to recording coordinates
|
|
1014
|
-
const recordingX = Math.round(displayPosition.x * scaleX);
|
|
1015
|
-
const recordingY = Math.round(displayPosition.y * scaleY);
|
|
1016
|
-
|
|
1017
|
-
return {
|
|
1018
|
-
x: recordingX,
|
|
1019
|
-
y: recordingY,
|
|
1020
|
-
width: physicalWidth,
|
|
1021
|
-
height: physicalHeight,
|
|
1022
|
-
scaleX: scaleX,
|
|
1023
|
-
scaleY: scaleY,
|
|
1024
|
-
logicalWidth: logicalWidth,
|
|
1025
|
-
logicalHeight: logicalHeight
|
|
1026
|
-
};
|
|
1027
|
-
} catch (error) {
|
|
1028
|
-
console.warn('Failed to calculate recording coordinates:', error.message);
|
|
1029
|
-
// Fallback: 1:1 mapping
|
|
1030
|
-
return {
|
|
1031
|
-
x: displayPosition.x,
|
|
1032
|
-
y: displayPosition.y,
|
|
1033
|
-
width: displayPosition.x,
|
|
1034
|
-
height: displayPosition.y,
|
|
1035
|
-
scaleX: 1,
|
|
1036
|
-
scaleY: 1
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
905
|
/**
|
|
1042
906
|
* Global koordinatları en uygun display'e relative çevirir (sync version)
|
|
1043
907
|
*/
|
package/package.json
CHANGED
package/src/cursor_tracker.mm
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
#import <ApplicationServices/ApplicationServices.h>
|
|
6
6
|
#import <Carbon/Carbon.h>
|
|
7
7
|
#import <Accessibility/Accessibility.h>
|
|
8
|
+
#import <dispatch/dispatch.h>
|
|
8
9
|
|
|
9
10
|
// Global state for cursor tracking
|
|
10
11
|
static bool g_isCursorTracking = false;
|
|
@@ -49,34 +50,13 @@ static CGEventRef eventTapCallback(CGEventTapProxy proxy, CGEventType type, CGEv
|
|
|
49
50
|
return event;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
//
|
|
53
|
-
NSString*
|
|
53
|
+
// Accessibility tabanlı cursor tip tespiti
|
|
54
|
+
static NSString* detectCursorTypeUsingAccessibility(CGPoint cursorPos) {
|
|
54
55
|
@autoreleasepool {
|
|
55
|
-
g_cursorTypeCounter++;
|
|
56
|
-
|
|
57
56
|
@try {
|
|
58
57
|
// ACCESSIBILITY API BASED CURSOR DETECTION
|
|
59
58
|
// Determine cursor type based on the UI element under the cursor
|
|
60
59
|
|
|
61
|
-
// MACOS 14 FIX: Get cursor position for accessibility API
|
|
62
|
-
CGPoint cursorPos;
|
|
63
|
-
|
|
64
|
-
if (@available(macOS 10.15, *)) {
|
|
65
|
-
// Use NSEvent method for macOS 14 compatibility
|
|
66
|
-
NSPoint mouseLocationInWindow = [NSEvent mouseLocation];
|
|
67
|
-
|
|
68
|
-
// Convert NSEvent bottom-left coordinates to top-left
|
|
69
|
-
CGDirectDisplayID primaryDisplay = CGMainDisplayID();
|
|
70
|
-
CGRect primaryBounds = CGDisplayBounds(primaryDisplay);
|
|
71
|
-
|
|
72
|
-
cursorPos = CGPointMake(
|
|
73
|
-
mouseLocationInWindow.x,
|
|
74
|
-
primaryBounds.size.height - mouseLocationInWindow.y
|
|
75
|
-
);
|
|
76
|
-
} else {
|
|
77
|
-
// Fallback for older macOS versions
|
|
78
|
-
cursorPos = CGEventGetLocation(CGEventCreate(NULL));
|
|
79
|
-
}
|
|
80
60
|
AXUIElementRef systemWide = AXUIElementCreateSystemWide();
|
|
81
61
|
AXUIElementRef elementAtPosition = NULL;
|
|
82
62
|
AXError error = AXUIElementCopyElementAtPosition(systemWide, cursorPos.x, cursorPos.y, &elementAtPosition);
|
|
@@ -298,9 +278,11 @@ NSString* getCursorType() {
|
|
|
298
278
|
}
|
|
299
279
|
}
|
|
300
280
|
|
|
301
|
-
CFRelease(elementAtPosition);
|
|
302
281
|
}
|
|
303
282
|
|
|
283
|
+
if (elementAtPosition) {
|
|
284
|
+
CFRelease(elementAtPosition);
|
|
285
|
+
}
|
|
304
286
|
if (systemWide) {
|
|
305
287
|
CFRelease(systemWide);
|
|
306
288
|
}
|
|
@@ -310,16 +292,244 @@ NSString* getCursorType() {
|
|
|
310
292
|
cursorType = @"default";
|
|
311
293
|
}
|
|
312
294
|
|
|
313
|
-
NSLog(@"🎯
|
|
295
|
+
NSLog(@"🎯 AX CURSOR TYPE: %@", cursorType);
|
|
314
296
|
return cursorType;
|
|
315
297
|
|
|
316
298
|
} @catch (NSException *exception) {
|
|
317
|
-
NSLog(@"Error in
|
|
299
|
+
NSLog(@"Error in detectCursorTypeUsingAccessibility: %@", exception);
|
|
318
300
|
return @"default";
|
|
319
301
|
}
|
|
320
302
|
}
|
|
321
303
|
}
|
|
322
304
|
|
|
305
|
+
static NSString* cursorTypeFromCursorName(NSString *value) {
|
|
306
|
+
if (!value || [value length] == 0) {
|
|
307
|
+
return nil;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
NSString *normalized = [[value stringByReplacingOccurrencesOfString:@"_" withString:@"-"] lowercaseString];
|
|
311
|
+
|
|
312
|
+
if ([normalized containsString:@"arrow"]) {
|
|
313
|
+
return @"default";
|
|
314
|
+
}
|
|
315
|
+
if ([normalized containsString:@"ibeam"] ||
|
|
316
|
+
[normalized containsString:@"insertion"] ||
|
|
317
|
+
[normalized containsString:@"text"]) {
|
|
318
|
+
return @"text";
|
|
319
|
+
}
|
|
320
|
+
if ([normalized containsString:@"openhand"]) {
|
|
321
|
+
return @"grab";
|
|
322
|
+
}
|
|
323
|
+
if ([normalized containsString:@"closedhand"]) {
|
|
324
|
+
return @"grabbing";
|
|
325
|
+
}
|
|
326
|
+
if ([normalized containsString:@"pointing"] ||
|
|
327
|
+
([normalized containsString:@"hand"] && ![normalized containsString:@"closed"])) {
|
|
328
|
+
return @"pointer";
|
|
329
|
+
}
|
|
330
|
+
if ([normalized containsString:@"crosshair"]) {
|
|
331
|
+
return @"crosshair";
|
|
332
|
+
}
|
|
333
|
+
if ([normalized containsString:@"not-allowed"] ||
|
|
334
|
+
[normalized containsString:@"notallowed"] ||
|
|
335
|
+
[normalized containsString:@"forbidden"]) {
|
|
336
|
+
return @"not-allowed";
|
|
337
|
+
}
|
|
338
|
+
if ([normalized containsString:@"dragcopy"] || [normalized containsString:@"copy"]) {
|
|
339
|
+
return @"copy";
|
|
340
|
+
}
|
|
341
|
+
if ([normalized containsString:@"draglink"] || [normalized containsString:@"alias"]) {
|
|
342
|
+
return @"alias";
|
|
343
|
+
}
|
|
344
|
+
if ([normalized containsString:@"context"] && [normalized containsString:@"menu"]) {
|
|
345
|
+
return @"context-menu";
|
|
346
|
+
}
|
|
347
|
+
if ([normalized containsString:@"zoom"]) {
|
|
348
|
+
if ([normalized containsString:@"out"]) {
|
|
349
|
+
return @"zoom-out";
|
|
350
|
+
}
|
|
351
|
+
return @"zoom-in";
|
|
352
|
+
}
|
|
353
|
+
if ([normalized containsString:@"resize"] || [normalized containsString:@"size"]) {
|
|
354
|
+
BOOL diagonalUp = [normalized containsString:@"diagonalup"] || [normalized containsString:@"nesw"];
|
|
355
|
+
BOOL diagonalDown = [normalized containsString:@"diagonaldown"] || [normalized containsString:@"nwse"];
|
|
356
|
+
BOOL horizontal = [normalized containsString:@"leftright"] ||
|
|
357
|
+
[normalized containsString:@"horizontal"] ||
|
|
358
|
+
([normalized containsString:@"left"] && [normalized containsString:@"right"]);
|
|
359
|
+
BOOL vertical = [normalized containsString:@"updown"] ||
|
|
360
|
+
[normalized containsString:@"vertical"] ||
|
|
361
|
+
([normalized containsString:@"up"] && [normalized containsString:@"down"]);
|
|
362
|
+
|
|
363
|
+
if (diagonalUp) {
|
|
364
|
+
return @"nesw-resize";
|
|
365
|
+
}
|
|
366
|
+
if (diagonalDown) {
|
|
367
|
+
return @"nwse-resize";
|
|
368
|
+
}
|
|
369
|
+
if (vertical) {
|
|
370
|
+
return @"ns-resize";
|
|
371
|
+
}
|
|
372
|
+
if (horizontal) {
|
|
373
|
+
return @"col-resize";
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return nil;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
static NSString* cursorTypeFromNSCursor(NSCursor *cursor) {
|
|
381
|
+
if (!cursor) {
|
|
382
|
+
return nil;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (cursor == [NSCursor arrowCursor]) {
|
|
386
|
+
return @"default";
|
|
387
|
+
}
|
|
388
|
+
if (cursor == [NSCursor IBeamCursor]) {
|
|
389
|
+
return @"text";
|
|
390
|
+
}
|
|
391
|
+
if ([NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)] &&
|
|
392
|
+
cursor == [NSCursor IBeamCursorForVerticalLayout]) {
|
|
393
|
+
return @"text";
|
|
394
|
+
}
|
|
395
|
+
if (cursor == [NSCursor pointingHandCursor]) {
|
|
396
|
+
return @"pointer";
|
|
397
|
+
}
|
|
398
|
+
if (cursor == [NSCursor crosshairCursor]) {
|
|
399
|
+
return @"crosshair";
|
|
400
|
+
}
|
|
401
|
+
if (cursor == [NSCursor openHandCursor]) {
|
|
402
|
+
return @"grab";
|
|
403
|
+
}
|
|
404
|
+
if (cursor == [NSCursor closedHandCursor]) {
|
|
405
|
+
return @"grabbing";
|
|
406
|
+
}
|
|
407
|
+
if (cursor == [NSCursor operationNotAllowedCursor]) {
|
|
408
|
+
return @"not-allowed";
|
|
409
|
+
}
|
|
410
|
+
if (cursor == [NSCursor dragCopyCursor]) {
|
|
411
|
+
return @"copy";
|
|
412
|
+
}
|
|
413
|
+
if (cursor == [NSCursor dragLinkCursor]) {
|
|
414
|
+
return @"alias";
|
|
415
|
+
}
|
|
416
|
+
if (cursor == [NSCursor contextualMenuCursor]) {
|
|
417
|
+
return @"context-menu";
|
|
418
|
+
}
|
|
419
|
+
if ([NSCursor respondsToSelector:@selector(resizeLeftRightCursor)] &&
|
|
420
|
+
(cursor == [NSCursor resizeLeftRightCursor] ||
|
|
421
|
+
cursor == [NSCursor resizeLeftCursor] ||
|
|
422
|
+
cursor == [NSCursor resizeRightCursor])) {
|
|
423
|
+
return @"col-resize";
|
|
424
|
+
}
|
|
425
|
+
if ([NSCursor respondsToSelector:@selector(resizeUpDownCursor)] &&
|
|
426
|
+
(cursor == [NSCursor resizeUpDownCursor] ||
|
|
427
|
+
cursor == [NSCursor resizeUpCursor] ||
|
|
428
|
+
cursor == [NSCursor resizeDownCursor])) {
|
|
429
|
+
return @"ns-resize";
|
|
430
|
+
}
|
|
431
|
+
if ([NSCursor respondsToSelector:@selector(disappearingItemCursor)] &&
|
|
432
|
+
cursor == [NSCursor disappearingItemCursor]) {
|
|
433
|
+
return @"default";
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
NSString *derived = cursorTypeFromCursorName(NSStringFromClass([cursor class]));
|
|
437
|
+
if (derived) {
|
|
438
|
+
return derived;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
derived = cursorTypeFromCursorName([cursor description]);
|
|
442
|
+
if (derived) {
|
|
443
|
+
return derived;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return nil;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
static NSString* detectSystemCursorType(void) {
|
|
450
|
+
__block NSString *cursorType = nil;
|
|
451
|
+
|
|
452
|
+
void (^fetchCursorBlock)(void) = ^{
|
|
453
|
+
NSCursor *currentCursor = nil;
|
|
454
|
+
if ([NSCursor respondsToSelector:@selector(currentSystemCursor)]) {
|
|
455
|
+
currentCursor = [NSCursor currentSystemCursor];
|
|
456
|
+
}
|
|
457
|
+
if (!currentCursor) {
|
|
458
|
+
currentCursor = [NSCursor currentCursor];
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
NSString *derivedType = cursorTypeFromNSCursor(currentCursor);
|
|
462
|
+
if (derivedType) {
|
|
463
|
+
cursorType = derivedType;
|
|
464
|
+
} else if (currentCursor) {
|
|
465
|
+
cursorType = @"default";
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
NSLog(@"🎯 SYSTEM CURSOR TYPE: %@", cursorType ? cursorType : @"(nil)");
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
if ([NSThread isMainThread]) {
|
|
472
|
+
fetchCursorBlock();
|
|
473
|
+
} else {
|
|
474
|
+
dispatch_sync(dispatch_get_main_queue(), fetchCursorBlock);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
return cursorType;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
NSString* getCursorType() {
|
|
481
|
+
@autoreleasepool {
|
|
482
|
+
g_cursorTypeCounter++;
|
|
483
|
+
|
|
484
|
+
NSString *systemCursorType = detectSystemCursorType();
|
|
485
|
+
if (systemCursorType && ![systemCursorType isEqualToString:@"default"]) {
|
|
486
|
+
NSLog(@"🎯 FINAL CURSOR TYPE: %@", systemCursorType);
|
|
487
|
+
return systemCursorType;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
NSString *axCursorType = nil;
|
|
491
|
+
BOOL hasCursorPosition = NO;
|
|
492
|
+
CGPoint cursorPos = CGPointZero;
|
|
493
|
+
|
|
494
|
+
CGEventRef event = CGEventCreate(NULL);
|
|
495
|
+
if (event) {
|
|
496
|
+
cursorPos = CGEventGetLocation(event);
|
|
497
|
+
hasCursorPosition = YES;
|
|
498
|
+
CFRelease(event);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (!hasCursorPosition) {
|
|
502
|
+
if ([NSThread isMainThread]) {
|
|
503
|
+
cursorPos = [NSEvent mouseLocation];
|
|
504
|
+
hasCursorPosition = YES;
|
|
505
|
+
} else {
|
|
506
|
+
__block CGPoint fallbackPos = CGPointZero;
|
|
507
|
+
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
508
|
+
fallbackPos = [NSEvent mouseLocation];
|
|
509
|
+
});
|
|
510
|
+
cursorPos = fallbackPos;
|
|
511
|
+
hasCursorPosition = YES;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (hasCursorPosition) {
|
|
516
|
+
axCursorType = detectCursorTypeUsingAccessibility(cursorPos);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
NSString *finalType = nil;
|
|
520
|
+
if (axCursorType && ![axCursorType isEqualToString:@"default"]) {
|
|
521
|
+
finalType = axCursorType;
|
|
522
|
+
} else if (systemCursorType && [systemCursorType length] > 0) {
|
|
523
|
+
finalType = systemCursorType;
|
|
524
|
+
} else {
|
|
525
|
+
finalType = @"default";
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
NSLog(@"🎯 FINAL CURSOR TYPE: %@", finalType);
|
|
529
|
+
return finalType;
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
|
|
323
533
|
// Dosyaya yazma helper fonksiyonu
|
|
324
534
|
void writeToFile(NSDictionary *cursorData) {
|
|
325
535
|
@autoreleasepool {
|
|
@@ -363,31 +573,7 @@ CGEventRef eventCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef eve
|
|
|
363
573
|
return event;
|
|
364
574
|
}
|
|
365
575
|
|
|
366
|
-
|
|
367
|
-
CGPoint rawLocation;
|
|
368
|
-
|
|
369
|
-
if (@available(macOS 10.15, *)) {
|
|
370
|
-
// For event callbacks, we can still use CGEventGetLocation
|
|
371
|
-
// but we'll apply coordinate correction if needed
|
|
372
|
-
rawLocation = CGEventGetLocation(event);
|
|
373
|
-
|
|
374
|
-
// Additional validation for macOS 14 scaled displays
|
|
375
|
-
if (rawLocation.x > 5000 || rawLocation.y > 5000) {
|
|
376
|
-
// Coordinates seem unreasonable, try NSEvent method as backup
|
|
377
|
-
NSPoint mouseLocationInWindow = [NSEvent mouseLocation];
|
|
378
|
-
|
|
379
|
-
// Convert NSEvent bottom-left coordinates to top-left
|
|
380
|
-
CGDirectDisplayID primaryDisplay = CGMainDisplayID();
|
|
381
|
-
CGRect primaryBounds = CGDisplayBounds(primaryDisplay);
|
|
382
|
-
|
|
383
|
-
rawLocation = CGPointMake(
|
|
384
|
-
mouseLocationInWindow.x,
|
|
385
|
-
primaryBounds.size.height - mouseLocationInWindow.y
|
|
386
|
-
);
|
|
387
|
-
}
|
|
388
|
-
} else {
|
|
389
|
-
rawLocation = CGEventGetLocation(event);
|
|
390
|
-
}
|
|
576
|
+
CGPoint rawLocation = CGEventGetLocation(event);
|
|
391
577
|
|
|
392
578
|
// Apply DPR scaling correction for Retina displays
|
|
393
579
|
NSDictionary *scalingInfo = getDisplayScalingInfo(rawLocation);
|
|
@@ -455,28 +641,11 @@ void cursorTimerCallback() {
|
|
|
455
641
|
return;
|
|
456
642
|
}
|
|
457
643
|
|
|
458
|
-
//
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
if (
|
|
462
|
-
|
|
463
|
-
NSPoint mouseLocationInWindow = [NSEvent mouseLocation];
|
|
464
|
-
|
|
465
|
-
// Convert NSEvent bottom-left coordinates to top-left
|
|
466
|
-
CGDirectDisplayID primaryDisplay = CGMainDisplayID();
|
|
467
|
-
CGRect primaryBounds = CGDisplayBounds(primaryDisplay);
|
|
468
|
-
|
|
469
|
-
rawLocation = CGPointMake(
|
|
470
|
-
mouseLocationInWindow.x,
|
|
471
|
-
primaryBounds.size.height - mouseLocationInWindow.y
|
|
472
|
-
);
|
|
473
|
-
} else {
|
|
474
|
-
// Fallback for older macOS versions
|
|
475
|
-
CGEventRef event = CGEventCreate(NULL);
|
|
476
|
-
rawLocation = CGEventGetLocation(event);
|
|
477
|
-
if (event) {
|
|
478
|
-
CFRelease(event);
|
|
479
|
-
}
|
|
644
|
+
// Get cursor position with DPR scaling correction
|
|
645
|
+
CGEventRef event = CGEventCreate(NULL);
|
|
646
|
+
CGPoint rawLocation = CGEventGetLocation(event);
|
|
647
|
+
if (event) {
|
|
648
|
+
CFRelease(event);
|
|
480
649
|
}
|
|
481
650
|
|
|
482
651
|
// Apply DPR scaling correction for Retina displays
|
|
@@ -809,48 +978,23 @@ Napi::Value GetCursorPosition(const Napi::CallbackInfo& info) {
|
|
|
809
978
|
Napi::Env env = info.Env();
|
|
810
979
|
|
|
811
980
|
@try {
|
|
812
|
-
//
|
|
813
|
-
|
|
814
|
-
CGPoint rawLocation;
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
// Try NSEvent method first (more reliable on macOS 14)
|
|
818
|
-
NSPoint mouseLocationInWindow = [NSEvent mouseLocation];
|
|
819
|
-
|
|
820
|
-
// NSEvent.mouseLocation returns coordinates in the global coordinate space
|
|
821
|
-
// where (0,0) is at bottom-left of PRIMARY SCREEN
|
|
822
|
-
// CGDisplayBounds uses (0,0) at top-left
|
|
823
|
-
// We need to convert Y coordinate from bottom-left to top-left
|
|
824
|
-
|
|
825
|
-
CGDirectDisplayID primaryDisplay = CGMainDisplayID();
|
|
826
|
-
CGRect primaryBounds = CGDisplayBounds(primaryDisplay);
|
|
827
|
-
|
|
828
|
-
rawLocation = CGPointMake(
|
|
829
|
-
mouseLocationInWindow.x,
|
|
830
|
-
primaryBounds.size.height - mouseLocationInWindow.y
|
|
831
|
-
);
|
|
832
|
-
|
|
833
|
-
NSLog(@"🔧 macOS 14 cursor fix: NSEvent(%.0f,%.0f) -> CGPoint(%.0f,%.0f)",
|
|
834
|
-
mouseLocationInWindow.x, mouseLocationInWindow.y,
|
|
835
|
-
rawLocation.x, rawLocation.y);
|
|
836
|
-
} else {
|
|
837
|
-
// Fallback for older macOS versions
|
|
838
|
-
CGEventRef event = CGEventCreate(NULL);
|
|
839
|
-
rawLocation = CGEventGetLocation(event);
|
|
840
|
-
if (event) {
|
|
841
|
-
CFRelease(event);
|
|
842
|
-
}
|
|
981
|
+
// Get raw cursor position (may be scaled on Retina displays)
|
|
982
|
+
CGEventRef event = CGEventCreate(NULL);
|
|
983
|
+
CGPoint rawLocation = CGEventGetLocation(event);
|
|
984
|
+
if (event) {
|
|
985
|
+
CFRelease(event);
|
|
843
986
|
}
|
|
844
|
-
|
|
987
|
+
|
|
845
988
|
// Get display scaling information
|
|
846
989
|
NSDictionary *scalingInfo = getDisplayScalingInfo(rawLocation);
|
|
847
990
|
CGPoint logicalLocation = rawLocation;
|
|
848
|
-
|
|
991
|
+
|
|
849
992
|
if (scalingInfo) {
|
|
850
993
|
CGFloat scaleFactor = [[scalingInfo objectForKey:@"scaleFactor"] doubleValue];
|
|
851
994
|
NSRect displayBounds = [[scalingInfo objectForKey:@"displayBounds"] rectValue];
|
|
852
|
-
|
|
853
|
-
//
|
|
995
|
+
|
|
996
|
+
// CGEventGetLocation returns LOGICAL coordinates (correct for JS layer)
|
|
997
|
+
// Keep logical coordinates - transformation happens in JS layer
|
|
854
998
|
logicalLocation = rawLocation;
|
|
855
999
|
}
|
|
856
1000
|
|
|
@@ -944,4 +1088,4 @@ Napi::Object InitCursorTracker(Napi::Env env, Napi::Object exports) {
|
|
|
944
1088
|
exports.Set("getCursorTrackingStatus", Napi::Function::New(env, GetCursorTrackingStatus));
|
|
945
1089
|
|
|
946
1090
|
return exports;
|
|
947
|
-
}
|
|
1091
|
+
}
|
package/src/mac_recorder.mm
CHANGED
|
@@ -577,60 +577,15 @@ Napi::Value GetDisplays(const Napi::CallbackInfo& info) {
|
|
|
577
577
|
CGDirectDisplayID displayID = activeDisplays[i];
|
|
578
578
|
CGRect displayBounds = CGDisplayBounds(displayID);
|
|
579
579
|
bool isPrimary = (displayID == CGMainDisplayID());
|
|
580
|
-
|
|
581
|
-
// Calculate scale factor and physical dimensions
|
|
582
|
-
CGSize logicalSize = displayBounds.size;
|
|
583
|
-
CGFloat scaleFactor = 1.0;
|
|
584
|
-
CGSize physicalSize = logicalSize;
|
|
585
|
-
CGSize actualPhysicalSize = logicalSize;
|
|
586
|
-
|
|
587
|
-
// Get actual display mode info first (most accurate)
|
|
588
|
-
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayID);
|
|
589
|
-
if (mode) {
|
|
590
|
-
size_t modePixelWidth = CGDisplayModeGetPixelWidth(mode);
|
|
591
|
-
size_t modePixelHeight = CGDisplayModeGetPixelHeight(mode);
|
|
592
|
-
actualPhysicalSize = CGSizeMake(modePixelWidth, modePixelHeight);
|
|
593
|
-
CGDisplayModeRelease(mode);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
// Use NSScreen for backing scale factor (this is the UI scaling)
|
|
597
|
-
NSArray *screens = [NSScreen screens];
|
|
598
|
-
for (NSScreen *screen in screens) {
|
|
599
|
-
NSDictionary *screenDescription = [screen deviceDescription];
|
|
600
|
-
NSNumber *screenNumber = [screenDescription objectForKey:@"NSScreenNumber"];
|
|
601
|
-
if (screenNumber && [screenNumber unsignedIntValue] == displayID) {
|
|
602
|
-
scaleFactor = [screen backingScaleFactor];
|
|
603
|
-
|
|
604
|
-
// For cursor tracking, we want to use the logical coordinates that macOS reports
|
|
605
|
-
// Physical size should be what the system actually uses for display output
|
|
606
|
-
physicalSize = actualPhysicalSize;
|
|
607
|
-
|
|
608
|
-
NSLog(@"🔍 Display %u scale analysis:", displayID);
|
|
609
|
-
NSLog(@" Logical bounds: %.0fx%.0f", logicalSize.width, logicalSize.height);
|
|
610
|
-
NSLog(@" NSScreen backing scale: %.1fx", scaleFactor);
|
|
611
|
-
NSLog(@" CGDisplayMode pixels: %.0fx%.0f", actualPhysicalSize.width, actualPhysicalSize.height);
|
|
612
|
-
NSLog(@" Calculated scale: %.2fx", actualPhysicalSize.width / logicalSize.width);
|
|
613
|
-
break;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
// Fallback if NSScreen method didn't work
|
|
618
|
-
if (scaleFactor == 1.0 && actualPhysicalSize.width > logicalSize.width) {
|
|
619
|
-
scaleFactor = actualPhysicalSize.width / logicalSize.width;
|
|
620
|
-
physicalSize = actualPhysicalSize;
|
|
621
|
-
}
|
|
622
|
-
|
|
580
|
+
|
|
623
581
|
NSDictionary *displayInfo = @{
|
|
624
582
|
@"id": @(displayID), // Direct CGDirectDisplayID
|
|
625
583
|
@"name": [NSString stringWithFormat:@"Display %u", (unsigned int)(i + 1)],
|
|
626
|
-
@"width": @((int)
|
|
627
|
-
@"height": @((int)
|
|
584
|
+
@"width": @((int)displayBounds.size.width),
|
|
585
|
+
@"height": @((int)displayBounds.size.height),
|
|
628
586
|
@"x": @((int)displayBounds.origin.x),
|
|
629
587
|
@"y": @((int)displayBounds.origin.y),
|
|
630
|
-
@"isPrimary": @(isPrimary)
|
|
631
|
-
@"scaleFactor": @(scaleFactor),
|
|
632
|
-
@"physicalWidth": @((int)physicalSize.width),
|
|
633
|
-
@"physicalHeight": @((int)physicalSize.height)
|
|
588
|
+
@"isPrimary": @(isPrimary)
|
|
634
589
|
};
|
|
635
590
|
[displays addObject:displayInfo];
|
|
636
591
|
}
|
|
@@ -640,16 +595,13 @@ Napi::Value GetDisplays(const Napi::CallbackInfo& info) {
|
|
|
640
595
|
|
|
641
596
|
for (NSUInteger i = 0; i < displays.count; i++) {
|
|
642
597
|
NSDictionary *display = displays[i];
|
|
643
|
-
NSLog(@"Display %lu: ID=%u, Name=%@,
|
|
598
|
+
NSLog(@"Display %lu: ID=%u, Name=%@, Size=%@x%@",
|
|
644
599
|
(unsigned long)i,
|
|
645
600
|
[display[@"id"] unsignedIntValue],
|
|
646
601
|
display[@"name"],
|
|
647
602
|
display[@"width"],
|
|
648
|
-
display[@"height"]
|
|
649
|
-
|
|
650
|
-
display[@"physicalHeight"],
|
|
651
|
-
[display[@"scaleFactor"] doubleValue]);
|
|
652
|
-
|
|
603
|
+
display[@"height"]);
|
|
604
|
+
|
|
653
605
|
Napi::Object displayObj = Napi::Object::New(env);
|
|
654
606
|
displayObj.Set("id", Napi::Number::New(env, [display[@"id"] unsignedIntValue]));
|
|
655
607
|
displayObj.Set("name", Napi::String::New(env, [display[@"name"] UTF8String]));
|
|
@@ -658,9 +610,6 @@ Napi::Value GetDisplays(const Napi::CallbackInfo& info) {
|
|
|
658
610
|
displayObj.Set("x", Napi::Number::New(env, [display[@"x"] doubleValue]));
|
|
659
611
|
displayObj.Set("y", Napi::Number::New(env, [display[@"y"] doubleValue]));
|
|
660
612
|
displayObj.Set("isPrimary", Napi::Boolean::New(env, [display[@"isPrimary"] boolValue]));
|
|
661
|
-
displayObj.Set("scaleFactor", Napi::Number::New(env, [display[@"scaleFactor"] doubleValue]));
|
|
662
|
-
displayObj.Set("physicalWidth", Napi::Number::New(env, [display[@"physicalWidth"] doubleValue]));
|
|
663
|
-
displayObj.Set("physicalHeight", Napi::Number::New(env, [display[@"physicalHeight"] doubleValue]));
|
|
664
613
|
result[i] = displayObj;
|
|
665
614
|
}
|
|
666
615
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// Pure ScreenCaptureKit implementation - NO AVFoundation
|
|
4
4
|
static SCStream * API_AVAILABLE(macos(12.3)) g_stream = nil;
|
|
5
|
-
static
|
|
5
|
+
static SCRecordingOutput * API_AVAILABLE(macos(15.0)) g_recordingOutput = nil;
|
|
6
6
|
static id<SCStreamDelegate> API_AVAILABLE(macos(12.3)) g_streamDelegate = nil;
|
|
7
7
|
static BOOL g_isRecording = NO;
|
|
8
8
|
static BOOL g_isCleaningUp = NO; // Prevent recursive cleanup
|
|
@@ -42,8 +42,7 @@ static NSString *g_outputPath = nil;
|
|
|
42
42
|
|
|
43
43
|
+ (BOOL)isScreenCaptureKitAvailable {
|
|
44
44
|
if (@available(macOS 15.0, *)) {
|
|
45
|
-
|
|
46
|
-
return [SCShareableContent class] != nil && [SCStream class] != nil && recordingOutputClass != nil;
|
|
45
|
+
return [SCShareableContent class] != nil && [SCStream class] != nil && [SCRecordingOutput class] != nil;
|
|
47
46
|
}
|
|
48
47
|
return NO;
|
|
49
48
|
}
|
|
@@ -276,23 +275,17 @@ static NSString *g_outputPath = nil;
|
|
|
276
275
|
}
|
|
277
276
|
|
|
278
277
|
if (@available(macOS 15.0, *)) {
|
|
279
|
-
// Create recording output configuration
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
// Note: Specific audio routing handled by ScreenCaptureKit automatically
|
|
291
|
-
|
|
292
|
-
// Create recording output with correct initializer
|
|
293
|
-
g_recordingOutput = [[recordingOutputClass alloc] initWithConfiguration:recordingConfig
|
|
294
|
-
delegate:nil];
|
|
295
|
-
}
|
|
278
|
+
// Create recording output configuration
|
|
279
|
+
SCRecordingOutputConfiguration *recordingConfig = [[SCRecordingOutputConfiguration alloc] init];
|
|
280
|
+
recordingConfig.outputURL = outputURL;
|
|
281
|
+
recordingConfig.videoCodecType = AVVideoCodecTypeH264;
|
|
282
|
+
|
|
283
|
+
// Audio configuration - using available properties
|
|
284
|
+
// Note: Specific audio routing handled by ScreenCaptureKit automatically
|
|
285
|
+
|
|
286
|
+
// Create recording output with correct initializer
|
|
287
|
+
g_recordingOutput = [[SCRecordingOutput alloc] initWithConfiguration:recordingConfig
|
|
288
|
+
delegate:nil];
|
|
296
289
|
if (shouldCaptureMic && shouldCaptureSystemAudio) {
|
|
297
290
|
NSLog(@"🔧 Created SCRecordingOutput with microphone and system audio");
|
|
298
291
|
} else if (shouldCaptureMic) {
|
|
@@ -327,9 +320,7 @@ static NSString *g_outputPath = nil;
|
|
|
327
320
|
BOOL outputAdded = NO;
|
|
328
321
|
|
|
329
322
|
if (@available(macOS 15.0, *)) {
|
|
330
|
-
|
|
331
|
-
outputAdded = [g_stream addRecordingOutput:g_recordingOutput error:&outputError];
|
|
332
|
-
}
|
|
323
|
+
outputAdded = [g_stream addRecordingOutput:g_recordingOutput error:&outputError];
|
|
333
324
|
}
|
|
334
325
|
|
|
335
326
|
if (!outputAdded || outputError) {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[{"x":661,"y":888,"timestamp":75,"unixTimeMs":1758662417142,"cursorType":"text","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}}]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[{"x":661,"y":888,"timestamp":28,"unixTimeMs":1758662420161,"cursorType":"text","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":691,"y":857,"timestamp":468,"unixTimeMs":1758662420601,"cursorType":"text","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":796,"y":749,"timestamp":490,"unixTimeMs":1758662420623,"cursorType":"text","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":971,"y":567,"timestamp":515,"unixTimeMs":1758662420648,"cursorType":"text","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1262,"y":304,"timestamp":525,"unixTimeMs":1758662420658,"cursorType":"text","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1519,"y":95,"timestamp":583,"unixTimeMs":1758662420716,"cursorType":"pointer","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":0,"timestamp":621,"unixTimeMs":1758662420754,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1707,"y":0,"timestamp":1510,"unixTimeMs":1758662421643,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1704,"y":0,"timestamp":1526,"unixTimeMs":1758662421659,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":0,"timestamp":1549,"unixTimeMs":1758662421682,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1705,"y":0,"timestamp":1633,"unixTimeMs":1758662421766,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":0,"timestamp":1653,"unixTimeMs":1758662421786,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1707,"y":0,"timestamp":1989,"unixTimeMs":1758662422122,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}}]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[{"x":1709,"y":0,"timestamp":33,"unixTimeMs":1758662423222,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1707,"y":3,"timestamp":654,"unixTimeMs":1758662423843,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1704,"y":8,"timestamp":677,"unixTimeMs":1758662423866,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1704,"y":10,"timestamp":697,"unixTimeMs":1758662423886,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1703,"y":13,"timestamp":718,"unixTimeMs":1758662423907,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":2,"timestamp":780,"unixTimeMs":1758662423969,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":0,"timestamp":802,"unixTimeMs":1758662423991,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1706,"y":3,"timestamp":968,"unixTimeMs":1758662424157,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1698,"y":15,"timestamp":989,"unixTimeMs":1758662424178,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1691,"y":29,"timestamp":1016,"unixTimeMs":1758662424205,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1688,"y":36,"timestamp":1029,"unixTimeMs":1758662424218,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1687,"y":41,"timestamp":1056,"unixTimeMs":1758662424245,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1687,"y":42,"timestamp":1072,"unixTimeMs":1758662424261,"cursorType":"ns-resize","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1689,"y":38,"timestamp":1094,"unixTimeMs":1758662424283,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1700,"y":23,"timestamp":1116,"unixTimeMs":1758662424305,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":9,"timestamp":1134,"unixTimeMs":1758662424323,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":1,"timestamp":1157,"unixTimeMs":1758662424346,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1707,"y":1,"timestamp":1554,"unixTimeMs":1758662424743,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":5,"timestamp":1578,"unixTimeMs":1758662424767,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1694,"y":13,"timestamp":1594,"unixTimeMs":1758662424783,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1690,"y":19,"timestamp":1618,"unixTimeMs":1758662424807,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1685,"y":25,"timestamp":1634,"unixTimeMs":1758662424823,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1684,"y":28,"timestamp":1658,"unixTimeMs":1758662424847,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1686,"y":30,"timestamp":1700,"unixTimeMs":1758662424889,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1691,"y":30,"timestamp":1720,"unixTimeMs":1758662424909,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1699,"y":30,"timestamp":1746,"unixTimeMs":1758662424935,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":25,"timestamp":1764,"unixTimeMs":1758662424953,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":16,"timestamp":1783,"unixTimeMs":1758662424972,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":10,"timestamp":1808,"unixTimeMs":1758662424997,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":0,"timestamp":1825,"unixTimeMs":1758662425014,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":0,"timestamp":1890,"unixTimeMs":1758662425079,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1690,"y":1,"timestamp":1919,"unixTimeMs":1758662425108,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1682,"y":4,"timestamp":1930,"unixTimeMs":1758662425119,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1672,"y":12,"timestamp":1949,"unixTimeMs":1758662425138,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1669,"y":16,"timestamp":1976,"unixTimeMs":1758662425165,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1665,"y":22,"timestamp":1991,"unixTimeMs":1758662425180,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}}]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
[{"x":1698,"y":14,"timestamp":31,"unixTimeMs":1758662426275,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1701,"y":11,"timestamp":51,"unixTimeMs":1758662426295,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1705,"y":6,"timestamp":76,"unixTimeMs":1758662426320,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1708,"y":1,"timestamp":95,"unixTimeMs":1758662426339,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1706,"y":8,"timestamp":426,"unixTimeMs":1758662426670,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1703,"y":13,"timestamp":449,"unixTimeMs":1758662426693,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1701,"y":16,"timestamp":467,"unixTimeMs":1758662426711,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1699,"y":19,"timestamp":489,"unixTimeMs":1758662426733,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1701,"y":17,"timestamp":573,"unixTimeMs":1758662426817,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":15,"timestamp":595,"unixTimeMs":1758662426839,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1704,"y":12,"timestamp":623,"unixTimeMs":1758662426867,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1705,"y":9,"timestamp":635,"unixTimeMs":1758662426879,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1707,"y":6,"timestamp":660,"unixTimeMs":1758662426904,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1708,"y":4,"timestamp":678,"unixTimeMs":1758662426922,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1708,"y":2,"timestamp":702,"unixTimeMs":1758662426946,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":0,"timestamp":744,"unixTimeMs":1758662426988,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1708,"y":3,"timestamp":890,"unixTimeMs":1758662427134,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1705,"y":8,"timestamp":917,"unixTimeMs":1758662427161,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":12,"timestamp":928,"unixTimeMs":1758662427172,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1701,"y":14,"timestamp":951,"unixTimeMs":1758662427195,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1705,"y":10,"timestamp":1036,"unixTimeMs":1758662427280,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":5,"timestamp":1058,"unixTimeMs":1758662427302,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":2,"timestamp":1079,"unixTimeMs":1758662427323,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":0,"timestamp":1100,"unixTimeMs":1758662427344,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1706,"y":5,"timestamp":1222,"unixTimeMs":1758662427466,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1704,"y":8,"timestamp":1244,"unixTimeMs":1758662427488,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":13,"timestamp":1266,"unixTimeMs":1758662427510,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1701,"y":16,"timestamp":1288,"unixTimeMs":1758662427532,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":14,"timestamp":1371,"unixTimeMs":1758662427615,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1703,"y":12,"timestamp":1395,"unixTimeMs":1758662427639,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1705,"y":9,"timestamp":1432,"unixTimeMs":1758662427676,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1706,"y":6,"timestamp":1454,"unixTimeMs":1758662427698,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1706,"y":4,"timestamp":1494,"unixTimeMs":1758662427738,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1704,"y":7,"timestamp":1561,"unixTimeMs":1758662427805,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":10,"timestamp":1578,"unixTimeMs":1758662427822,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1702,"y":12,"timestamp":1617,"unixTimeMs":1758662427861,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1704,"y":12,"timestamp":1661,"unixTimeMs":1758662427905,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1706,"y":12,"timestamp":1685,"unixTimeMs":1758662427929,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1708,"y":11,"timestamp":1726,"unixTimeMs":1758662427970,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":9,"timestamp":1748,"unixTimeMs":1758662427992,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":7,"timestamp":1769,"unixTimeMs":1758662428013,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1709,"y":5,"timestamp":1791,"unixTimeMs":1758662428035,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1707,"y":5,"timestamp":1850,"unixTimeMs":1758662428094,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}},{"x":1708,"y":3,"timestamp":1978,"unixTimeMs":1758662428222,"cursorType":"default","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":1710,"height":1112,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":1710,"height":1112}}]
|