Address warnings, rip out photos, and make the button responsive

This commit is contained in:
Sami Samhuri 2023-10-26 13:56:52 -07:00
parent 707bf2292c
commit 54a288b661
8 changed files with 56 additions and 371 deletions

View file

@ -25,7 +25,6 @@
1675A98F1E00A74A00B80903 /* SwiftyCamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1675A98B1E00A74A00B80903 /* SwiftyCamViewController.swift */; }; 1675A98F1E00A74A00B80903 /* SwiftyCamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1675A98B1E00A74A00B80903 /* SwiftyCamViewController.swift */; };
1675A9901E00A74A00B80903 /* SwiftyCamViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1675A98C1E00A74A00B80903 /* SwiftyCamViewControllerDelegate.swift */; }; 1675A9901E00A74A00B80903 /* SwiftyCamViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1675A98C1E00A74A00B80903 /* SwiftyCamViewControllerDelegate.swift */; };
168505E81E288B4C005B4537 /* VideoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 168505E71E288B4C005B4537 /* VideoViewController.swift */; }; 168505E81E288B4C005B4537 /* VideoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 168505E71E288B4C005B4537 /* VideoViewController.swift */; };
168505EA1E288D80005B4537 /* PhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 168505E91E288D80005B4537 /* PhotoViewController.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
@ -46,7 +45,6 @@
1675A98B1E00A74A00B80903 /* SwiftyCamViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwiftyCamViewController.swift; path = ../../Source/SwiftyCamViewController.swift; sourceTree = "<group>"; }; 1675A98B1E00A74A00B80903 /* SwiftyCamViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwiftyCamViewController.swift; path = ../../Source/SwiftyCamViewController.swift; sourceTree = "<group>"; };
1675A98C1E00A74A00B80903 /* SwiftyCamViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwiftyCamViewControllerDelegate.swift; path = ../../Source/SwiftyCamViewControllerDelegate.swift; sourceTree = "<group>"; }; 1675A98C1E00A74A00B80903 /* SwiftyCamViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SwiftyCamViewControllerDelegate.swift; path = ../../Source/SwiftyCamViewControllerDelegate.swift; sourceTree = "<group>"; };
168505E71E288B4C005B4537 /* VideoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoViewController.swift; sourceTree = "<group>"; }; 168505E71E288B4C005B4537 /* VideoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VideoViewController.swift; sourceTree = "<group>"; };
168505E91E288D80005B4537 /* PhotoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -102,7 +100,6 @@
1675A9771E00A68300B80903 /* ViewController.swift */, 1675A9771E00A68300B80903 /* ViewController.swift */,
16298B551E2703DC0056D413 /* SwiftyRecordButton.swift */, 16298B551E2703DC0056D413 /* SwiftyRecordButton.swift */,
168505E71E288B4C005B4537 /* VideoViewController.swift */, 168505E71E288B4C005B4537 /* VideoViewController.swift */,
168505E91E288D80005B4537 /* PhotoViewController.swift */,
1675A9791E00A68300B80903 /* Main.storyboard */, 1675A9791E00A68300B80903 /* Main.storyboard */,
1675A97C1E00A68300B80903 /* Assets.xcassets */, 1675A97C1E00A68300B80903 /* Assets.xcassets */,
1675A97E1E00A68300B80903 /* LaunchScreen.storyboard */, 1675A97E1E00A68300B80903 /* LaunchScreen.storyboard */,
@ -255,7 +252,6 @@
168505E81E288B4C005B4537 /* VideoViewController.swift in Sources */, 168505E81E288B4C005B4537 /* VideoViewController.swift in Sources */,
1675A9761E00A68300B80903 /* AppDelegate.swift in Sources */, 1675A9761E00A68300B80903 /* AppDelegate.swift in Sources */,
1675A98F1E00A74A00B80903 /* SwiftyCamViewController.swift in Sources */, 1675A98F1E00A74A00B80903 /* SwiftyCamViewController.swift in Sources */,
168505EA1E288D80005B4537 /* PhotoViewController.swift in Sources */,
056AAB091F97CB1700F6A978 /* Orientation.swift in Sources */, 056AAB091F97CB1700F6A978 /* Orientation.swift in Sources */,
16298B561E2703DC0056D413 /* SwiftyRecordButton.swift in Sources */, 16298B561E2703DC0056D413 /* SwiftyRecordButton.swift in Sources */,
1675A98D1E00A74A00B80903 /* PreviewView.swift in Sources */, 1675A98D1E00A74A00B80903 /* PreviewView.swift in Sources */,

