AVClub 0.1.4 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,9 +12,9 @@ I just moved more code into the Manager class, and renamed "AVCamManager" to
12
12
  "AVClub", since that's the central "wrapper" class.
13
13
 
14
14
  This tool - and AVFoundation in general - is much more low level than the
15
- UIImagePickerController (see Camera Programming Topics for iOS). If you're
16
- looking for an easy off-the-shelf solution, use BW::Camera or an instance of
17
- UIImagePickerController.
15
+ `UIImagePickerController` (see Camera Programming Topics for iOS). If you're
16
+ looking for an easy off-the-shelf solution, use `BubbleWrap::Camera` or an
17
+ instance of `UIImagePickerController`.
18
18
 
19
19
  Working with AVFoundation is like holding a dozen loose wires, plugging them all
20
20
  into each other, and hoping that a photo or video comes out the end. If it goes
@@ -23,14 +23,14 @@ wrong, lemme know.
23
23
 
24
24
  The basic process is this:
25
25
 
26
- Create a view for where you want the camera to appear. Or don't, it's optional.
27
- If you want to take a picture using the front camera with no preview, you can
28
- do it! (creepy! :-P)
26
+ Create a view-finder, for where you want the preview image to appear. Or don't,
27
+ it's optional.
29
28
 
30
29
  1. Create a "club" - `AVClub.new`.
31
30
  2. Assign your controller as the delegate - `club.delegate = self`.
32
- 3. and when you're ready - `startInView(viewfinder_view)`. You can start and
33
- stop the session by calling `club.stopSession`
31
+ 3. When you're ready, pass the view-finder to AVClub:
32
+ `club.startInView(viewfinder_view)`. You can start and stop the session by
33
+ calling `club.stopSession ; club.startSession`
34
34
 
35
35
  ```ruby
36
36
  def viewDidLoad
@@ -41,16 +41,35 @@ def viewDidLoad
41
41
  end
42
42
  ```
43
43
 
44
-
45
- For convenience, there is an included `AVClubController` class that adds two
46
- methods you can use or refer to:
44
+ You might have noticed that AVClub uses `camelCased` method names, rather than
45
+ the more rubyesque `snake_case`. This is to distinguish it as an *Objective-C*
46
+ class. *However*, for convenience, there is an included `AVClubController`
47
+ class that is a *Ruby* class, and so uses `snake_case`. It adds two methods you
48
+ can use or refer to: `start_in_view(viewfinder)` (it just passes it on to the
49
+ `AVClub` object, `@club`) and `rotate_camera_to(orientation:duration:)`.
47
50
 
48
51
  ```ruby
49
52
  # this method creates the club, assigns it to self.club, and assigns the
50
53
  # viewFinderView that you pass to self.viewFinderView
51
- def startInView(view)
54
+ def viewWillAppear(animated)
55
+ self.start_in_view(view)
56
+ end
57
+
58
+ # you have to tell AVClub to rotate the image using rotate_camera_to()
59
+ def willRotateToInterfaceOrientation(to_interface_orientation, duration:duration)
60
+ # you'll need to adjust the frame yourself!
52
61
 
53
- # call this in willRotateToInterfaceOrientation(toInterfaceOrientation,
54
- # duration:duration) and pass the new camera frame
55
- def rotateCameraTo(new_frame, orientation:toInterfaceOrientation, duration:duration)
62
+ case to_interface_orientation
63
+ when UIInterfaceOrientationLandscapeLeft
64
+ new_frame = CGRect.new([0, 0], [480, 320])
65
+ when UIInterfaceOrientationLandscapeRight
66
+ new_frame = CGRect.new([0, 0], [480, 320])
67
+ when UIInterfaceOrientationPortrait
68
+ new_frame = CGRect.new([0, 0], [320, 480])
69
+ when UIInterfaceOrientationPortraitUpsideDown
70
+ new_frame = CGRect.new([0, 0], [320, 480])
71
+ end
72
+
73
+ rotate_camera_to(new_frame, orientation: to_interface_orientation, duration:duration)
74
+ end
56
75
  ```
data/Rakefile CHANGED
@@ -1,16 +1,17 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  $:.unshift("/Library/RubyMotion/lib")
3
3
  require 'motion/project'
4
+ if File.exists?(File.expand_path('~/.rubymotion.rb'))
5
+ require '~/.rubymotion.rb'
6
+ end
4
7
 
5
8
 
6
9
  Motion::Project::App.setup do |app|
