motion-capture 1.0.1 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/project/motion-capture.rb +176 -166
  3. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d2ea866d57338e676627eaa74c23c490d6e8fd06
4
- data.tar.gz: 0f31ebdf4127769dbfac818379cb5372e45f870e
3
+ metadata.gz: add5c836f6f0803ee318c5e70fddc996b7147bb4
4
+ data.tar.gz: 1d6af1f376fc2efcf7f84ca8a74e26ec6eb224b8
5
5
  SHA512:
6
- metadata.gz: e5e8c4a930c9b6cc47e7479b0ddd84cc186ae717a8dc27f850c4e544fff6c48d43d4ba15d0c5d5a3d8a3a212bd65da00166c17fc010e6adc92d3b5e66167502c
7
- data.tar.gz: d719496998b5a1f5d80ba12da71d9a8dff5265d7ece8c37feb262d719cb19ef592e60d66bfa412e3684a606cb84036dcc95cece83dd51b06e4df3082426710a5
6
+ metadata.gz: a44554d9deac436ec6940cbe0bc9fbf96011d736cb5a6c79a59a950384b9b61287b35098c26961fa64af2543d9494d6b5c176814f2118cafddce0fe1452191ee
7
+ data.tar.gz: 98ecacd33e94384f1bf33c404283d9a69a4a13ac37dd91086392f8a1affdb4e266100e498ce23cce3dbd4a07e1f1984ff1b232517dc1d1e9e63aa81aef569b7f
@@ -1,230 +1,240 @@
1
- class Motion
2
- class Capture
3
- DEFAULT_OPTIONS = { device: :default }
1
+ module Motion; class Capture
2
+ CAMERA_POSITIONS = { rear: AVCaptureDevicePositionBack, front: AVCaptureDevicePositionFront }
3
+ FLASH_MODES = { on: AVCaptureFlashModeOn, off: AVCaptureFlashModeOff, auto: AVCaptureFlashModeAuto }
4
4
 
5
- attr_accessor :options, :device
5
+ attr_reader :options, :device
6
6
 
7
- def initialize(options = {})
8
- self.options = options.merge(DEFAULT_OPTIONS)
9
- end
10
-
11
- def start!
12
- use_camera(options[:device])
13
-
14
- add_ouput(still_image_output)
15
- end
7
+ def initialize(options = {})
8
+ @options = options
9
+ end
16
10
 
17
- def stop!
18
- session.stopRunning
11
+ def on_error(block)
12
+ @error_callback = block
13
+ end
19
14
 
20
- remove_outputs
21
- remove_inputs
15
+ def start!
16
+ use_camera(options.fetch(:device, :default))
22
17
 
23
- @_still_image_output = nil
24
- @_session = nil
25
- @_capture_preview_view = nil
26
- end
18
+ add_ouput(still_image_output)
19
+ end
27
20
 
28
- def capture(&block)
29
- still_image_connection = still_image_output.connectionWithMediaType(AVMediaTypeVideo)
21
+ def stop!
22
+ session.stopRunning
30
23
 
31
- if still_image_connection.isVideoOrientationSupported
32
- still_image_connection.setVideoOrientation(UIDevice.currentDevice.orientation)
33
- end
24
+ remove_outputs
25
+ remove_inputs
34
26
 
35
- still_image_output.captureStillImageAsynchronouslyFromConnection(still_image_connection, completionHandler: lambda { |image_data_sample_buffer, error|
36
- if image_data_sample_buffer
37
- image_data = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(image_data_sample_buffer)
27
+ @still_image_output = nil
28
+ @session = nil
29
+ @capture_preview_view = nil
30
+ end
38
31
 
39
- block.call(image_data)
40
- else
41
- p "Error capturing image: #{error.localizedDescription}"
42
- end
43
- })
44
- end
32
+ def running?
33
+ session && session.running?
34
+ end
45
35
 
