Захват видео с AVFoundation

Я смотрел на Stack, и я нашел похожие вопросы к этому, но никто не работал у меня. Я полный новичок для Swift 3.0. По сути, я пытаюсь записать видео с помощью AVFoundation. До сих пор мне удалось захватить неподвижное изображение, и это код, который у меня есть до сих пор

func beginSession() {
    do {
        let deviceInput = try  AVCaptureDeviceInput(device: captureDevice) as AVCaptureDeviceInput
        if captureSession.inputs.isEmpty {
            self.captureSession.addInput(deviceInput)
        }
        stillImageOutput.outputSettings = [AVVideoCodecKey:AVVideoCodecJPEG]

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

    }
    catch {
        print("error: \(error.localizedDescription)")
    }

    guard let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) else {
        print("no preview layer")
        return
    }

    self.view.layer.addSublayer(previewLayer)
    previewLayer.frame = self.view.layer.frame
    captureSession.startRunning()

    // Subviews
    self.view.addSubview(imgOverlay)
    self.view.addSubview(blur)
    self.view.addSubview(label)
    self.view.addSubview(Flip)
    self.view.addSubview(btnCapture)
}

и

 // SAVE PHOTO
func saveToCamera() {
    if let videoConnection = stillImageOutput.connection(withMediaType: AVMediaTypeVideo) {
        stillImageOutput.captureStillImageAsynchronously(from: videoConnection, completionHandler: { (CMSampleBuffer, Error) in
            if let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(CMSampleBuffer) {
                if let cameraImage = UIImage(data: imageData) {
                    self.flippedImage = UIImage(cgImage: cameraImage.cgImage!, scale: cameraImage.scale, orientation: UIImageOrientation.rightMirrored)
                    UIImageWriteToSavedPhotosAlbum(self.flippedImage, nil, nil, nil)

                }
            }
        })
    }

}

Ответ 1

Я собираюсь упростить вам задачу, разместив весь код, необходимый для создания видеомагнитофона в AVFoundation. Этот код должен работать, если вы просто скопируете и вставите его как есть. Единственное, что вам нужно помнить, это то, что вам нужно подключить выход camPreview к UIView в ViewController в StoryBoard. Этот UIView должен занимать все содержимое экрана. Я объясню код, чтобы вы могли провести собственное расследование и изменить видеорегистратор в соответствии с потребностями своего приложения. Вам также необходимо убедиться, что вы прикрепили соответствующие разрешения на конфиденциальность к info.plist, которые являются Конфиденциальностью - Описание использования микрофона и Конфиденциальностью - Описание использования камеры, иначе вы увидите только черный экран.

ПРИМЕЧАНИЕ. Справа внизу я добавил способ воспроизведения записанного видео под заголовком "Воспроизведение записанного видео".

РЕДАКТИРОВАТЬ - Я забыл две вещи, которые привели к сбою во время записи, но я добавил их сейчас.

Swift 4

import UIKit

import AVFoundation