7
10
  # Use `rake config' to see complete project settings.
8
11
  app.name = 'AVClub-Demo'
9
12
  app.files.insert(0, 'lib/AVClub/AVClubController.rb')
10
- # app.files_dependencies 'app/camera_controller.rb' => 'lib/AVClub/AVClubController.rb'
11
13
 
12
- app.vendor_project('vendor/AVClub', :xcode)
13
- # app.detect_dependencies = false
14
+ app.vendor_project('vendor/AVClub', :static, cflags: '-fobjc-arc')
14
15
  app.frameworks.concat [
15
16
  'MediaPlayer',
16
17
  'QuartzCore',
@@ -1,18 +1,17 @@
1
1
  class CameraController < AVClubController
2
- attr_accessor :record_button, :still_button, :toggle_button;
2
+ attr_accessor :record_button, :still_button, :toggle_button
3
3
 
4
4
  def viewDidLoad
5
5
  super
6
6
  self.view.backgroundColor = UIColor.darkGrayColor
7
7
 
8
- self.viewFinderView = UIView.alloc.initWithFrame(UIEdgeInsetsInsetRect(self.view.bounds, [50, 20, 20, 20]))
9
- self.viewFinderView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
10
- UIViewAutoresizingFlexibleWidth
11
- self.viewFinderView.backgroundColor = UIColor.lightGrayColor
12
- self.view.addSubview(self.viewFinderView)
8
+ view_finder = UIView.alloc.initWithFrame(UIEdgeInsetsInsetRect(self.view.bounds, [50, 20, 20, 20]))
9
+ view_finder.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth
10
+ view_finder.backgroundColor = UIColor.lightGrayColor
11
+ self.view.addSubview(view_finder)
13
12
 
14
13
  ### important ###
15
- startInView(self.viewFinderView)
14
+ start_in_view(view_finder)
16
15
 
17
16
  width = 0
18
17
  height = 0
@@ -22,7 +21,7 @@ class CameraController < AVClubController
22
21
  width += CGRectGetWidth(button.frame)
23
22
  height = CGRectGetHeight(button.frame)
24
23
 
25
- button.addTarget(self, action: 'toggleCamera:', forControlEvents:UIControlEventTouchUpInside)
24
+ button.addTarget(self, action: 'toggle_camera:', forControlEvents:UIControlEventTouchUpInside)
26
25
  end
27
26
  width += 10
28
27
 
@@ -31,7 +30,7 @@ class CameraController < AVClubController
31
30
  button.sizeToFit
32
31
  width += CGRectGetWidth(button.frame)
33
32
 
34
- button.addTarget(self, action: 'toggleRecording:', forControlEvents:UIControlEventTouchUpInside)
33
+ button.addTarget(self, action: 'toggle_recording:', forControlEvents:UIControlEventTouchUpInside)
35
34
  end
36
35
  width += 10
37
36
 
@@ -40,7 +39,7 @@ class CameraController < AVClubController
40
39
  button.sizeToFit
41
40
  width += CGRectGetWidth(button.frame)
42
41
 
43
- button.addTarget(self, action: 'captureStillImage:', forControlEvents:UIControlEventTouchUpInside)
42
+ button.addTarget(self, action: 'capture_still_image:', forControlEvents:UIControlEventTouchUpInside)
44
43
  end
45
44
 
46
45
  left = (CGRectGetWidth(self.view.frame) - width) / 2.0
@@ -69,27 +68,26 @@ class CameraController < AVClubController
69
68
  self.update_button_states
70
69
 
71
70
  # Add a single tap gesture to focus on the point tapped, then lock focus
72
- singleTap = UITapGestureRecognizer.alloc.initWithTarget(self, action:'tapToAutoFocus:')
71
+ singleTap = UITapGestureRecognizer.alloc.initWithTarget(self, action:'tap_to_auto_focus:')
73
72
  singleTap.setDelegate(self)
74
73
  singleTap.setNumberOfTapsRequired(1)
75
- self.viewFinderView.addGestureRecognizer(singleTap)
74
+ view_finder.addGestureRecognizer(singleTap)
76
75
  end
77
76
 
78
- # Auto focus at a particular point. The focus mode will change to locked once
79
- # the auto focus happens.
80
- def tapToAutoFocus(gestureRecognizer)
77
+ # Auto focus at a particular point. The focus mode will remain locked.
78
+ def tap_to_auto_focus(gesture_recognizer)
81
79
  return unless club.videoInput
82
80
 
83
81
  if club.videoInput.device.isFocusPointOfInterestSupported
84
- tapPoint = gestureRecognizer.locationInView(viewFinderView)
82
+ tapPoint = gesture_recognizer.locationInView(gesture_recognizer.view)
85
83
  convertedFocusPoint = club.convertToPointOfInterestFromViewCoordinates(tapPoint)
86
84
  club.autoFocusAtPoint(convertedFocusPoint)
87
85
  end
88
86
  end
89
87
 
90
- # Change to continuous auto focus. The camera will constantly focus at the
91
- # point choosen.
92
- def tapToContinouslyAutoFocus(gestureRecognizer)
88
+ # Change to continuous auto focus. The camera will focus at the point choosen,
89
+ # and then continue to auto focus.
90
+ def tapToContinouslyAutoFocus(gesture_recognizer)
93
91
  return unless club.videoInput
94
92
 
95
93
  if club.videoInput.device.isFocusPointOfInterestSupported
@@ -97,7 +95,7 @@ class CameraController < AVClubController
97
95
  end
98
96
  end
99
97
 
100
- def toggleCamera(sender)
98
+ def toggle_camera(sender)
101
99
  # Toggle between cameras when there is more than one
102
100
  club.toggleCamera
103
101
 
@@ -105,9 +103,9 @@ class CameraController < AVClubController
105
103
  club.continuousFocusAtPoint(CGPoint.new(0.5, 0.5))
106
104
  end
107
105
 
108
- def toggleRecording(sender)
106
+ def toggle_recording(sender)
109
107
  # Start recording if there isn't a recording running. Stop recording if there is.
110
- record_button.setEnabled(false)
108
+ record_button.enabled = false
111
109
  unless club.recorder.isRecording
112
110
  club.startRecording
113
111
  else
@@ -115,11 +113,11 @@ class CameraController < AVClubController
115
113
  end
116
114
  end
117
115
 
118
- def captureStillImage(sender)
116
+ def capture_still_image(sender)
119
117
  return unless still_button.isEnabled
120
118
 
121
119
  # Capture a still image
122
- still_button.setEnabled(false)
120
+ still_button.enabled = false
123
121
  club.captureStillImageAnimated(true)
124
122
  end
125
123
 
@@ -172,10 +170,10 @@ class CameraController < AVClubController
172
170
  update_button_states
173
171
  end
174
172
 
175
- def willRotateToInterfaceOrientation(toInterfaceOrientation, duration:duration)
173
+ def willRotateToInterfaceOrientation(to_interface_duration, duration:duration)
176
174
  super
177
175
 
178
- case toInterfaceOrientation
176
+ case to_interface_duration
179
177
  when UIInterfaceOrientationLandscapeLeft
180
178
  new_frame = CGRect.new([0, 0], [480, 320])
181
179
  when UIInterfaceOrientationLandscapeRight
@@ -187,7 +185,7 @@ class CameraController < AVClubController
187
185
  end
188
186
 
189
187
  ### important ###
190
- rotateCameraTo(new_frame, orientation:toInterfaceOrientation, duration:duration)
188
+ rotate_camera_to(new_frame, orientation:to_interface_duration, duration:duration)
191
189
  end
192
190
 
193
191
  end
@@ -1,25 +1,25 @@
1
1
  class AVClubController < UIViewController
2
2
  attr_accessor :club
3
- attr_accessor :viewFinderView
3
+ attr_accessor :view_finder_view
4
4
 
5
- def startInView(view)
6
- self.viewFinderView = view
5
+ def start_in_view(view)
6
+ @view_finder_view = view
7
7
 
8
- unless club
9
- self.club = AVClub.new
10
- self.club.delegate = self
11
- self.club.startInView(view)
8
+ unless @club
9
+ @club = AVClub.new
10
+ @club.delegate = self
11
+ @club.startInView(view)
12
12
  end
13
13
  end
14
14
 
15
15
  def club(club, didFailWithError:error)
16
- alertView = UIAlertView.alloc.initWithTitle(error.localizedDescription,
17
- message:error.localizedFailureReason,
18
- delegate:nil,
19
- cancelButtonTitle:'OK',
20
- otherButtonTitles:nil
21
- )
22
- alertView.show
16
+ alert_view = UIAlertView.alloc.initWithTitle(error.localizedDescription,
17
+ message:error.localizedFailureReason,
18
+ delegate:nil,
19
+ cancelButtonTitle:'OK',
20
+ otherButtonTitles:nil
21
+ )
22
+ alert_view.show
23
23
  end
24
24
 
25
25
  def club(club, stillImageCaptured:image, error:error)
@@ -37,19 +37,19 @@ class AVClubController < UIViewController
37
37
  def clubDeviceConfigurationChanged(club)
38
38
  end
39
39
 
40
- def rotateCameraTo(new_frame, orientation:toInterfaceOrientation, duration:duration)
41
- return unless viewFinderView
40
+ def rotate_camera_to(new_frame, orientation:to_interface_orientation, duration:duration)
41
+ return unless @view_finder_view
42
42
 
43
- captureVideoPreviewLayer = nil
44
- viewFinderView.layer.sublayers.each do |layer|
43
+ capture_video_preview_layer = nil
44
+ @view_finder_view.layer.sublayers.each do |layer|
45
45
  if layer.is_a? AVCaptureVideoPreviewLayer
46
- captureVideoPreviewLayer = layer
46
+ capture_video_preview_layer = layer
47
47
  break
48
48
  end
49
49
  end
50
- return unless captureVideoPreviewLayer
50
+ return unless capture_video_preview_layer
51
51
 
52
- case toInterfaceOrientation
52
+ case to_interface_orientation
53
53
  when UIInterfaceOrientationLandscapeLeft
54
54
  rotation = Math::PI / 2
55
55
  when UIInterfaceOrientationLandscapeRight
@@ -60,10 +60,14 @@ class AVClubController < UIViewController
60
60
  rotation = 2 * Math::PI
61
61
  end
62
62
 
63
- captureVideoPreviewLayer.masksToBounds = true
63
+ capture_video_preview_layer.masksToBounds = true
64
64
  UIView.animateWithDuration(duration, animations:lambda{
65
- captureVideoPreviewLayer.frame = new_frame
66
- captureVideoPreviewLayer.orientation = toInterfaceOrientation
65
+ transform = CATransform3DMakeRotation(rotation, 0, 0, 1.0)
66
+ capture_video_preview_layer.anchorPoint = [0.5, 0.5]
67
+ capture_video_preview_layer.transform = transform
68
+ capture_video_preview_layer.frame = new_frame
69
+ club.orientation = to_interface_orientation
67
70
  })
68
71
  end
72
+
69
73
  end
@@ -1,3 +1,3 @@
1
1
  module AVClub
2
- VERSION = '0.1.4'
2
+ VERSION = '1.0.3'
3
3
  end
@@ -21,7 +21,7 @@ Motion::Project::App.setup do |app|
21
21
  app.files.insert(insert_point, file)
22
22
  end
23
23
 
24
- app.vendor_project(File.join(File.dirname(__FILE__), '../vendor/AVClub'), :xcode)
24
+ app.vendor_project(File.join(File.dirname(__FILE__), '../vendor/AVClub'), :static, cflags: '-fobjc-arc')
25
25
 
26
26
  app.frameworks.concat [
27
27
  'MediaPlayer',
@@ -70,6 +70,8 @@
70
70
  -(BOOL)isMirrored;
71
71
  -(void)startRecordingWithOrientation:(AVCaptureVideoOrientation)videoOrientation;
72
72
  -(void)stopRecording;
73
+ - (AVCaptureConnection*) audioConnection;
74
+ - (AVCaptureConnection*) videoConnection;
73
75
 
74
76
  @end
75
77
 
@@ -66,10 +66,10 @@
66
66
  AVCaptureMovieFileOutput *aMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
67
67
  if ([aSession canAddOutput:aMovieFileOutput])
68
68
  [aSession addOutput:aMovieFileOutput];
69
- [self setMovieFileOutput:aMovieFileOutput];
69
+ self.movieFileOutput = aMovieFileOutput;
70
70
 
71
- [self setSession:aSession];
72
- [self setOutputFileURL:anOutputFileURL];
71
+ self.session = aSession;
72
+ self.outputFileURL = anOutputFileURL;
73
73
  }
74
74
 
75
75
  return self;
@@ -80,34 +80,40 @@
80
80
  [[self session] removeOutput:[self movieFileOutput]];
81
81
  }