46
- def capture_and_save(&block)
47
- still_image_connection = still_image_output.connectionWithMediaType(AVMediaTypeVideo)
36
+ def capture(&block)
37
+ still_image_output.captureStillImageAsynchronouslyFromConnection(still_image_connection, completionHandler: -> (buffer, error) {
38
+ if error
39
+ error_callback.call(error)
40
+ else
41
+ image_data = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer)
48
42
 
49
- if still_image_connection.isVideoOrientationSupported
50
- still_image_connection.setVideoOrientation(UIDevice.currentDevice.orientation)
43
+ block.call(image_data)
51
44
  end
45
+ })
46
+ end
52
47
 
53
- still_image_output.captureStillImageAsynchronouslyFromConnection(still_image_connection, completionHandler: lambda { |image_data_sample_buffer, error|
54
- if image_data_sample_buffer
55
- image_data = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(image_data_sample_buffer)
56
-
57
- assets_library.writeImageDataToSavedPhotosAlbum(image_data, metadata: nil, completionBlock: lambda { |asset_url, error|
58
- block.call(asset_url)
59
- })
60
- else
61
- p "Error capturing image: #{error.localizedDescription}"
62
- end
63
- })
64
- end
48
+ def capture_image(&block)
49
+ capture do |jpeg_data|
50
+ image = UIImage.imageWithData(jpeg_data)
65
51
 
66
- def assets_library
67
- @_assets_library ||= ALAssetsLibrary.alloc.init
52
+ block.call(image)
68
53
  end
54
+ end
69
55
 
70
- def capture_preview_view(options)
71
- @_capture_preview_view ||= begin
72
- start!
56
+ def capture_and_save(&block)
57
+ capture do |jpeg_data|
58
+ save_data(jpeg_data) do |asset_url|
59
+ block.call(jpeg_data, asset_url)
60
+ end
61
+ end
62
+ end
73
63
 
74
- UIView.alloc.initWithFrame(options.fetch(:frame, CGRectZero)).tap do |view|
75
- view.backgroundColor = UIColor.whiteColor
64
+ def capture_image_and_save(&block)
65
+ capture do |jpeg_data|
66
+ save_data(jpeg_data) do |asset_url|
67
+ image = UIImage.imageWithData(jpeg_data)
76
68
 
77
- view.layer.addSublayer(preview_layer_for_view(view))
78
- end
69
+ block.call(image, asset_url)
79
70
  end
80
71
  end
72
+ end
81
73
 
82
- def use_camera(camera)
83
- device = camera_devices[camera]
74
+ def save_data(jpeg_data, &block)
75
+ assets_library.writeImageDataToSavedPhotosAlbum(jpeg_data, metadata: nil, completionBlock: -> (asset_url, error) {
76
+ error ? error_callback.call(error) : block.call(asset_url)
77
+ })
78
+ end
84
79
 
85
- error = Pointer.new(:object)
80
+ def attach(view, options = {})
81
+ preview_layer = preview_layer_for_view(view, options)
86
82
 
87
- self.device = device
88
- input = AVCaptureDeviceInput.deviceInputWithDevice(device, error: error)
83
+ view.layer.addSublayer(preview_layer)
84
+ end
89
85
 
90
- if input
91
- set_input(input)
92
- else
93
- p error[0].description
94
- end
95
- end
86
+ def use_camera(target_camera = :default)
87
+ @device = camera_devices[target_camera]
96
88
 
97
- def toggle_camera
98
- if using_rear_camera?
99
- use_camera(:front)
100
- else
101
- use_camera(:rear)
102
- end
89
+ error_pointer = Pointer.new(:object)
90
+
91
+ if input = AVCaptureDeviceInput.deviceInputWithDevice(device, error: error_pointer)
92
+ set_input(input)
93
+ else
94
+ error_callback.call(error_pointer[0])
103
95
  end
96
+ end
97
+
98
+ def toggle_camera
99
+ target_camera = using_rear_camera? ? :front : :rear
104
100
 