class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

    @IBOutlet weak var camPreview: UIView!

    let cameraButton = UIView()

    let captureSession = AVCaptureSession()

    let movieOutput = AVCaptureMovieFileOutput()

    var previewLayer: AVCaptureVideoPreviewLayer!

    var activeInput: AVCaptureDeviceInput!

    var outputURL: URL!

    override func viewDidLoad() {
        super.viewDidLoad()

        if setupSession() {
            setupPreview()
            startSession()
        }

        cameraButton.isUserInteractionEnabled = true

        let cameraButtonRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.startCapture))

        cameraButton.addGestureRecognizer(cameraButtonRecognizer)

        cameraButton.frame = CGRect(x: 0, y: 0, width: 100, height: 100)

        cameraButton.backgroundColor = UIColor.red

        camPreview.addSubview(cameraButton)

    }

    func setupPreview() {
        // Configure previewLayer
        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        previewLayer.frame = camPreview.bounds
        previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        camPreview.layer.addSublayer(previewLayer)
    }

    //MARK:- Setup Camera

    func setupSession() -> Bool {

        captureSession.sessionPreset = AVCaptureSession.Preset.high

        // Setup Camera
        let camera = AVCaptureDevice.default(for: AVMediaType.video)!

        do {

            let input = try AVCaptureDeviceInput(device: camera)

            if captureSession.canAddInput(input) {
                captureSession.addInput(input)
                activeInput = input
            }
        } catch {
            print("Error setting device video input: \(error)")
            return false
        }

        // Setup Microphone
        let microphone = AVCaptureDevice.default(for: AVMediaType.audio)!

        do {
            let micInput = try AVCaptureDeviceInput(device: microphone)
            if captureSession.canAddInput(micInput) {
                captureSession.addInput(micInput)
            }
        } catch {
            print("Error setting device audio input: \(error)")
            return false
        }


        // Movie output
        if captureSession.canAddOutput(movieOutput) {
            captureSession.addOutput(movieOutput)
        }

        return true
    }

    func setupCaptureMode(_ mode: Int) {
        // Video Mode

    }

    //MARK:- Camera Session
    func startSession() {

        if !captureSession.isRunning {
            videoQueue().async {
                self.captureSession.startRunning()
            }
        }
    }

    func stopSession() {
        if captureSession.isRunning {
            videoQueue().async {
                self.captureSession.stopRunning()
            }
        }
    }

    func videoQueue() -> DispatchQueue {
        return DispatchQueue.main
    }

    func currentVideoOrientation() -> AVCaptureVideoOrientation {
        var orientation: AVCaptureVideoOrientation

        switch UIDevice.current.orientation {
            case .portrait:
                orientation = AVCaptureVideoOrientation.portrait
            case .landscapeRight:
                orientation = AVCaptureVideoOrientation.landscapeLeft
            case .portraitUpsideDown:
                orientation = AVCaptureVideoOrientation.portraitUpsideDown
            default:
                 orientation = AVCaptureVideoOrientation.landscapeRight
         }

         return orientation
     }

    @objc func startCapture() {

        startRecording()

    }

    //EDIT 1: I FORGOT THIS AT FIRST

    func tempURL() -> URL? {
        let directory = NSTemporaryDirectory() as NSString

        if directory != "" {
            let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
            return URL(fileURLWithPath: path)
        }

        return nil
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        let vc = segue.destination as! VideoPlaybackViewController

        vc.videoURL = sender as? URL

    }

    func startRecording() {

        if movieOutput.isRecording == false {

            let connection = movieOutput.connection(with: AVMediaType.video)

            if (connection?.isVideoOrientationSupported)! {
                connection?.videoOrientation = currentVideoOrientation()
            }

            if (connection?.isVideoStabilizationSupported)! {
                connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
            }

            let device = activeInput.device

            if (device.isSmoothAutoFocusSupported) {

                do {
                    try device.lockForConfiguration()
                    device.isSmoothAutoFocusEnabled = false
                    device.unlockForConfiguration()
                } catch {
                   print("Error setting configuration: \(error)")
                }

            }

            //EDIT2: And I forgot this
            outputURL = tempURL()
            movieOutput.startRecording(to: outputURL, recordingDelegate: self)

            }
            else {
                stopRecording()
            }

       }    

   func stopRecording() {

       if movieOutput.isRecording == true {
           movieOutput.stopRecording()
        }
   }

    func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {

    }

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

        if (error != nil) {

            print("Error recording movie: \(error!.localizedDescription)")

        } else {

            let videoRecorded = outputURL! as URL

            performSegue(withIdentifier: "showVideo", sender: videoRecorded)

        }

    }

}

Свифт 3

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

@IBOutlet weak var camPreview: UIView!

let cameraButton = UIView()

let captureSession = AVCaptureSession()

let movieOutput = AVCaptureMovieFileOutput()

var previewLayer: AVCaptureVideoPreviewLayer!

var activeInput: AVCaptureDeviceInput!

var outputURL: URL!

override func viewDidLoad() {
    super.viewDidLoad()

    if setupSession() {
        setupPreview()
        startSession()
    }

    cameraButton.isUserInteractionEnabled = true

    let cameraButtonRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.startCapture))

    cameraButton.addGestureRecognizer(cameraButtonRecognizer)

    cameraButton.frame = CGRect(x: 0, y: 0, width: 100, height: 100)

    cameraButton.backgroundColor = UIColor.red

    camPreview.addSubview(cameraButton)

}

func setupPreview() {
    // Configure previewLayer
    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = camPreview.bounds
    previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
    camPreview.layer.addSublayer(previewLayer)
}

//MARK:- Setup Camera

func setupSession() -> Bool {

    captureSession.sessionPreset = AVCaptureSessionPresetHigh

    // Setup Camera
    let camera = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)

    do {
        let input = try AVCaptureDeviceInput(device: camera)
        if captureSession.canAddInput(input) {
            captureSession.addInput(input)
            activeInput = input
        }
    } catch {
        print("Error setting device video input: \(error)")
        return false
    }

    // Setup Microphone
    let microphone = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)

    do {
        let micInput = try AVCaptureDeviceInput(device: microphone)
        if captureSession.canAddInput(micInput) {
            captureSession.addInput(micInput)
        }
    } catch {
        print("Error setting device audio input: \(error)")
        return false
    }


    // Movie output
    if captureSession.canAddOutput(movieOutput) {
        captureSession.addOutput(movieOutput)
    }

    return true
}

