Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fill view with IOS camera preview layer

Tags:

ios

swift

Working through a tutorial, and I'm trying to make a full screen preview. Currently, my camera seems very square, and I am fairly confident this might be an aspect fit issue. The camera seems to hit the right and left bounds. How can I pin the my preview to the bottom of the nav bar and the bottom of the screen, and the sides?

import UIKit
import AVFoundation

class HomeViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {

    let captureSession = AVCaptureSession()
    var previewLayer:CALayer!

    var captureDevice:AVCaptureDevice!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        prepareCamera()
    }

    func prepareCamera(){
        captureSession.sessionPreset = AVCaptureSessionPresetPhoto

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

    func beginSession () {
        do {
            let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice)
            captureSession.addInput(captureDeviceInput)
        } catch {
            print(error.localizedDescription)
        }

        if let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) {
            self.previewLayer = previewLayer
            self.view.layer.addSublayer(self.previewLayer)
            self.previewLayer.frame = self.view.layer.frame
//ADD CONSTRAINTS HERE

            captureSession.startRunning()

            let dataOutput = AVCaptureVideoDataOutput()
            dataOutput.videoSettings = [(kCVPixelBufferPixelFormatTypeKey as NSString):NSNumber(value:kCVPixelFormatType_32BGRA)]

            dataOutput.alwaysDiscardsLateVideoFrames = true

            if captureSession.canAddOutput(dataOutput) {
                captureSession.addOutput(dataOutput)
            }

            captureSession.commitConfiguration()

//            let queue = DispatchQueue(label: com.willkie.captureQueue)
//            dataOutput.setSampleBufferDelegate(self, queue: queue)
        }
    }

    func captureOutput(_ captureOutput: AVCaptureOutput!, didDrop sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

why???

like image 242
user1093111 Avatar asked Dec 10 '22 10:12

user1093111


2 Answers

I think probably changing your this particular line should work -

self.previewLayer.frame = self.view.layer.frame 

to

self.previewLayer.frame = self.view.layer.bounds

Also you should add your sublayer only after you have adjusted the frame in the above code. Right now you have added before.

self.view.layer.addSublayer(self.previewLayer)

And you also need to add gravity

previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

If it still doesn't work, add a custom view to your viewcontroller and set it to the size on which you want to show the camera preview and then you can use this -

self.previewLayer.frame = self.customViewOutlet.layer.bounds
like image 196
Kapil G Avatar answered Dec 28 '22 19:12

Kapil G


I solved it with Swift 4 like this:

Don't forget to import AVKit

override func viewDidLoad() {
    super.viewDidLoad()

    let captureSession = AVCaptureSession()

    guard let captureDevice = AVCaptureDevice.default(for: .video),
        let input = try? AVCaptureDeviceInput(device: captureDevice) else {return}

    captureSession.addInput(input)
    captureSession.startRunning()

    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = view.frame
    previewLayer.videoGravity = .resizeAspectFill
    view.layer.addSublayer(previewLayer)

}
like image 44
JulianKro Avatar answered Dec 28 '22 18:12

JulianKro