node-mac-recorder 2.16.1 โ†’ 2.16.2

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.
@@ -44,7 +44,9 @@
44
44
  "Bash(ELECTRON_RUN_AS_NODE=1 node -e \"\nconsole.log(''๐ŸŽค Testing microphone only'');\nconst MacRecorder = require(''./index'');\nconst recorder = new MacRecorder();\n\nasync function testMicrophoneOnly() {\n try {\n const outputPath = ''./test-output/microphone-only-test.mov'';\n console.log(''๐Ÿ“น Starting microphone only recording...'');\n \n const success = await recorder.startRecording(outputPath, {\n captureCursor: false,\n includeMicrophone: true, // Sadece mikrofon Aร‡IK\n includeSystemAudio: false // Sistem sesi KAPALI\n });\n \n if (success) {\n console.log(''โœ… Microphone recording started - waiting 3 seconds'');\n await new Promise(resolve => setTimeout(resolve, 3000));\n \n console.log(''๐Ÿ›‘ Stopping microphone recording...'');\n await recorder.stopRecording();\n console.log(''โœ… Microphone only test completed!'');\n } else {\n console.log(''โŒ Recording failed to start'');\n }\n } catch (error) {\n console.log(''โŒ Error:'', error.message);\n }\n}\n\ntestMicrophoneOnly();\n\")",
45
45
  "Bash(ELECTRON_RUN_AS_NODE=1 node -e \"\nconsole.log(''๐Ÿš€ Full stress test - All features + Both audio sources'');\nconst MacRecorder = require(''./index'');\nconst recorder = new MacRecorder();\n\nasync function fullStressTest() {\n try {\n const outputPath = ''./test-output/full-stress-test.mov'';\n console.log(''๐Ÿ“น Starting full featured recording (stress test)...'');\n \n const success = await recorder.startRecording(outputPath, {\n captureCursor: true, // Cursor kayฤฑt\n includeMicrophone: true, // Mikrofon kayฤฑt\n includeSystemAudio: true, // Sistem sesi kayฤฑt\n captureArea: { // Crop area\n x: 300,\n y: 300,\n width: 800,\n height: 500\n }\n });\n \n if (success) {\n console.log(''โœ… Full stress test started - waiting 6 seconds'');\n await new Promise(resolve => setTimeout(resolve, 6000));\n \n console.log(''๐Ÿ›‘ Stopping full stress test...'');\n await recorder.stopRecording();\n console.log(''๐ŸŽ‰ FULL STRESS TEST COMPLETED WITHOUT CRASH!'');\n } else {\n console.log(''โŒ Recording failed to start'');\n }\n } catch (error) {\n console.log(''โŒ Error:'', error.message);\n console.log(''Stack:'', error.stack);\n }\n}\n\nfullStressTest();\n\")",
46
46
  "Bash(ELECTRON_RUN_AS_NODE=1 node -e \"\nconsole.log(''๐Ÿงช Testing version detection and fallback system'');\nconst MacRecorder = require(''./index'');\nconst recorder = new MacRecorder();\n\nasync function testVersionDetection() {\n try {\n const outputPath = ''./test-output/version-detection-test.mov'';\n console.log(''๐Ÿ“น Starting recording with version detection...'');\n \n const success = await recorder.startRecording(outputPath, {\n captureCursor: true,\n includeMicrophone: false,\n includeSystemAudio: true\n });\n \n if (success) {\n console.log(''โœ… Recording started - waiting 3 seconds'');\n await new Promise(resolve => setTimeout(resolve, 3000));\n \n console.log(''๐Ÿ›‘ Stopping recording...'');\n await recorder.stopRecording();\n console.log(''โœ… Version detection test completed successfully!'');\n } else {\n console.log(''โŒ Recording failed to start'');\n }\n } catch (error) {\n console.log(''โŒ Error:'', error.message);\n }\n}\n\ntestVersionDetection();\n\")",