func setupCaptureMode(_ mode: Int) {
        // Video Mode

}

//MARK:- Camera Session
func startSession() {


    if !captureSession.isRunning {
        videoQueue().async {
            self.captureSession.startRunning()
        }
    }
}

func stopSession() {
    if captureSession.isRunning {
        videoQueue().async {
            self.captureSession.stopRunning()
        }
    }
}

func videoQueue() -> DispatchQueue {
    return DispatchQueue.main
}



func currentVideoOrientation() -> AVCaptureVideoOrientation {
    var orientation: AVCaptureVideoOrientation

    switch UIDevice.current.orientation {
    case .portrait:
        orientation = AVCaptureVideoOrientation.portrait
    case .landscapeRight:
        orientation = AVCaptureVideoOrientation.landscapeLeft
    case .portraitUpsideDown:
        orientation = AVCaptureVideoOrientation.portraitUpsideDown
    default:
        orientation = AVCaptureVideoOrientation.landscapeRight
    }

    return orientation
}

func startCapture() {

    startRecording()

}

//EDIT 1: I FORGOT THIS AT FIRST

func tempURL() -> URL? {
    let directory = NSTemporaryDirectory() as NSString

    if directory != "" {
        let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
        return URL(fileURLWithPath: path)
    }

    return nil
}


func startRecording() {

    if movieOutput.isRecording == false {

        let connection = movieOutput.connection(withMediaType: AVMediaTypeVideo)
        if (connection?.isVideoOrientationSupported)! {
            connection?.videoOrientation = currentVideoOrientation()
        }

        if (connection?.isVideoStabilizationSupported)! {
            connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
        }

        let device = activeInput.device
        if (device?.isSmoothAutoFocusSupported)! {
            do {
                try device?.lockForConfiguration()
                device?.isSmoothAutoFocusEnabled = false
                device?.unlockForConfiguration()
            } catch {
                print("Error setting configuration: \(error)")
            }

        }

        //EDIT2: And I forgot this
        outputURL = tempURL()
        movieOutput.startRecording(toOutputFileURL: outputURL, recordingDelegate: self)

    }
    else {
        stopRecording()
    }

}

func stopRecording() {

    if movieOutput.isRecording == true {
        movieOutput.stopRecording()
    }
}

func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {

}

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    if (error != nil) {
        print("Error recording movie: \(error!.localizedDescription)")
    } else {

        _ = outputURL as URL

    }
    outputURL = nil
}



}

Вот как вы должны настроить контроллер представления

Setup your View Controller with campPreview

Разрешения для вашего Info.plist

plist permissions

Настройка записи делегатов

Вам необходимо соответствовать AVCaptureFileOutputRecordingDelegate. Согласно документам Apple, он определяет интерфейс для делегатов AVCaptureFileOutput, чтобы реагировать на события, которые происходят в процессе записи одного файла. Он поставляется с двумя методами, которые необходимо реализовать, и это последние два метода в нижней части кода. Во-первых,

func capture(_ captureOutput: AVCaptureFileOutput!, didStartRecordingToOutputFileAt fileURL: URL!, fromConnections connections: [Any]!) {
}

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

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    if (error != nil) {
        print("Error recording movie: \(error!.localizedDescription)")
    } else {

        _ = outputURL as URL

    }
    outputURL = nil
}

Это вызывается, когда видео закончило запись. В примере кода, который я дал, видео перестает записываться после повторного нажатия на красную квадратную кнопку. Когда видео прекратило запись, вы получите URL выходного файла. Это представляет ваше видео. Вы можете использовать это, чтобы, возможно, перейти к другому View Controller для воспроизведения видео в AVPlayer. Или вы можете сохранить его. В этом примере вы заметите, что я не так много сделал с выходным URL.

Чтобы начать запись видео, я использовал программно созданную кнопку, которая отображается в виде красного квадрата в левом углу и отвечает на UITapGesture. Вы можете сделать лучшую кнопку в своем приложении.

Настройка сеанса

