screen_recorder 0.1.3 → 0.1.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.
data/History.markdown
CHANGED
@@ -0,0 +1,205 @@
|
|
1
|
+
//
|
2
|
+
// MCScreenRecorder.m
|
3
|
+
// ScreenRecorder
|
4
|
+
//
|
5
|
+
// Created by Mark Rada on 12-04-07.
|
6
|
+
// Copyright (c) 2012 Marketcircle Incorporated. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#import "MCScreenRecorder.h"
|
10
|
+
|
11
|
+
|
12
|
+
@implementation MCScreenRecorder
|
13
|
+
|
14
|
+
@synthesize session;
|
15
|
+
@synthesize input;
|
16
|
+
@synthesize output;
|
17
|
+
@synthesize file;
|
18
|
+
@synthesize sema;
|
19
|
+
|
20
|
+
|
21
|
+
- (id)init
|
22
|
+
{
|
23
|
+
if ([super init]) {
|
24
|
+
self.session = [[AVCaptureSession alloc] init];
|
25
|
+
self.input = [[AVCaptureScreenInput alloc] initWithDisplayID:CGMainDisplayID()];
|
26
|
+
|
27
|
+
self.input.capturesMouseClicks = YES;
|
28
|
+
|
29
|
+
self.output = [[AVCaptureMovieFileOutput alloc] init];
|
30
|
+
self.output.delegate = self;
|
31
|
+
|
32
|
+
[self.session addInput:self.input];
|
33
|
+
[self.session addOutput:self.output];
|
34
|
+
|
35
|
+
self.sema = dispatch_semaphore_create(0);
|
36
|
+
|
37
|
+
return self;
|
38
|
+
}
|
39
|
+
return nil;
|
40
|
+
}
|
41
|
+
|
42
|
+
- (void)dealloc
|
43
|
+
{
|
44
|
+
dispatch_release(self.sema);
|
45
|
+
|
46
|
+
self.file = nil;
|
47
|
+
|
48
|
+
[self.output release];
|
49
|
+
[self.input release];
|
50
|
+
[self.session release];
|
51
|
+
[super dealloc];
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
#define SEMA_WAIT_TIME dispatch_time(DISPATCH_TIME_NOW, (30LL * NSEC_PER_SEC))
|
56
|
+
|
57
|
+
static
|
58
|
+
NSURL*
|
59
|
+
default_file_name()
|
60
|
+
{
|
61
|
+
static NSDateFormatter* formatter;
|
62
|
+
static NSURL* homeDir;
|
63
|
+
static dispatch_once_t default_name_generator_token;
|
64
|
+
dispatch_once(&default_name_generator_token, ^{
|
65
|
+
formatter = [[NSDateFormatter alloc] init];
|
66
|
+
[formatter setDateFormat:@"YYYYMMDDHHmmss"];
|
67
|
+
|
68
|
+
homeDir = [NSURL fileURLWithPath:[@"~/Movies/" stringByExpandingTildeInPath]];
|
69
|
+
});
|
70
|
+
|
71
|
+
NSString* date = [formatter stringFromDate:[NSDate date]];
|
72
|
+
NSURL* path = [homeDir URLByAppendingPathComponent:[@"TestRecording-" stringByAppendingString:date]];
|
73
|
+
return [path URLByAppendingPathExtension:@"mov"];
|
74
|
+
}
|
75
|
+
|
76
|
+
- (BOOL) start
|
77
|
+
{
|
78
|
+
NSURL* path = default_file_name();
|
79
|
+
BOOL result = [self start:path];
|
80
|
+
[path release];
|
81
|
+
return result;
|
82
|
+
}
|
83
|
+
|
84
|
+
- (BOOL) start:(NSURL*)file_name
|
85
|
+
{
|
86
|
+
self.file = file_name;
|
87
|
+
|
88
|
+
[self.session startRunning];
|
89
|
+
[self.output startRecordingToOutputFileURL:self.file
|
90
|
+
recordingDelegate:self];
|
91
|
+
|
92
|
+
if (dispatch_semaphore_wait(self.sema, SEMA_WAIT_TIME))
|
93
|
+
return NO;
|
94
|
+
else
|
95
|
+
return YES;
|
96
|
+
}
|
97
|
+
|
98
|
+
- (BOOL)isStarted
|
99
|
+
{
|
100
|
+
return self.output.isRecording;
|
101
|
+
}
|
102
|
+
|
103
|
+
- (double) length
|
104
|
+
{
|
105
|
+
CMTime duration = self.output.recordedDuration;
|
106
|
+
return (double)duration.value / (double)duration.timescale;
|
107
|
+
}
|
108
|
+
|
109
|
+
- (size_t)size
|
110
|
+
{
|
111
|
+
return self.output.recordedFileSize;
|
112
|
+
}
|
113
|
+
|
114
|
+
- (BOOL) stop
|
115
|
+
{
|
116
|
+
[self.session stopRunning];
|
117
|
+
[self.output stopRecording];
|
118
|
+
|
119
|
+
if (dispatch_semaphore_wait(self.sema, SEMA_WAIT_TIME))
|
120
|
+
return NO;
|
121
|
+
|
122
|
+
// need to wait for some callbacks because we want synchronousness
|
123
|
+
switch (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 30, false))
|
124
|
+
{
|
125
|
+
case kCFRunLoopRunStopped:
|
126
|
+
break;
|
127
|
+
case kCFRunLoopRunTimedOut:
|
128
|
+
NSLog(@"Did not get callback");
|
129
|
+
return NO;
|
130
|
+
default:
|
131
|
+
NSLog(@"Unexpected result from waiting for callback");
|
132
|
+
return NO;
|
133
|
+
}
|
134
|
+
|
135
|
+
if (dispatch_semaphore_wait(self.sema, SEMA_WAIT_TIME))
|
136
|
+
return NO;
|
137
|
+
else
|
138
|
+
return YES;
|
139
|
+
}
|
140
|
+
|
141
|
+
|
142
|
+
#pragma mark AVCaptureFileOutputDelegate
|
143
|
+
|
144
|
+
- (void)captureOutput:(AVCaptureFileOutput*)captureOutput
|
145
|
+
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
|
146
|
+
fromConnection:(AVCaptureConnection*)connection
|
147
|
+
{
|
148
|
+
}
|
149
|
+
|
150
|
+
- (void)captureOutput:(AVCaptureFileOutput*)captureOutput
|
151
|
+
didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer
|
152
|
+
fromConnection:(AVCaptureConnection*)connection
|
153
|
+
{
|
154
|
+
NSLog(@"MCScreenRecorder: dropped same data from recording.\n%@", self);
|
155
|
+
}
|
156
|
+
|
157
|
+
- (BOOL)captureOutputShouldProvideSampleAccurateRecordingStart:(AVCaptureOutput*)captureOutput
|
158
|
+
{
|
159
|
+
return YES;
|
160
|
+
}
|
161
|
+
|
162
|
+
|
163
|
+
#pragma mark AVCaptureFileOutputRecordingDelegate
|
164
|
+
|
165
|
+
- (void)captureOutput:(AVCaptureFileOutput*)captureOutput
|
166
|
+
didFinishRecordingToOutputFileAtURL:(NSURL*)outputFileURL
|
167
|
+
fromConnections:(NSArray*)connections
|
168
|
+
error:(NSError*)error
|
169
|
+
{
|
170
|
+
CFRunLoopStop(CFRunLoopGetCurrent());
|
171
|
+
dispatch_semaphore_signal(self.sema);
|
172
|
+
}
|
173
|
+
|
174
|
+
- (void)captureOutput:(AVCaptureFileOutput*)captureOutput
|
175
|
+
didPauseRecordingToOutputFileAtURL:(NSURL*)fileURL
|
176
|
+
fromConnections:(NSArray*)connections
|
177
|
+
{
|
178
|
+
CFRunLoopStop(CFRunLoopGetCurrent());
|
179
|
+
dispatch_semaphore_signal(self.sema);
|
180
|
+
}
|
181
|
+
|
182
|
+
- (void)captureOutput:(AVCaptureFileOutput*)captureOutput
|
183
|
+
didResumeRecordingToOutputFileAtURL:(NSURL*)fileURL
|
184
|
+
fromConnections:(NSArray*)connections
|
185
|
+
{
|
186
|
+
CFRunLoopStop(CFRunLoopGetCurrent());
|
187
|
+
dispatch_semaphore_signal(self.sema);
|
188
|
+
}
|
189
|
+
|
190
|
+
- (void)captureOutput:(AVCaptureFileOutput*)captureOutput
|
191
|
+
didStartRecordingToOutputFileAtURL:(NSURL*)fileURL
|
192
|
+
fromConnections:(NSArray*)connections
|
193
|
+
{
|
194
|
+
dispatch_semaphore_signal(self.sema);
|
195
|
+
}
|
196
|
+
|
197
|
+
- (void)captureOutput:(AVCaptureFileOutput*)captureOutput
|
198
|
+
willFinishRecordingToOutputFileAtURL:(NSURL*)fileURL
|
199
|
+
fromConnections:(NSArray*)connections
|
200
|
+
error:(NSError*)error
|
201
|
+
{
|
202
|
+
dispatch_semaphore_signal(self.sema);
|
203
|
+
}
|
204
|
+
|
205
|
+
@end
|
@@ -198,15 +198,16 @@ Init_screen_recorder()
|
|
198
198
|
* Screen recordings, easy as pi.
|
199
199
|
*
|
200
200
|
* Things that you need to be concerned about:
|
201
|
-
*
|
202
|
-
*
|
203
|
-
*
|
204
|
-
*
|
205
|
-
*
|
206
|
-
*
|
207
|
-
*
|
208
|
-
*
|
209
|
-
*
|
201
|
+
*
|
202
|
+
* * screen going to sleep (we can resolve this issue later)
|
203
|
+
* * short recordings (~1 second) don't work too well; it looks like
|
204
|
+
* the last bit of the buffer does not get saved so the last ~0.5
|
205
|
+
* seconds are not saved to disk (we could add a 0.5 second sleep)
|
206
|
+
* * small memory leak when a recording starts on Mountain Lion with MacRuby
|
207
|
+
* * constantly leaking memory during recording on Lion with MacRuby
|
208
|
+
* * run loop hack is not needed if code is already being called from
|
209
|
+
* in a run loop in MacRuby
|
210
|
+
* * pausing is not working...not sure why; so it is not exposed for now
|
210
211
|
*/
|
211
212
|
rb_cRecorder = rb_define_class("ScreenRecorder", rb_cObject);
|
212
213
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: screen_recorder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-12-
|
12
|
+
date: 2012-12-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: yard
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- ext/screen_recorder/screen_recorder.c
|
77
77
|
- ext/screen_recorder/MCScreenRecorder.h
|
78
78
|
- ext/screen_recorder/extconf.rb
|
79
|
+
- ext/screen_recorder/MCScreenRecorder.m
|
79
80
|
- Rakefile
|
80
81
|
- README.markdown
|
81
82
|
- History.markdown
|
@@ -95,7 +96,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
96
|
version: '0'
|
96
97
|
segments:
|
97
98
|
- 0
|
98
|
-
hash:
|
99
|
+
hash: 3129088737322312987
|
99
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
101
|
none: false
|
101
102
|
requirements:
|
@@ -104,7 +105,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
105
|
version: '0'
|
105
106
|
segments:
|
106
107
|
- 0
|
107
|
-
hash:
|
108
|
+
hash: 3129088737322312987
|
108
109
|
requirements: []
|
109
110
|
rubyforge_project:
|
110
111
|
rubygems_version: 1.8.24
|