node-mac-recorder 2.16.23 โ†’ 2.16.25

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,7 @@
1
1
  {
2
2
  "permissions": {
3
3
  "allow": [
4
- "Bash(FORCE_AVFOUNDATION=1 node -e \"\nconsole.log(''๐Ÿงช Testing fixed window selector screen ID mapping...'');\nconst WindowSelector = require(''./window-selector.js'');\nconst selector = new WindowSelector();\n\nconst testResults = [];\n\nselector.checkPermissions().then(perms => {\n console.log(''โœ… Permissions OK'');\n console.log('''');\n console.log(''๐Ÿ“‹ Expected Screen IDs from MacRecorder:'');\n console.log('' MacBook (Primary): ID=1, Position=(0,0)'');\n console.log('' External Display: ID=3, Position=(-3440,-56)'');\n console.log('''');\n \n return selector.startSelection();\n}).then(() => {\n console.log(''โœ… Window selection started'');\n console.log(''๐ŸŽฏ Move cursor over windows on BOTH displays to see CGDirectDisplayID mapping logs'');\n console.log('''');\n \n setTimeout(() => {\n console.log(''โฐ Test complete - stopping window selection'');\n selector.stopSelection();\n }, 15000);\n \n}).catch(console.error);\")"
4
+ "Bash(FORCE_AVFOUNDATION=1 node -e \"\nconsole.log(''๐Ÿงช Testing external display recording WITH AUDIO - debug version...'');\nconst MacRecorder = require(''./index.js'');\nconst recorder = new MacRecorder();\n\nrecorder.startRecording(''/tmp/external-audio-debug.mov'', {\n displayId: 3, // External display\n includeMicrophone: true,\n includeSystemAudio: true,\n captureCursor: true\n})\n .then(success => {\n console.log(''Start result:'', success ? ''โœ… SUCCESS'' : ''โŒ FAILED'');\n if (success) {\n setTimeout(() => {\n console.log(''โน๏ธ Stopping recording...'');\n recorder.stopRecording().then(() => {\n console.log(''โœ… Recording stopped'');\n const fs = require(''fs'');\n if (fs.existsSync(''/tmp/external-audio-debug.mov'')) {\n const size = Math.round(fs.statSync(''/tmp/external-audio-debug.mov'').size/1024);\n console.log(''๐Ÿ“น File size:'', size + ''KB'');\n if (size > 100) {\n console.log(''๐ŸŽ‰ External display recording with audio SUCCESS!'');\n } else {\n console.log(''โš ๏ธ File too small, may have failed'');\n }\n } else {\n console.log(''โŒ No output file created'');\n }\n });\n }, 4000); // 4 seconds recording\n }\n })\n .catch(console.error);\n\")"
5
5
  ],
6
6
  "deny": [],
7
7
  "ask": []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-mac-recorder",
3
- "version": "2.16.23",
3
+ "version": "2.16.25",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -567,50 +567,24 @@ Napi::Value GetDisplays(const Napi::CallbackInfo& info) {
567
567
  Napi::Env env = info.Env();
568
568
 
569
569
  @try {
570
- // Get displays using NSScreen instead of ScreenCapture
571
- NSArray *screens = [NSScreen screens];
570
+ // Get active displays directly using CGDirectDisplayID
572
571
  NSMutableArray *displays = [NSMutableArray array];
573
-
574
- // Get real CGDirectDisplayIDs first
575
572
  CGDirectDisplayID activeDisplays[32];
576
573
  uint32_t displayCount;
577
574
  CGGetActiveDisplayList(32, activeDisplays, &displayCount);
578
575
 
579
- for (NSUInteger i = 0; i < [screens count]; i++) {
580
- NSScreen *screen = [screens objectAtIndex:i];
581
- NSRect frame = [screen frame];
582
-
583
- // Find matching CGDirectDisplayID
584
- CGDirectDisplayID displayID = 0;
585
- bool isPrimary = false;
586
-
587
- for (uint32_t j = 0; j < displayCount; j++) {
588
- CGDirectDisplayID candidateID = activeDisplays[j];
589
- CGRect displayBounds = CGDisplayBounds(candidateID);
590
-
591
- if (fabs(frame.origin.x - displayBounds.origin.x) < 1.0 &&
592
- fabs(frame.origin.y - displayBounds.origin.y) < 1.0 &&
593
- fabs(frame.size.width - displayBounds.size.width) < 1.0 &&
594
- fabs(frame.size.height - displayBounds.size.height) < 1.0) {
595
- displayID = candidateID;
596
- isPrimary = (candidateID == CGMainDisplayID());
597
- break;
598
- }
599
- }
600
-
601
- // Fallback if no match found
602
- if (displayID == 0 && i < displayCount) {
603
- displayID = activeDisplays[i];
604
- isPrimary = (displayID == CGMainDisplayID());
605
- }
576
+ for (uint32_t i = 0; i < displayCount; i++) {
577
+ CGDirectDisplayID displayID = activeDisplays[i];
578
+ CGRect displayBounds = CGDisplayBounds(displayID);
579
+ bool isPrimary = (displayID == CGMainDisplayID());
606
580
 
607
581
  NSDictionary *displayInfo = @{
608
- @"id": @(displayID), // Use real display ID
609
- @"name": [NSString stringWithFormat:@"Display %lu", (unsigned long)(i + 1)],
610
- @"width": @((int)frame.size.width),
611
- @"height": @((int)frame.size.height),
612
- @"x": @((int)frame.origin.x),
613
- @"y": @((int)frame.origin.y),
582
+ @"id": @(displayID), // Direct CGDirectDisplayID
583
+ @"name": [NSString stringWithFormat:@"Display %u", (unsigned int)(i + 1)],
584
+ @"width": @((int)displayBounds.size.width),
585
+ @"height": @((int)displayBounds.size.height),
586
+ @"x": @((int)displayBounds.origin.x),
587
+ @"y": @((int)displayBounds.origin.y),
614
588
  @"isPrimary": @(isPrimary)
615
589
  };
616
590
  [displays addObject:displayInfo];
@@ -77,6 +77,10 @@ static NSString *g_outputPath = nil;
77
77
  NSLog(@"๐Ÿ”ง Config: cursor=%@ mic=%@ system=%@ display=%@ window=%@ crop=%@",
78
78
  captureCursor, includeMicrophone, includeSystemAudio, displayId, windowId, captureRect);
79
79
 
80
+ // CRITICAL DEBUG: Log EXACT audio parameter values
81
+ NSLog(@"๐Ÿ” AUDIO DEBUG: includeMicrophone type=%@ value=%d", [includeMicrophone class], [includeMicrophone boolValue]);
82
+ NSLog(@"๐Ÿ” AUDIO DEBUG: includeSystemAudio type=%@ value=%d", [includeSystemAudio class], [includeSystemAudio boolValue]);
83
+
80
84
  // Get shareable content
81
85
  [SCShareableContent getShareableContentWithCompletionHandler:^(SCShareableContent *content, NSError *contentError) {
82
86
  if (contentError) {
@@ -87,6 +91,15 @@ static NSString *g_outputPath = nil;
87
91
  NSLog(@"โœ… Got %lu displays, %lu windows for pure recording",
88
92
  content.displays.count, content.windows.count);
89
93
 
94
+ // CRITICAL DEBUG: List all available displays in ScreenCaptureKit
95
+ NSLog(@"๐Ÿ” ScreenCaptureKit available displays:");
96
+ for (SCDisplay *display in content.displays) {
97
+ NSLog(@" Display ID=%u, Size=%dx%d, Frame=(%.0f,%.0f,%.0fx%.0f)",
98
+ display.displayID, (int)display.width, (int)display.height,
99
+ display.frame.origin.x, display.frame.origin.y,
100
+ display.frame.size.width, display.frame.size.height);
101
+ }
102
+
90
103
  SCContentFilter *filter = nil;
91
104
  NSInteger recordingWidth = 0;
92
105
  NSInteger recordingHeight = 0;
@@ -121,12 +134,20 @@ static NSString *g_outputPath = nil;
121
134
 
122
135
  if (displayId && [displayId integerValue] != 0) {
123
136
  // Find specific display
137
+ NSLog(@"๐ŸŽฏ Looking for display ID=%@ in ScreenCaptureKit list", displayId);
124
138
  for (SCDisplay *display in content.displays) {
139
+ NSLog(@" Checking display ID=%u vs requested=%u", display.displayID, [displayId unsignedIntValue]);
125
140
  if (display.displayID == [displayId unsignedIntValue]) {
126
141
  targetDisplay = display;
142
+ NSLog(@"โœ… FOUND matching display ID=%u", display.displayID);
127
143
  break;
128
144
  }
129
145
  }
146
+
147
+ if (!targetDisplay) {
148
+ NSLog(@"โŒ Display ID=%@ NOT FOUND in ScreenCaptureKit - using first display as fallback", displayId);
149
+ targetDisplay = content.displays.firstObject;
150
+ }
130
151
  } else {
131
152
  // Use first display
132
153
  targetDisplay = content.displays.firstObject;
@@ -188,8 +209,10 @@ static NSString *g_outputPath = nil;
188
209
  recordingWidth, recordingHeight, shouldShowCursor);
189
210
 
190
211
  // AUDIO SUPPORT - Enable both microphone and system audio
212
+ NSLog(@"๐Ÿ” AUDIO PROCESSING: includeMicrophone=%@ includeSystemAudio=%@", includeMicrophone, includeSystemAudio);
191
213
  BOOL shouldCaptureMic = includeMicrophone ? [includeMicrophone boolValue] : NO;
192
214
  BOOL shouldCaptureSystemAudio = includeSystemAudio ? [includeSystemAudio boolValue] : NO;
215
+ NSLog(@"๐Ÿ” AUDIO COMPUTED: shouldCaptureMic=%d shouldCaptureSystemAudio=%d", shouldCaptureMic, shouldCaptureSystemAudio);
193
216
 
194
217
  // Enable audio if either microphone or system audio is requested
195
218
  if (@available(macOS 13.0, *)) {
@@ -2360,33 +2360,15 @@ Napi::Value GetSelectedWindowInfo(const Napi::CallbackInfo& info) {
2360
2360
  windowScreen = mainScreen;
2361
2361
  }
2362
2362
 
2363
- // CRITICAL FIX: Add screen information using real CGDirectDisplayID
2363
+ // Simple screen information - no complex mapping
2364
2364
  NSRect screenFrame = [windowScreen frame];
2365
+ NSNumber *screenNumber = [windowScreen deviceDescription][@"NSScreenNumber"];
2365
2366
 
2366
- // Find real CGDirectDisplayID for this screen (matching GetDisplays logic)
2367
- CGDirectDisplayID realDisplayID = 0;
2368
- CGDirectDisplayID activeDisplays[32];
2369
- uint32_t displayCount;
2370
- CGGetActiveDisplayList(32, activeDisplays, &displayCount);
2371
-
2372
- for (uint32_t j = 0; j < displayCount; j++) {
2373
- CGDirectDisplayID candidateID = activeDisplays[j];
2374
- CGRect displayBounds = CGDisplayBounds(candidateID);
2375
-
2376
- if (fabs(screenFrame.origin.x - displayBounds.origin.x) < 1.0 &&
2377
- fabs(screenFrame.origin.y - displayBounds.origin.y) < 1.0 &&
2378
- fabs(screenFrame.size.width - displayBounds.size.width) < 1.0 &&
2379
- fabs(screenFrame.size.height - displayBounds.size.height) < 1.0) {
2380
- realDisplayID = candidateID;
2381
- break;
2382
- }
2383
- }
2384
-
2385
- NSLog(@"๐Ÿ” Window screen mapping: Frame=(%.0f,%.0f,%.0fx%.0f) โ†’ CGDirectDisplayID=%u",
2367
+ NSLog(@"๐Ÿ” Window screen: Frame=(%.0f,%.0f,%.0fx%.0f) ScreenNumber=%@",
2386
2368
  screenFrame.origin.x, screenFrame.origin.y,
2387
- screenFrame.size.width, screenFrame.size.height, realDisplayID);
2369
+ screenFrame.size.width, screenFrame.size.height, screenNumber);
2388
2370
 
2389
- result.Set("screenId", Napi::Number::New(env, realDisplayID));
2371
+ result.Set("screenId", Napi::Number::New(env, [screenNumber unsignedIntValue]));
2390
2372
  result.Set("screenX", Napi::Number::New(env, (int)screenFrame.origin.x));
2391
2373
  result.Set("screenY", Napi::Number::New(env, (int)screenFrame.origin.y));
2392
2374
  result.Set("screenWidth", Napi::Number::New(env, (int)screenFrame.size.width));