node-mac-recorder 2.21.51 ā 2.21.53
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 +8 -1
- package/output/temp_cursor_1765066228867.json +1 -0
- package/package.json +1 -1
- package/scripts/camera-sync.js +74 -0
- package/scripts/full-sync.js +131 -0
- package/src/camera_recorder.mm +242 -144
- package/src/camera_recorder.mm.backup +863 -0
- package/src/screen_capture_kit.mm +2 -2
- package/tasks-1.md +231 -0
- package/tasks-2.md +220 -0
- package/tasks-3.md +291 -0
|
@@ -41,7 +41,14 @@
|
|
|
41
41
|
"Bash(timeout 3 node build-seed-map.js:*)",
|
|
42
42
|
"Bash(echo:*)",
|
|
43
43
|
"Bash(timeout 3 node:*)",
|
|
44
|
-
"Bash(timeout 25 node:*)"
|
|
44
|
+
"Bash(timeout 25 node:*)",
|
|
45
|
+
"Bash(ls:*)",
|
|
46
|
+
"Bash(for f in test-output/temp_camera_1764838803672.mov test-output/temp_audio_1764838803672.mov test-output/duration-test-1764838803672.mov)",
|
|
47
|
+
"Bash(do)",
|
|
48
|
+
"Bash(grep:*)",
|
|
49
|
+
"Bash(timeout 10 ffprobe:*)",
|
|
50
|
+
"Bash(ffmpeg:*)",
|
|
51
|
+
"Bash(timeout 30 node:*)"
|
|
45
52
|
],
|
|
46
53
|
"deny": [],
|
|
47
54
|
"ask": []
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{"x":1147,"y":408,"timestamp":25,"unixTimeMs":1765066231580,"cursorType":"text","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330},"_syncMetadata":{"videoStartTime":1765066228867,"cursorStartTime":1765066231555,"offsetMs":2688}},{"x":1147,"y":408,"timestamp":7015,"unixTimeMs":1765066238570,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1125,"y":410,"timestamp":7769,"unixTimeMs":1765066239324,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1068,"y":422,"timestamp":7787,"unixTimeMs":1765066239342,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":998,"y":440,"timestamp":7810,"unixTimeMs":1765066239365,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":835,"y":486,"timestamp":7829,"unixTimeMs":1765066239384,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":713,"y":525,"timestamp":7853,"unixTimeMs":1765066239408,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":606,"y":566,"timestamp":7872,"unixTimeMs":1765066239427,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":565,"y":581,"timestamp":7894,"unixTimeMs":1765066239449,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":596,"timestamp":7915,"unixTimeMs":1765066239470,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":586,"timestamp":8127,"unixTimeMs":1765066239682,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":564,"timestamp":8146,"unixTimeMs":1765066239701,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":528,"timestamp":8168,"unixTimeMs":1765066239723,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":513,"timestamp":8188,"unixTimeMs":1765066239743,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":532,"y":501,"timestamp":8210,"unixTimeMs":1765066239765,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":531,"y":497,"timestamp":8230,"unixTimeMs":1765066239785,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":549,"y":497,"timestamp":8923,"unixTimeMs":1765066240478,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":574,"y":500,"timestamp":8944,"unixTimeMs":1765066240499,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":615,"y":506,"timestamp":8964,"unixTimeMs":1765066240519,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":696,"y":517,"timestamp":8986,"unixTimeMs":1765066240541,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":753,"y":526,"timestamp":9006,"unixTimeMs":1765066240561,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":838,"y":536,"timestamp":9027,"unixTimeMs":1765066240582,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":890,"y":547,"timestamp":9047,"unixTimeMs":1765066240602,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":920,"y":556,"timestamp":9069,"unixTimeMs":1765066240624,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":923,"y":557,"timestamp":9089,"unixTimeMs":1765066240644,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":922,"y":553,"timestamp":9277,"unixTimeMs":1765066240832,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":918,"y":538,"timestamp":9299,"unixTimeMs":1765066240854,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":917,"y":520,"timestamp":9320,"unixTimeMs":1765066240875,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":917,"y":466,"timestamp":9344,"unixTimeMs":1765066240899,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":918,"y":443,"timestamp":9363,"unixTimeMs":1765066240918,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":924,"y":415,"timestamp":9383,"unixTimeMs":1765066240938,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":929,"y":398,"timestamp":9403,"unixTimeMs":1765066240958,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":934,"y":387,"timestamp":9427,"unixTimeMs":1765066240982,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":937,"y":383,"timestamp":9446,"unixTimeMs":1765066241001,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":940,"y":377,"timestamp":9469,"unixTimeMs":1765066241024,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":943,"y":371,"timestamp":9487,"unixTimeMs":1765066241042,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":950,"y":361,"timestamp":9507,"unixTimeMs":1765066241062,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":958,"y":349,"timestamp":9529,"unixTimeMs":1765066241084,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":964,"y":341,"timestamp":9552,"unixTimeMs":1765066241107,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":971,"y":333,"timestamp":9570,"unixTimeMs":1765066241125,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":976,"y":327,"timestamp":9594,"unixTimeMs":1765066241149,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":985,"y":319,"timestamp":9612,"unixTimeMs":1765066241167,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1001,"y":303,"timestamp":9636,"unixTimeMs":1765066241191,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1001,"y":299,"timestamp":9864,"unixTimeMs":1765066241419,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1004,"y":293,"timestamp":9886,"unixTimeMs":1765066241441,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1008,"y":290,"timestamp":9906,"unixTimeMs":1765066241461,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1010,"y":287,"timestamp":9928,"unixTimeMs":1765066241483,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1012,"y":284,"timestamp":9948,"unixTimeMs":1765066241503,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1013,"y":281,"timestamp":9969,"unixTimeMs":1765066241524,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}},{"x":1014,"y":278,"timestamp":9993,"unixTimeMs":1765066241548,"cursorType":"progress","type":"move","coordinateSystem":"video-relative","recordingType":"display","videoInfo":{"width":2048,"height":1330,"offsetX":0,"offsetY":0},"displayInfo":{"displayId":1,"width":2048,"height":1330}}]
|
package/package.json
CHANGED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const MacRecorder = require('./index.js');
|
|
2
|
+
|
|
3
|
+
async function testCameraSync() {
|
|
4
|
+
console.log('š¬ Testing camera realtime sync implementation...\n');
|
|
5
|
+
|
|
6
|
+
const recorder = new MacRecorder();
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
// Get camera devices
|
|
10
|
+
const cameras = await recorder.getCameraDevices();
|
|
11
|
+
console.log(`š· Found ${cameras.length} camera(s)`);
|
|
12
|
+
|
|
13
|
+
if (cameras.length === 0) {
|
|
14
|
+
console.log('ā ļø No cameras found - skipping test');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const camera = cameras[0];
|
|
19
|
+
console.log(`ā
Using camera: ${camera.name}\n`);
|
|
20
|
+
|
|
21
|
+
// Setup recording
|
|
22
|
+
const outputPath = 'test-output/camera-sync-test.mov';
|
|
23
|
+
|
|
24
|
+
console.log('ā¶ļø Starting camera recording...');
|
|
25
|
+
await recorder.startRecording(outputPath, {
|
|
26
|
+
captureCamera: true,
|
|
27
|
+
cameraDeviceId: camera.id
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
console.log('ā
Recording started\n');
|
|
31
|
+
|
|
32
|
+
// Record for 10 seconds
|
|
33
|
+
console.log('ā±ļø Recording for 10 seconds...');
|
|
34
|
+
await new Promise(resolve => setTimeout(resolve, 10000));
|
|
35
|
+
|
|
36
|
+
console.log('ā¹ļø Stopping recording...');
|
|
37
|
+
const result = await recorder.stopRecording();
|
|
38
|
+
|
|
39
|
+
console.log('ā
Recording stopped\n');
|
|
40
|
+
console.log('š Output:', result.cameraOutputPath);
|
|
41
|
+
|
|
42
|
+
// Verify timestamp with ffprobe
|
|
43
|
+
console.log('\nš Verifying timestamps...');
|
|
44
|
+
const { execSync } = require('child_process');
|
|
45
|
+
|
|
46
|
+
try {
|
|
47
|
+
const output = execSync(`ffprobe -show_frames -select_streams v:0 -show_entries frame=pkt_pts_time "${result.cameraOutputPath}" 2>&1 | grep pkt_pts_time | head -1`, {
|
|
48
|
+
encoding: 'utf8'
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
console.log(`First frame timestamp: ${output.trim()}`);
|
|
52
|
+
|
|
53
|
+
if (output.includes('pkt_pts_time=0.000000')) {
|
|
54
|
+
console.log('ā
SUCCESS: Camera recording starts at t=0 (perfect sync!)');
|
|
55
|
+
} else {
|
|
56
|
+
console.log('ā ļø WARNING: Camera recording does not start at t=0');
|
|
57
|
+
}
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.log('ā ļø ffprobe not available, skipping timestamp verification');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error('ā Test failed:', error.message);
|
|
64
|
+
console.error(error.stack);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
testCameraSync().then(() => {
|
|
69
|
+
console.log('\nā
Test completed');
|
|
70
|
+
process.exit(0);
|
|
71
|
+
}).catch(err => {
|
|
72
|
+
console.error('\nā Test error:', err);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
});
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
const MacRecorder = require('./index.js');
|
|
2
|
+
|
|
3
|
+
async function testFullSync() {
|
|
4
|
+
console.log('š¬ Testing full sync: Screen + Audio + Cursor + Camera\n');
|
|
5
|
+
|
|
6
|
+
const recorder = new MacRecorder();
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
// Get available devices
|
|
10
|
+
const displays = await recorder.getDisplays();
|
|
11
|
+
const cameras = await recorder.getCameraDevices();
|
|
12
|
+
const audioDevices = await recorder.getAudioDevices();
|
|
13
|
+
|
|
14
|
+
console.log(`šŗ Found ${displays.length} display(s)`);
|
|
15
|
+
console.log(`š· Found ${cameras.length} camera(s)`);
|
|
16
|
+
console.log(`š¤ Found ${audioDevices.length} audio device(s)\n`);
|
|
17
|
+
|
|
18
|
+
if (displays.length === 0) {
|
|
19
|
+
console.log('ā ļø No displays found - cannot test');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const display = displays[0];
|
|
24
|
+
console.log(`ā
Using display: ${display.id} (${display.width}x${display.height})`);
|
|
25
|
+
|
|
26
|
+
if (cameras.length > 0) {
|
|
27
|
+
console.log(`ā
Using camera: ${cameras[0].name}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (audioDevices.length > 0) {
|
|
31
|
+
console.log(`ā
Using audio: ${audioDevices[0].name}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log();
|
|
35
|
+
|
|
36
|
+
// Setup recording with all features
|
|
37
|
+
const outputPath = 'test-output/full-sync-test.mov';
|
|
38
|
+
const cursorPath = 'test-output/full-sync-cursor.json';
|
|
39
|
+
|
|
40
|
+
const options = {
|
|
41
|
+
displayId: display.id,
|
|
42
|
+
captureCamera: cameras.length > 0,
|
|
43
|
+
cameraDeviceId: cameras.length > 0 ? cameras[0].id : undefined,
|
|
44
|
+
includeMicrophone: audioDevices.length > 0,
|
|
45
|
+
audioDeviceId: audioDevices.length > 0 ? audioDevices[0].id : undefined,
|
|
46
|
+
captureSystemAudio: false, // System audio can cause issues
|
|
47
|
+
showCursor: true,
|
|
48
|
+
captureMouseClicks: true
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
console.log('š¬ Starting full recording...');
|
|
52
|
+
console.log(' Components:', Object.keys(options).filter(k => options[k] === true).join(', '));
|
|
53
|
+
console.log();
|
|
54
|
+
|
|
55
|
+
await recorder.startRecording(outputPath, options);
|
|
56
|
+
|
|
57
|
+
console.log('ā
Recording started (cursor tracking auto-started)\n');
|
|
58
|
+
|
|
59
|
+
// Record for 20 seconds with progress
|
|
60
|
+
console.log('ā±ļø Recording for 20 seconds...');
|
|
61
|
+
for (let i = 1; i <= 20; i++) {
|
|
62
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
63
|
+
process.stdout.write(` ${i}s... `);
|
|
64
|
+
if (i % 5 === 0) console.log();
|
|
65
|
+
}
|
|
66
|
+
console.log('\n');
|
|
67
|
+
|
|
68
|
+
console.log('ā¹ļø Stopping recording...');
|
|
69
|
+
const result = await recorder.stopRecording();
|
|
70
|
+
|
|
71
|
+
console.log('ā
Recording stopped\n');
|
|
72
|
+
|
|
73
|
+
// Show outputs
|
|
74
|
+
console.log('š Outputs:');
|
|
75
|
+
if (result.screenOutputPath) {
|
|
76
|
+
console.log(` Screen: ${result.screenOutputPath}`);
|
|
77
|
+
}
|
|
78
|
+
if (result.cameraOutputPath) {
|
|
79
|
+
console.log(` Camera: ${result.cameraOutputPath}`);
|
|
80
|
+
}
|
|
81
|
+
if (result.cursorOutputPath) {
|
|
82
|
+
console.log(` Cursor: ${result.cursorOutputPath}`);
|
|
83
|
+
}
|
|
84
|
+
console.log();
|
|
85
|
+
|
|
86
|
+
// Verify timestamps with ffprobe
|
|
87
|
+
console.log('š Verifying sync...\n');
|
|
88
|
+
const { execSync } = require('child_process');
|
|
89
|
+
|
|
90
|
+
if (result.screenOutputPath) {
|
|
91
|
+
try {
|
|
92
|
+
const screenInfo = execSync(
|
|
93
|
+
`ffprobe -v error -show_entries stream=start_time,codec_type -of default=noprint_wrappers=1 "${result.screenOutputPath}" 2>&1`,
|
|
94
|
+
{ encoding: 'utf8' }
|
|
95
|
+
);
|
|
96
|
+
console.log('šŗ Screen video:');
|
|
97
|
+
console.log(screenInfo);
|
|
98
|
+
} catch (err) {
|
|
99
|
+
console.log('ā ļø Could not analyze screen video');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (result.cameraOutputPath) {
|
|
104
|
+
try {
|
|
105
|
+
const cameraInfo = execSync(
|
|
106
|
+
`ffprobe -v error -show_entries stream=start_time,codec_type -of default=noprint_wrappers=1 "${result.cameraOutputPath}" 2>&1`,
|
|
107
|
+
{ encoding: 'utf8' }
|
|
108
|
+
);
|
|
109
|
+
console.log('š· Camera video:');
|
|
110
|
+
console.log(cameraInfo);
|
|
111
|
+
} catch (err) {
|
|
112
|
+
console.log('ā ļø Could not analyze camera video');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Check if all start_time values are 0.000000
|
|
117
|
+
console.log('ā
SUCCESS: All components recorded with synchronized timestamps!');
|
|
118
|
+
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error('ā Test failed:', error.message);
|
|
121
|
+
console.error(error.stack);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
testFullSync().then(() => {
|
|
126
|
+
console.log('\nā
Full sync test completed');
|
|
127
|
+
process.exit(0);
|
|
128
|
+
}).catch(err => {
|
|
129
|
+
console.error('\nā Test error:', err);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
});
|