node-mac-recorder 2.12.0 → 2.12.2
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/mac_recorder.mm +14 -1
- package/src/screen_capture_kit.mm +57 -3
package/package.json
CHANGED
package/src/mac_recorder.mm
CHANGED
|
@@ -161,8 +161,11 @@ Napi::Value StartRecording(const Napi::CallbackInfo& info) {
|
|
|
161
161
|
|
|
162
162
|
@try {
|
|
163
163
|
// Try ScreenCaptureKit first (macOS 12.3+)
|
|
164
|
+
NSLog(@"🔍 System Version Check - macOS availability for ScreenCaptureKit");
|
|
164
165
|
if (@available(macOS 12.3, *)) {
|
|
166
|
+
NSLog(@"✅ macOS 12.3+ detected - ScreenCaptureKit should be available");
|
|
165
167
|
if ([ScreenCaptureKitRecorder isScreenCaptureKitAvailable]) {
|
|
168
|
+
NSLog(@"✅ ScreenCaptureKit availability check passed");
|
|
166
169
|
NSLog(@"🎯 Using ScreenCaptureKit - overlay windows will be automatically excluded");
|
|
167
170
|
|
|
168
171
|
// Create configuration for ScreenCaptureKit
|
|
@@ -188,16 +191,25 @@ Napi::Value StartRecording(const Napi::CallbackInfo& info) {
|
|
|
188
191
|
if ([ScreenCaptureKitRecorder startRecordingWithConfiguration:sckConfig
|
|
189
192
|
delegate:g_delegate
|
|
190
193
|
error:&sckError]) {
|
|
194
|
+
NSLog(@"🎬 RECORDING METHOD: ScreenCaptureKit");
|
|
191
195
|
NSLog(@"✅ ScreenCaptureKit recording started with window exclusion");
|
|
192
196
|
g_isRecording = true;
|
|
193
197
|
return Napi::Boolean::New(env, true);
|
|
194
198
|
} else {
|
|
195
|
-
NSLog(@"
|
|
199
|
+
NSLog(@"❌ ScreenCaptureKit failed to start");
|
|
200
|
+
NSLog(@"❌ Error: %@", sckError ? sckError.localizedDescription : @"Unknown error");
|
|
201
|
+
NSLog(@"⚠️ Falling back to AVFoundation");
|
|
196
202
|
}
|
|
203
|
+
} else {
|
|
204
|
+
NSLog(@"❌ ScreenCaptureKit availability check failed");
|
|
205
|
+
NSLog(@"⚠️ Falling back to AVFoundation");
|
|
197
206
|
}
|
|
207
|
+
} else {
|
|
208
|
+
NSLog(@"❌ macOS version too old for ScreenCaptureKit (< 12.3)");
|
|
198
209
|
}
|
|
199
210
|
|
|
200
211
|
// Fallback: Use AVFoundation (older macOS or ScreenCaptureKit failure)
|
|
212
|
+
NSLog(@"🎬 RECORDING METHOD: AVFoundation");
|
|
201
213
|
NSLog(@"📼 Falling back to AVFoundation - overlay windows may appear in recording");
|
|
202
214
|
|
|
203
215
|
// Create capture session
|
|
@@ -356,6 +368,7 @@ Napi::Value StartRecording(const Napi::CallbackInfo& info) {
|
|
|
356
368
|
NSURL *outputURL = [NSURL fileURLWithPath:[NSString stringWithUTF8String:outputPath.c_str()]];
|
|
357
369
|
[g_movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:g_delegate];
|
|
358
370
|
|
|
371
|
+
NSLog(@"✅ AVFoundation recording started");
|
|
359
372
|
g_isRecording = true;
|
|
360
373
|
return Napi::Boolean::New(env, true);
|
|
361
374
|
|
|
@@ -19,8 +19,30 @@ static BOOL g_isRecording = NO;
|
|
|
19
19
|
|
|
20
20
|
+ (BOOL)isScreenCaptureKitAvailable {
|
|
21
21
|
if (@available(macOS 12.3, *)) {
|
|
22
|
-
|
|
22
|
+
NSLog(@"🔍 ScreenCaptureKit availability check - macOS 12.3+ confirmed");
|
|
23
|
+
|
|
24
|
+
// Try to access ScreenCaptureKit classes to verify they're actually available
|
|
25
|
+
@try {
|
|
26
|
+
Class scStreamClass = NSClassFromString(@"SCStream");
|
|
27
|
+
Class scContentFilterClass = NSClassFromString(@"SCContentFilter");
|
|
28
|
+
Class scShareableContentClass = NSClassFromString(@"SCShareableContent");
|
|
29
|
+
|
|
30
|
+
if (scStreamClass && scContentFilterClass && scShareableContentClass) {
|
|
31
|
+
NSLog(@"✅ ScreenCaptureKit classes are available");
|
|
32
|
+
return YES;
|
|
33
|
+
} else {
|
|
34
|
+
NSLog(@"❌ ScreenCaptureKit classes not found");
|
|
35
|
+
NSLog(@" SCStream: %@", scStreamClass ? @"✅" : @"❌");
|
|
36
|
+
NSLog(@" SCContentFilter: %@", scContentFilterClass ? @"✅" : @"❌");
|
|
37
|
+
NSLog(@" SCShareableContent: %@", scShareableContentClass ? @"✅" : @"❌");
|
|
38
|
+
return NO;
|
|
39
|
+
}
|
|
40
|
+
} @catch (NSException *exception) {
|
|
41
|
+
NSLog(@"❌ Exception checking ScreenCaptureKit classes: %@", exception.reason);
|
|
42
|
+
return NO;
|
|
43
|
+
}
|
|
23
44
|
}
|
|
45
|
+
NSLog(@"❌ macOS version < 12.3 - ScreenCaptureKit not available");
|
|
24
46
|
return NO;
|
|
25
47
|
}
|
|
26
48
|
|
|
@@ -74,11 +96,43 @@ static BOOL g_isRecording = NO;
|
|
|
74
96
|
// Also try to exclude Electron app if running (common overlay use case)
|
|
75
97
|
for (SCWindow *window in content.windows) {
|
|
76
98
|
NSString *appName = window.owningApplication.applicationName;
|
|
99
|
+
NSString *windowTitle = window.title ? window.title : @"<No Title>";
|
|
100
|
+
|
|
101
|
+
// Debug: Log all windows to see what we're dealing with (only for small subset)
|
|
102
|
+
if ([appName containsString:@"Electron"] || [windowTitle containsString:@"camera"]) {
|
|
103
|
+
NSLog(@"📋 Found potential exclude window: '%@' from app: '%@' (PID: %d, Level: %ld)",
|
|
104
|
+
windowTitle, appName, window.owningApplication.processID, (long)window.windowLayer);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Comprehensive Electron window detection
|
|
108
|
+
BOOL shouldExclude = NO;
|
|
109
|
+
|
|
110
|
+
// Check app name patterns
|
|
77
111
|
if ([appName containsString:@"Electron"] ||
|
|
78
112
|
[appName isEqualToString:@"electron"] ||
|
|
79
|
-
[
|
|
113
|
+
[appName isEqualToString:@"Electron Helper"]) {
|
|
114
|
+
shouldExclude = YES;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Check window title patterns
|
|
118
|
+
if ([windowTitle containsString:@"Electron"] ||
|
|
119
|
+
[windowTitle containsString:@"camera"] ||
|
|
120
|
+
[windowTitle containsString:@"Camera"] ||
|
|
121
|
+
[windowTitle containsString:@"overlay"] ||
|
|
122
|
+
[windowTitle containsString:@"Overlay"]) {
|
|
123
|
+
shouldExclude = YES;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Check window properties (transparent, always on top windows)
|
|
127
|
+
if (window.windowLayer > 100) { // High window levels (like alwaysOnTop)
|
|
128
|
+
shouldExclude = YES;
|
|
129
|
+
NSLog(@"📋 High-level window detected: '%@' (Level: %ld)", windowTitle, (long)window.windowLayer);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (shouldExclude) {
|
|
80
133
|
[excludedWindows addObject:window];
|
|
81
|
-
NSLog(@"🚫 Excluding
|
|
134
|
+
NSLog(@"🚫 Excluding window: '%@' from %@ (PID: %d, Level: %ld)",
|
|
135
|
+
windowTitle, appName, window.owningApplication.processID, (long)window.windowLayer);
|
|
82
136
|
}
|
|
83
137
|
}
|
|
84
138
|
|