it-swarm.com.de

Video mit AVFoundation Swift speichern

Hallo, ich folgte einem Kurs von Jared Davidson, um eine benutzerdefinierte Kameraansicht zu erstellen und Bilder mit AVFoundation zu speichern. https://www.youtube.com/watch?v=w0O3ZGUS3pk

Ich möchte jedoch Videos anstelle von Bildern aufnehmen und speichern. Kann mir hier jemand helfen? Ich bin sicher, es ist einfach, aber die Dokumentation von Apple ist in Objective-C geschrieben, und ich kann sie nicht entschlüsseln.

Das ist mein Code. Vielen Dank.

import UIKit
import AVFoundation

class ViewController: UIViewController {

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


    @IBOutlet var cameraView: UIView!

    override func viewWillAppear(animated: Bool) {

        let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
        for device in devices {
            if device.position == AVCaptureDevicePosition.Front{


                do{

                    let input = try AVCaptureDeviceInput(device: device as! AVCaptureDevice)

                    if captureSession.canAddInput(input){

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

                        if captureSession.canAddOutput(sessionOutput){

                            captureSession.addOutput(sessionOutput)
                            captureSession.startRunning()

                            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                            previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
                            previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
                            cameraView.layer.addSublayer(previewLayer)

                            previewLayer.position = CGPoint(x: self.cameraView.frame.width / 2, y: self.cameraView.frame.height / 2)
                            previewLayer.bounds = cameraView.frame


                        }

                    }

                }
                catch{

                    print("Error")
                }

            }
        }    

    }


    @IBAction func TakePhoto(sender: AnyObject) {

        if let videoConnection = sessionOutput.connectionWithMediaType(AVMediaTypeVideo){

            sessionOutput.captureStillImageAsynchronouslyFromConnection(videoConnection, completionHandler: {
                buffer, error in

                let imageData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(buffer)
                UIImageWriteToSavedPhotosAlbum(UIImage(data: imageData)!, nil, nil, nil)

            })

        }

    }

}
12
Kervon Ryan

Sie können das Video in einer Datei speichern, indem Sie eine AVCaptureMovieFileOutput erstellen und zu Ihrer Capturesitzung hinzufügen und Ihre ViewController der AVCaptureFileOutputRecordingDelegate anpassen.

In diesem Beispiel werden 5 Sekunden Video in einer Datei namens "output.mov" im Verzeichnis Documents der App aufgezeichnet. 

class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

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

    @IBOutlet var cameraView: UIView!

    override func viewWillAppear(animated: Bool) {
        self.cameraView = self.view

        let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo)
        for device in devices {
            if device.position == AVCaptureDevicePosition.Front{


                do{

                    let input = try AVCaptureDeviceInput(device: device as! AVCaptureDevice)

                    if captureSession.canAddInput(input){

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

                        if captureSession.canAddOutput(sessionOutput){

                            captureSession.addOutput(sessionOutput)

                            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                            previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
                            previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
                            cameraView.layer.addSublayer(previewLayer)

                            previewLayer.position = CGPoint(x: self.cameraView.frame.width / 2, y: self.cameraView.frame.height / 2)
                            previewLayer.bounds = cameraView.frame


                        }

                        captureSession.addOutput(movieOutput)

                        captureSession.startRunning()

                        let paths = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
                        let fileUrl = paths[0].URLByAppendingPathComponent("output.mov")
                        try? NSFileManager.defaultManager().removeItemAtURL(fileUrl)
                        movieOutput.startRecordingToOutputFileURL(fileUrl, recordingDelegate: self)

                        let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(5 * Double(NSEC_PER_SEC)))
                        dispatch_after(delayTime, dispatch_get_main_queue()) {
                            print("stopping")
                            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)
        }
    }

}
18

Danke dafür. Es war sehr hilfreich für mich. Hier ist eine Version von Rhythmic Fistman 's Antwort auf Swift 3 portiert mit den erforderlichen Importanweisungen und Delegatmethoden.

import UIKit
import AVFoundation