82
82
 
83
+ - (AVCaptureConnection *)videoConnection
84
+ {
85
+ return [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self movieFileOutput] connections]];
86
+ }
87
+
88
+ - (AVCaptureConnection *)audioConnection
89
+ {
90
+ return [AVCamUtilities connectionWithMediaType:AVMediaTypeAudio fromConnections:[[self movieFileOutput] connections]];
91
+ }
92
+
93
+
83
94
  -(BOOL)isOrientationSupported
84
95
  {
85
- AVCaptureConnection *videoConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self movieFileOutput] connections]];
86
- return [videoConnection isVideoOrientationSupported];
96
+ return [self.videoConnection isVideoOrientationSupported];
87
97
  }
88
98
 
89
99
  -(void)setOrientation:(AVCaptureVideoOrientation)orientation
90
100
  {
91
- AVCaptureConnection *videoConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self movieFileOutput] connections]];
92
- return [videoConnection setVideoOrientation:orientation];
101
+ return [self.videoConnection setVideoOrientation:orientation];
93
102
  }
94
103
 
95
104
  -(BOOL)isMirrored
96
105
  {
97
- AVCaptureConnection *videoConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self movieFileOutput] connections]];
98
- return [videoConnection isVideoMirrored];
106
+ return [self.videoConnection isVideoMirrored];
99
107
  }
