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.
}
}
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
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)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With