Видеорегистратору нужен сеанс захвата, который я настроил в setupSession(). Здесь вы добавляете устройства ввода AVCapture, которые включают камеру и микрофон. Согласно Apple, AVCaptureDeviceInput является конкретным подклассом AVCaptureInput, который вы используете для захвата данных из объекта AVCaptureDevice. Тем не менее, пользователь должен предоставить вам доступ к их использованию, поэтому в вашем info.plist вы должны добавить Конфиденциальность - Описание использования микрофона и Конфиденциальность - Описание использования камеры и указать причину, по которой вы хотите использовать видеомагнитофон и микрофон. Если вы этого не сделаете, вы получите только черный экран. Предварительная установка сеанса является постоянным значением, указывающим уровень качества или битрейт вывода. Я установил это на высокий уровень, но есть и другие варианты, которые вы можете изучить. Аргумент movieOutput имеет тип AVCaptureMovieFileOutput, который, согласно Apple, является конкретным подклассом AVCaptureFileOutput, который используется для захвата данных в фильм QuickTime. Это то, что на самом деле позволяет вам записывать и сохранять видео.

Настройка предварительного просмотра

Здесь вы настраиваете слой предварительного просмотра камеры, что делается в setupPreview(). Вы устанавливаете слой предварительного просмотра с созданным вами сеансом захвата с помощью следующего AVCaptureVideoPreviewLayer (session: captureSession).

Начиная сессию

Последний шаг - запустить сеанс, который выполняется в startSession(). Вы проверяете, запущен ли уже сеанс, а если нет, то запускаете его.

if !captureSession.isRunning {
    videoQueue().async {
        self.captureSession.startRunning()
    }
}

Начало записи

Когда вы нажимаете красную кнопку, вызывается метод startRecording(). Здесь я добавил методы для обработки ориентации видео и стабилизации видео. Наконец, мы снова видим переменную movieOutput, которую мы установили ранее в нашем сеансе. Мы вызываем его для записи нашего фильма в outputURL и говорим, что наши методы-делегаты для обработки начала и конца записи находятся в одном контроллере представления (эти два последних метода).

Остановить запись

Так уж получилось, что когда вы снова нажмете красную кнопку, снова вызывается startRecoding, но он заметит, что что-то записывается, и вызовет stopRecording.

Воспроизведение записанного видео

Я щедрый сегодня, поэтому я добавлю это тоже.

Создайте новый контроллер представления и назовите его VideoPlayback. Подключите его к своему первому ViewController, используя переход в раскадровке. Дайте Sege идентификатор "showVideo". Создайте UIView и заполните экран VideoPlayback и создайте выход для его контроллера представления, называемого videoView. Добавьте следующий код в ваш новый контроллер представления VideoPlayback:

Swift 4

import UIKit
import AVFoundation

class VideoPlayback: UIViewController {

    let avPlayer = AVPlayer()
    var avPlayerLayer: AVPlayerLayer!

    var videoURL: URL!
    //connect this to your uiview in storyboard
    @IBOutlet weak var videoView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        avPlayerLayer = AVPlayerLayer(player: avPlayer)
        avPlayerLayer.frame = view.bounds
        avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
        videoView.layer.insertSublayer(avPlayerLayer, at: 0)

        view.layoutIfNeeded()

        let playerItem = AVPlayerItem(url: videoURL as URL)
        avPlayer.replaceCurrentItem(with: playerItem)

        avPlayer.play()
    }
}

Свифт 3

import UIKit
import AVFoundation

class VideoPlayback: UIViewController {

    let avPlayer = AVPlayer()
    var avPlayerLayer: AVPlayerLayer!

    var videoURL: URL!
    //connect this to your uiview in storyboard
    @IBOutlet weak var videoView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        avPlayerLayer = AVPlayerLayer(player: avPlayer)
        avPlayerLayer.frame = view.bounds
        avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        videoView.layer.insertSublayer(avPlayerLayer, at: 0)

        view.layoutIfNeeded()

        let playerItem = AVPlayerItem(url: videoURL as URL)
        avPlayer.replaceCurrentItem(with: playerItem)

        avPlayer.play()
    }
}

Теперь вернитесь к последнему методу делегата и измените его следующим образом:

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {

    if (error != nil) {
        print("Error recording movie: \(error!.localizedDescription)")
    } else {

        let videoRecorded = outputURL! as URL

        performSegue(withIdentifier: "showVideo", sender: videoRecorded)
    }
}

Наконец, создайте метод подготовки к переходу, который инициализирует videoURL, который будет воспроизводиться с AVPlayer.

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    let vc = segue.destination as! VideoPlayback
    vc.videoURL = sender as! URL
}

