Слой предварительного просмотра не ограничен UIView - PullRequest
0 голосов
/ 05 февраля 2020

Мой код Swift ниже пытается ограничить previewLayer границами UIView, который называется видом с камеры. Однако этого не происходит. PreviewLayer намного больше, чем ограничение cameraView UIView. CameraView ограничивается ограничениями раскадровки. Я просто хочу, чтобы 2 объекта имели одинаковую позицию и размер.

enter image description here

enter image description here

           import AVFoundation;import UIKit
    class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {
    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {

    }


    var captureSession = AVCaptureSession()
    var sessionOutput = AVCaptureStillImageOutput()
    var movieOutput = AVCaptureMovieFileOutput()
    var previewLayer = AVCaptureVideoPreviewLayer()

    @IBOutlet var cameraView: UIView!



    override func viewWillAppear(_ animated: Bool) {


        let devices = AVCaptureDevice.devices(for: AVMediaType.video)
        for device in devices {
            if device.position == AVCaptureDevice.Position.front{


                do{

                    let input = try AVCaptureDeviceInput(device: device )

                    if captureSession.canAddInput(input){

                        captureSession.addInput(input)
                        sessionOutput.outputSettings = [AVVideoCodecKey : AVVideoCodecType.jpeg]

                        if captureSession.canAddOutput(sessionOutput){

                            captureSession.addOutput(sessionOutput)




                        }

                        captureSession.addOutput(movieOutput)

                        captureSession.startRunning()

                        _ = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
                        let documentURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
                        let fileURL = documentURL.appendingPathComponent("tempImage.jpg")
                        try? FileManager.default.removeItem(at: fileURL)
                        movieOutput.startRecording(to: fileURL, recordingDelegate: self)


                        let deadlineTime = DispatchTime.now() + .seconds(1)
                        DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
                            print("test")
                            self.movieOutput.stopRecording()
                        }



                    }

                }
                catch{

                    print("Error")
                }

            }
            viewDidAppear(animated )
        }

        func viewdidappeare(_ animated: Bool) {
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            self.previewLayer.frame = self.cameraView.bounds
            previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
            previewLayer.connection!.videoOrientation = AVCaptureVideoOrientation.portrait
            self.cameraView.layer.insertSublayer(self.previewLayer, at: 0)





        }






    func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) {
        print("FINISHED \(error)")
        // save video to camera roll
        if error == nil {
            UISaveVideoAtPathToSavedPhotosAlbum(outputFileURL.path!, nil, nil, nil)
        }
    }

    }
    }

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Вы можете попробовать это следующим образом:

override func viewDidAppear(_ animated: Bool) { 
       super.viewDidAppear(animated)
       self.previewLayer.frame = self.cameraView.bounds
 }

И

previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
previewLayer.connection!.videoOrientation = AVCaptureVideoOrientation.portrait
self.cameraView.layer.insertSublayer(self.previewLayer, at: 0)

Итак, Ваш полный обновленный код:

import AVFoundation
import UIKit

class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {

    }


    var captureSession = AVCaptureSession()
    var sessionOutput = AVCaptureStillImageOutput()
    var movieOutput = AVCaptureMovieFileOutput()
    var previewLayer = AVCaptureVideoPreviewLayer()

    @IBOutlet var cameraView: UIView!


    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.previewLayer.frame = self.cameraView.bounds

    }

    override func viewWillAppear(_ animated: Bool) {


        let devices = AVCaptureDevice.devices(for: AVMediaType.video)
        for device in devices {
            if device.position == AVCaptureDevice.Position.front{


                do{

                    let input = try AVCaptureDeviceInput(device: device )

                    if captureSession.canAddInput(input){

                        captureSession.addInput(input)
                        sessionOutput.outputSettings = [AVVideoCodecKey : AVVideoCodecType.jpeg]

                        if captureSession.canAddOutput(sessionOutput){

                            captureSession.addOutput(sessionOutput)

                            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)

                            previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
                            previewLayer.connection!.videoOrientation = AVCaptureVideoOrientation.portrait
                            self.cameraView.layer.insertSublayer(self.previewLayer, at: 0)


                        }

                        captureSession.addOutput(movieOutput)

                        captureSession.startRunning()

                        _ = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
                        let documentURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
                        let fileURL = documentURL.appendingPathComponent("tempImage.jpg")
                        try? FileManager.default.removeItem(at: fileURL)
                        movieOutput.startRecording(to: fileURL, recordingDelegate: self)


                        let deadlineTime = DispatchTime.now() + .seconds(1)
                        DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
                            print("test")
                            self.movieOutput.stopRecording()
                        }



                    }

                }
                catch{

                    print("Error")
                }

            }
        }
    }

    func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) {
        print("FINISHED \(error)")
        // save video to camera roll
        if error == nil {
            UISaveVideoAtPathToSavedPhotosAlbum(outputFileURL.path!, nil, nil, nil)
        }
    }
}
0 голосов
/ 06 февраля 2020

Проблема заключается в том, что подслои не изменяются автоматически, когда их родитель изменяет свой размер. Вы должны сделать это вручную, например, в layoutSublayers:

override func layoutSublayers(of layer: CALayer) {
    previewLayer.bounds = cameraView.frame
}
...