class ViewController: UIViewController,
AVCaptureFileOutputRecordingDelegate {

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

@IBOutlet var cameraView: UIView!

override func viewWillAppear(_ animated: Bool) {
    self.cameraView = self.view

    let devices = AVCaptureDevice.devices(withMediaType: AVMediaTypeVideo)
    for device in devices! {
        if (device as AnyObject).position == AVCaptureDevicePosition.front{


            do{

                let input = try AVCaptureDeviceInput(device: device as! AVCaptureDevice)

                if captureSession.canAddInput(input){

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

                    if captureSession.canAddOutput(sessionOutput){

                        captureSession.addOutput(sessionOutput)

                        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
                        previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
                        previewLayer.connection.videoOrientation = AVCaptureVideoOrientation.portrait
                        cameraView.layer.addSublayer(previewLayer)

                        previewLayer.position = CGPoint(x: self.cameraView.frame.width / 2, y: self.cameraView.frame.height / 2)
                        previewLayer.bounds = cameraView.frame


                    }

                    captureSession.addOutput(movieOutput)

                    captureSession.startRunning()

                    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
                    let fileUrl = paths[0].appendingPathComponent("output.mov")
                    try? FileManager.default.removeItem(at: fileUrl)
                    movieOutput.startRecording(toOutputFileURL: fileUrl, recordingDelegate: self)

                    let delayTime = DispatchTime.now() + 5
                    DispatchQueue.main.asyncAfter(deadline: delayTime) {
                        print("stopping")
                        self.movieOutput.stopRecording()
                    }
                }

            }
            catch{

                print("Error")
            }

        }
    }

}


//MARK: AVCaptureFileOutputRecordingDelegate Methods

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

}

func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    print("FINISHED \(error)")
    // save video to camera roll
    if error == nil {
        UISaveVideoAtPathToSavedPhotosAlbum(outputFileURL.path, nil, nil, nil)
    }
}

}
7
Steve Graff

sie können diesen Code verwenden, um Ihre Videos in der Fotobibliothek zu speichern. Sie müssen die folgenden Parameter angeben, in denen OutputURL.path der Dateisystempfad der Filmdatei ist, die Sie im Camera Roll-Album speichern möchten Bei den übrigen Parametern können Sie entweder die entsprechenden Werte übergeben oder auch Null zuweisen, je nach Bedarf

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

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


        UISaveVideoAtPathToSavedPhotosAlbum(outputFileURL.path, nil, #selector(CameraController.video(_:didFinishSavingWithError:contextInfo:)), nil)

    }
    outputURL = nil

}
2
Soma Sharma

Für das Tonaufnahmeproblem,

Fügen Sie diesen Code hinzu, wenn Sie die captureSession erstellen

askMicroPhonePermission (Abschluss: {(isMicrophonePermissionGiven) in

            if isMicrophonePermissionGiven {
                do {
                    try self.captureSession.addInput(AVCaptureDeviceInput(device: self.captureAudio))
                } catch {
                    print("Error creating the database")
                }
            }
        })

//////////////////////////////////////////// //////////////

die Funktion askMicroPhonePermission sieht wie folgt aus

func askMicroPhonePermission(completion: @escaping (_ success: Bool)-> Void) {
    switch AVAudioSession.sharedInstance().recordPermission() {
    case AVAudioSessionRecordPermission.granted:
        completion(true)
    case AVAudioSessionRecordPermission.denied:
        completion(false) //show alert if required
    case AVAudioSessionRecordPermission.undetermined:
        AVAudioSession.sharedInstance().requestRecordPermission({ (granted) in
            if granted {
                completion(true)
            } else {
                completion(false) // show alert if required
            }
        })
    default:
        completion(false)
    }
}

Und Sie müssen den NSMicrophoneUsageDescription-Schlüsselwert in der Datei info.plist hinzufügen.

0
Pamali

nach if (device as AnyObject).position == AVCaptureDevicePosition.front{

hinzufügen 

// Audio Input
                let audioInputDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)

                do
                {
                    let audioInput = try AVCaptureDeviceInput(device: audioInputDevice)

                    // Add Audio Input
                    if captureSession.canAddInput(audioInput)
                    {
                        captureSession.addInput(audioInput)
                    }
                    else
                    {
                        NSLog("Can't Add Audio Input")
                    }
                }
                catch let error
                {
                    NSLog("Error Getting Input Device: \(error)")
                }

Vielen Dank

0
Biks