100
108
 
101
109
  -(BOOL)recordsVideo
102
110
  {
103
- AVCaptureConnection *videoConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self movieFileOutput] connections]];
104
- return [videoConnection isActive];
111
+ return [self.videoConnection isActive];
105
112
  }
106
113
 
107
114
  -(BOOL)recordsAudio
108
115
  {
109
- AVCaptureConnection *audioConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeAudio fromConnections:[[self movieFileOutput] connections]];
110
- return [audioConnection isActive];
116
+ return [self.audioConnection isActive];
111
117
  }
112
118
 
113
119
  -(BOOL)isRecording
@@ -117,12 +123,11 @@
117
123
 
118
124
  -(void)startRecordingWithOrientation:(AVCaptureVideoOrientation)videoOrientation;
119
125
  {
120
- AVCaptureConnection *videoConnection = [AVCamUtilities connectionWithMediaType:AVMediaTypeVideo fromConnections:[[self movieFileOutput] connections]];
121
- if ( ! videoConnection )
126
+ if ( ! self.videoConnection )
122
127
  return;
123
128
 
124
- if ([videoConnection isVideoOrientationSupported])
125
- [videoConnection setVideoOrientation:videoOrientation];
129
+ if ([self.videoConnection isVideoOrientationSupported])
130
+ [self.videoConnection setVideoOrientation:videoOrientation];
126
131
 
127
132
  [[self movieFileOutput] startRecordingToOutputFileURL:[self outputFileURL] recordingDelegate:self];
128
133
  }
