node-mac-recorder 2.4.11 → 2.4.13
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/binding.gyp +5 -12
- package/index.js +25 -104
- package/install.js +2 -19
- package/package.json +2 -6
- package/src/audio_capture.mm +40 -96
- package/src/cursor_tracker.mm +4 -3
- package/src/mac_recorder.mm +673 -753
- package/src/screen_capture.h +0 -5
- package/src/screen_capture.mm +60 -139
- package/src/window_selector.mm +113 -399
- package/window-selector.js +34 -112
- package/ELECTRON-INTEGRATION.md +0 -710
- package/WINDOW_SELECTOR_USAGE.md +0 -447
- package/backup/binding.gyp +0 -44
- package/backup/src/audio_capture.mm +0 -116
- package/backup/src/cursor_tracker.mm +0 -518
- package/backup/src/mac_recorder.mm +0 -829
- package/backup/src/screen_capture.h +0 -19
- package/backup/src/screen_capture.mm +0 -162
- package/backup/src/screen_capture_kit.h +0 -15
- package/backup/src/window_selector.mm +0 -1457
- package/electron-window-selector.js +0 -698
- package/node-mac-recorder-2.4.2.tgz +0 -0
- package/prebuilds/darwin-arm64/node.napi.node +0 -0
- package/test-api-compatibility.js +0 -92
- package/test-audio.js +0 -94
- package/test-comprehensive.js +0 -164
- package/test-electron-window-selector.js +0 -119
- package/test-overlay-fix.js +0 -72
- package/test-recording.js +0 -142
- package/test-sck-availability.js +0 -26
- package/test-sck-simple.js +0 -37
- package/test-sck.js +0 -56
- package/test-screencapture-overlay.js +0 -54
- package/test-simple-windows.js +0 -29
- package/test-sync.js +0 -52
- package/test-window-details.js +0 -34
- package/test-windows.js +0 -57
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#ifndef SCREEN_CAPTURE_H
|
|
2
|
-
#define SCREEN_CAPTURE_H
|
|
3
|
-
|
|
4
|
-
#import <Foundation/Foundation.h>
|
|
5
|
-
#import <CoreGraphics/CoreGraphics.h>
|
|
6
|
-
|
|
7
|
-
@interface ScreenCapture : NSObject
|
|
8
|
-
|
|
9
|
-
+ (NSArray *)getAvailableDisplays;
|
|
10
|
-
+ (BOOL)captureDisplay:(CGDirectDisplayID)displayID
|
|
11
|
-
toFile:(NSString *)filePath
|
|
12
|
-
rect:(CGRect)rect
|
|
13
|
-
includeCursor:(BOOL)includeCursor;
|
|
14
|
-
+ (CGImageRef)createScreenshotFromDisplay:(CGDirectDisplayID)displayID
|
|
15
|
-
rect:(CGRect)rect;
|
|
16
|
-
|
|
17
|
-
@end
|
|
18
|
-
|
|
19
|
-
#endif // SCREEN_CAPTURE_H
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
#import <AVFoundation/AVFoundation.h>
|
|
2
|
-
#import <CoreGraphics/CoreGraphics.h>
|
|
3
|
-
#import <AppKit/AppKit.h>
|
|
4
|
-
|
|
5
|
-
@interface ScreenCapture : NSObject
|
|
6
|
-
|
|
7
|
-
+ (NSArray *)getAvailableDisplays;
|
|
8
|
-
+ (BOOL)captureDisplay:(CGDirectDisplayID)displayID
|
|
9
|
-
toFile:(NSString *)filePath
|
|
10
|
-
rect:(CGRect)rect
|
|
11
|
-
includeCursor:(BOOL)includeCursor;
|
|
12
|
-
+ (CGImageRef)createScreenshotFromDisplay:(CGDirectDisplayID)displayID
|
|
13
|
-
rect:(CGRect)rect;
|
|
14
|
-
|
|
15
|
-
@end
|
|
16
|
-
|
|
17
|
-
@implementation ScreenCapture
|
|
18
|
-
|
|
19
|
-
+ (NSArray *)getAvailableDisplays {
|
|
20
|
-
NSMutableArray *displays = [NSMutableArray array];
|
|
21
|
-
|
|
22
|
-
uint32_t displayCount;
|
|
23
|
-
CGGetActiveDisplayList(0, NULL, &displayCount);
|
|
24
|
-
|
|
25
|
-
CGDirectDisplayID *displayList = (CGDirectDisplayID *)malloc(displayCount * sizeof(CGDirectDisplayID));
|
|
26
|
-
CGGetActiveDisplayList(displayCount, displayList, &displayCount);
|
|
27
|
-
|
|
28
|
-
// Get NSScreen list for consistent coordinate system
|
|
29
|
-
NSArray<NSScreen *> *screens = [NSScreen screens];
|
|
30
|
-
|
|
31
|
-
for (uint32_t i = 0; i < displayCount; i++) {
|
|
32
|
-
CGDirectDisplayID displayID = displayList[i];
|
|
33
|
-
|
|
34
|
-
// Find corresponding NSScreen for this display ID
|
|
35
|
-
NSScreen *matchingScreen = nil;
|
|
36
|
-
for (NSScreen *screen in screens) {
|
|
37
|
-
// Match by display ID (requires screen.deviceDescription lookup)
|
|
38
|
-
NSDictionary *deviceDescription = [screen deviceDescription];
|
|
39
|
-
NSNumber *screenDisplayID = [deviceDescription objectForKey:@"NSScreenNumber"];
|
|
40
|
-
if (screenDisplayID && [screenDisplayID unsignedIntValue] == displayID) {
|
|
41
|
-
matchingScreen = screen;
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Use NSScreen.frame if found, fallback to CGDisplayBounds
|
|
47
|
-
CGRect bounds;
|
|
48
|
-
if (matchingScreen) {
|
|
49
|
-
NSRect screenFrame = [matchingScreen frame];
|
|
50
|
-
bounds = CGRectMake(screenFrame.origin.x, screenFrame.origin.y, screenFrame.size.width, screenFrame.size.height);
|
|
51
|
-
} else {
|
|
52
|
-
bounds = CGDisplayBounds(displayID);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Create display info dictionary
|
|
56
|
-
NSDictionary *displayInfo = @{
|
|
57
|
-
@"id": @(displayID),
|
|
58
|
-
@"name": [NSString stringWithFormat:@"Display %d", i + 1],
|
|
59
|
-
@"width": @(bounds.size.width),
|
|
60
|
-
@"height": @(bounds.size.height),
|
|
61
|
-
@"x": @(bounds.origin.x),
|
|
62
|
-
@"y": @(bounds.origin.y),
|
|
63
|
-
@"isPrimary": @(CGDisplayIsMain(displayID))
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
[displays addObject:displayInfo];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
free(displayList);
|
|
70
|
-
return [displays copy];
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
+ (BOOL)captureDisplay:(CGDirectDisplayID)displayID
|
|
74
|
-
toFile:(NSString *)filePath
|
|
75
|
-
rect:(CGRect)rect
|
|
76
|
-
includeCursor:(BOOL)includeCursor {
|
|
77
|
-
|
|
78
|
-
CGImageRef screenshot = [self createScreenshotFromDisplay:displayID rect:rect];
|
|
79
|
-
if (!screenshot) {
|
|
80
|
-
return NO;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Create image destination
|
|
84
|
-
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
|
|
85
|
-
CGImageDestinationRef destination = CGImageDestinationCreateWithURL(
|
|
86
|
-
(__bridge CFURLRef)fileURL,
|
|
87
|
-
kUTTypePNG,
|
|
88
|
-
1,
|
|
89
|
-
NULL
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
if (!destination) {
|
|
93
|
-
CGImageRelease(screenshot);
|
|
94
|
-
return NO;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Add cursor if requested
|
|
98
|
-
if (includeCursor) {
|
|
99
|
-
// Get cursor position
|
|
100
|
-
CGPoint cursorPos = CGEventGetLocation(CGEventCreate(NULL));
|
|
101
|
-
|
|
102
|
-
// Create mutable image context
|
|
103
|
-
size_t width = CGImageGetWidth(screenshot);
|
|
104
|
-
size_t height = CGImageGetHeight(screenshot);
|
|
105
|
-
|
|
106
|
-
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
|
107
|
-
CGContextRef context = CGBitmapContextCreate(
|
|
108
|
-
NULL, width, height, 8, width * 4,
|
|
109
|
-
colorSpace, kCGImageAlphaPremultipliedFirst
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
if (context) {
|
|
113
|
-
// Draw original screenshot
|
|
114
|
-
CGContextDrawImage(context, CGRectMake(0, 0, width, height), screenshot);
|
|
115
|
-
|
|
116
|
-
// Draw cursor (simplified - just a small circle)
|
|
117
|
-
CGRect displayBounds = CGDisplayBounds(displayID);
|
|
118
|
-
CGFloat relativeX = cursorPos.x - displayBounds.origin.x;
|
|
119
|
-
CGFloat relativeY = height - (cursorPos.y - displayBounds.origin.y);
|
|
120
|
-
|
|
121
|
-
if (!CGRectIsNull(rect)) {
|
|
122
|
-
relativeX -= rect.origin.x;
|
|
123
|
-
relativeY -= rect.origin.y;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (relativeX >= 0 && relativeX < width && relativeY >= 0 && relativeY < height) {
|
|
127
|
-
CGContextSetRGBFillColor(context, 1.0, 0.0, 0.0, 0.8); // Red cursor
|
|
128
|
-
CGContextFillEllipseInRect(context, CGRectMake(relativeX - 5, relativeY - 5, 10, 10));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
CGImageRef finalImage = CGBitmapContextCreateImage(context);
|
|
132
|
-
CGContextRelease(context);
|
|
133
|
-
CGImageRelease(screenshot);
|
|
134
|
-
screenshot = finalImage;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
CGColorSpaceRelease(colorSpace);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Save image
|
|
141
|
-
CGImageDestinationAddImage(destination, screenshot, NULL);
|
|
142
|
-
BOOL success = CGImageDestinationFinalize(destination);
|
|
143
|
-
|
|
144
|
-
CFRelease(destination);
|
|
145
|
-
CGImageRelease(screenshot);
|
|
146
|
-
|
|
147
|
-
return success;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
+ (CGImageRef)createScreenshotFromDisplay:(CGDirectDisplayID)displayID
|
|
151
|
-
rect:(CGRect)rect {
|
|
152
|
-
|
|
153
|
-
if (CGRectIsNull(rect)) {
|
|
154
|
-
// Capture entire display
|
|
155
|
-
return CGDisplayCreateImage(displayID);
|
|
156
|
-
} else {
|
|
157
|
-
// Capture specific rect
|
|
158
|
-
return CGDisplayCreateImageForRect(displayID, rect);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
@end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#import <Foundation/Foundation.h>
|
|
2
|
-
#import <ScreenCaptureKit/ScreenCaptureKit.h>
|
|
3
|
-
#import <AVFoundation/AVFoundation.h>
|
|
4
|
-
|
|
5
|
-
API_AVAILABLE(macos(12.3))
|
|
6
|
-
@interface ScreenCaptureKitRecorder : NSObject
|
|
7
|
-
|
|
8
|
-
+ (BOOL)isScreenCaptureKitAvailable;
|
|
9
|
-
+ (BOOL)startRecordingWithConfiguration:(NSDictionary *)config
|
|
10
|
-
delegate:(id)delegate
|
|
11
|
-
error:(NSError **)error;
|
|
12
|
-
+ (void)stopRecording;
|
|
13
|
-
+ (BOOL)isRecording;
|
|
14
|
-
|
|
15
|
-
@end
|