47
- "Bash(ELECTRON_RUN_AS_NODE=1 node -e \"\nconsole.log(''๐Ÿงช Testing Electron safety measures'');\nconst MacRecorder = require(''./index'');\nconst recorder = new MacRecorder();\n\nasync function testElectronSafety() {\n try {\n const outputPath = ''./test-output/electron-safe-test.mov'';\n console.log(''๐Ÿ“น Starting recording in Electron environment...'');\n \n const success = await recorder.startRecording(outputPath, {\n captureCursor: true,\n includeMicrophone: false,\n includeSystemAudio: true\n });\n \n if (success) {\n console.log(''โœ… Recording started safely in Electron - waiting 3 seconds'');\n await new Promise(resolve => setTimeout(resolve, 3000));\n \n console.log(''๐Ÿ›‘ Stopping recording...'');\n await recorder.stopRecording();\n console.log(''โœ… Electron safety test completed successfully!'');\n } else {\n console.log(''โš ๏ธ Recording failed to start (expected in some cases)'');\n }\n } catch (error) {\n console.log(''โŒ Error:'', error.message);\n }\n}\n\ntestElectronSafety();\n\")"
47
+ "Bash(ELECTRON_RUN_AS_NODE=1 node -e \"\nconsole.log(''๐Ÿงช Testing Electron safety measures'');\nconst MacRecorder = require(''./index'');\nconst recorder = new MacRecorder();\n\nasync function testElectronSafety() {\n try {\n const outputPath = ''./test-output/electron-safe-test.mov'';\n console.log(''๐Ÿ“น Starting recording in Electron environment...'');\n \n const success = await recorder.startRecording(outputPath, {\n captureCursor: true,\n includeMicrophone: false,\n includeSystemAudio: true\n });\n \n if (success) {\n console.log(''โœ… Recording started safely in Electron - waiting 3 seconds'');\n await new Promise(resolve => setTimeout(resolve, 3000));\n \n console.log(''๐Ÿ›‘ Stopping recording...'');\n await recorder.stopRecording();\n console.log(''โœ… Electron safety test completed successfully!'');\n } else {\n console.log(''โš ๏ธ Recording failed to start (expected in some cases)'');\n }\n } catch (error) {\n console.log(''โŒ Error:'', error.message);\n }\n}\n\ntestElectronSafety();\n\")",
48
+ "Bash(FORCE_AVFOUNDATION=1 node -e \"\nconsole.log(''๐Ÿงช Testing AVFoundation fallback path'');\nconst MacRecorder = require(''./index'');\nconst recorder = new MacRecorder();\n\nasync function testAVFoundationPath() {\n try {\n const outputPath = ''./test-output/force-avfoundation-test.mov'';\n console.log(''๐Ÿ“น Testing AVFoundation (force mode)...'');\n \n const success = await recorder.startRecording(outputPath, {\n captureCursor: true,\n includeMicrophone: false,\n includeSystemAudio: true\n });\n \n if (success) {\n console.log(''โœ… Recording started'');\n await new Promise(resolve => setTimeout(resolve, 2000));\n \n await recorder.stopRecording();\n console.log(''โœ… AVFoundation test completed!'');\n } else {\n console.log(''โŒ Recording failed'');\n }\n } catch (error) {\n console.log(''โŒ Error:'', error.message);\n }\n}\n\ntestAVFoundationPath();\n\")",
49
+ "Bash(FORCE_AVFOUNDATION=1 node -e \"\nconsole.log(''๐Ÿงช Testing AVFoundation fallback path (macOS 14 simulation)'');\nconst MacRecorder = require(''./index'');\nconst recorder = new MacRecorder();\n\nasync function testAVFoundationPath() {\n try {\n const outputPath = ''./test-output/force-avfoundation-test.mov'';\n console.log(''๐Ÿ“น Testing AVFoundation (simulating macOS 14)...'');\n \n const success = await recorder.startRecording(outputPath, {\n captureCursor: true,\n includeMicrophone: false,\n includeSystemAudio: true\n });\n \n if (success) {\n console.log(''โœ… Recording started with AVFoundation'');\n await new Promise(resolve => setTimeout(resolve, 3000));\n \n await recorder.stopRecording();\n console.log(''โœ… AVFoundation test completed successfully!'');\n console.log(''This is how it should work on macOS 14'');\n } else {\n console.log(''โŒ Recording failed to start'');\n }\n } catch (error) {\n console.log(''โŒ Error:'', error.message);\n }\n}\n\ntestAVFoundationPath();\n\")"
48
50
  ],
