node-mac-recorder 2.16.14 โ 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 AVFoundation
|
|
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
|
@@ -53,14 +53,42 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
|
|
|
53
53
|
return false;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
// Get display dimensions
|
|
56
|
+
// Get display dimensions with proper scaling for macOS 14/13 compatibility
|
|
57
57
|
CGRect displayBounds = CGDisplayBounds(displayID);
|
|
58
|
-
CGSize displaySize = CGSizeMake(CGDisplayPixelsWide(displayID), CGDisplayPixelsHigh(displayID));
|
|
59
|
-
CGSize recordingSize = captureRect.size.width > 0 ? captureRect.size : displaySize;
|
|
60
58
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
// Get both logical (bounds) and physical (pixels) dimensions
|
|
60
|
+
CGSize logicalSize = displayBounds.size;
|
|
61
|
+
CGSize physicalSize = CGSizeMake(CGDisplayPixelsWide(displayID), CGDisplayPixelsHigh(displayID));
|
|
62
|
+
|
|
63
|
+
// Calculate scale factor
|
|
64
|
+
CGFloat scaleX = physicalSize.width / logicalSize.width;
|
|
65
|
+
CGFloat scaleY = physicalSize.height / logicalSize.height;
|
|
66
|
+
CGFloat scaleFactor = MAX(scaleX, scaleY); // Use max to handle non-uniform scaling
|
|
67
|
+
|
|
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);
|
|
79
|
+
|
|
80
|
+
NSLog(@"๐ฅ๏ธ Display bounds (logical): %.0fx%.0f", logicalSize.width, logicalSize.height);
|
|
81
|
+
NSLog(@"๐ฅ๏ธ Display pixels (physical): %.0fx%.0f", physicalSize.width, physicalSize.height);
|
|
82
|
+
|
|
83
|
+
if (scaleFactor > 1.5) {
|
|
84
|
+
NSLog(@"๐ Scale factor: %.1fx โ Retina display detected (macOS 14/13 scaling fix applied)", scaleFactor);
|
|
85
|
+
} else if (scaleFactor > 1.1) {
|
|
86
|
+
NSLog(@"๐ Scale factor: %.1fx โ Non-standard scaling detected", scaleFactor);
|
|
87
|
+
} else {
|
|
88
|
+
NSLog(@"๐ Scale factor: %.1fx โ Standard display", scaleFactor);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
NSLog(@"๐ฏ Recording size: %.0fx%.0f (using logical dimensions for AVFoundation)", recordingSize.width, recordingSize.height);
|
|
64
92
|
|
|
65
93
|
// Video settings with macOS compatibility
|
|
66
94
|
NSString *codecKey;
|
|
@@ -123,9 +151,37 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
|
|
|
123
151
|
g_avStartTime = CMTimeMakeWithSeconds(CACurrentMediaTime(), 600);
|
|
124
152
|
[g_avWriter startSessionAtSourceTime:g_avStartTime];
|
|
125
153
|
|
|
126
|
-
// Store recording parameters
|
|
154
|
+
// Store recording parameters with scaling correction
|
|
127
155
|
g_avDisplayID = displayID;
|
|
128
|
-
|
|
156
|
+
|
|
157
|
+
// Apply scaling to capture rect if provided (for macOS 14/13 compatibility)
|
|
158
|
+
if (!CGRectIsEmpty(captureRect)) {
|
|
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
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
g_avCaptureRect = CGRectZero; // Full screen
|
|
182
|
+
NSLog(@"๐ฅ๏ธ Full screen capture (actual image dimensions)");
|
|
183
|
+
}
|
|
184
|
+
|
|
129
185
|
g_avFrameNumber = 0;
|
|
130
186
|
|
|
131
187
|
// Start capture timer (10 FPS for Electron compatibility)
|
|
@@ -184,8 +240,11 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
|
|
|
184
240
|
size_t imageWidth = CGImageGetWidth(screenImage);
|
|
185
241
|
size_t imageHeight = CGImageGetHeight(screenImage);
|
|
186
242
|
|
|
243
|
+
NSLog(@"๐ Debug: Buffer %zux%zu, Image %zux%zu", bufferWidth, bufferHeight, imageWidth, imageHeight);
|
|
244
|
+
|
|
187
245
|
if (bufferWidth != imageWidth || bufferHeight != imageHeight) {
|
|
188
|
-
NSLog(@"โ ๏ธ
|
|
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");
|
|
189
248
|
}
|
|
190
249
|
|
|
191
250
|
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
|
package/src/window_selector.mm
CHANGED
|
@@ -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
|
}
|