Теперь, чтобы проверить, вернитесь и начните запись видео. При втором касании красного квадрата будет выполнена передача, и вы увидите, что записанное видео воспроизводится автоматически.

Ответ 2

Основываясь на удивительном ответе @gwinyai, я сделал подобный фреймворк Camera. https://github.com/eonist/HybridCamera. Он также поддерживает фотографирование и не имеет проблемы с ошибкой, описанной @Makim Kniazev, которая была вызвана этой строкой:

if (connection?.isVideoStabilizationSupported)! {
    connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
}

Ответ 3

От @gwinyai ответ обновлен до последней версии (swift 4)

import UIKit
import AVFoundation


class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

@IBOutlet weak var camPreview: UIView!
let captureSession = AVCaptureSession()
let movieOutput = AVCaptureMovieFileOutput()

var previewLayer: AVCaptureVideoPreviewLayer!
var activeInput: AVCaptureDeviceInput!
var outputURL: URL!

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

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
func setupPreview() {
    // Configure previewLayer
    previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    previewLayer.frame = camPreview.bounds
    previewLayer.videoGravity = .resizeAspectFill
    camPreview.layer.addSublayer(previewLayer)
}

//MARK:- Setup Camera

func setupSession() -> Bool {
    captureSession.sessionPreset = AVCaptureSession.Preset.high

    // Setup Camera
    let camera = AVCaptureDevice.default(for: .video)

    do {
        let input = try AVCaptureDeviceInput(device: camera!)
        if captureSession.canAddInput(input) {
            captureSession.addInput(input)
            activeInput = input
        }
    } catch {
        print("Error setting device video input: \(error)")
        return false
    }

    // Setup Microphone
    let microphone = AVCaptureDevice.default(for: .audio)

    do {
        let micInput = try AVCaptureDeviceInput(device: microphone!)
        if captureSession.canAddInput(micInput) {
            captureSession.addInput(micInput)
        }
    } catch {
        print("Error setting device audio input: \(error)")
        return false
    }


    // Movie output
    if captureSession.canAddOutput(movieOutput) {
        captureSession.addOutput(movieOutput)
    }

    return true
}

func setupCaptureMode(_ mode: Int) {
    // Video Mode

}

//MARK:- Camera Session
func startSession() {


    if !captureSession.isRunning {
        videoQueue().async {
            self.captureSession.startRunning()
        }
    }
}

func stopSession() {
    if captureSession.isRunning {
        videoQueue().async {
            self.captureSession.stopRunning()
        }
    }
}

func videoQueue() -> DispatchQueue {
    return DispatchQueue.main
}



func currentVideoOrientation() -> AVCaptureVideoOrientation {
    var orientation: AVCaptureVideoOrientation

    switch UIDevice.current.orientation {
    case .portrait:
        orientation = AVCaptureVideoOrientation.portrait
    case .landscapeRight:
        orientation = AVCaptureVideoOrientation.landscapeLeft
    case .portraitUpsideDown:
        orientation = AVCaptureVideoOrientation.portraitUpsideDown
    default:
        orientation = AVCaptureVideoOrientation.landscapeRight
    }

    return orientation
}

func startCapture() {

    startRecording()

}

//EDIT 1: I FORGOT THIS AT FIRST

func tempURL() -> URL? {
    let directory = NSTemporaryDirectory() as NSString

    if directory != "" {
        let path = directory.appendingPathComponent(NSUUID().uuidString + ".mp4")
        return URL(fileURLWithPath: path)
    }

    return nil
}


func startRecording() {

    if movieOutput.isRecording == false {

        let connection = movieOutput.connection(with: .video)
        if (connection?.isVideoOrientationSupported)! {
            connection?.videoOrientation = currentVideoOrientation()
        }

        if (connection?.isVideoStabilizationSupported)! {
            connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
        }

        let device = activeInput.device
        if (device.isSmoothAutoFocusSupported) {
            do {
                try device.lockForConfiguration()
                device.isSmoothAutoFocusEnabled = false
                device.unlockForConfiguration()
            } catch {
                print("Error setting configuration: \(error)")
            }

        }

        //EDIT2: And I forgot this
        outputURL = tempURL()
        movieOutput.startRecording(to: outputURL, recordingDelegate: self)

    }
    else {
        stopRecording()
    }

}

func stopRecording() {

    if movieOutput.isRecording == true {
        movieOutput.stopRecording()
    }
}

func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {

}

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
    if (error != nil) {
        print("Error recording movie: \(error!.localizedDescription)")
    } else {
        _ = outputURL as URL
    }
    outputURL = nil
}

}