This repository has been archived by the owner on May 10, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.m
85 lines (73 loc) · 2.97 KB
/
main.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface ScreenRecorder : NSObject <AVCaptureFileOutputRecordingDelegate>
- (void)startRecordingScreen:(NSScreen *)screen rect:(CGRect)rect saveToFileURL:(NSURL *)dst;
- (void)stop:(BOOL)blockUntilStopped;
@end
@implementation ScreenRecorder {
AVCaptureSession *_session;
AVCaptureMovieFileOutput *_output;
}
static CMTime RefreshRateForDisplayID(CGDirectDisplayID displayID) {
CVDisplayLinkRef displayLink;
assert(CVDisplayLinkCreateWithCGDisplay(displayID, &displayLink) == kCVReturnSuccess);
CVTime refreshRate = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(displayLink);
CVDisplayLinkRelease(displayLink);
return CMTimeMake(refreshRate.timeValue, refreshRate.timeScale);
}
- (void)startRecordingScreen:(NSScreen *)screen rect:(CGRect)rect saveToFileURL:(NSURL *)dst {
assert(!_session);
assert(!_output);
AVCaptureScreenInput *input;
CGDirectDisplayID displayID = [screen.deviceDescription[@"NSScreenNumber"] unsignedIntValue];
assert(_session = [[AVCaptureSession alloc] init]);
assert(input = [[AVCaptureScreenInput alloc] initWithDisplayID:displayID]);
input.cropRect = rect;
#if 0
input.scaleFactor = 1.0/[screen backingScaleFactor];
#endif
input.minFrameDuration = RefreshRateForDisplayID(displayID);
assert(_output = [[AVCaptureMovieFileOutput alloc] init]);
assert([_session canAddInput:input]);
[_session addInput:input];
assert([_session canAddOutput:_output]);
[_session addOutput:_output];
[_session startRunning];
[[NSFileManager defaultManager] removeItemAtURL:dst error:nil];
[_output startRecordingToOutputFileURL:dst recordingDelegate:self];
}
- (void)stop:(BOOL)blockUntilStopped {
[_output stopRecording];
if (blockUntilStopped)
while (_session) // nil'd when file output complete
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate distantPast]];
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput
didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
fromConnections:(NSArray *)connections
error:(NSError *)error {
if (error) NSLog(@"%@", error);
dispatch_async(dispatch_get_main_queue(), ^{
[_session stopRunning];
_session = nil;
_output = nil;
});
}
@end
int main(int argc, const char *argv[]) {
if (argc != 7)
return fprintf(stderr, "Usage: record-screen x y w h duration path\n"), -1;
@autoreleasepool {
int x = strtol(argv[1], NULL, 10);
int y = strtol(argv[2], NULL, 10);
int w = strtol(argv[3], NULL, 10);
int h = strtol(argv[4], NULL, 10);
float duration = strtof(argv[5], NULL);
NSString *path = [NSString stringWithUTF8String:argv[6]];
ScreenRecorder *recorder = [ScreenRecorder new];
[recorder startRecordingScreen:[NSScreen mainScreen] rect:CGRectMake(x, y, w , h) saveToFileURL:[NSURL fileURLWithPath:path]];
[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:duration]];
[recorder stop:YES];
}
}