motion-capture 1.0.1 → 1.1.1

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