screen_recorder 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ --no-cache
2
+ --no-output
3
+ --verbose
4
+ --markup markdown
5
+ --markup-provider kramdown
6
+ --readme README.markdown
7
+ --hide-void-return
8
+ lib/**/*.rb
9
+ ext/**/*{.m,.c}
@@ -0,0 +1,19 @@
1
+ # 0.1.2 - MacRuby Release
2
+
3
+ * Appease GC era compiler used by MacRuby
4
+
5
+ # 0.1.1 - Derp Release
6
+
7
+ * Fixed `ScreenRecorder#stop` return value
8
+
9
+ # 0.1.0 - Initial Release
10
+
11
+ * CRuby and MacRuby compatible
12
+
13
+ * Added `ScreenRecorder` class
14
+ * Added `ScreenRecorder#start` method
15
+ * Added `ScreenRecorder#started?` method
16
+ * Added `ScreenRecorder#stop` method
17
+ * Added `ScreenRecorder#length` method
18
+ * Added `ScreenRecorder#size` method
19
+ * Added `ScreenRecorder.record` method
@@ -0,0 +1,63 @@
1
+ # Screen Recorder
2
+
3
+ A port of `screen_recorder.rb` from from [AXElements](http://github.com/Marketcircle/AXElements),
4
+ but cleaned up and rewritten in C to be more portable across languages and
5
+ runtimes.
6
+
7
+ [Documentation](http://rdoc.info/gems/screen_recorder/frames)
8
+
9
+
10
+ ## Examples
11
+
12
+ require 'screen_recorder'
13
+
14
+ # in block form
15
+ ScreenRecorder.record do
16
+ sleep 10 # go and do stuff
17
+ end
18
+ # now go check ~/Movies
19
+
20
+ # in "classic" form
21
+ recorder = ScreenRecorder.new
22
+ recorder.start
23
+ # go do stuff
24
+ recorder.stop
25
+ # now go check ~/Movies
26
+
27
+ Both block and non-block forms take an optional string, which should
28
+ be a path to save the recording (the default saves to `~/Movies`).
29
+
30
+
31
+ ## TODO
32
+
33
+ * Expose recorder options at initialization (e.g. turn off mouse clicks)
34
+
35
+
36
+ ## Copyright
37
+
38
+ Copyright (c) 2012, Mark Rada
39
+ All rights reserved.
40
+
41
+ Redistribution and use in source and binary forms, with or without
42
+ modification, are permitted provided that the following conditions are met:
43
+
44
+ * Redistributions of source code must retain the above copyright
45
+ notice, this list of conditions and the following disclaimer.
46
+ * Redistributions in binary form must reproduce the above copyright
47
+ notice, this list of conditions and the following disclaimer in the
48
+ documentation and/or other materials provided with the distribution.
49
+ * Neither the name of Mark Rada nor the names of its
50
+ contributors may be used to endorse or promote products derived
51
+ from this software without specific prior written permission.
52
+
53
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
54
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
55
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
56
+ DISCLAIMED. IN NO EVENT SHALL Mark Rada BE LIABLE FOR ANY
57
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
59
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
61
+ IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
62
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
63
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,33 @@
1
+ task :default => :test
2
+
3
+ require 'rake/clean'
4
+ CLEAN.include '*.plist', '*.gch'
5
+
6
+ desc 'Startup an IRb console with screen_recorder loaded'
7
+ task :console => [:compile] do
8
+ sh 'irb -Ilib -rscreen_recorder'
9
+ end
10
+
11
+ require 'rake/testtask'
12
+ Rake::TestTask.new do |t|
13
+ t.libs << '.'
14
+ t.pattern = 'test/*_test.rb'
15
+ end
16
+ task :test => :compile
17
+
18
+
19
+ # Gem stuff
20
+
21
+ require 'rubygems/package_task'
22
+ SPEC = Gem::Specification.load('screen_recorder.gemspec')
23
+
24
+ Gem::PackageTask.new(SPEC) { }
25
+
26
+ desc 'Build and install gem (not including deps)'
27
+ task :install => :gem do
28
+ require 'rubygems/installer'
29
+ Gem::Installer.new("pkg/#{SPEC.file_name}").install
30
+ end
31
+
32
+ require 'rake/extensiontask'
33
+ Rake::ExtensionTask.new('screen_recorder', SPEC)
@@ -0,0 +1,42 @@
1
+ //
2
+ // MCScreenRecorder.h
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 <Foundation/Foundation.h>
10
+ #import <AVFoundation/AVFoundation.h>
11
+
12
+ @interface MCScreenRecorder : NSObject <AVCaptureFileOutputDelegate, AVCaptureFileOutputRecordingDelegate> {
13
+ }
14
+
15
+ @property (assign) AVCaptureSession* session;
16
+ @property (assign) AVCaptureScreenInput* input;
17
+ @property (assign) AVCaptureMovieFileOutput* output;
18
+
19
+ // File that the recording will be saved to
20
+ @property (assign) NSURL* file;
21
+
22
+ // Used for pseudo run-loop synchronization
23
+ @property (assign) dispatch_semaphore_t sema;
24
+
25
+ - (BOOL) start;
26
+ - (BOOL) start:(NSURL*)file_name;
27
+ - (BOOL) isStarted;
28
+ - (double) length;
29
+ - (size_t) size;
30
+ - (BOOL) stop;
31
+
32
+ #pragma mark AVCaptureFileOutputDelegate
33
+ - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection;
34
+
35
+ #pragma mark AVCaptureFileOutputRecordingDelegate
36
+ - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error;
37
+ - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didPauseRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections;
38
+ - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didResumeRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections;
39
+ - (void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections;
40
+ - (void)captureOutput:(AVCaptureFileOutput *)captureOutput willFinishRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections error:(NSError *)error;
41
+
42
+ @end
@@ -0,0 +1,23 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << ' -std=c99 -Wall -Werror -pedantic -ObjC'
4
+ $LIBS << ' -framework AVFoundation -framework Cocoa'
5
+
6
+ if RUBY_ENGINE == 'macruby'
7
+ $CFLAGS.gsub! /-Werror/, '' # due to GC era warning that doesn't apply
8
+ $CFLAGS << ' -fobjc-gc'
9
+ else
10
+ unless RbConfig::CONFIG["CC"].match /clang/
11
+ clang = `which clang`.chomp
12
+ if clang.empty?
13
+ $stdout.puts "Clang not installed. Cannot build C extension"
14
+ raise "Clang not installed. Cannot build C extension"
15
+ else
16
+ RbConfig::MAKEFILE_CONFIG["CC"] = clang
17
+ RbConfig::MAKEFILE_CONFIG["CXX"] = clang
18
+ end
19
+ end
20
+ $CFLAGS << ' -DNOT_MACRUBY'
21
+ end
22
+
23
+ create_makefile 'screen_recorder/screen_recorder'
@@ -0,0 +1,217 @@
1
+ #import <Cocoa/Cocoa.h>
2
+ #import <AVFoundation/AVFoundation.h>
3
+
4
+ #include "ruby.h"
5
+ #include "MCScreenRecorder.h"
6
+
7
+ static VALUE rb_cRecorder;
8
+ static ID sel_new;
9
+
10
+ static
11
+ void
12
+ rb_recorder_finalizer(id recorder)
13
+ {
14
+ #if NOT_MACRUBY
15
+ [recorder release];
16
+ #else
17
+ #endif
18
+ }
19
+
20
+ static
21
+ VALUE
22
+ rb_objc_wrap(id obj)
23
+ {
24
+ return Data_Wrap_Struct(rb_cRecorder, 0, rb_recorder_finalizer, obj);
25
+ }
26
+ #define OBJC_WRAP(x) (rb_objc_wrap(x))
27
+
28
+ static
29
+ MCScreenRecorder*
30
+ rb_objc_unwrap(VALUE obj)
31
+ {
32
+ MCScreenRecorder* recorder;
33
+ Data_Get_Struct(obj, MCScreenRecorder, recorder);
34
+ return recorder;
35
+ }
36
+ #define OBJC_UNWRAP(x) (rb_objc_unwrap(x))
37
+
38
+ static
39
+ VALUE
40
+ rb_recorder_alloc(VALUE klass)
41
+ {
42
+ MCScreenRecorder* recorder = [[MCScreenRecorder alloc] init];
43
+ return OBJC_WRAP(recorder);
44
+ }
45
+
46
+ /*
47
+ * Synchrnously start recording
48
+ *
49
+ * You can optionally specify a file name for the recording; if you do
50
+ * not then a default name will be provided in the form
51
+ * `~/Movies/TestRecording-20121017123230.mov`
52
+ * (the timestamp will be different for you).
53
+ *
54
+ * @param file_name [String] (__optional__)
55
+ * @return [Boolean]
56
+ */
57
+ static
58
+ VALUE
59
+ rb_recorder_start(int argc, VALUE* argv, VALUE self)
60
+ {
61
+ BOOL result = NO;
62
+ NSString* path = nil;
63
+ NSURL* path_url = nil;
64
+
65
+ switch (argc)
66
+ {
67
+ case 0:
68
+ result = ([OBJC_UNWRAP(self) start]);
69
+ break;
70
+ case 1:
71
+ default:
72
+ path = [NSString stringWithCString:StringValueCStr(argv[0])
73
+ encoding:NSUTF8StringEncoding];
74
+ path_url = [NSURL fileURLWithPath:path];
75
+ result = [OBJC_UNWRAP(self) start:path_url];
76
+ [path release];
77
+ [path_url release];
78
+ }
79
+
80
+ return (result ? Qtrue : Qfalse);
81
+ }
82
+
83
+ /*
84
+ * Whether or not the recording has begun
85
+ *
86
+ * This will be `true` after calling {#start} until {#stop} is called.
87
+ */
88
+ static
89
+ VALUE
90
+ rb_recorder_started(VALUE self)
91
+ {
92
+ return ([OBJC_UNWRAP(self) isStarted] ? Qtrue : Qfalse);
93
+ }
94
+
95
+ /*
96
+ * Duration of the recording, in seconds
97
+ *
98
+ * @return [Float]
99
+ */
100
+ static
101
+ VALUE
102
+ rb_recorder_length(VALUE self)
103
+ {
104
+ return DBL2NUM([OBJC_UNWRAP(self) length]);
105
+ }
106
+
107
+ /*
108
+ * Size of the recording on disk, in bytes
109
+ *
110
+ * @return [Fixnum]
111
+ */
112
+ static
113
+ VALUE
114
+ rb_recorder_size(VALUE self)
115
+ {
116
+ return SIZET2NUM([OBJC_UNWRAP(self) size]);
117
+ }
118
+
119
+ /*
120
+ * Synchronously stop recording and finish up commiting any data to disk
121
+ *
122
+ * A recording cannot be {#start}ed again after it has been stopped. You
123
+ * will need to start a new recording.
124
+ *
125
+ * @return [Boolean]
126
+ */
127
+ static
128
+ VALUE
129
+ rb_recorder_stop(VALUE self)
130
+ {
131
+ return ([OBJC_UNWRAP(self) stop] ? Qtrue : Qfalse);
132
+ }
133
+
134
+ /*
135
+ * Path to the screen recording on disk
136
+ *
137
+ * This is `nil` until the screen recording begins.
138
+ *
139
+ * @return [String,nil]
140
+ */
141
+ static
142
+ VALUE
143
+ rb_recorder_file(VALUE self)
144
+ {
145
+ NSString* name = [[OBJC_UNWRAP(self) file] path];
146
+ if (name)
147
+ return rb_str_new_cstr([name cStringUsingEncoding:NSUTF8StringEncoding]);
148
+ else
149
+ return Qnil;
150
+ }
151
+
152
+ static
153
+ VALUE
154
+ rb_recorder_yielder(VALUE self)
155
+ {
156
+ rb_yield(self);
157
+ return rb_recorder_file(self);
158
+ }
159
+
160
+ /*
161
+ * Record the screen while executing the given block
162
+ *
163
+ * You may optionally specify the path to save the recording to, just
164
+ * as when calling {#start}.
165
+ *
166
+ * The path to the recording will be returned. The recorder object is yielded.
167
+ *
168
+ * @yield
169
+ * @yieldparam recorder [ScreenRecorder]
170
+ * @param file_name [String] (__optional__)
171
+ * @return [String]
172
+ */
173
+ static
174
+ VALUE
175
+ rb_recorder_record(int argc, VALUE* argv, VALUE self)
176
+ {
177
+ VALUE recorder = rb_funcall(rb_cRecorder, sel_new, 0);
178
+ rb_recorder_start(argc, argv, recorder);
179
+ return rb_ensure(rb_recorder_yielder, recorder, rb_recorder_stop, recorder);
180
+ }
181
+
182
+
183
+ void
184
+ Init_screen_recorder()
185
+ {
186
+ sel_new = rb_intern("new");
187
+
188
+ /*
189
+ * Document-class: ScreenRecorder
190
+ *
191
+ * Screen recordings, easy as pi.
192
+ *
193
+ * Things that you need to be concerned about:
194
+ * - screen going to sleep (we can resolve this issue later)
195
+ * - short recordings (~1 second) don't work too well; it looks like
196
+ * the last bit of the buffer does not get saved so the last ~0.5
197
+ * seconds are not saved to disk (we could add a 0.5 second sleep)
198
+ * - small memory leak when a recording starts on Mountain Lion (GC)
199
+ * - constantly leaking memory during recording on Lion (GC)
200
+ * - run loop hack is not needed if code is already being called from
201
+ * in a run loop
202
+ * - pausing is not working...not sure why; so it is not exposed for now
203
+ *
204
+ */
205
+ rb_cRecorder = rb_define_class("ScreenRecorder", rb_cObject);
206
+
207
+ rb_define_alloc_func(rb_cRecorder, rb_recorder_alloc);
208
+
209
+ rb_define_method(rb_cRecorder, "start", rb_recorder_start, -1);
210
+ rb_define_method(rb_cRecorder, "started?", rb_recorder_started, 0);
211
+ rb_define_method(rb_cRecorder, "length", rb_recorder_length, 0);
212
+ rb_define_method(rb_cRecorder, "size", rb_recorder_size, 0);
213
+ rb_define_method(rb_cRecorder, "stop", rb_recorder_stop, 0);
214
+ rb_define_method(rb_cRecorder, "file", rb_recorder_file, 0);
215
+
216
+ rb_define_singleton_method(rb_cRecorder, "record", rb_recorder_record, -1);
217
+ }
@@ -0,0 +1,4 @@
1
+ class ScreenRecorder
2
+ # @return [String]
3
+ VERSION = '0.1.2'
4
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: screen_recorder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mark Rada
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: yard
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.8.3
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.8.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: kramdown
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.14.1
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.14.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake-compiler
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.8.1
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.1
62
+ description: ! 'screen_recorder is a wrapper around some of the OS X AVFoundation
63
+ framework.
64
+
65
+
66
+ Originally extracted from the AXElements project.
67
+
68
+ '
69
+ email: markrada26@gmail.com
70
+ executables: []
71
+ extensions:
72
+ - ext/screen_recorder/extconf.rb
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/screen_recorder/version.rb
76
+ - ext/screen_recorder/screen_recorder.c
77
+ - ext/screen_recorder/MCScreenRecorder.h
78
+ - ext/screen_recorder/extconf.rb
79
+ - Rakefile
80
+ - README.markdown
81
+ - History.markdown
82
+ - .yardopts
83
+ homepage: http://github.com/ferrous26/screen_recorder
84
+ licenses:
85
+ - BSD 3-clause
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ segments:
97
+ - 0
98
+ hash: 127306656123456593
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
101
+ requirements:
102
+ - - ! '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ segments:
106
+ - 0
107
+ hash: 127306656123456593
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 1.8.24
111
+ signing_key:
112
+ specification_version: 3
113
+ summary: A class that allows recording your screen in OS X
114
+ test_files: []