Commit 43e1c383 by Daniel Dahan

final touches before README and release of CaptureView

parent 996a1254
...@@ -121,26 +121,40 @@ class ViewController: UIViewController, CaptureViewDelegate, CaptureSessionDeleg ...@@ -121,26 +121,40 @@ class ViewController: UIViewController, CaptureViewDelegate, CaptureSessionDeleg
:name: captureSessionWillSwitchCameras :name: captureSessionWillSwitchCameras
*/ */
func captureSessionWillSwitchCameras(capture: CaptureSession, position: AVCaptureDevicePosition) { func captureSessionWillSwitchCameras(capture: CaptureSession, position: AVCaptureDevicePosition) {
if .Back == position { // ... do something
let img: UIImage? = UIImage(named: "ic_flash_off_white")
captureView.captureSession.flashMode = .Off
flashButton.setImage(img, forState: .Normal)
flashButton.setImage(img, forState: .Highlighted)
}
} }
/** /**
:name: captureSessionDidSwitchCamerapublic s :name: captureSessionDidSwitchCameras
*/ */
func captureSessionDidSwitchCameras(capture: CaptureSession, position: AVCaptureDevicePosition) { func captureSessionDidSwitchCameras(capture: CaptureSession, position: AVCaptureDevicePosition) {
var img: UIImage?
if .Back == position { if .Back == position {
let img: UIImage? = UIImage(named: "ic_flash_auto_white")
captureView.captureSession.flashMode = .Auto captureView.captureSession.flashMode = .Auto
img = UIImage(named: "ic_flash_auto_white")
flashButton.setImage(img, forState: .Normal)
flashButton.setImage(img, forState: .Highlighted)
img = UIImage(named: "ic_camera_front_white")
switchCamerasButton.setImage(img, forState: .Normal)
switchCamerasButton.setImage(img, forState: .Highlighted)
} else {
captureView.captureSession.flashMode = .Off
img = UIImage(named: "ic_flash_off_white")
flashButton.setImage(img, forState: .Normal) flashButton.setImage(img, forState: .Normal)
flashButton.setImage(img, forState: .Highlighted) flashButton.setImage(img, forState: .Highlighted)
img = UIImage(named: "ic_camera_rear_white")
switchCamerasButton.setImage(img, forState: .Normal)
switchCamerasButton.setImage(img, forState: .Highlighted)
} }
} }
/**
:name: captureViewDidPressFlashButton
*/
func captureViewDidPressFlashButton(captureView: CaptureView, button: UIButton) { func captureViewDidPressFlashButton(captureView: CaptureView, button: UIButton) {
if .Back == captureView.captureSession.cameraPosition { if .Back == captureView.captureSession.cameraPosition {
var img: UIImage? var img: UIImage?
...@@ -191,16 +205,7 @@ class ViewController: UIViewController, CaptureViewDelegate, CaptureSessionDeleg ...@@ -191,16 +205,7 @@ class ViewController: UIViewController, CaptureViewDelegate, CaptureSessionDeleg
:name: captureViewDidPressSwitchCamerasButton :name: captureViewDidPressSwitchCamerasButton
*/ */
func captureViewDidPressSwitchCamerasButton(captureView: CaptureView, button: UIButton) { func captureViewDidPressSwitchCamerasButton(captureView: CaptureView, button: UIButton) {
var img: UIImage? // ... do something
if .Back == captureView.captureSession.cameraPosition {
img = UIImage(named: "ic_camera_front_white")
} else if .Front == captureView.captureSession.cameraPosition {
img = UIImage(named: "ic_camera_rear_white")
}
switchCamerasButton.setImage(img, forState: .Normal)
switchCamerasButton.setImage(img, forState: .Highlighted)
} }
/** /**
......
...@@ -53,7 +53,6 @@ public class CapturePreviewView : MaterialView { ...@@ -53,7 +53,6 @@ public class CapturePreviewView : MaterialView {
:name: preparePreviewLayer :name: preparePreviewLayer
*/ */
private func preparePreviewLayer() { private func preparePreviewLayer() {
layer.addAnimation(MaterialAnimation.transition(.Fade), forKey: kCATransition)
layer.backgroundColor = MaterialColor.black.CGColor layer.backgroundColor = MaterialColor.black.CGColor
layer.masksToBounds = true layer.masksToBounds = true
(layer as! AVCaptureVideoPreviewLayer).videoGravity = AVLayerVideoGravityResizeAspectFill (layer as! AVCaptureVideoPreviewLayer).videoGravity = AVLayerVideoGravityResizeAspectFill
......
...@@ -214,35 +214,35 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate { ...@@ -214,35 +214,35 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
:name: caneraSupportsTapToFocus :name: caneraSupportsTapToFocus
*/ */
public var cameraSupportsTapToFocus: Bool { public var cameraSupportsTapToFocus: Bool {
return activeCamera!.focusPointOfInterestSupported return nil == activeCamera ? false : activeCamera!.focusPointOfInterestSupported
} }
/** /**
:name: cameraSupportsTapToExpose :name: cameraSupportsTapToExpose
*/ */
public var cameraSupportsTapToExpose: Bool { public var cameraSupportsTapToExpose: Bool {
return activeCamera!.exposurePointOfInterestSupported return nil == activeCamera ? false : activeCamera!.exposurePointOfInterestSupported
} }
/** /**
:name: cameraHasFlash :name: cameraHasFlash
*/ */
public var cameraHasFlash: Bool { public var cameraHasFlash: Bool {
return activeCamera!.hasFlash return nil == activeCamera ? false : activeCamera!.hasFlash
} }
/** /**
:name: cameraHasTorch :name: cameraHasTorch
*/ */
public var cameraHasTorch: Bool { public var cameraHasTorch: Bool {
return activeCamera!.hasTorch return nil == activeCamera ? false : activeCamera!.hasTorch
} }
/** /**
:name: cameraPosition :name: cameraPosition
*/ */
public var cameraPosition: AVCaptureDevicePosition { public var cameraPosition: AVCaptureDevicePosition? {
return activeCamera!.position return activeCamera?.position
} }
/** /**
...@@ -392,25 +392,25 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate { ...@@ -392,25 +392,25 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
/** /**
:name: switchCameras :name: switchCameras
*/ */
public func switchCameras(completion: ((success: Bool) -> Void)? = nil) { public func switchCameras() {
if canSwitchCameras { if canSwitchCameras {
do { do {
self.delegate?.captureSessionWillSwitchCameras?(self, position: self.cameraPosition) if let v: AVCaptureDevicePosition = self.cameraPosition {
let videoInput: AVCaptureDeviceInput? = try AVCaptureDeviceInput(device: self.inactiveCamera!) self.delegate?.captureSessionWillSwitchCameras?(self, position: v)
self.session.beginConfiguration() let videoInput: AVCaptureDeviceInput? = try AVCaptureDeviceInput(device: self.inactiveCamera!)
self.session.removeInput(self.activeVideoInput) self.session.beginConfiguration()
self.session.removeInput(self.activeVideoInput)
if self.session.canAddInput(videoInput) {
self.session.addInput(videoInput) if self.session.canAddInput(videoInput) {
self.activeVideoInput = videoInput self.session.addInput(videoInput)
} else { self.activeVideoInput = videoInput
self.session.addInput(self.activeVideoInput) } else {
self.session.addInput(self.activeVideoInput)
}
self.session.commitConfiguration()
self.delegate?.captureSessionDidSwitchCameras?(self, position: self.cameraPosition!)
} }
self.session.commitConfiguration()
completion?(success: true)
self.delegate?.captureSessionDidSwitchCameras?(self, position: self.cameraPosition)
} catch let e as NSError { } catch let e as NSError {
completion?(success: false)
self.delegate?.captureSessionFailedWithError?(self, error: e) self.delegate?.captureSessionFailedWithError?(self, error: e)
} }
} }
...@@ -545,14 +545,15 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate { ...@@ -545,14 +545,15 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
*/ */
public func captureStillImage() { public func captureStillImage() {
dispatch_async(sessionQueue) { dispatch_async(sessionQueue) {
let connection: AVCaptureConnection = self.imageOutput.connectionWithMediaType(AVMediaTypeVideo) if let v: AVCaptureConnection = self.imageOutput.connectionWithMediaType(AVMediaTypeVideo) {
connection.videoOrientation = self.currentVideoOrientation v.videoOrientation = self.currentVideoOrientation
self.imageOutput.captureStillImageAsynchronouslyFromConnection(connection) { (sampleBuffer: CMSampleBuffer!, error: NSError!) -> Void in self.imageOutput.captureStillImageAsynchronouslyFromConnection(v) { (sampleBuffer: CMSampleBuffer!, error: NSError!) -> Void in
if nil == error { if nil == error {
let data: NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer) let data: NSData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer)
self.delegate?.captureStillImageAsynchronously?(self, image: UIImage(data: data)!) self.delegate?.captureStillImageAsynchronously?(self, image: UIImage(data: data)!)
} else { } else {
self.delegate?.captureStillImageAsynchronouslyFailedWithError?(self, error: error!) self.delegate?.captureStillImageAsynchronouslyFailedWithError?(self, error: error!)
}
} }
} }
} }
...@@ -564,30 +565,40 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate { ...@@ -564,30 +565,40 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
public func startRecording() { public func startRecording() {
if !isRecording { if !isRecording {
dispatch_async(sessionQueue) { dispatch_async(sessionQueue) {
let connection: AVCaptureConnection = self.movieOutput.connectionWithMediaType(AVMediaTypeVideo) if let v: AVCaptureConnection = self.movieOutput.connectionWithMediaType(AVMediaTypeVideo) {
connection.videoOrientation = self.currentVideoOrientation v.videoOrientation = self.currentVideoOrientation
connection.preferredVideoStabilizationMode = .Auto v.preferredVideoStabilizationMode = .Auto
let device: AVCaptureDevice = self.activeCamera!
if device.smoothAutoFocusSupported {
do {
try device.lockForConfiguration()
device.smoothAutoFocusEnabled = true
device.unlockForConfiguration()
} catch let e as NSError {
self.delegate?.captureSessionFailedWithError?(self, error: e)
}
} }
if let v: AVCaptureDevice = self.activeCamera {
self.movieOutputURL = self.uniqueURL() if v.smoothAutoFocusSupported {
if let v: NSURL = self.movieOutputURL { do {
self.movieOutput.startRecordingToOutputFileURL(v, recordingDelegate: self) try v.lockForConfiguration()
v.smoothAutoFocusEnabled = true
v.unlockForConfiguration()
} catch let e as NSError {
self.delegate?.captureSessionFailedWithError?(self, error: e)
}
}
self.movieOutputURL = self.uniqueURL()
if let v: NSURL = self.movieOutputURL {
self.movieOutput.startRecordingToOutputFileURL(v, recordingDelegate: self)
}
} }
} }
} }
} }
/** /**
:name: stopRecording
*/
public func stopRecording() {
if isRecording {
movieOutput.stopRecording()
}
}
/**
:name: captureOutput :name: captureOutput
*/ */
public func captureOutput(captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAtURL fileURL: NSURL!, fromConnections connections: [AnyObject]!) { public func captureOutput(captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAtURL fileURL: NSURL!, fromConnections connections: [AnyObject]!) {
...@@ -604,15 +615,6 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate { ...@@ -604,15 +615,6 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
} }
/** /**
:name: stopRecording
*/
public func stopRecording() {
if isRecording {
movieOutput.stopRecording()
}
}
/**
:name: prepareSession :name: prepareSession
*/ */
private func prepareSession() { private func prepareSession() {
...@@ -666,12 +668,6 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate { ...@@ -666,12 +668,6 @@ public class CaptureSession : NSObject, AVCaptureFileOutputRecordingDelegate {
private func prepareMovieOutput() { private func prepareMovieOutput() {
if session.canAddOutput(movieOutput) { if session.canAddOutput(movieOutput) {
session.addOutput(movieOutput) session.addOutput(movieOutput)
// By calling this, it removes the stutter that occurs
// when calling the record button.
let connection: AVCaptureConnection = self.movieOutput.connectionWithMediaType(AVMediaTypeVideo)
connection.videoOrientation = self.currentVideoOrientation
connection.preferredVideoStabilizationMode = .Auto
} }
} }
......
...@@ -104,6 +104,11 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -104,6 +104,11 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
private var tapToResetGesture: UITapGestureRecognizer? private var tapToResetGesture: UITapGestureRecognizer?
/** /**
:name: captureMode
*/
public lazy var captureMode: CaptureMode = .Video
/**
:name: tapToFocusEnabled :name: tapToFocusEnabled
*/ */
public var tapToFocusEnabled: Bool = false { public var tapToFocusEnabled: Bool = false {
...@@ -146,7 +151,7 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -146,7 +151,7 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
/** /**
:name: tapToResetEnabled :name: tapToResetEnabled
*/ */
private var tapToResetEnabled: Bool = false { public var tapToResetEnabled: Bool = false {
didSet { didSet {
if tapToResetEnabled { if tapToResetEnabled {
prepareResetLayer() prepareResetLayer()
...@@ -166,11 +171,6 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -166,11 +171,6 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
} }
/** /**
:name: captureMode
*/
public private(set) lazy var captureMode: CaptureMode = .Video
/**
:name: contentInsets :name: contentInsets
*/ */
public var contentInsets: MaterialEdgeInsets = .None { public var contentInsets: MaterialEdgeInsets = .None {
...@@ -284,6 +284,8 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -284,6 +284,8 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
*/ */
public override func layoutSubviews() { public override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
previewView.frame = bounds
if let v: UIButton = cameraButton { if let v: UIButton = cameraButton {
v.frame.origin.y = bounds.height - contentInsetsRef.bottom - v.bounds.height v.frame.origin.y = bounds.height - contentInsetsRef.bottom - v.bounds.height
v.frame.origin.x = contentInsetsRef.left v.frame.origin.x = contentInsetsRef.left
...@@ -296,7 +298,9 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -296,7 +298,9 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
v.frame.origin.y = bounds.height - contentInsetsRef.bottom - v.bounds.height v.frame.origin.y = bounds.height - contentInsetsRef.bottom - v.bounds.height
v.frame.origin.x = bounds.width - v.bounds.width - contentInsetsRef.right v.frame.origin.x = bounds.width - v.bounds.width - contentInsetsRef.right
} }
(previewView.layer as! AVCaptureVideoPreviewLayer).connection.videoOrientation = captureSession.currentVideoOrientation if let v: AVCaptureConnection = (previewView.layer as! AVCaptureVideoPreviewLayer).connection {
v.videoOrientation = captureSession.currentVideoOrientation
}
} }
/** /**
...@@ -331,7 +335,6 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -331,7 +335,6 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
} }
insertSubview(previewView, atIndex: 0) insertSubview(previewView, atIndex: 0)
MaterialLayout.alignToParent(self, child: previewView)
if let v: UIButton = captureButton { if let v: UIButton = captureButton {
insertSubview(v, atIndex: 1) insertSubview(v, atIndex: 1)
...@@ -393,10 +396,8 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -393,10 +396,8 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
:name: handleSwitchCamerasButton :name: handleSwitchCamerasButton
*/ */
internal func handleSwitchCamerasButton(button: UIButton) { internal func handleSwitchCamerasButton(button: UIButton) {
previewView.layer.addAnimation(MaterialAnimation.transition(.Fade), forKey: kCATransition) captureSession.switchCameras()
captureSession.switchCameras { (success: Bool) in (delegate as? CaptureViewDelegate)?.captureViewDidPressSwitchCamerasButton?(self, button: button)
(self.delegate as? CaptureViewDelegate)?.captureViewDidPressSwitchCamerasButton?(self, button: button)
}
} }
/** /**
...@@ -410,7 +411,6 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -410,7 +411,6 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
captureSession.stopRecording() captureSession.stopRecording()
stopTimer() stopTimer()
} else { } else {
previewView.layer.addAnimation(MaterialAnimation.transition(.Fade), forKey: kCATransition)
captureSession.startRecording() captureSession.startRecording()
startTimer() startTimer()
} }
...@@ -496,7 +496,6 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate { ...@@ -496,7 +496,6 @@ public class CaptureView : MaterialView, UIGestureRecognizerDelegate {
:name: preparePreviewView :name: preparePreviewView
*/ */
private func preparePreviewView() { private func preparePreviewView() {
previewView.translatesAutoresizingMaskIntoConstraints = false
(previewView.layer as! AVCaptureVideoPreviewLayer).session = captureSession.session (previewView.layer as! AVCaptureVideoPreviewLayer).session = captureSession.session
captureSession.startSession() captureSession.startSession()
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment