Created
April 16, 2015 19:30
-
-
Save MihaelIsaev/273e4e8ddaaf062d2155 to your computer and use it in GitHub Desktop.
This is the example of camera view for iOS written in Swift
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import AVFoundation | |
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { | |
@IBOutlet weak var myView: UIView! | |
var session: AVCaptureSession? | |
var device: AVCaptureDevice? | |
var input: AVCaptureDeviceInput? | |
var output: AVCaptureMetadataOutput? | |
var prevLayer: AVCaptureVideoPreviewLayer? | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
createSession() | |
} | |
override func viewDidAppear(animated: Bool) { | |
super.viewDidAppear(animated) | |
prevLayer?.frame.size = myView.frame.size | |
} | |
func createSession() { | |
session = AVCaptureSession() | |
device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) | |
var error: NSError? = nil | |
input = AVCaptureDeviceInput(device: device, error: &error) | |
if error == nil { | |
session?.addInput(input) | |
} else { | |
println("camera input error: \(error)") | |
} | |
prevLayer = AVCaptureVideoPreviewLayer(session: session) | |
prevLayer?.frame.size = myView.frame.size | |
prevLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill | |
prevLayer?.connection.videoOrientation = transformOrientation(UIInterfaceOrientation(rawValue: UIApplication.sharedApplication().statusBarOrientation.rawValue)!) | |
myView.layer.addSublayer(prevLayer) | |
session?.startRunning() | |
} | |
func cameraWithPosition(position: AVCaptureDevicePosition) -> AVCaptureDevice? { | |
let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) | |
for device in devices { | |
if device.position == position { | |
return device as? AVCaptureDevice | |
} | |
} | |
return nil | |
} | |
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) { | |
coordinator.animateAlongsideTransition({ (context) -> Void in | |
self.prevLayer?.connection.videoOrientation = self.transformOrientation(UIInterfaceOrientation(rawValue: UIApplication.sharedApplication().statusBarOrientation.rawValue)!) | |
self.prevLayer?.frame.size = self.myView.frame.size | |
}, completion: { (context) -> Void in | |
}) | |
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator) | |
} | |
func transformOrientation(orientation: UIInterfaceOrientation) -> AVCaptureVideoOrientation { | |
switch orientation { | |
case .LandscapeLeft: | |
return .LandscapeLeft | |
case .LandscapeRight: | |
return .LandscapeRight | |
case .PortraitUpsideDown: | |
return .PortraitUpsideDown | |
default: | |
return .Portrait | |
} | |
} | |
@IBAction func switchCameraSide(sender: AnyObject) { | |
if let sess = session { | |
let currentCameraInput: AVCaptureInput = sess.inputs[0] as! AVCaptureInput | |
sess.removeInput(currentCameraInput) | |
var newCamera: AVCaptureDevice | |
if (currentCameraInput as! AVCaptureDeviceInput).device.position == .Back { | |
newCamera = self.cameraWithPosition(.Front)! | |
} else { | |
newCamera = self.cameraWithPosition(.Back)! | |
} | |
let newVideoInput = AVCaptureDeviceInput(device: newCamera, error: nil) | |
session?.addInput(newVideoInput) | |
} | |
} | |
} |
Excellent. Thank you
This is an update with iOS 12 and Swift 4
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
@IBOutlet weak var cameraView: UIView!
var session: AVCaptureSession?
var device: AVCaptureDevice?
var input: AVCaptureDeviceInput?
var output: AVCaptureMetadataOutput?
var prevLayer: AVCaptureVideoPreviewLayer?
override func viewDidLoad() {
super.viewDidLoad()
createSession()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
prevLayer?.frame.size = cameraView.frame.size
}
func createSession() {
session = AVCaptureSession()
device = AVCaptureDevice.default(for: AVMediaType.video)
do{
input = try AVCaptureDeviceInput(device: device!)
}
catch{
print(error)
}
if let input = input{
session?.addInput(input)
}
prevLayer = AVCaptureVideoPreviewLayer(session: session!)
prevLayer?.frame.size = cameraView.frame.size
prevLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
prevLayer?.connection?.videoOrientation = transformOrientation(orientation: UIInterfaceOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!)
cameraView.layer.addSublayer(prevLayer!)
session?.startRunning()
}
func cameraWithPosition(position: AVCaptureDevice.Position) -> AVCaptureDevice? {
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInTelephotoCamera, .builtInTrueDepthCamera, .builtInWideAngleCamera, ], mediaType: .video, position: position)
if let device = deviceDiscoverySession.devices.first {
return device
}
return nil
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: { (context) -> Void in
self.prevLayer?.connection?.videoOrientation = self.transformOrientation(orientation: UIInterfaceOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!)
self.prevLayer?.frame.size = self.cameraView.frame.size
}, completion: { (context) -> Void in
})
super.viewWillTransition(to: size, with: coordinator)
}
func transformOrientation(orientation: UIInterfaceOrientation) -> AVCaptureVideoOrientation {
switch orientation {
case .landscapeLeft:
return .landscapeLeft
case .landscapeRight:
return .landscapeRight
case .portraitUpsideDown:
return .portraitUpsideDown
default:
return .portrait
}
}
@IBAction func switchCameraSide(sender: AnyObject) {
if let sess = session {
let currentCameraInput: AVCaptureInput = sess.inputs[0]
sess.removeInput(currentCameraInput)
var newCamera: AVCaptureDevice
if (currentCameraInput as! AVCaptureDeviceInput).device.position == .back {
newCamera = self.cameraWithPosition(position: .front)!
} else {
newCamera = self.cameraWithPosition(position: .back)!
}
var newVideoInput: AVCaptureDeviceInput?
do{
newVideoInput = try AVCaptureDeviceInput(device: newCamera)
}
catch{
print(error)
}
if let newVideoInput = newVideoInput{
session?.addInput(newVideoInput)
}
}
}
}
Hi @romanus your code is helpful, thanks!
I want to record a video in press button in this view how can i do any idea ?
Update:
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {
@IBOutlet weak var cameraView: UIView!
var session: AVCaptureSession?
var device: AVCaptureDevice?
var input: AVCaptureDeviceInput?
var output: AVCaptureMetadataOutput?
var prevLayer: AVCaptureVideoPreviewLayer?
override func viewDidLoad() {
super.viewDidLoad()
createSession()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
prevLayer?.frame.size = cameraView.frame.size
}
func createSession() {
session = AVCaptureSession()
device = AVCaptureDevice.default(for: AVMediaType.video)
do{
input = try AVCaptureDeviceInput(device: device!)
}
catch{
print(error)
}
if let input = input{
session?.addInput(input)
}
prevLayer = AVCaptureVideoPreviewLayer(session: session!)
prevLayer?.frame.size = cameraView.frame.size
prevLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
prevLayer?.connection?.videoOrientation = transformOrientation(orientation: UIInterfaceOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!)
cameraView.layer.addSublayer(prevLayer!)
session?.startRunning()
}
func cameraWithPosition(position: AVCaptureDevice.Position) -> AVCaptureDevice? {
if #available(iOS 11.1, *) {
let deviceDiscoverySession = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInTelephotoCamera, .builtInTrueDepthCamera, .builtInWideAngleCamera, ], mediaType: .video, position: position)
if let device = deviceDiscoverySession.devices.first {
return device
}
else {
//add code here
}
return nil
}
func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: { (context) -> Void in
self.prevLayer?.connection?.videoOrientation = self.transformOrientation(orientation: UIInterfaceOrientation(rawValue: UIApplication.shared.statusBarOrientation.rawValue)!)
self.prevLayer?.frame.size = self.cameraView.frame.size
}, completion: { (context) -> Void in
})
super.viewWillTransition(to: size, with: coordinator)
}
return device
}
func transformOrientation(orientation: UIInterfaceOrientation) -> AVCaptureVideoOrientation {
switch orientation {
case .landscapeLeft:
return .landscapeLeft
case .landscapeRight:
return .landscapeRight
case .portraitUpsideDown:
return .portraitUpsideDown
default:
return .portrait
}
}
@IBAction func switchCameraSide(sender: AnyObject) {
if let sess = session {
let currentCameraInput: AVCaptureInput = sess.inputs[0]
sess.removeInput(currentCameraInput)
var newCamera: AVCaptureDevice
if (currentCameraInput as! AVCaptureDeviceInput).device.position == .back {
newCamera = self.cameraWithPosition(position: .front)!
} else {
newCamera = self.cameraWithPosition(position: .back)!
}
var newVideoInput: AVCaptureDeviceInput?
do{
newVideoInput = try AVCaptureDeviceInput(device: newCamera)
}
catch{
print(error)
}
if let newVideoInput = newVideoInput{
session?.addInput(newVideoInput)
}
}
}
}
Wow guys I just noticed that you're making updates in the comments! You are awesome! 🚀
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is helpful, thanks!