node-mac-recorder 2.16.33 → 2.17.0

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.
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "permissions": {
3
3
  "allow": [
4
- "Bash(node:*)"
4
+ "Bash(node:*)",
5
+ "Bash(chmod:*)",
6
+ "Bash(cat:*)"
5
7
  ],
6
8
  "deny": [],
7
9
  "ask": []
package/index.js CHANGED
@@ -315,6 +315,11 @@ class MacRecorder extends EventEmitter {
315
315
 
316
316
  return new Promise((resolve, reject) => {
317
317
  try {
318
+ // Create cursor file path with timestamp in the same directory as video
319
+ const timestamp = Date.now();
320
+ const outputDir = path.dirname(outputPath);
321
+ const cursorFilePath = path.join(outputDir, `temp_cursor_${timestamp}.json`);
322
+
318
323
  // Native kayıt başlat
319
324
  const recordingOptions = {
320
325
  includeMicrophone: this.options.includeMicrophone === true, // Only if explicitly enabled
@@ -351,6 +356,20 @@ class MacRecorder extends EventEmitter {
351
356
  this.isRecording = true;
352
357
  this.recordingStartTime = Date.now();
353
358
 
359
+ // Start cursor tracking automatically with recording
360
+ this.startCursorCapture(cursorFilePath, {
361
+ windowRelative: !!this.options.windowId,
362
+ windowInfo: this.options.windowId ? {
363
+ x: this.options.captureArea?.x || 0,
364
+ y: this.options.captureArea?.y || 0,
365
+ width: this.options.captureArea?.width || 1920,
366
+ height: this.options.captureArea?.height || 1080,
367
+ displayId: this.options.displayId
368
+ } : null
369
+ }).catch(cursorError => {
370
+ console.warn('Cursor tracking failed to start:', cursorError.message);
371
+ });
372
+
354
373
  // Timer başlat (progress tracking için)
355
374
  this.recordingTimer = setInterval(() => {
356
375
  const elapsed = Math.floor(
@@ -441,6 +460,13 @@ class MacRecorder extends EventEmitter {
441
460
  success = true; // Assume success to avoid throwing
442
461
  }
443
462
 
463
+ // Stop cursor tracking automatically
464
+ if (this.cursorCaptureInterval) {
465
+ this.stopCursorCapture().catch(cursorError => {
466
+ console.warn('Cursor tracking failed to stop:', cursorError.message);
467
+ });
468
+ }
469
+
444
470
  // Timer durdur
445
471
  if (this.recordingTimer) {
446
472
  clearInterval(this.recordingTimer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.16.33",
3
+ "version": "2.17.0",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -0,0 +1,120 @@
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 testIntegratedRecording() {
16
+ console.log('🎬 Testing integrated screen 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 displays and windows
29
+ const displays = await recorder.getDisplays();
30
+ const windows = await recorder.getWindows();
31
+
32
+ console.log(`📺 Found ${displays.length} displays and ${windows.length} windows`);
33
+
34
+ // Setup recording options
35
+ const timestamp = Date.now();
36
+ const videoPath = path.join(outputDir, `integrated-test-${timestamp}.mov`);
37
+
38
+ console.log(`🎥 Starting recording to: ${videoPath}`);
39
+ console.log('📍 Cursor tracking will start automatically and create a JSON file in the same directory');
40
+
41
+ // Start recording (cursor tracking will start automatically)
42
+ // Use the primary display (displayId: 1) where cursor is located
43
+ await recorder.startRecording(videoPath, {
44
+ includeMicrophone: false,
45
+ includeSystemAudio: false,
46
+ captureCursor: true,
47
+ displayId: 1 // Use primary display where cursor is located
48
+ });
49
+
50
+ console.log('✅ Recording started successfully!');
51
+ console.log('🖱️ Cursor tracking started automatically');
52
+ console.log('⏰ Recording for 5 seconds...');
53
+ console.log('💡 Move your mouse around to generate cursor data');
54
+
55
+ // Wait for 5 seconds
56
+ await new Promise(resolve => setTimeout(resolve, 5000));
57
+
58
+ console.log('🛑 Stopping recording...');
59
+
60
+ // Stop recording (cursor tracking will stop automatically)
61
+ const result = await recorder.stopRecording();
62
+
63
+ console.log('✅ Recording stopped:', result);
64
+ console.log('📁 Checking output files...');
65
+
66
+ // Wait a moment for files to be written
67
+ await new Promise(resolve => setTimeout(resolve, 1000));
68
+
69
+ // Check for video file
70
+ if (fs.existsSync(videoPath)) {
71
+ const videoStats = fs.statSync(videoPath);
72
+ console.log(`📹 Video file created: ${videoPath} (${videoStats.size} bytes)`);
73
+ } else {
74
+ console.log('❌ Video file not found');
75
+ }
76
+
77
+ // Check for cursor file
78
+ const files = fs.readdirSync(outputDir);
79
+ const cursorFile = files.find(f => f.startsWith('temp_cursor_') && f.endsWith('.json'));
80
+
81
+ if (cursorFile) {
82
+ const cursorPath = path.join(outputDir, cursorFile);
83
+ const cursorStats = fs.statSync(cursorPath);
84
+ console.log(`🖱️ Cursor file created: ${cursorFile} (${cursorStats.size} bytes)`);
85
+
86
+ // Read and validate cursor data
87
+ try {
88
+ const cursorData = JSON.parse(fs.readFileSync(cursorPath, 'utf8'));
89
+ console.log(`📊 Cursor data points: ${cursorData.length}`);
90
+
91
+ if (cursorData.length > 0) {
92
+ const first = cursorData[0];
93
+ const last = cursorData[cursorData.length - 1];
94
+ console.log(`📍 First cursor position: (${first.x}, ${first.y}) at ${first.timestamp}ms`);
95
+ console.log(`📍 Last cursor position: (${last.x}, ${last.y}) at ${last.timestamp}ms`);
96
+ console.log(`📐 Coordinate system: ${first.coordinateSystem || 'global'}`);
97
+ }
98
+ } catch (parseError) {
99
+ console.log('⚠️ Could not parse cursor data:', parseError.message);
100
+ }
101
+ } else {
102
+ console.log('❌ Cursor file not found');
103
+ }
104
+
105
+ console.log('✅ Test completed successfully!');
106
+
107
+ } catch (error) {
108
+ console.error('❌ Test failed:', error.message);
109
+ console.error(error.stack);
110
+ }
111
+ }
112
+
113
+ // Run the test
114
+ testIntegratedRecording().then(() => {
115
+ console.log('🏁 All tests finished');
116
+ process.exit(0);
117
+ }).catch(error => {
118
+ console.error('💥 Fatal error:', error);
119
+ process.exit(1);
120
+ });