node-mac-recorder 2.13.3 → 2.13.4
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/screen_capture_kit.mm +43 -40
package/package.json
CHANGED
|
@@ -57,45 +57,45 @@ static BOOL g_writerStarted = NO;
|
|
|
57
57
|
NSLog(@"✅ Electron-safe video writer started");
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
// Ultra-conservative Electron-safe sample buffer processing
|
|
61
|
+
@autoreleasepool {
|
|
62
|
+
if (!g_writerStarted || !g_assetWriterInput || !g_pixelBufferAdaptor) {
|
|
63
|
+
return; // Skip if not ready
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Rate limiting for Electron stability
|
|
67
|
+
static NSTimeInterval lastProcessTime = 0;
|
|
68
|
+
NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate];
|
|
69
|
+
if (currentTime - lastProcessTime < 0.1) { // Max 10 FPS for stability
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
lastProcessTime = currentTime;
|
|
63
73
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// Check if pixel buffer has valid dimensions
|
|
67
|
-
size_t width = CVPixelBufferGetWidth(pixelBuffer);
|
|
68
|
-
size_t height = CVPixelBufferGetHeight(pixelBuffer);
|
|
74
|
+
if (g_assetWriterInput.isReadyForMoreMediaData) {
|
|
75
|
+
CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
|
|
69
76
|
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
77
|
+
if (pixelBuffer && g_pixelBufferAdaptor) {
|
|
78
|
+
// Ultra-conservative validation
|
|
79
|
+
size_t width = CVPixelBufferGetWidth(pixelBuffer);
|
|
80
|
+
size_t height = CVPixelBufferGetHeight(pixelBuffer);
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
82
|
+
if (width == 1280 && height == 720) { // Exact match only
|
|
83
|
+
CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
|
|
84
|
+
CMTime relativeTime = CMTimeSubtract(presentationTime, g_startTime);
|
|
85
|
+
|
|
86
|
+
// Conservative time validation
|
|
87
|
+
if (CMTimeGetSeconds(relativeTime) >= 0 && CMTimeGetSeconds(relativeTime) < 30) {
|
|
88
|
+
BOOL success = [g_pixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:relativeTime];
|
|
89
|
+
if (success) {
|
|
90
|
+
g_currentTime = relativeTime;
|
|
91
|
+
static int safeFrameCount = 0;
|
|
92
|
+
safeFrameCount++;
|
|
93
|
+
if (safeFrameCount % 10 == 0) {
|
|
94
|
+
NSLog(@"✅ Electron-safe: %d frames", safeFrameCount);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
81
97
|
}
|
|
82
|
-
} else {
|
|
83
|
-
NSLog(@"⚠️ Failed to append valid pixel buffer (%dx%d) at time %f", (int)width, (int)height, CMTimeGetSeconds(relativeTime));
|
|
84
|
-
NSLog(@"Asset writer status: %ld, error: %@", (long)g_assetWriter.status, g_assetWriter.error);
|
|
85
98
|
}
|
|
86
|
-
} else {
|
|
87
|
-
static int invalidSizeCount = 0;
|
|
88
|
-
invalidSizeCount++;
|
|
89
|
-
if (invalidSizeCount % 50 == 0) {
|
|
90
|
-
NSLog(@"⚠️ Invalid pixel buffer dimensions: %dx%d (%d times)", (int)width, (int)height, invalidSizeCount);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
} else {
|
|
94
|
-
// Only log occasionally to avoid spam
|
|
95
|
-
static int nullBufferCount = 0;
|
|
96
|
-
nullBufferCount++;
|
|
97
|
-
if (nullBufferCount % 100 == 0) {
|
|
98
|
-
NSLog(@"⚠️ Null pixel buffer (%d times) - adaptor: %p", nullBufferCount, g_pixelBufferAdaptor);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
}
|
|
@@ -137,12 +137,14 @@ static BOOL g_writerStarted = NO;
|
|
|
137
137
|
// Simple content filter - no exclusions for now
|
|
138
138
|
SCContentFilter *filter = [[SCContentFilter alloc] initWithDisplay:targetDisplay excludingWindows:@[]];
|
|
139
139
|
|
|
140
|
-
//
|
|
140
|
+
// Electron-optimized stream configuration (lower resource usage)
|
|
141
141
|
SCStreamConfiguration *streamConfig = [[SCStreamConfiguration alloc] init];
|
|
142
142
|
streamConfig.width = 1280;
|
|
143
143
|
streamConfig.height = 720;
|
|
144
|
-
streamConfig.minimumFrameInterval = CMTimeMake(1,
|
|
144
|
+
streamConfig.minimumFrameInterval = CMTimeMake(1, 10); // 10 FPS for stability
|
|
145
145
|
streamConfig.pixelFormat = kCVPixelFormatType_32BGRA;
|
|
146
|
+
streamConfig.capturesAudio = NO; // Disable audio for simplicity
|
|
147
|
+
streamConfig.excludesCurrentProcessAudio = YES;
|
|
146
148
|
|
|
147
149
|
// Create Electron-safe delegates
|
|
148
150
|
g_streamDelegate = [[ElectronSafeDelegate alloc] init];
|
|
@@ -211,19 +213,20 @@ static BOOL g_writerStarted = NO;
|
|
|
211
213
|
return;
|
|
212
214
|
}
|
|
213
215
|
|
|
214
|
-
//
|
|
216
|
+
// Ultra-conservative Electron video settings
|
|
215
217
|
NSDictionary *videoSettings = @{
|
|
216
218
|
AVVideoCodecKey: AVVideoCodecTypeH264,
|
|
217
219
|
AVVideoWidthKey: @1280,
|
|
218
220
|
AVVideoHeightKey: @720,
|
|
219
221
|
AVVideoCompressionPropertiesKey: @{
|
|
220
|
-
AVVideoAverageBitRateKey: @(1280 * 720 *
|
|
221
|
-
AVVideoMaxKeyFrameIntervalKey: @
|
|
222
|
+
AVVideoAverageBitRateKey: @(1280 * 720 * 1), // Lower bitrate
|
|
223
|
+
AVVideoMaxKeyFrameIntervalKey: @10,
|
|
224
|
+
AVVideoProfileLevelKey: AVVideoProfileLevelH264BaselineAutoLevel
|
|
222
225
|
}
|
|
223
226
|
};
|
|
224
227
|
|
|
225
228
|
g_assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];
|
|
226
|
-
g_assetWriterInput.expectsMediaDataInRealTime =
|
|
229
|
+
g_assetWriterInput.expectsMediaDataInRealTime = NO; // Safer for Electron
|
|
227
230
|
|
|
228
231
|
// Pixel buffer attributes matching ScreenCaptureKit format
|
|
229
232
|
NSDictionary *pixelBufferAttributes = @{
|