node-mac-recorder 2.16.8 โ 2.16.10
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.
- package/package.json +1 -1
- package/src/avfoundation_recorder.mm +34 -6
- package/src/mac_recorder.mm +6 -0
package/package.json
CHANGED
|
@@ -57,9 +57,17 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
|
|
|
57
57
|
CGRect displayBounds = CGDisplayBounds(displayID);
|
|
58
58
|
CGSize recordingSize = captureRect.size.width > 0 ? captureRect.size : displayBounds.size;
|
|
59
59
|
|
|
60
|
-
// Video settings
|
|
60
|
+
// Video settings with macOS compatibility
|
|
61
|
+
NSString *codecKey;
|
|
62
|
+
if (@available(macOS 10.13, *)) {
|
|
63
|
+
codecKey = AVVideoCodecTypeH264;
|
|
64
|
+
} else {
|
|
65
|
+
// Fallback for older macOS versions
|
|
66
|
+
codecKey = AVVideoCodecH264;
|
|
67
|
+
}
|
|
68
|
+
|
|
61
69
|
NSDictionary *videoSettings = @{
|
|
62
|
-
AVVideoCodecKey:
|
|
70
|
+
AVVideoCodecKey: codecKey,
|
|
63
71
|
AVVideoWidthKey: @((int)recordingSize.width),
|
|
64
72
|
AVVideoHeightKey: @((int)recordingSize.height),
|
|
65
73
|
AVVideoCompressionPropertiesKey: @{
|
|
@@ -68,19 +76,30 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
|
|
|
68
76
|
}
|
|
69
77
|
};
|
|
70
78
|
|
|
79
|
+
NSLog(@"๐ง Using codec: %@", codecKey);
|
|
80
|
+
|
|
71
81
|
// Create video input
|
|
72
82
|
g_avVideoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
|
|
73
83
|
g_avVideoInput.expectsMediaDataInRealTime = YES;
|
|
74
84
|
|
|
75
|
-
// Create pixel buffer adaptor
|
|
85
|
+
// Create pixel buffer adaptor with compatibility
|
|
86
|
+
OSType pixelFormat;
|
|
87
|
+
if (@available(macOS 13.0, *)) {
|
|
88
|
+
pixelFormat = kCVPixelFormatType_32ARGB; // Modern format
|
|
89
|
+
} else {
|
|
90
|
+
pixelFormat = kCVPixelFormatType_32BGRA; // Legacy compatibility
|
|
91
|
+
}
|
|
92
|
+
|
|
76
93
|
NSDictionary *pixelBufferAttributes = @{
|
|
77
|
-
(NSString*)kCVPixelBufferPixelFormatTypeKey: @(
|
|
94
|
+
(NSString*)kCVPixelBufferPixelFormatTypeKey: @(pixelFormat),
|
|
78
95
|
(NSString*)kCVPixelBufferWidthKey: @((int)recordingSize.width),
|
|
79
96
|
(NSString*)kCVPixelBufferHeightKey: @((int)recordingSize.height),
|
|
80
97
|
(NSString*)kCVPixelBufferCGImageCompatibilityKey: @YES,
|
|
81
98
|
(NSString*)kCVPixelBufferCGBitmapContextCompatibilityKey: @YES
|
|
82
99
|
};
|
|
83
100
|
|
|
101
|
+
NSLog(@"๐ง Using pixel format: %u", pixelFormat);
|
|
102
|
+
|
|
84
103
|
g_avPixelBufferAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:g_avVideoInput sourcePixelBufferAttributes:pixelBufferAttributes];
|
|
85
104
|
|
|
86
105
|
// Add input to writer
|
|
@@ -145,11 +164,20 @@ extern "C" bool startAVFoundationRecording(const std::string& outputPath,
|
|
|
145
164
|
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
|
|
146
165
|
|
|
147
166
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
167
|
+
|
|
168
|
+
// Match bitmap info to pixel format for compatibility
|
|
169
|
+
CGBitmapInfo bitmapInfo;
|
|
170
|
+
OSType currentPixelFormat = CVPixelBufferGetPixelFormatType(pixelBuffer);
|
|
171
|
+
if (currentPixelFormat == kCVPixelFormatType_32ARGB) {
|
|
172
|
+
bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big;
|
|
173
|
+
} else { // kCVPixelFormatType_32BGRA
|
|
174
|
+
bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little;
|
|
175
|
+
}
|
|
176
|
+
|
|
148
177
|
CGContextRef context = CGBitmapContextCreate(pixelData,
|
|
149
178
|
CVPixelBufferGetWidth(pixelBuffer),
|
|
150
179
|
CVPixelBufferGetHeight(pixelBuffer),
|
|
151
|
-
8, bytesPerRow, colorSpace,
|
|
152
|
-
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little);
|
|
180
|
+
8, bytesPerRow, colorSpace, bitmapInfo);
|
|
153
181
|
|
|
154
182
|
if (context) {
|
|
155
183
|
CGContextDrawImage(context, CGRectMake(0, 0, CVPixelBufferGetWidth(pixelBuffer), CVPixelBufferGetHeight(pixelBuffer)), screenImage);
|
package/src/mac_recorder.mm
CHANGED
|
@@ -74,7 +74,13 @@ Napi::Value StartRecording(const Napi::CallbackInfo& info) {
|
|
|
74
74
|
return env.Null();
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
// IMPORTANT: Clean up any stale recording state before starting
|
|
78
|
+
// This fixes the issue where macOS 14/13 users get "recording already in progress"
|
|
79
|
+
NSLog(@"๐งน Cleaning up any previous recording state...");
|
|
80
|
+
cleanupRecording();
|
|
81
|
+
|
|
77
82
|
if (g_isRecording) {
|
|
83
|
+
NSLog(@"โ ๏ธ Still recording after cleanup - forcing stop");
|
|
78
84
|
return Napi::Boolean::New(env, false);
|
|
79
85
|
}
|
|
80
86
|
|