105
- def toggle_flash
106
- if device && device.hasFlash
107
- error = Pointer.new(:object)
108
- if device.lockForConfiguration(error)
109
- if flash_on?
110
- turn_flash_off
111
- else
112
- turn_flash_on
113
- end
114
-
115
- device.unlockForConfiguration
116
- else
117
- p error[0].description
118
- end
101
+ use_camera(target_camera)
102
+ end
103
+
104
+ def toggle_flash
105
+ if device && device.hasFlash
106
+ configure_with_lock do
107
+ target_mode = flash_on? ? :off : :on
108
+
109
+ set_flash(target_mode)
119
110
  end
120
111
  end
112
+ end
113
+
114
+ def set_flash(mode = :auto)
115
+ device.flashMode = FLASH_MODES[mode] if FLASH_MODES.keys.include? mode
116
+ end
121
117
 
122
- private
118
+ private
123
119
 
124
- def set_input(input)
125
- remove_inputs
120
+ def error_callback
121
+ @error_callback ||= -> (error) { p "An error occurred: #{error.localizedDescription}." }
122
+ end
126
123
 
127
- add_input(input)
124
+ def still_image_connection
125
+ @still_image_connection ||= still_image_output.connectionWithMediaType(AVMediaTypeVideo).tap do |connection|
126
+ connection.setVideoOrientation(UIDevice.currentDevice.orientation) if connection.videoOrientationSupported?
128
127
  end
128
+ end
129
129
 
130
- def set_output(output)
131
- remove_outputs
130
+ def assets_library
131
+ @assets_library ||= ALAssetsLibrary.alloc.init
132
+ end
132
133
 
133
- add_output(output)
134
- end
134
+ def configure_with_lock(&block)
135
+ error_pointer = Pointer.new(:object)
135
136
 
136
- def remove_inputs
137
- session.inputs.each do |input|
138
- remove_input(input)
139
- end
140
- end
137
+ if device.lockForConfiguration(error_pointer)
138
+ block.call
141
139
 
142
- def remove_outputs
143
- session.outputs.each do |output|
144
- remove_output(output)
145
- end
140
+ device.unlockForConfiguration
141
+ else
142
+ error_callback.call(error_pointer[0])
146
143
  end
144
+ end
147
145
 
148
- def remove_input(input)
149
- session.removeInput(input)
150
- end
146
+ def set_input(input)
147
+ remove_inputs
151
148
 
152
- def remove_output(output)
153
- session.removeOutput(output)
154
- end
149
+ add_input(input)
150
+ end
155
151
 
156
- def add_input(input)
157
- session.addInput(input)
158
- end
152
+ def set_output(output)
153
+ remove_outputs
159
154
 
160
- def add_ouput(output)
161
- session.addOutput(output)
162
- end
155
+ add_output(output)
156
+ end
163
157
 
164
- def default_camera
165
- AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
158
+ def remove_inputs
159
+ session.inputs.each do |input|
160
+ remove_input(input)
166
161
  end
162
+ end
167
163
 
168
- def rear_camera
169
- capture_devices.select { |device| device.position == camera_position_mapping[:rear] }.first
164
+ def remove_outputs
165
+ session.outputs.each do |output|
166
+ remove_output(output)
170
167
  end
168
+ end
171
169
 
172
- def front_camera
173
- capture_devices.select { |device| device.position == camera_position_mapping[:front] }.first
174
- end
170
+ def remove_input(input)
171
+ session.removeInput(input)
172
+ end
175
173
 
176
- def using_rear_camera?
177
- device.position == AVCaptureDevicePositionBack
178
- end
174
+ def remove_output(output)
175
+ session.removeOutput(output)
176
+ end
179
177
 
180
- def camera_position_mapping
181
- { rear: AVCaptureDevicePositionBack, front: AVCaptureDevicePositionFront }
182
- end
178
+ def add_input(input)
179
+ session.addInput(input)
180
+ end
183
181
 
184
- def camera_devices
185
- { default: default_camera, rear: rear_camera, front: front_camera }
186
- end
182
+ def add_ouput(output)
183
+ session.addOutput(output)
184
+ end
187
185
 
188
- def capture_devices
189
- @_capture_devices ||= AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
190
- end
186
+ def default_camera
187
+ AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
188
+ end
191
189
 
