iOS Swift Tutorial: Basic Custom Camera App – AVFoundation

In this tutorial you are going to create a custom camera interface. You can use it for your own camera driven apps and add exactly the style you want.

➡️ Web: http://www.brianadvent.com

➡️ Tutorial Files
https://github.com/brianadvent/CustomCamera

✉️ COMMENTS ✉️
If you have questions about the video or Cocoa programming, please comment below.

Comments

Dirtstar Teatray says:

Here is my updated Code :-)import UIKit
import AVFoundation@available(iOS 10.0, *)
class brian: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
   
    let captureSession = AVCaptureSession()
    var previewLayer:CALayer!   //! means we can initialise this later
    var captureDevice:AVCaptureDevice!
    var takePhoto = false    override func viewDidLoad() {
        super.viewDidLoad()
    }
   
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        prepareCamera()
    }
   
    func prepareCamera() {
        captureSession.sessionPreset = AVCaptureSession.Preset.photo
       
        let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back).devices
        captureDevice = availableDevices.first
        beginSession()
    }
   
    func beginSession() {
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice)
            captureSession.addInput(captureDeviceInput)
        } catch {
            print(error.localizedDescription)
        }
        let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        self.previewLayer = previewLayer
        self.view.layer.addSublayer(self.previewLayer)
        self.previewLayer.frame = self.view.layer.frame
        captureSession.startRunning()
       
        let dataOutput = AVCaptureVideoDataOutput()
        dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString):NSNumber(value:kCVPixelFormatType_32BGRA)] as [String : Any]
        dataOutput.alwaysDiscardsLateVideoFrames = true
       
        if captureSession.canAddOutput(dataOutput) {
            captureSession.addOutput(dataOutput)
        }
       
        captureSession.commitConfiguration()
       
        let queue = DispatchQueue(label: “clockworksciencce”)
        dataOutput.setSampleBufferDelegate(self, queue: queue)
       
       
    } //end beginSession()    @IBAction func takePhoto(_ sender: Any) {
        takePhoto = true
    }
   
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        if takePhoto {
            takePhoto = false
           
            if let image = self.getImageFromSampleBuffer(buffer: sampleBuffer) {
               
                let photoVC = UIStoryboard(name: “Main”, bundle: nil).instantiateViewController(withIdentifier: “PhotoVC”) as! PhotoViewController
               
                photoVC.takenPhoto = image
               
                DispatchQueue.main.async {
                    self.present(photoVC, animated: true, completion: {
                        self.stopCaptureSession()
                    })
                   
                }
            }
           
        }
    } //end captureOutput()
   
   
    func getImageFromSampleBuffer(buffer:CMSampleBuffer) -> UIImage?  //CM stands for Core Media
    {
        if let pixelBuffer = CMSampleBufferGetImageBuffer(buffer) {
            let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
            let context = CIContext()
            let imageRect = CGRect(x: 0, y: 0, width: CVPixelBufferGetWidth(pixelBuffer), height: CVPixelBufferGetHeight(pixelBuffer))
           
            if let image = context.createCGImage(ciImage, from: imageRect) {
                return UIImage(cgImage: image, scale: UIScreen.main.scale, orientation: .right )
            }
        }
        return nil  //if it doesn’t work return a nil
    }
   
    func stopCaptureSession () {
        self.captureSession.stopRunning()
       
        if let inputs = captureSession.inputs as? [AVCaptureDeviceInput] {
            for input in inputs {
                self.captureSession.removeInput(input)
            }
        }
    }
   
}

Dirtstar Teatray says:

I’m running XCode 9.4.1 and I just had to make a few tweaks to get this working in the latest version but it works just as good as in the tutorial above. I changed the name of the class to brian in tribute to the maestro.

Robert Berguer says:

what is your accent?

Kev stuckbykevDOTcom says:

hi brian great videos. i have a question, I have used this video’s code in my iPad app but it comes to a slow crawl when the view Controller loads the camera. It takes at lease 30 seconds for the view controller to finally animate in. (Also, I’m testing this in simulator and not on a real device) any thoughts??

Bhautik Ziniya says:

Hi Brian i want to capture a square video using sample buffer line insta can you guid how can i achive square video.

Thomas Bender says:

Hi Brian, thanks for the great video. Unfortunately I get the following error message, regrettably I don’t get it fixed. Can you or someone else here give me a tip. Thank you
Error: Initializer for conditional binding must have Optional type, not ‘[AVCaptureDevice]’
in the if statement ” if let availableDevices = AVCaptureDevice.DiscoverySession(deviceTypes:[.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back).devices
{ ….” in ViewController.swift

James Noble says:

your voice is so relaxing, you should do asmr instead of programming vids lmao

Daniel Erazo says:

i tried getting through the whole thing but all along the way xcode compiler just kept screaming at me. Not sure if this video even works anymore to be honest

Mohameth Seck says:

What about recording video

Swisstipi Designer says:

God this is confusing… You completely lost me when you started setting up the dataOuput. But other than that great tutorial!

Mikael Teklehaimanot says:

Thanks Brian! Your vids are awesome!

marc B says:

That is pretty awesome! Thanks

BGT Productions says:

How could I make the camera viewing on a UIView? I’m tinkering with writing imageView.layer.addSublayer(self.previewLayer) but that doesn’t seem to be enough. Any suggestions? (imageView is a UIView)

Dae Nou says:

Hi Brian, great explanations, thanks! I would like to use the camera also in landscapeviews. How I supposed to it? Thanks für your answer.

Matthew Drill says:

This worked fine in the project I started just to follow this tutorial, but when I tried to incorporate this into an already existing project, I am getting an error “Type ‘String’ has no member ‘.builtInWideAngleCamera'” at the line

if let availableDevices = AVCaptureDeviceDiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: .back).devices{
captureDevice = availableDevices.first
beginSession()
}

in the prepareCamera function

Do you have any idea how to fix this?

Daniel says:

Such a shame that AVFoundation is so complex. Great tutorial, Brian!

Tomer Nakash says:

How do I program a camera app that will take a photo with auto focus and right after that it will take a photo with the shortest focal length the phone can capture??

shivam khandelwal says:

An AVCaptureInput instance may not be added to more than one session . getting an error….help me to resolve?

Adie Olami says:

Hi brian, I tried accessing photos from photo library with a button but I get error. How can I use photo library with avfoundation

Amanda Zong says:

Using this tutorial, I was able to program an app that takes a picture and shows it to me in Photo View Controller. However, when I click the “go back” button and it brings me back to the View Controller screen, the video feed is frozen and I’m unable to take another picture. How can I fix this? Thanks!

TheSweeneyT says:

anyone knows which part of code i should change to have a video camera recorder?

dont mug yourself says:

mine comes up with “terminating with uncaught exception of type NSException”

Mitsuko Megumi says:

Thanks, Brian!

Anonymous says:

my capture output delegate function never gets called

Paul Martin Patio says:

Good Day Sir such a wonderful tutorial. May I ask sir can i add a custom frame border in the image before saving. Thanks for reply 😀

Justin Geeslin says:

Thanks Brian!

Write a comment

*

Human Verification: In order to verify that you are a human and not a spam bot, please enter the answer into the following box below based on the instructions contained in the graphic.


Do you like our videos?
Do you want to see more like that?

Please click below to support us on Facebook!

Send this to a friend

▷ Other ReviewsVehicles   Show Cars   Motorbikes   Scooters   Rims & Tires   Luxury BoatsFashion   Sunglasses   Luxury Watches   Luxury Purses   Jeans Wear   High Heels   Perfumes   Jewellery   Cosmetics   Shaving Helpers   Fashion HatsFooding   Chef Club   Fooding Helpers   Coktails & LiquorsSports   Sport Shoes   Fitness & Detox   Golf Gear   Racquets   Diving Equipment   Ski Gear   Snowboards   Surf Boards   Rollers & SkatesEntertainment   DIY Guides   Zik Instruments   Published Books   Music Albums   Cine Movies   Trading Helpers   Make Money   Fishing Equipment   Paintball Supplies   Trading Card Games   Telescopes   Knives   VapesHigh Tech   Flat Screens   Tech Devices   Camera Lenses   Printers   USB Devices   PC Hardware   Network Gear   Cloud Servers   Software Helpers   Programmer Helpers   Mobile Apps   Hearing AidsHome   Home Furniture   Home Appliances   Beddings   Floor Layings   Barbecues   Aquarium Gear   Safe Boxes   Office Supplies   Security Locks   Cleaning ProductsKids   Baby Strollers   Child Car Seats   Remote ControlledTravel   Luggages & Bags   Airlines Seats   Hotel Rooms   Fun Trips   Cruise Ships   Mexico Tours