View file

@ -1,51 +0,0 @@
/*Copyright (c) 2016, Andrew Walz.
Redistribution and use in source and binary forms, with or without modification,are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
import UIKit
class PhotoViewController: UIViewController {
override var prefersStatusBarHidden: Bool {
return true
}
private var backgroundImage: UIImage
init(image: UIImage) {
self.backgroundImage = image
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.gray
let backgroundImageView = UIImageView(frame: view.frame)
backgroundImageView.contentMode = UIView.ContentMode.scaleAspectFit
backgroundImageView.image = backgroundImage
view.addSubview(backgroundImageView)
let cancelButton = UIButton(frame: CGRect(x: 10.0, y: 10.0, width: 30.0, height: 30.0))
cancelButton.setImage(#imageLiteral(resourceName: "cancel"), for: UIControl.State())
cancelButton.addTarget(self, action: #selector(cancel), for: .touchUpInside)
view.addSubview(cancelButton)
}
@objc func cancel() {
dismiss(animated: true, completion: nil)
}
}

View file

@ -62,10 +62,7 @@ class VideoViewController: UIViewController {
// Allow background audio to continue to play // Allow background audio to continue to play
do { do {
if #available(iOS 10.0, *) { try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: .default, options: [])
try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: .default, options: [])
} else {
}
} catch let error as NSError { } catch let error as NSError {
print(error) print(error)
} }

View file

@ -27,7 +27,6 @@ class ViewController: SwiftyCamViewController, SwiftyCamViewControllerDelegate {
super.viewDidLoad() super.viewDidLoad()
shouldPrompToAppSettings = true shouldPrompToAppSettings = true
cameraDelegate = self cameraDelegate = self
maximumVideoDuration = 10.0
shouldUseDeviceOrientation = true shouldUseDeviceOrientation = true
allowAutoRotate = true allowAutoRotate = true
audioEnabled = true audioEnabled = true
@ -56,11 +55,6 @@ class ViewController: SwiftyCamViewController, SwiftyCamViewControllerDelegate {
} }
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didTake photo: UIImage) {
let newVC = PhotoViewController(image: photo)
self.present(newVC, animated: true, completion: nil)
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didBeginRecordingVideo camera: SwiftyCamViewController.CameraSelection) { func swiftyCam(_ swiftyCam: SwiftyCamViewController, didBeginRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
print("Did Begin Recording") print("Did Begin Recording")
captureButton.growButton() captureButton.growButton()

View file

@ -71,6 +71,8 @@ class Orientation {
return AVCaptureVideoOrientation.landscapeRight return AVCaptureVideoOrientation.landscapeRight
case .portraitUpsideDown: case .portraitUpsideDown:
return AVCaptureVideoOrientation.portraitUpsideDown return AVCaptureVideoOrientation.portraitUpsideDown
@unknown default:
return .portrait
} }
} }

View file

@ -20,33 +20,21 @@ import UIKit
/// Delegate for SwiftyCamButton /// Delegate for SwiftyCamButton
public protocol SwiftyCamButtonDelegate: class { public protocol SwiftyCamButtonDelegate: AnyObject {
/// Called when UITapGestureRecognizer begins /// Called when the button is first pressed
func buttonWasTapped()
/// Called When UILongPressGestureRecognizer enters UIGestureRecognizerState.began
func buttonDidBeginLongPress()
/// Called When UILongPressGestureRecognizer enters UIGestureRecognizerState.end
func buttonDidEndLongPress() func buttonDidBeginPress()
/// Called when the maximum duration is reached /// Called when the button is released
func longPressDidReachMaximumDuration() func buttonDidEndPress()
/// Sets the maximum duration of the video recording
func setMaxiumVideoDuration() -> Double
} }
// MARK: Public View Declaration // MARK: Public View Declaration
/// UIButton Subclass for Capturing Photo and Video with SwiftyCamViewController /// UIButton Subclass for Capturing Video with SwiftyCamViewController
open class SwiftyCamButton: UIButton { open class SwiftyCamButton: UIButton {
@ -58,84 +46,27 @@ open class SwiftyCamButton: UIButton {
public var buttonEnabled = true public var buttonEnabled = true
/// Maximum duration variable open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
fileprivate var timer : Timer?
/// Initialization Declaration
override public init(frame: CGRect) {
super.init(frame: frame)
createGestureRecognizers()
}
/// Initialization Declaration
if buttonEnabled {
required public init?(coder aDecoder: NSCoder) { delegate?.buttonDidBeginPress()
super.init(coder: aDecoder)
createGestureRecognizers()
}
/// UITapGestureRecognizer Function
@objc fileprivate func Tap() {
guard buttonEnabled == true else {
return
}
delegate?.buttonWasTapped()
}
/// UILongPressGestureRecognizer Function
@objc fileprivate func LongPress(_ sender:UILongPressGestureRecognizer!) {
guard buttonEnabled == true else {
return
}
switch sender.state {
case .began:
delegate?.buttonDidBeginLongPress()
startTimer()
case .cancelled, .ended, .failed:
invalidateTimer()
delegate?.buttonDidEndLongPress()
default:
break
} }
} }
/// Timer Finished open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
@objc fileprivate func timerFinished() {
invalidateTimer() if buttonEnabled {
delegate?.longPressDidReachMaximumDuration() delegate?.buttonDidEndPress()
}
/// Start Maximum Duration Timer
fileprivate func startTimer() {
if let duration = delegate?.setMaxiumVideoDuration() {
//Check if duration is set, and greater than zero
if duration != 0.0 && duration > 0.0 {
timer = Timer.scheduledTimer(timeInterval: duration, target: self, selector: #selector(SwiftyCamButton.timerFinished), userInfo: nil, repeats: false)
}
} }
} }
// End timer if UILongPressGestureRecognizer is ended before time has ended open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
fileprivate func invalidateTimer() {
timer?.invalidate() if buttonEnabled {
timer = nil delegate?.buttonDidEndPress()
} }
// Add Tap and LongPress gesture recognizers
fileprivate func createGestureRecognizers() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(SwiftyCamButton.Tap))
let longGesture = UILongPressGestureRecognizer(target: self, action: #selector(SwiftyCamButton.LongPress))
self.addGestureRecognizer(tapGesture)
self.addGestureRecognizer(longGesture)
} }
} }

View file

@ -115,22 +115,10 @@ open class SwiftyCamViewController: UIViewController {
public weak var cameraDelegate: SwiftyCamViewControllerDelegate? public weak var cameraDelegate: SwiftyCamViewControllerDelegate?
/// Maxiumum video duration if SwiftyCamButton is used
public var maximumVideoDuration : Double = 0.0
/// Video capture quality /// Video capture quality
public var videoQuality : VideoQuality = .high public var videoQuality : VideoQuality = .high
/// Sets whether flash is enabled for photo and video capture
@available(*, deprecated, message: "use flashMode .on or .off") //use flashMode
public var flashEnabled: Bool = false {
didSet{
self.flashMode = self.flashEnabled ? .on : .off
}
}
// Flash Mode // Flash Mode
public var flashMode:FlashMode = .off public var flashMode:FlashMode = .off
@ -172,7 +160,7 @@ open class SwiftyCamViewController: UIViewController {
public var defaultCamera = CameraSelection.rear public var defaultCamera = CameraSelection.rear
/// Sets wether the taken photo or video should be oriented according to the device orientation /// Sets wether the taken video should be oriented according to the device orientation
public var shouldUseDeviceOrientation = false { public var shouldUseDeviceOrientation = false {
didSet { didSet {
@ -259,10 +247,6 @@ open class SwiftyCamViewController: UIViewController {
fileprivate var movieFileOutput : AVCaptureMovieFileOutput? fileprivate var movieFileOutput : AVCaptureMovieFileOutput?
/// Photo File Output variable
fileprivate var photoFileOutput : AVCaptureStillImageOutput?
/// Video Device variable /// Video Device variable
fileprivate var videoDevice : AVCaptureDevice? fileprivate var videoDevice : AVCaptureDevice?
@ -477,31 +461,6 @@ open class SwiftyCamViewController: UIViewController {
/** /**
Capture photo from current session
UIImage will be returned with the SwiftyCamViewControllerDelegate function SwiftyCamDidTakePhoto(photo:)
*/
public func takePhoto() {
guard let device = videoDevice else {
return
}
if device.hasFlash == true && flashMode != .off /* TODO: Add Support for Retina Flash and add front flash */ {
changeFlashSettings(device: device, mode: flashMode)
capturePhotoAsyncronously(completionHandler: { (_) in })
}else{
if device.isFlashActive == true {
changeFlashSettings(device: device, mode: flashMode)
}
capturePhotoAsyncronously(completionHandler: { (_) in })
}
}
/**
Begin recording video of current session Begin recording video of current session
SwiftyCamViewControllerDelegate function SwiftyCamDidBeginRecordingVideo() will be called SwiftyCamViewControllerDelegate function SwiftyCamDidBeginRecordingVideo() will be called
@ -662,7 +621,6 @@ open class SwiftyCamViewController: UIViewController {
addVideoInput() addVideoInput()
addAudioInput() addAudioInput()
configureVideoOutput() configureVideoOutput()
configurePhotoOutput()
session.commitConfiguration() session.commitConfiguration()
} }
@ -790,12 +748,10 @@ open class SwiftyCamViewController: UIViewController {
connection.preferredVideoStabilizationMode = .auto connection.preferredVideoStabilizationMode = .auto
} }
if #available(iOS 11.0, *) { if let videoCodecType = videoCodecType {
if let videoCodecType = videoCodecType { if movieFileOutput.availableVideoCodecTypes.contains(videoCodecType) == true {
if movieFileOutput.availableVideoCodecTypes.contains(videoCodecType) == true { // Use the H.264 codec to encode the video.
// Use the H.264 codec to encode the video. movieFileOutput.setOutputSettings([AVVideoCodecKey: videoCodecType], for: connection)
movieFileOutput.setOutputSettings([AVVideoCodecKey: videoCodecType], for: connection)
}
} }
} }
} }
@ -803,67 +759,6 @@ open class SwiftyCamViewController: UIViewController {
} }
} }
/// Configure Photo Output
fileprivate func configurePhotoOutput() {
let photoFileOutput = AVCaptureStillImageOutput()
if self.session.canAddOutput(photoFileOutput) {
photoFileOutput.outputSettings = [AVVideoCodecKey: AVVideoCodecJPEG]
self.session.addOutput(photoFileOutput)
self.photoFileOutput = photoFileOutput
}
}
/**
Returns a UIImage from Image Data.
- Parameter imageData: Image Data returned from capturing photo from the capture session.
- Returns: UIImage from the image data, adjusted for proper orientation.
*/
fileprivate func processPhoto(_ imageData: Data) -> UIImage {
let dataProvider = CGDataProvider(data: imageData as CFData)
let cgImageRef = CGImage(jpegDataProviderSource: dataProvider!, decode: nil, shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
// Set proper orientation for photo
// If camera is currently set to front camera, flip image
let image = UIImage(cgImage: cgImageRef!, scale: 1.0, orientation: self.orientation.getImageOrientation(forCamera: self.currentCamera))
return image
}
fileprivate func capturePhotoAsyncronously(completionHandler: @escaping(Bool) -> ()) {
guard sessionRunning == true else {
print("[SwiftyCam]: Cannot take photo. Capture session is not running")
return
}
if let videoConnection = photoFileOutput?.connection(with: AVMediaType.video) {
photoFileOutput?.captureStillImageAsynchronously(from: videoConnection, completionHandler: {(sampleBuffer, error) in
if (sampleBuffer != nil) {
let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(sampleBuffer!)
let image = self.processPhoto(imageData!)
// Call delegate and return new image
DispatchQueue.main.async {
self.cameraDelegate?.swiftyCam(self, didTake: image)
}
completionHandler(true)
} else {
completionHandler(false)
}
})
} else {
completionHandler(false)
}
}
/// Handle Denied App Privacy Settings /// Handle Denied App Privacy Settings
fileprivate func promptToAppSettings() { fileprivate func promptToAppSettings() {
@ -874,13 +769,7 @@ open class SwiftyCamViewController: UIViewController {
let alertController = UIAlertController(title: "AVCam", message: message, preferredStyle: .alert) let alertController = UIAlertController(title: "AVCam", message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Alert OK button"), style: .cancel, handler: nil)) alertController.addAction(UIAlertAction(title: NSLocalizedString("OK", comment: "Alert OK button"), style: .cancel, handler: nil))
alertController.addAction(UIAlertAction(title: NSLocalizedString("Settings", comment: "Alert button to open Settings"), style: .default, handler: { action in alertController.addAction(UIAlertAction(title: NSLocalizedString("Settings", comment: "Alert button to open Settings"), style: .default, handler: { action in
if #available(iOS 10.0, *) { UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
UIApplication.shared.openURL(URL(string: UIApplication.openSettingsURLString)!)
} else {
if let appSettings = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.openURL(appSettings)
}
}
})) }))
self.present(alertController, animated: true, completion: nil) self.present(alertController, animated: true, completion: nil)
}) })
@ -905,52 +794,15 @@ open class SwiftyCamViewController: UIViewController {
case .resolution1920x1080: return AVCaptureSession.Preset.hd1920x1080.rawValue case .resolution1920x1080: return AVCaptureSession.Preset.hd1920x1080.rawValue
case .iframe960x540: return AVCaptureSession.Preset.iFrame960x540.rawValue case .iframe960x540: return AVCaptureSession.Preset.iFrame960x540.rawValue
case .iframe1280x720: return AVCaptureSession.Preset.iFrame1280x720.rawValue case .iframe1280x720: return AVCaptureSession.Preset.iFrame1280x720.rawValue
case .resolution3840x2160: case .resolution3840x2160: return AVCaptureSession.Preset.hd4K3840x2160.rawValue
if #available(iOS 9.0, *) {
return AVCaptureSession.Preset.hd4K3840x2160.rawValue
}
else {
print("[SwiftyCam]: Resolution 3840x2160 not supported")
return AVCaptureSession.Preset.high.rawValue
}
} }
} }
/// Get Devices /// Get Devices
fileprivate class func deviceWithMediaType(_ mediaType: String, preferringPosition position: AVCaptureDevice.Position) -> AVCaptureDevice? { fileprivate class func deviceWithMediaType(_ mediaType: String, preferringPosition position: AVCaptureDevice.Position) -> AVCaptureDevice? {
if #available(iOS 10.0, *) { let avDevice = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: AVMediaType(rawValue: mediaType), position: position)
let avDevice = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera, for: AVMediaType(rawValue: mediaType), position: position) return avDevice
return avDevice
} else {
// Fallback on earlier versions
let avDevice = AVCaptureDevice.devices(for: AVMediaType(rawValue: mediaType))
var avDeviceNum = 0
for device in avDevice {
print("deviceWithMediaType Position: \(device.position.rawValue)")
if device.position == position {
break
} else {
avDeviceNum += 1
}
}
return avDevice[avDeviceNum]
}
//return AVCaptureDevice.devices(for: AVMediaType(rawValue: mediaType), position: position).first
}
/// Enable or disable flash for photo
fileprivate func changeFlashSettings(device: AVCaptureDevice, mode: FlashMode) {
do {
try device.lockForConfiguration()
device.flashMode = mode.AVFlashMode
device.unlockForConfiguration()
} catch {
print("[SwiftyCam]: \(error)")
}
} }
/// Enable flash /// Enable flash
@ -1012,14 +864,7 @@ fileprivate func changeFlashSettings(device: AVCaptureDevice, mode: FlashMode) {
} }
do{ do{
if #available(iOS 10.0, *) { try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.mixWithOthers, .allowBluetooth, .allowAirPlay, .allowBluetoothA2DP])
try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.mixWithOthers, .allowBluetooth, .allowAirPlay, .allowBluetoothA2DP])
} else {
let options: [AVAudioSession.CategoryOptions] = [.mixWithOthers, .allowBluetooth]
let category = AVAudioSession.Category.playAndRecord
let selector = NSSelectorFromString("setCategory:withOptions:error:")
AVAudioSession.sharedInstance().perform(selector, with: category, with: options)
}
try AVAudioSession.sharedInstance().setActive(true) try AVAudioSession.sharedInstance().setActive(true)
session.automaticallyConfiguresApplicationAudioSession = false session.automaticallyConfiguresApplicationAudioSession = false
} }
@ -1050,34 +895,15 @@ fileprivate func changeFlashSettings(device: AVCaptureDevice, mode: FlashMode) {
extension SwiftyCamViewController : SwiftyCamButtonDelegate { extension SwiftyCamViewController : SwiftyCamButtonDelegate {
/// Sets the maximum duration of the SwiftyCamButton /// Begin video when the button is pressed down
public func setMaxiumVideoDuration() -> Double { public func buttonDidBeginPress() {
return maximumVideoDuration
}
/// Set UITapGesture to take photo
public func buttonWasTapped() {
takePhoto()
}
/// Set UILongPressGesture start to begin video
public func buttonDidBeginLongPress() {
startVideoRecording() startVideoRecording()
} }
/// Set UILongPressGesture begin to begin end video /// End video when the button is released
public func buttonDidEndPress() {
public func buttonDidEndLongPress() {
stopVideoRecording()
}
/// Called if maximum duration is reached
public func longPressDidReachMaximumDuration() {
stopVideoRecording() stopVideoRecording()
} }
} }
@ -1117,13 +943,21 @@ extension SwiftyCamViewController {
/// Handle pinch gesture /// Handle pinch gesture
private var firstCaptureDevice: AVCaptureDevice? {
AVCaptureDevice.DiscoverySession(
deviceTypes: [.builtInDualCamera, .builtInWideAngleCamera],
mediaType: .video,
position: .unspecified
).devices.first
}
@objc fileprivate func zoomGesture(pinch: UIPinchGestureRecognizer) { @objc fileprivate func zoomGesture(pinch: UIPinchGestureRecognizer) {
guard pinchToZoom == true && self.currentCamera == .rear else { guard pinchToZoom == true && self.currentCamera == .rear else {
//ignore pinch //ignore pinch
return return
} }
do { do {
let captureDevice = AVCaptureDevice.devices().first let captureDevice = firstCaptureDevice
try captureDevice?.lockForConfiguration() try captureDevice?.lockForConfiguration()
zoomScale = min(maxZoomScale, max(1.0, min(beginZoomScale * pinch.scale, captureDevice!.activeFormat.videoMaxZoomFactor))) zoomScale = min(maxZoomScale, max(1.0, min(beginZoomScale * pinch.scale, captureDevice!.activeFormat.videoMaxZoomFactor)))
@ -1198,7 +1032,7 @@ extension SwiftyCamViewController {
let translationDifference = currentTranslation - previousPanTranslation let translationDifference = currentTranslation - previousPanTranslation
do { do {
let captureDevice = AVCaptureDevice.devices().first let captureDevice = firstCaptureDevice
try captureDevice?.lockForConfiguration() try captureDevice?.lockForConfiguration()
let currentZoom = captureDevice?.videoZoomFactor ?? 0.0 let currentZoom = captureDevice?.videoZoomFactor ?? 0.0

View file

@ -21,12 +21,12 @@ import AVFoundation
/// Delegate for SwiftyCamViewController /// Delegate for SwiftyCamViewController
public protocol SwiftyCamViewControllerDelegate: class { public protocol SwiftyCamViewControllerDelegate: AnyObject {
/** /**
SwiftyCamViewControllerDelegate function called when when SwiftyCamViewController session did start running. SwiftyCamViewControllerDelegate function called when when SwiftyCamViewController session did start running.
Photos and video capture will be enabled. Video capture will be enabled.
- Parameter swiftyCam: Current SwiftyCamViewController - Parameter swiftyCam: Current SwiftyCamViewController
*/ */
@ -34,22 +34,13 @@ public protocol SwiftyCamViewControllerDelegate: class {
/** /**
SwiftyCamViewControllerDelegate function called when when SwiftyCamViewController session did stops running. SwiftyCamViewControllerDelegate function called when when SwiftyCamViewController session did stops running.
Photos and video capture will be disabled. Video capture will be disabled.
- Parameter swiftyCam: Current SwiftyCamViewController - Parameter swiftyCam: Current SwiftyCamViewController
*/ */
func swiftyCamSessionDidStopRunning(_ swiftyCam: SwiftyCamViewController) func swiftyCamSessionDidStopRunning(_ swiftyCam: SwiftyCamViewController)
/**
SwiftyCamViewControllerDelegate function called when the takePhoto() function is called.
- Parameter swiftyCam: Current SwiftyCamViewController session
- Parameter photo: UIImage captured from the current session
*/
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didTake photo: UIImage)
/** /**
SwiftyCamViewControllerDelegate function called when SwiftyCamViewController begins recording video. SwiftyCamViewControllerDelegate function called when SwiftyCamViewController begins recording video.
@ -142,21 +133,14 @@ public extension SwiftyCamViewControllerDelegate {
// Optional // Optional
} }
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didTake photo: UIImage) {
// Optional
}
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didBeginRecordingVideo camera: SwiftyCamViewController.CameraSelection) { func swiftyCam(_ swiftyCam: SwiftyCamViewController, didBeginRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
// Optional // Optional
} }
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishRecordingVideo camera: SwiftyCamViewController.CameraSelection) { func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishRecordingVideo camera: SwiftyCamViewController.CameraSelection) {
// Optional // Optional
} }
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishProcessVideoAt url: URL) { func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFinishProcessVideoAt url: URL) {
// Optional // Optional
} }
@ -168,13 +152,11 @@ public extension SwiftyCamViewControllerDelegate {
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didSwitchCameras camera: SwiftyCamViewController.CameraSelection) { func swiftyCam(_ swiftyCam: SwiftyCamViewController, didSwitchCameras camera: SwiftyCamViewController.CameraSelection) {
// Optional // Optional
} }
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFocusAtPoint point: CGPoint) { func swiftyCam(_ swiftyCam: SwiftyCamViewController, didFocusAtPoint point: CGPoint) {
// Optional // Optional
} }
func swiftyCam(_ swiftyCam: SwiftyCamViewController, didChangeZoomLevel zoom: CGFloat) { func swiftyCam(_ swiftyCam: SwiftyCamViewController, didChangeZoomLevel zoom: CGFloat) {
// Optional // Optional
} }