192
- def preview_layer_for_view(view)
193
- AVCaptureVideoPreviewLayer.layerWithSession(session).tap do |layer|
194
- layer_bounds = view.layer.bounds
190
+ def rear_camera
191
+ capture_devices.select { |device| device.position == CAMERA_POSITIONS[:rear] }.first
192
+ end
195
193
 
196
- layer.bounds = layer_bounds
197
- layer.position = CGPointMake(CGRectGetMidX(layer_bounds), CGRectGetMidY(layer_bounds))
198
- layer.videoGravity = AVLayerVideoGravityResizeAspectFill
199
- end
200
- end
194
+ def front_camera
195
+ capture_devices.select { |device| device.position == CAMERA_POSITIONS[:front] }.first
196
+ end
201
197
 
202
- def flash_on?
203
- device.flashMode == AVCaptureFlashModeOn
204
- end
198
+ def using_rear_camera?
199
+ device.position == CAMERA_POSITIONS[:rear]
200
+ end
205
201
 
206
- def turn_flash_on
207
- device.flashMode = AVCaptureFlashModeOn
208
- end
202
+ def camera_devices
203
+ { default: default_camera, rear: rear_camera, front: front_camera }
204
+ end
209
205
 
210
- def turn_flash_off
211
- device.flashMode = AVCaptureFlashModeOff
206
+ def capture_devices
207
+ @capture_devices ||= AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
208
+ end
209
+
210
+ def preview_layer_for_view(view, options = {})
211
+ AVCaptureVideoPreviewLayer.layerWithSession(session).tap do |layer|
212
+ layer_bounds = view.layer.bounds
213
+
214
+ layer.bounds = layer_bounds
215
+ layer.position = CGPointMake(CGRectGetMidX(layer_bounds), CGRectGetMidY(layer_bounds))
216
+ layer.zPosition = options.fetch(:z_position, -100)
217
+ layer.videoGravity = options.fetch(:video_gravity, AVLayerVideoGravityResizeAspectFill)
212
218
  end
219
+ end
213
220
 
214
- def session
215
- @_session ||= AVCaptureSession.alloc.init.tap do |session|
216
- session.sessionPreset = AVCaptureSessionPresetMedium
221
+ def flash_on?
222
+ [FLASH_MODES[:on], FLASH_MODES[:auto]].include? device.flashMode
223
+ end
217
224
 
218
- session.startRunning
219
- end
225
+ def session
226
+ @session ||= AVCaptureSession.alloc.init.tap do |session|
227
+ session.sessionPreset = AVCaptureSessionPresetMedium
228
+
229
+ session.startRunning
220
230
  end
231
+ end
221
232
 
222
- def still_image_output
223
- @_still_image_output ||= AVCaptureStillImageOutput.alloc.init.tap do |output|
224
- settings = { 'AVVideoCodeKey' => AVVideoCodecJPEG }
233
+ def still_image_output
234
+ @still_image_output ||= AVCaptureStillImageOutput.alloc.init.tap do |output|
235
+ settings = { 'AVVideoCodeKey' => AVVideoCodecJPEG }
225
236
 
226
- output.setOutputSettings(settings)
227
- end
237
+ output.setOutputSettings(settings)
228
238
  end
229
239
  end
230
- end
240
+ end; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-capture
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Devon Blandin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-07-12 00:00:00.000000000 Z
11
+ date: 2013-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -24,7 +24,7 @@ dependencies:
24
24
  - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- description: AVFoundation wrapper to support custom camera controllers
27
+ description: Easily create custom camera controllers
28
28
  email:
29
29
  - dblandin@gmail.com
30
30
  executables: []
@@ -54,8 +54,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
54
  version: '0'
55
55
  requirements: []
56
56
  rubyforge_project:
57
- rubygems_version: 2.0.0
57
+ rubygems_version: 2.1.3
58
58
  signing_key:
59
59
  specification_version: 4
60
- summary: AVFoundation wrapper to support custom camera controllers
60
+ summary: RubyMotion AVFoundation wrapper
61
61
  test_files: []