@@ -134,6 +139,7 @@
134
139
 
135
140
  @end
136
141
 
142
+
137
143
  @implementation AVCamRecorder (FileOutputDelegate)
138
144
 
139
145
  - (void) captureOutput:(AVCaptureFileOutput *)captureOutput
@@ -1,8 +1,8 @@
1
1
  //
2
2
  // AVClub.h
3
- // AVClub
3
+ // AVClub. Based on the AVCam demo by Apple.
4
4
  //
5
- // Created by Colin Thomas-Arnold on 11/16/12.
5
+ // Created by Colin T.A. Gray on 11/16/12.
6
6
  // Copyright (c) 2012 colinta. All rights reserved.
7
7
  //
8
8
 
@@ -37,12 +37,15 @@
37
37
  - (void) startSession;
38
38
  - (void) stopSession;
39
39
 
40
- - (CGPoint)convertToPointOfInterestFromViewCoordinates:(CGPoint)viewCoordinates;
40
+ - (CGPoint) convertToPointOfInterestFromViewCoordinates:(CGPoint)viewCoordinates;
41
41
  - (void) startRecording;
42
42
  - (void) stopRecording;
43
43
  - (void) saveImageToLibrary:(UIImage*)image;
44
44
  - (void) captureStillImage;
45
45
  - (void) captureStillImageAnimated:(BOOL)animated;
46
+ - (AVCaptureDevice *) frontFacingCamera;
47
+ - (AVCaptureDevice *) backFacingCamera;
48
+ - (AVCaptureDevicePosition) currentCamera;
46
49
  - (BOOL) toggleCamera;
47
50
  - (BOOL) toggleCameraAnimated:(BOOL)animated;
48
51
  - (void) autoFocusAtPoint:(CGPoint)point;