使用AVFoundation Swift保存视频

Ker*_*yan 13 avfoundation ios swift swift2

嗨我按照Jared Davidson的课程创建了自定义相机视图并使用AVFoundation保存图片. https://www.youtube.com/watch?v=w0O3ZGUS3pk

但是,我想录制和保存视频而不是图像.有人可以帮我吗?我确定它很简单,但苹果的文档是用Objective-C编写的,我无法解读它.

这是我的代码.谢谢.

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)

            })

        }

    }

}
Run Code Online (Sandbox Code Playgroud)

Rhy*_*man 20

您可以通过创建和添加AVCaptureMovieFileOutput捕获会话来保存将视频记录到文件中,并使您ViewController符合AVCaptureFileOutputRecordingDelegate.

此示例将5秒的视频记录到应用程序的Documents目录中名为"output.mov"的文件中.

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)
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 您可以在 Xcode > Devices > iPhone > _app name_ > Download Container 中从设备下载 Documents 目录。您可以通过从 `didFinishRecordingToOutputFileAtURL` 委托方法调用 `UISaveVideoAtPathToSavedPhotosAlbum()` 来将视频保存到相机胶卷。如果您的问题得到解答,请接受此答案。 (2认同)

小智 7

这次真是万分感谢.这对我很有帮助.下面是Rhythmic Fistman的一个版本,其中包含使用所需的import语句和委托方法移植到Swift 3.

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)
    }
}

}
Run Code Online (Sandbox Code Playgroud)