node-mac-recorder 2.16.15 โ†’ 2.16.16

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 area recording with scaling...'');\nconst MacRecorder = require(''./index.js'');\nconst recorder = new MacRecorder();\n\nconst options = {\n captureArea: {\n x: 200,\n y: 200, \n width: 800,\n height: 600\n }\n};\n\nrecorder.startRecording(''/tmp/area-scaling-test.mov'', options)\n .then(success => {\n console.log(''Area recording:'', success ? ''โœ… SUCCESS'' : ''โŒ FAILED'');\n if (success) {\n setTimeout(() => {\n recorder.stopRecording().then(() => {\n console.log(''โœ… Area scaling test complete'');\n const fs = require(''fs'');\n if (fs.existsSync(''/tmp/area-scaling-test.mov'')) {\n const size = Math.round(fs.statSync(''/tmp/area-scaling-test.mov'').size/1024);\n console.log(''๐Ÿ“น File size:'', size + ''KB'');\n }\n });\n }, 2000);\n }\n })\n .catch(console.error);\n\")"
4
+ "Bash(FORCE_AVFOUNDATION=1 node -e \"\nconsole.log(''๐Ÿงช Testing CRITICAL AVFoundation scaling fix...'');\nconst MacRecorder = require(''./index.js'');\nconst recorder = new MacRecorder();\n\nrecorder.startRecording(''/tmp/critical-scaling-test.mov'')\n .then(success => {\n console.log(''Start:'', success ? ''โœ… SUCCESS'' : ''โŒ FAILED'');\n if (success) {\n setTimeout(() => {\n recorder.stopRecording().then(() => {\n console.log(''โœ… Test complete'');\n const fs = require(''fs'');\n if (fs.existsSync(''/tmp/critical-scaling-test.mov'')) {\n const size = Math.round(fs.statSync(''/tmp/critical-scaling-test.mov'').size/1024);\n console.log(''๐Ÿ“น File size:'', size + ''KB'');\n }\n });\n }, 3000);\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.15",
3
+ "version": "2.16.16",
4
4
  "description": "Native macOS screen recording package for Node.js applications",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -65,8 +65,17 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
65
65
  CGFloat scaleY = physicalSize.height / logicalSize.height;
66
66
  CGFloat scaleFactor = MAX(scaleX, scaleY); // Use max to handle non-uniform scaling
67
67
 
68
- // For AVFoundation, use logical size (what CGDisplayCreateImage actually captures)
69
- CGSize recordingSize = captureRect.size.width > 0 ? captureRect.size : logicalSize;
68
+ // CRITICAL FIX: Use actual captured image dimensions, not logical size
69
+ // CGDisplayCreateImage may return higher resolution on Retina displays
70
+ CGImageRef testImage = CGDisplayCreateImage(displayID);
71
+ CGSize actualImageSize = CGSizeMake(CGImageGetWidth(testImage), CGImageGetHeight(testImage));
72
+ CGImageRelease(testImage);
73
+
74
+ // For AVFoundation, use actual image size that CGDisplayCreateImage returns
75
+ CGSize recordingSize = captureRect.size.width > 0 ? captureRect.size : actualImageSize;
76
+
77
+ NSLog(@"๐ŸŽฏ CRITICAL: Logical %.0fx%.0f โ†’ Actual image %.0fx%.0f",
78
+ logicalSize.width, logicalSize.height, actualImageSize.width, actualImageSize.height);
70
79
 
71
80
  NSLog(@"๐Ÿ–ฅ๏ธ Display bounds (logical): %.0fx%.0f", logicalSize.width, logicalSize.height);
72
81
  NSLog(@"๐Ÿ–ฅ๏ธ Display pixels (physical): %.0fx%.0f", physicalSize.width, physicalSize.height);
@@ -147,13 +156,30 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
147
156
 
148
157
  // Apply scaling to capture rect if provided (for macOS 14/13 compatibility)
