screen_recorder 0.1.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.
@@ -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: []