node-mac-recorder 2.17.20 โ 2.17.21
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 +3 -1
- package/index.js +17 -198
- package/package.json +1 -1
- package/publish.sh +18 -0
- package/src/cursor_tracker.mm +37 -20
- package/cursor-debug-test.js +0 -60
- package/cursor-dpr-test.js +0 -73
- package/cursor-dpr-test.json +0 -1
- package/cursor-macbook-test.js +0 -63
- package/cursor-permission-test.js +0 -46
- package/cursor-scaling-debug.js +0 -53
- package/cursor-simple-test.js +0 -26
- package/debug-audio.js +0 -79
- package/debug-coordinates.js +0 -69
- package/debug-macos14.js +0 -110
- package/debug-primary-window.js +0 -84
- package/debug-screen-selection.js +0 -81
- package/debug-window-selector.js +0 -178
- package/test-cursor-fix.js +0 -105
- package/test-cursor-types.js +0 -117
- package/test-display-coordinates.js +0 -72
- package/test-integrated-recording.js +0 -120
- package/test-menubar-offset.js +0 -110
- package/test-output/temp_cursor_1758313956591.json +0 -1
- package/test-primary-cursor.js +0 -154
- package/test-primary-fix.js +0 -120
- package/test-recording-with-cursor.js +0 -83
- package/test-unified-cursor.js +0 -75
- package/test-window-recording.js +0 -149
package/test-primary-cursor.js
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
const MacRecorder = require('./index.js');
|
|
2
|
-
|
|
3
|
-
async function testPrimaryCursor() {
|
|
4
|
-
console.log('๐งช Testing cursor coordinates on primary vs secondary displays...');
|
|
5
|
-
|
|
6
|
-
const recorder = new MacRecorder();
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
// Get available displays and windows
|
|
10
|
-
const displays = await recorder.getDisplays();
|
|
11
|
-
const windows = await recorder.getWindows();
|
|
12
|
-
|
|
13
|
-
console.log('\n๐ฑ Available displays:');
|
|
14
|
-
displays.forEach((display, i) => {
|
|
15
|
-
const type = display.isPrimary ? 'PRIMARY' : 'SECONDARY';
|
|
16
|
-
console.log(` ${i + 1}. ${type} Display ${display.id}: ${display.resolution} at (${display.x}, ${display.y})`);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
// Find windows on each display
|
|
20
|
-
const primaryDisplay = displays.find(d => d.isPrimary);
|
|
21
|
-
const secondaryDisplay = displays.find(d => !d.isPrimary);
|
|
22
|
-
|
|
23
|
-
console.log('\n๐ช Finding windows on each display:');
|
|
24
|
-
|
|
25
|
-
const primaryWindows = windows.filter(window => {
|
|
26
|
-
const windowCenterX = window.x + window.width / 2;
|
|
27
|
-
const windowCenterY = window.y + window.height / 2;
|
|
28
|
-
return (windowCenterX >= primaryDisplay.x &&
|
|
29
|
-
windowCenterX < primaryDisplay.x + primaryDisplay.width &&
|
|
30
|
-
windowCenterY >= primaryDisplay.y &&
|
|
31
|
-
windowCenterY < primaryDisplay.y + primaryDisplay.height);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
const secondaryWindows = secondaryDisplay ? windows.filter(window => {
|
|
35
|
-
const windowCenterX = window.x + window.width / 2;
|
|
36
|
-
const windowCenterY = window.y + window.height / 2;
|
|
37
|
-
return (windowCenterX >= secondaryDisplay.x &&
|
|
38
|
-
windowCenterX < secondaryDisplay.x + secondaryDisplay.width &&
|
|
39
|
-
windowCenterY >= secondaryDisplay.y &&
|
|
40
|
-
windowCenterY < secondaryDisplay.y + secondaryDisplay.height);
|
|
41
|
-
}) : [];
|
|
42
|
-
|
|
43
|
-
console.log(`\n๐ Window distribution:`);
|
|
44
|
-
console.log(` Primary display: ${primaryWindows.length} windows`);
|
|
45
|
-
console.log(` Secondary display: ${secondaryWindows.length} windows`);
|
|
46
|
-
|
|
47
|
-
// Test each display type
|
|
48
|
-
for (const displayType of ['primary', 'secondary']) {
|
|
49
|
-
const display = displayType === 'primary' ? primaryDisplay : secondaryDisplay;
|
|
50
|
-
const windowList = displayType === 'primary' ? primaryWindows : secondaryWindows;
|
|
51
|
-
|
|
52
|
-
if (!display) {
|
|
53
|
-
console.log(`\nโ ๏ธ No ${displayType} display found, skipping...`);
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (windowList.length === 0) {
|
|
58
|
-
console.log(`\nโ ๏ธ No windows found on ${displayType} display, skipping...`);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const testWindow = windowList[0];
|
|
63
|
-
console.log(`\n๐ฏ Testing ${displayType.toUpperCase()} display (${display.id}):`);
|
|
64
|
-
console.log(` Display bounds: (${display.x}, ${display.y}) ${display.width}x${display.height}`);
|
|
65
|
-
console.log(` Test window: "${testWindow.title}" at (${testWindow.x}, ${testWindow.y}) ${testWindow.width}x${testWindow.height}`);
|
|
66
|
-
|
|
67
|
-
// Calculate window position relative to display
|
|
68
|
-
const windowRelativeX = testWindow.x - display.x;
|
|
69
|
-
const windowRelativeY = testWindow.y - display.y;
|
|
70
|
-
console.log(` Window relative to display: (${windowRelativeX}, ${windowRelativeY})`);
|
|
71
|
-
|
|
72
|
-
// Test cursor capture
|
|
73
|
-
const outputFile = `./test-output/cursor-${displayType}-${Date.now()}.json`;
|
|
74
|
-
|
|
75
|
-
console.log(`\n๐ฑ๏ธ Starting cursor test for ${displayType} display...`);
|
|
76
|
-
console.log(' Move mouse over the test window for 3 seconds');
|
|
77
|
-
|
|
78
|
-
await recorder.startCursorCapture(outputFile, {
|
|
79
|
-
windowRelative: true,
|
|
80
|
-
windowInfo: {
|
|
81
|
-
x: testWindow.x,
|
|
82
|
-
y: testWindow.y,
|
|
83
|
-
width: testWindow.width,
|
|
84
|
-
height: testWindow.height,
|
|
85
|
-
displayId: display.id,
|
|
86
|
-
targetDisplay: display
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// Capture for 3 seconds
|
|
91
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
92
|
-
|
|
93
|
-
await recorder.stopCursorCapture();
|
|
94
|
-
|
|
95
|
-
// Analyze results
|
|
96
|
-
const fs = require('fs');
|
|
97
|
-
if (fs.existsSync(outputFile)) {
|
|
98
|
-
const cursorData = JSON.parse(fs.readFileSync(outputFile, 'utf8'));
|
|
99
|
-
|
|
100
|
-
console.log(`\n๐ ${displayType.toUpperCase()} Display Results:`);
|
|
101
|
-
console.log(` Captured events: ${cursorData.length}`);
|
|
102
|
-
|
|
103
|
-
if (cursorData.length > 0) {
|
|
104
|
-
const inBounds = cursorData.filter(event =>
|
|
105
|
-
event.x >= 0 && event.x < testWindow.width &&
|
|
106
|
-
event.y >= 0 && event.y < testWindow.height
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
const outOfBounds = cursorData.filter(event =>
|
|
110
|
-
event.x < 0 || event.x >= testWindow.width ||
|
|
111
|
-
event.y < 0 || event.y >= testWindow.height
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
console.log(` Events in bounds: ${inBounds.length}/${cursorData.length} (${Math.round(inBounds.length/cursorData.length*100)}%)`);
|
|
115
|
-
console.log(` Events out of bounds: ${outOfBounds.length}`);
|
|
116
|
-
|
|
117
|
-
if (outOfBounds.length > 0) {
|
|
118
|
-
console.log(` โ ISSUE DETECTED on ${displayType} display!`);
|
|
119
|
-
console.log(` Sample out-of-bounds coordinates:`);
|
|
120
|
-
outOfBounds.slice(0, 5).forEach(event => {
|
|
121
|
-
console.log(` (${event.x}, ${event.y}) - should be 0-${testWindow.width}, 0-${testWindow.height}`);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// Analyze the offset pattern
|
|
125
|
-
const xOffsets = outOfBounds.map(e => e.x);
|
|
126
|
-
const yOffsets = outOfBounds.map(e => e.y);
|
|
127
|
-
const avgXOffset = xOffsets.reduce((a, b) => a + b, 0) / xOffsets.length;
|
|
128
|
-
const avgYOffset = yOffsets.reduce((a, b) => a + b, 0) / yOffsets.length;
|
|
129
|
-
|
|
130
|
-
console.log(` ๐ Average coordinate offsets: X=${avgXOffset.toFixed(1)}, Y=${avgYOffset.toFixed(1)}`);
|
|
131
|
-
} else {
|
|
132
|
-
console.log(` โ
All coordinates within bounds on ${displayType} display`);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Show coordinate samples
|
|
136
|
-
console.log(` Sample coordinates (first 3):`);
|
|
137
|
-
cursorData.slice(0, 3).forEach((event, i) => {
|
|
138
|
-
console.log(` ${i+1}. (${event.x}, ${event.y}) - ${event.coordinateSystem}`);
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
console.log('\n๐ Analysis Summary:');
|
|
145
|
-
console.log(' If primary display shows out-of-bounds coordinates,');
|
|
146
|
-
console.log(' but secondary display works correctly, this indicates');
|
|
147
|
-
console.log(' a coordinate transformation issue specific to primary displays.');
|
|
148
|
-
|
|
149
|
-
} catch (error) {
|
|
150
|
-
console.error('โ Test failed:', error.message);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
testPrimaryCursor().catch(console.error);
|
package/test-primary-fix.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
const MacRecorder = require('./index.js');
|
|
2
|
-
|
|
3
|
-
async function testPrimaryFix() {
|
|
4
|
-
console.log('๐งช Testing fixed cursor coordinates on primary display...');
|
|
5
|
-
|
|
6
|
-
const recorder = new MacRecorder();
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
const displays = await recorder.getDisplays();
|
|
10
|
-
const windows = await recorder.getWindows();
|
|
11
|
-
|
|
12
|
-
const primaryDisplay = displays.find(d => d.isPrimary);
|
|
13
|
-
const primaryWindows = windows.filter(window => {
|
|
14
|
-
const windowCenterX = window.x + window.width / 2;
|
|
15
|
-
const windowCenterY = window.y + window.height / 2;
|
|
16
|
-
return (windowCenterX >= primaryDisplay.x &&
|
|
17
|
-
windowCenterX < primaryDisplay.x + primaryDisplay.width &&
|
|
18
|
-
windowCenterY >= primaryDisplay.y &&
|
|
19
|
-
windowCenterY < primaryDisplay.y + primaryDisplay.height);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
if (primaryWindows.length === 0) {
|
|
23
|
-
console.log('โ No windows found on primary display');
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const testWindow = primaryWindows[0];
|
|
28
|
-
|
|
29
|
-
console.log('\n๐ฏ Testing PRIMARY display window recording:');
|
|
30
|
-
console.log(` Display: ${primaryDisplay.width}x${primaryDisplay.height} at (${primaryDisplay.x}, ${primaryDisplay.y})`);
|
|
31
|
-
console.log(` Window: "${testWindow.title}" ${testWindow.width}x${testWindow.height} at (${testWindow.x}, ${testWindow.y})`);
|
|
32
|
-
|
|
33
|
-
// Calculate expected coordinates
|
|
34
|
-
console.log('\n๐ Expected transformation:');
|
|
35
|
-
console.log(` Window top-left (${testWindow.x}, ${testWindow.y}) should become (0, 0)`);
|
|
36
|
-
console.log(` Window bottom-right (${testWindow.x + testWindow.width}, ${testWindow.y + testWindow.height}) should become (${testWindow.width}, ${testWindow.height})`);
|
|
37
|
-
|
|
38
|
-
// Start cursor capture
|
|
39
|
-
const outputFile = `./test-output/primary-fix-test-${Date.now()}.json`;
|
|
40
|
-
|
|
41
|
-
await recorder.startCursorCapture(outputFile, {
|
|
42
|
-
windowRelative: true,
|
|
43
|
-
windowInfo: {
|
|
44
|
-
x: testWindow.x,
|
|
45
|
-
y: testWindow.y,
|
|
46
|
-
width: testWindow.width,
|
|
47
|
-
height: testWindow.height,
|
|
48
|
-
displayId: primaryDisplay.id
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
console.log('\n๐ฑ๏ธ Move mouse over the test window for 5 seconds...');
|
|
53
|
-
console.log(` Try to move cursor to different corners of the window`);
|
|
54
|
-
console.log(` Window boundaries: (0,0) to (${testWindow.width}, ${testWindow.height})`);
|
|
55
|
-
|
|
56
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
57
|
-
|
|
58
|
-
await recorder.stopCursorCapture();
|
|
59
|
-
|
|
60
|
-
// Analyze results
|
|
61
|
-
const fs = require('fs');
|
|
62
|
-
if (fs.existsSync(outputFile)) {
|
|
63
|
-
const cursorData = JSON.parse(fs.readFileSync(outputFile, 'utf8'));
|
|
64
|
-
|
|
65
|
-
console.log('\n๐ PRIMARY Display Test Results:');
|
|
66
|
-
console.log(` Captured events: ${cursorData.length}`);
|
|
67
|
-
|
|
68
|
-
if (cursorData.length > 0) {
|
|
69
|
-
const inBounds = cursorData.filter(event =>
|
|
70
|
-
event.x >= 0 && event.x < testWindow.width &&
|
|
71
|
-
event.y >= 0 && event.y < testWindow.height
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
const outOfBounds = cursorData.filter(event =>
|
|
75
|
-
event.x < 0 || event.x >= testWindow.width ||
|
|
76
|
-
event.y < 0 || event.y >= testWindow.height
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
console.log(` Events in bounds: ${inBounds.length}/${cursorData.length} (${Math.round(inBounds.length/cursorData.length*100)}%)`);
|
|
80
|
-
|
|
81
|
-
if (outOfBounds.length > 0) {
|
|
82
|
-
console.log(` โ STILL HAVE ISSUES: ${outOfBounds.length} events out of bounds`);
|
|
83
|
-
console.log(` Sample problematic coordinates:`);
|
|
84
|
-
outOfBounds.slice(0, 3).forEach(event => {
|
|
85
|
-
console.log(` (${event.x}, ${event.y}) - should be within 0-${testWindow.width}, 0-${testWindow.height}`);
|
|
86
|
-
});
|
|
87
|
-
} else {
|
|
88
|
-
console.log(` โ
ALL COORDINATES WITHIN BOUNDS - Primary display fix successful!`);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Show coordinate range
|
|
92
|
-
const xCoords = cursorData.map(e => e.x);
|
|
93
|
-
const yCoords = cursorData.map(e => e.y);
|
|
94
|
-
const minX = Math.min(...xCoords);
|
|
95
|
-
const maxX = Math.max(...xCoords);
|
|
96
|
-
const minY = Math.min(...yCoords);
|
|
97
|
-
const maxY = Math.max(...yCoords);
|
|
98
|
-
|
|
99
|
-
console.log(` Coordinate ranges: X=${minX} to ${maxX}, Y=${minY} to ${maxY}`);
|
|
100
|
-
|
|
101
|
-
// Check coordinate system
|
|
102
|
-
const firstEvent = cursorData[0];
|
|
103
|
-
console.log(` Coordinate system: ${firstEvent.coordinateSystem}`);
|
|
104
|
-
|
|
105
|
-
if (firstEvent.coordinateSystem === "window-relative") {
|
|
106
|
-
console.log(` โ
Coordinate system correctly set`);
|
|
107
|
-
} else {
|
|
108
|
-
console.log(` โ Coordinate system incorrect: ${firstEvent.coordinateSystem}`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
} else {
|
|
112
|
-
console.log('โ No output file created');
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
} catch (error) {
|
|
116
|
-
console.error('โ Test failed:', error.message);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
testPrimaryFix().catch(console.error);
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const MacRecorder = require('./index.js');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
async function testRecordingWithCursor() {
|
|
8
|
-
const recorder = new MacRecorder();
|
|
9
|
-
|
|
10
|
-
console.log('๐ฏ Testing recording with cursor tracking...');
|
|
11
|
-
|
|
12
|
-
// Create test output directory
|
|
13
|
-
const outputDir = './test-output';
|
|
14
|
-
if (!fs.existsSync(outputDir)) {
|
|
15
|
-
fs.mkdirSync(outputDir);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const videoPath = path.join(outputDir, `test-recording-${Date.now()}.mov`);
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
console.log('Starting recording with auto cursor tracking...');
|
|
22
|
-
|
|
23
|
-
// Start recording (should auto-start cursor tracking)
|
|
24
|
-
await recorder.startRecording(videoPath, {
|
|
25
|
-
captureCursor: true, // This should trigger auto cursor tracking
|
|
26
|
-
quality: 'low',
|
|
27
|
-
frameRate: 10
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
console.log('โ
Recording started successfully');
|
|
31
|
-
console.log('๐ฅ Recording for 3 seconds...');
|
|
32
|
-
|
|
33
|
-
// Wait 3 seconds
|
|
34
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
35
|
-
|
|
36
|
-
console.log('Stopping recording...');
|
|
37
|
-
const stopResult = await recorder.stopRecording();
|
|
38
|
-
console.log('โ
Recording stopped:', stopResult);
|
|
39
|
-
|
|
40
|
-
// Wait a bit for file to be written
|
|
41
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
42
|
-
|
|
43
|
-
// Check if files exist
|
|
44
|
-
if (fs.existsSync(videoPath)) {
|
|
45
|
-
const videoStats = fs.statSync(videoPath);
|
|
46
|
-
console.log('๐น Video file size:', videoStats.size, 'bytes');
|
|
47
|
-
} else {
|
|
48
|
-
console.log('โ Video file not found:', videoPath);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Check for cursor files
|
|
52
|
-
const cursorFiles = fs.readdirSync(outputDir).filter(f => f.includes('cursor') && f.endsWith('.json'));
|
|
53
|
-
console.log('๐ Cursor files found:', cursorFiles.length);
|
|
54
|
-
|
|
55
|
-
if (cursorFiles.length > 0) {
|
|
56
|
-
const cursorFile = path.join(outputDir, cursorFiles[0]);
|
|
57
|
-
const cursorContent = fs.readFileSync(cursorFile, 'utf8');
|
|
58
|
-
console.log('๐ Cursor file size:', cursorContent.length, 'bytes');
|
|
59
|
-
|
|
60
|
-
if (cursorContent.trim()) {
|
|
61
|
-
try {
|
|
62
|
-
const cursorData = JSON.parse(cursorContent);
|
|
63
|
-
console.log('๐ Cursor data points:', cursorData.length);
|
|
64
|
-
} catch (parseError) {
|
|
65
|
-
console.log('โ ๏ธ Cursor file content preview:', cursorContent.substring(0, 200));
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
} catch (error) {
|
|
71
|
-
console.error('โ Test failed:', error.message);
|
|
72
|
-
console.error('Stack:', error.stack);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Run test
|
|
77
|
-
testRecordingWithCursor().then(() => {
|
|
78
|
-
console.log('\nโจ Test completed');
|
|
79
|
-
process.exit(0);
|
|
80
|
-
}).catch(error => {
|
|
81
|
-
console.error('๐ฅ Test error:', error);
|
|
82
|
-
process.exit(1);
|
|
83
|
-
});
|
package/test-unified-cursor.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const MacRecorder = require('./index.js');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
async function testUnifiedCursorTracking() {
|
|
8
|
-
const recorder = new MacRecorder();
|
|
9
|
-
|
|
10
|
-
console.log('๐ฏ Testing unified cursor tracking...');
|
|
11
|
-
|
|
12
|
-
// Create test output directory
|
|
13
|
-
const outputDir = './test-output';
|
|
14
|
-
if (!fs.existsSync(outputDir)) {
|
|
15
|
-
fs.mkdirSync(outputDir);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const cursorFilePath = path.join(outputDir, `unified-cursor-${Date.now()}.json`);
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
console.log('Starting native cursor tracking...');
|
|
22
|
-
|
|
23
|
-
// Test native cursor tracking
|
|
24
|
-
const result = await recorder.startCursorCapture(cursorFilePath);
|
|
25
|
-
console.log('โ
Cursor tracking started:', result);
|
|
26
|
-
|
|
27
|
-
console.log('\n๐ฅ Move your mouse around for 5 seconds...');
|
|
28
|
-
|
|
29
|
-
// Wait 5 seconds
|
|
30
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
31
|
-
|
|
32
|
-
console.log('\nStopping cursor tracking...');
|
|
33
|
-
const stopped = recorder.stopCursorCapture();
|
|
34
|
-
console.log('โ
Cursor tracking stopped:', stopped);
|
|
35
|
-
|
|
36
|
-
// Wait a bit for file to be written
|
|
37
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
38
|
-
|
|
39
|
-
// Check if file exists and has content
|
|
40
|
-
if (fs.existsSync(cursorFilePath)) {
|
|
41
|
-
const fileContent = fs.readFileSync(cursorFilePath, 'utf8');
|
|
42
|
-
console.log('๐ File size:', fileContent.length, 'bytes');
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
const cursorData = JSON.parse(fileContent);
|
|
46
|
-
console.log('๐ Cursor data points:', cursorData.length);
|
|
47
|
-
|
|
48
|
-
if (cursorData.length > 0) {
|
|
49
|
-
console.log('๐ First point:', cursorData[0]);
|
|
50
|
-
console.log('๐ Last point:', cursorData[cursorData.length - 1]);
|
|
51
|
-
|
|
52
|
-
// Check coordinate system
|
|
53
|
-
const coordinateSystems = [...new Set(cursorData.map(p => p.coordinateSystem))];
|
|
54
|
-
console.log('๐ง Coordinate systems used:', coordinateSystems);
|
|
55
|
-
}
|
|
56
|
-
} catch (parseError) {
|
|
57
|
-
console.log('โ ๏ธ File content (first 500 chars):', fileContent.substring(0, 500));
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
console.log('โ Output file not found:', cursorFilePath);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
} catch (error) {
|
|
64
|
-
console.error('โ Test failed:', error.message);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Run test
|
|
69
|
-
testUnifiedCursorTracking().then(() => {
|
|
70
|
-
console.log('\nโจ Test completed');
|
|
71
|
-
process.exit(0);
|
|
72
|
-
}).catch(error => {
|
|
73
|
-
console.error('๐ฅ Test error:', error);
|
|
74
|
-
process.exit(1);
|
|
75
|
-
});
|
package/test-window-recording.js
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const MacRecorder = require('./index.js');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
|
|
7
|
-
// Test output directory
|
|
8
|
-
const outputDir = './test-output';
|
|
9
|
-
if (!fs.existsSync(outputDir)) {
|
|
10
|
-
fs.mkdirSync(outputDir, { recursive: true });
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const recorder = new MacRecorder();
|
|
14
|
-
|
|
15
|
-
async function testWindowRecording() {
|
|
16
|
-
console.log('๐ฌ Testing window recording with automatic cursor tracking...');
|
|
17
|
-
|
|
18
|
-
try {
|
|
19
|
-
// Test permissions first
|
|
20
|
-
const permissions = await recorder.checkPermissions();
|
|
21
|
-
console.log('๐ Permissions:', permissions);
|
|
22
|
-
|
|
23
|
-
if (!permissions.screenRecording) {
|
|
24
|
-
console.log('โ Screen recording permission required');
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// Get windows
|
|
29
|
-
const windows = await recorder.getWindows();
|
|
30
|
-
console.log(`๐ช Found ${windows.length} windows`);
|
|
31
|
-
|
|
32
|
-
// Find a suitable window to record (preferably a visible one)
|
|
33
|
-
const visibleWindows = windows.filter(w => w.width > 200 && w.height > 100);
|
|
34
|
-
if (visibleWindows.length === 0) {
|
|
35
|
-
console.log('โ No suitable windows found for recording');
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const targetWindow = visibleWindows[0];
|
|
40
|
-
console.log(`๐ฏ Target window: ${targetWindow.appName} (${targetWindow.width}x${targetWindow.height})`);
|
|
41
|
-
console.log(`๐ Window position: (${targetWindow.x}, ${targetWindow.y})`);
|
|
42
|
-
|
|
43
|
-
// Setup recording options
|
|
44
|
-
const timestamp = Date.now();
|
|
45
|
-
const videoPath = path.join(outputDir, `window-test-${timestamp}.mov`);
|
|
46
|
-
|
|
47
|
-
console.log(`๐ฅ Starting window recording to: ${videoPath}`);
|
|
48
|
-
console.log('๐ฑ๏ธ Cursor tracking will use window-relative coordinates');
|
|
49
|
-
console.log('๐ก Move your mouse over the target window to generate cursor data');
|
|
50
|
-
|
|
51
|
-
// Start recording the specific window (cursor tracking will start automatically)
|
|
52
|
-
await recorder.startRecording(videoPath, {
|
|
53
|
-
includeMicrophone: false,
|
|
54
|
-
includeSystemAudio: false,
|
|
55
|
-
captureCursor: true,
|
|
56
|
-
windowId: targetWindow.id
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
console.log('โ
Window recording started successfully!');
|
|
60
|
-
console.log('๐ฑ๏ธ Cursor tracking started automatically with window-relative coordinates');
|
|
61
|
-
console.log('โฐ Recording for 8 seconds...');
|
|
62
|
-
console.log(`๐ Please move your mouse over the "${targetWindow.appName}" window`);
|
|
63
|
-
|
|
64
|
-
// Wait for 8 seconds
|
|
65
|
-
await new Promise(resolve => setTimeout(resolve, 8000));
|
|
66
|
-
|
|
67
|
-
console.log('๐ Stopping recording...');
|
|
68
|
-
|
|
69
|
-
// Stop recording (cursor tracking will stop automatically)
|
|
70
|
-
const result = await recorder.stopRecording();
|
|
71
|
-
|
|
72
|
-
console.log('โ
Recording stopped:', result);
|
|
73
|
-
console.log('๐ Checking output files...');
|
|
74
|
-
|
|
75
|
-
// Wait a moment for files to be written
|
|
76
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
77
|
-
|
|
78
|
-
// Check for video file
|
|
79
|
-
if (fs.existsSync(videoPath)) {
|
|
80
|
-
const videoStats = fs.statSync(videoPath);
|
|
81
|
-
console.log(`๐น Video file created: ${path.basename(videoPath)} (${videoStats.size} bytes)`);
|
|
82
|
-
} else {
|
|
83
|
-
console.log('โ Video file not found');
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Check for cursor file
|
|
87
|
-
const files = fs.readdirSync(outputDir);
|
|
88
|
-
const cursorFile = files.find(f => f.startsWith('temp_cursor_') && f.endsWith('.json'));
|
|
89
|
-
|
|
90
|
-
if (cursorFile) {
|
|
91
|
-
const cursorPath = path.join(outputDir, cursorFile);
|
|
92
|
-
const cursorStats = fs.statSync(cursorPath);
|
|
93
|
-
console.log(`๐ฑ๏ธ Cursor file created: ${cursorFile} (${cursorStats.size} bytes)`);
|
|
94
|
-
|
|
95
|
-
// Read and validate cursor data
|
|
96
|
-
try {
|
|
97
|
-
const cursorData = JSON.parse(fs.readFileSync(cursorPath, 'utf8'));
|
|
98
|
-
console.log(`๐ Cursor data points: ${cursorData.length}`);
|
|
99
|
-
|
|
100
|
-
if (cursorData.length > 0) {
|
|
101
|
-
const first = cursorData[0];
|
|
102
|
-
const last = cursorData[cursorData.length - 1];
|
|
103
|
-
|
|
104
|
-
console.log(`๐ First cursor position: (${first.x}, ${first.y}) at ${first.timestamp}ms`);
|
|
105
|
-
console.log(`๐ Last cursor position: (${last.x}, ${last.y}) at ${last.timestamp}ms`);
|
|
106
|
-
console.log(`๐ Coordinate system: ${first.coordinateSystem}`);
|
|
107
|
-
|
|
108
|
-
if (first.windowInfo) {
|
|
109
|
-
console.log(`๐ช Window info: ${first.windowInfo.width}x${first.windowInfo.height}`);
|
|
110
|
-
console.log(`๐ Original window position: (${first.windowInfo.originalWindow?.x}, ${first.windowInfo.originalWindow?.y})`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Analyze cursor positions
|
|
114
|
-
const windowRelativePositions = cursorData.filter(d => d.coordinateSystem === 'window-relative');
|
|
115
|
-
if (windowRelativePositions.length > 0) {
|
|
116
|
-
console.log(`โ
${windowRelativePositions.length} window-relative cursor positions recorded`);
|
|
117
|
-
|
|
118
|
-
// Check if coordinates are within window bounds
|
|
119
|
-
const validPositions = windowRelativePositions.filter(d =>
|
|
120
|
-
d.x >= 0 && d.y >= 0 &&
|
|
121
|
-
d.x <= targetWindow.width && d.y <= targetWindow.height
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
console.log(`โ
${validPositions.length}/${windowRelativePositions.length} positions within window bounds`);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
} catch (parseError) {
|
|
128
|
-
console.log('โ ๏ธ Could not parse cursor data:', parseError.message);
|
|
129
|
-
}
|
|
130
|
-
} else {
|
|
131
|
-
console.log('โ Cursor file not found');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
console.log('โ
Window recording test completed!');
|
|
135
|
-
|
|
136
|
-
} catch (error) {
|
|
137
|
-
console.error('โ Test failed:', error.message);
|
|
138
|
-
console.error(error.stack);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Run the test
|
|
143
|
-
testWindowRecording().then(() => {
|
|
144
|
-
console.log('๐ Window recording test finished');
|
|
145
|
-
process.exit(0);
|
|
146
|
-
}).catch(error => {
|
|
147
|
-
console.error('๐ฅ Fatal error:', error);
|
|
148
|
-
process.exit(1);
|
|
149
|
-
});
|