49
51
  "deny": []
50
52
  }
@@ -0,0 +1,111 @@
1
+ # macOS 13/14 Recording Troubleshooting Guide
2
+
3
+ ## Expected Behavior by macOS Version
4
+
5
+ The system automatically detects macOS version and uses the most compatible recording method:
6
+
7
+ - **macOS 15+**: Uses ScreenCaptureKit (30fps, full features)
8
+ - **macOS 14**: Uses AVFoundation fallback (15fps, stable)
9
+ - **macOS 13**: Uses AVFoundation fallback (15fps, limited features)
10
+ - **macOS < 13**: Not supported
11
+
12
+ ## Debug Steps for macOS 13/14 Issues
13
+
14
+ ### 1. Check Console Logs
15
+
16
+ When running your application, check for these log messages:
17
+
18
+ **macOS 14:**
19
+ ```
20
+ ๐Ÿ–ฅ๏ธ macOS Version: 14.x.x
21
+ ๐ŸŽฏ macOS 14 detected - using AVFoundation for better compatibility
22
+ ๐ŸŽฅ Using AVFoundation for macOS 14 compatibility
23
+ ๐ŸŽฅ RECORDING METHOD: AVFoundation (Fallback)
24
+ ```
25
+
26
+ **macOS 13:**
27
+ ```
28
+ ๐Ÿ–ฅ๏ธ macOS Version: 13.x.x
29
+ ๐ŸŽฏ macOS 13 detected - using AVFoundation (limited features)
30
+ ๐ŸŽฅ Using AVFoundation for macOS 13 compatibility (limited features)
31
+ ๐ŸŽฅ RECORDING METHOD: AVFoundation (Fallback)
32
+ ```
33
+
34
+ ### 2. Test AVFoundation Directly
35
+
36
+ You can force AVFoundation mode for testing:
37
+
38
+ ```javascript
39
+ // Set environment variable before running
40
+ process.env.FORCE_AVFOUNDATION = "1";
41
+
42
+ const MacRecorder = require('node-mac-recorder');
43
+ const recorder = new MacRecorder();
44
+
45
+ async function test() {
46
+ const success = await recorder.startRecording('./test.mov', {
47
+ captureCursor: true,
48
+ includeMicrophone: false,
49
+ includeSystemAudio: true
50
+ });
51
+
52
+ if (success) {
53
+ console.log('โœ… AVFoundation recording started');
54
+ setTimeout(async () => {
55
+ await recorder.stopRecording();
56
+ console.log('โœ… Recording completed');
57
+ }, 3000);
58
+ } else {
59
+ console.log('โŒ Recording failed');
60
+ }
61
+ }
62
+
63
+ test();
64
+ ```
65
+
66
+ ### 3. Common Issues and Solutions
67
+
68
+ **Issue**: Recording starts but no video file created
69
+ - **Cause**: Permission issues
70
+ - **Solution**: Check Screen Recording permission in System Preferences
71
+
72
+ **Issue**: Audio not recorded
73
+ - **Cause**: Microphone permission missing
74
+ - **Solution**: Check Microphone permission in System Preferences
75
+
76
+ **Issue**: Recording fails silently
77
+ - **Cause**: Invalid display ID or output path
78
+ - **Solution**: Use default display (don't specify displayId) and ensure output directory exists
79
+
80
+ ### 4. Permission Requirements
81
+
82
+ macOS 14 requires these permissions:
83
+ - โœ… Screen Recording (System Preferences > Privacy & Security)
84
+ - โœ… Microphone (if includeMicrophone: true)
85
+ - โœ… Accessibility (for cursor tracking)
86
+
87
+ ### 5. Technical Details
88
+
89
+ **AVFoundation Implementation (macOS 14):**
90
+ - Video: H.264 encoding at 15fps
91
+ - Audio: AAC encoding at 44.1kHz
92
+ - Screen capture: CGDisplayCreateImage
93
+ - Memory management: Automatic cleanup
94
+
95
+ **Differences from ScreenCaptureKit:**
96
+ - Lower frame rate (15fps vs 30fps) for stability
97
+ - No automatic window exclusion
98
+ - Simpler audio routing
99
+
100
+ **macOS 13 Specific Limitations:**
101
+ - Audio features may have reduced compatibility
102
+ - Some advanced recording options may not work
103
+ - Recommended to test thoroughly on target systems
104
+
105
+ ## Contact
106
+
107
+ If recording still fails on macOS 14 after following this guide, please provide:
108
+ 1. macOS version (`sw_vers`)
109
+ 2. Console logs from the application
110
+ 3. Permission status screenshots
111
+ 4. Minimal reproduction code
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.16.1",
3
+ "version": "2.16.2",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -192,18 +192,23 @@ Napi::Value StartRecording(const Napi::CallbackInfo& info) {
192
192
 
193
193
  // Check macOS version for ScreenCaptureKit compatibility
194
194
  NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
195
- BOOL isM15Plus = (osVersion.majorVersion > 15 ||
196
- (osVersion.majorVersion == 15 && osVersion.minorVersion >= 0));
197
- BOOL isM14Plus = (osVersion.majorVersion > 14 ||
198
- (osVersion.majorVersion == 14 && osVersion.minorVersion >= 0));
195
+ BOOL isM15Plus = (osVersion.majorVersion >= 15);
196
+ BOOL isM14Plus = (osVersion.majorVersion >= 14);
197
+ BOOL isM13Plus = (osVersion.majorVersion >= 13);
199
198
 
200
199
  NSLog(@"๐Ÿ–ฅ๏ธ macOS Version: %ld.%ld.%ld",
201
200
  (long)osVersion.majorVersion, (long)osVersion.minorVersion, (long)osVersion.patchVersion);
202
201
 
203
- // Try ScreenCaptureKit on macOS 14+ (with better compatibility on 15+)
204
- if (@available(macOS 12.3, *) && isM14Plus) {
205
- NSLog(@"โœ… macOS 14+ detected - ScreenCaptureKit available with %@ compatibility",
206
- isM15Plus ? @"full" : @"limited");
202
+ // Force AVFoundation for debugging/testing
203
+ BOOL forceAVFoundation = (getenv("FORCE_AVFOUNDATION") != NULL);
204
+ if (forceAVFoundation) {
205
+ NSLog(@"๐Ÿ”ง FORCE_AVFOUNDATION environment variable detected - skipping ScreenCaptureKit");
206
+ }
207
+
208
+ // Use ScreenCaptureKit only on macOS 15+ for maximum stability
209
+ // macOS 14 should use AVFoundation fallback
210
+ if (@available(macOS 12.3, *) && isM15Plus && !forceAVFoundation) {
211
+ NSLog(@"โœ… macOS 15+ detected - ScreenCaptureKit available with full compatibility");
207
212
 
208
213
  // Try ScreenCaptureKit with extensive safety measures
209
214
  @try {
@@ -275,20 +280,32 @@ Napi::Value StartRecording(const Napi::CallbackInfo& info) {
275
280
  NSLog(@"โŒ Exception during ScreenCaptureKit availability check: %@", availabilityException.reason);
276
281
  return Napi::Boolean::New(env, false);
277
282
  }
283
+ } else if (isM14Plus) {
284
+ // macOS 14 - directly use AVFoundation for better compatibility
285
+ NSLog(@"๐ŸŽฏ macOS 14 detected - using AVFoundation for better compatibility");
286
+ } else if (isM13Plus) {
287
+ // macOS 13 - use AVFoundation (limited features)
288
+ NSLog(@"๐ŸŽฏ macOS 13 detected - using AVFoundation (limited features)");
278
289
  } else {
279
- NSLog(@"โŒ macOS version too old for ScreenCaptureKit (< 12.3) - Recording not supported");
290
+ NSLog(@"โŒ macOS version too old (< 13.0) - Recording not supported");
280
291
  return Napi::Boolean::New(env, false);
281
292
  }
282
293
 
283
- // If we get here, ScreenCaptureKit failed
294
+ // AVFoundation fallback logic
284
295
  if (isElectron) {
285
296
  NSLog(@"โŒ ScreenCaptureKit failed in Electron - AVFoundation disabled for stability");
286
297
  NSLog(@"โŒ Recording not available in Electron when ScreenCaptureKit fails");
287
298
  return Napi::Boolean::New(env, false);
288
299
  }
289
300
 
290
- // Try AVFoundation fallback (only in non-Electron environments)
291
- NSLog(@"๐Ÿ”„ ScreenCaptureKit failed - attempting AVFoundation fallback");
301
+ // Try AVFoundation fallback (ScreenCaptureKit failed or macOS 13/14)
302
+ if (isM15Plus) {
303
+ NSLog(@"๐Ÿ”„ ScreenCaptureKit failed on macOS 15+ - attempting AVFoundation fallback");
304
+ } else if (isM14Plus) {
305
+ NSLog(@"๐ŸŽฅ Using AVFoundation for macOS 14 compatibility");
306
+ } else if (isM13Plus) {
307
+ NSLog(@"๐ŸŽฅ Using AVFoundation for macOS 13 compatibility (limited features)");
308
+ }
292
309
 
293
310
  @try {
294
311
  // Import AVFoundation recording functions (if available)
@@ -0,0 +1,56 @@
1
+ const MacRecorder = require('./index');
2
+
3
+ async function testMacOS14Recording() {
4
+ const recorder = new MacRecorder();
5
+
6
+ console.log('๐Ÿงช macOS 14 Recording Test');
7
+ console.log('This will test AVFoundation fallback path when ScreenCaptureKit fails or is not available');
8
+ console.log('');
9
+
10
+ try {
11
+ const outputPath = './test-output/macos14-test.mov';
12
+
13
+ console.log('๐Ÿ“น Starting recording test...');
14
+ console.log('Expected behavior on macOS 14:');
15
+ console.log(' 1. System detects macOS 14.x');
16
+ console.log(' 2. Skips ScreenCaptureKit (only for macOS 15+)');
17
+ console.log(' 3. Uses AVFoundation fallback');
18
+ console.log(' 4. Records at 15fps with H.264 encoding');
19
+ console.log('');
20
+
21
+ const success = await recorder.startRecording(outputPath, {
22
+ captureCursor: true,
23
+ includeMicrophone: false,
24
+ includeSystemAudio: true,
25
+ displayId: null // Use main display
26
+ });
27
+
28
+ if (success) {
29
+ console.log('โœ… Recording started successfully');
30
+ console.log('โฑ๏ธ Recording for 3 seconds...');
31
+
32
+ await new Promise(resolve => setTimeout(resolve, 3000));
33
+
34
+ console.log('๐Ÿ›‘ Stopping recording...');
35
+ await recorder.stopRecording();
36
+
37
+ console.log('โœ… macOS 14 test completed successfully!');
38
+ console.log('๐Ÿ“ Output file: ' + outputPath);
39
+ } else {
40
+ console.log('โŒ Recording failed to start');
41
+ console.log('');
42
+ console.log('Troubleshooting steps:');
43
+ console.log('1. Check Screen Recording permission in System Preferences');
44
+ console.log('2. Ensure macOS version is 14.0 or later');
45
+ console.log('3. Check console logs for detailed error messages');
46
+ }
47
+ } catch (error) {
48
+ console.log('โŒ Error during test:', error.message);
49
+ if (error.stack) {
50
+ console.log('Stack trace:', error.stack);
51
+ }
52
+ }
53
+ }
54
+
55
+ // Run the test
56
+ testMacOS14Recording();