149
158
  if (!CGRectIsEmpty(captureRect)) {
150
- // Note: captureRect comes in logical coordinates, keep as-is for CGDisplayCreateImage
151
- g_avCaptureRect = captureRect;
152
- NSLog(@"๐Ÿ”ฒ Capture area (logical): %.0f,%.0f %.0fx%.0f",
153
- captureRect.origin.x, captureRect.origin.y, captureRect.size.width, captureRect.size.height);
159
+ // Scale capture rect to match actual image dimensions if needed
160
+ CGFloat imageScaleX = actualImageSize.width / logicalSize.width;
161
+ CGFloat imageScaleY = actualImageSize.height / logicalSize.height;
162
+
163
+ if (imageScaleX > 1.1 || imageScaleY > 1.1) {
164
+ // Scale up capture rect for high-DPI displays
165
+ CGRect scaledRect = CGRectMake(
166
+ captureRect.origin.x * imageScaleX,
167
+ captureRect.origin.y * imageScaleY,
168
+ captureRect.size.width * imageScaleX,
169
+ captureRect.size.height * imageScaleY
170
+ );
171
+ g_avCaptureRect = scaledRect;
172
+ NSLog(@"๐Ÿ”ฒ Capture area scaled: %.0f,%.0f %.0fx%.0f (scale %.1fx%.1fx)",
173
+ scaledRect.origin.x, scaledRect.origin.y, scaledRect.size.width, scaledRect.size.height,
174
+ imageScaleX, imageScaleY);
175
+ } else {
176
+ g_avCaptureRect = captureRect;
177
+ NSLog(@"๐Ÿ”ฒ Capture area (no scaling): %.0f,%.0f %.0fx%.0f",
178
+ captureRect.origin.x, captureRect.origin.y, captureRect.size.width, captureRect.size.height);
179
+ }
154
180
  } else {
155
181
  g_avCaptureRect = CGRectZero; // Full screen
156
- NSLog(@"๐Ÿ–ฅ๏ธ Full screen capture (logical bounds)");
182
+ NSLog(@"๐Ÿ–ฅ๏ธ Full screen capture (actual image dimensions)");
157
183
  }
158
184
 
159
185
  g_avFrameNumber = 0;
@@ -214,8 +240,11 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
214
240
  size_t imageWidth = CGImageGetWidth(screenImage);
215
241
  size_t imageHeight = CGImageGetHeight(screenImage);
216
242
 
243
+ NSLog(@"๐Ÿ” Debug: Buffer %zux%zu, Image %zux%zu", bufferWidth, bufferHeight, imageWidth, imageHeight);
244
+
217
245
  if (bufferWidth != imageWidth || bufferHeight != imageHeight) {
218
- NSLog(@"โš ๏ธ Size mismatch! Buffer %zux%zu vs Image %zux%zu", bufferWidth, bufferHeight, imageWidth, imageHeight);
246
+ NSLog(@"โš ๏ธ CRITICAL SIZE MISMATCH! Buffer %zux%zu vs Image %zux%zu", bufferWidth, bufferHeight, imageWidth, imageHeight);
247
+ NSLog(@" This indicates Retina scaling issue on macOS 14/13");
219
248
  }
220
249
 
221
250
  CVPixelBufferLockBaseAddress(pixelBuffer, 0);
@@ -892,11 +892,21 @@ void updateOverlay() {
892
892
  CGFloat primaryOffsetX = primaryFrame.origin.x - combinedFrame.origin.x;
893
893
  CGFloat primaryOffsetY = primaryFrame.origin.y - combinedFrame.origin.y;
894
894
 
895
+ NSLog(@"๐Ÿ”ง PRIMARY DEBUG:");
896
+ NSLog(@" Primary frame: (%.0f,%.0f) %.0fx%.0f", primaryFrame.origin.x, primaryFrame.origin.y, primaryFrame.size.width, primaryFrame.size.height);
897
+ NSLog(@" Combined frame: (%.0f,%.0f) %.0fx%.0f", combinedFrame.origin.x, combinedFrame.origin.y, combinedFrame.size.width, combinedFrame.size.height);
898
+ NSLog(@" Primary offset: (%.0f,%.0f)", primaryOffsetX, primaryOffsetY);
899
+ NSLog(@" Window coords: (%.0f,%.0f) โ†’ Local: (%.0f,%.0f)", (CGFloat)x, (CGFloat)y, x + primaryOffsetX, ([g_overlayView frame].size.height - (y + primaryOffsetY)) - height);
900
+
895
901
  localX = x + primaryOffsetX;
896
902
  localY = ([g_overlayView frame].size.height - (y + primaryOffsetY)) - height;
897
903
 
898
904
  } else {
899
905
  // Secondary display windows: Apply standard coordinate transformation
906
+ NSLog(@"๐Ÿ”ง SECONDARY DEBUG:");
907
+ NSLog(@" GlobalOffset: (%.0f,%.0f)", globalOffset.x, globalOffset.y);
908
+ NSLog(@" Window coords: (%.0f,%.0f) โ†’ Local: (%.0f,%.0f)", (CGFloat)x, (CGFloat)y, x - globalOffset.x, ([g_overlayView frame].size.height - (y - globalOffset.y)) - height);
909
+
900
910
  localX = x - globalOffset.x;
901
911
  localY = ([g_overlayView frame].size.height - (y - globalOffset.y)) - height;
902
912
  }