Save Video Using AVFoundation Swift

后端 未结 6 1540
感情败类
感情败类 2021-02-05 08:57

Hi I followed a course by Jared Davidson to create a custom camera view and save pictures using AVFoundation. https://www.youtube.com/watch?v=w0O3ZGUS3pk

However I would

相关标签:
6条回答
  • 2021-02-05 09:21

    For the sound recording issue,

    Add this code when creating the captureSession

    askMicroPhonePermission(completion: { (isMicrophonePermissionGiven) in

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

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

    askMicroPhonePermission function is as follows

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

    And you have to add NSMicrophoneUsageDescription key value in info.plist file.

    0 讨论(0)
  • 2021-02-05 09:22
    func getCurrentFrame(url:String) -> UIImage? {
       let asset = AVAsset(url: URL(string: url)!)
        let assetImgGenerate = AVAssetImageGenerator(asset: asset)
        assetImgGenerate.appliesPreferredTrackTransform = true
        //Can set this to improve performance if target size is known before hand
        //assetImgGenerate.maximumSize = CGSize(width,height)
        let time = CMTimeMakeWithSeconds(1.0, preferredTimescale: 600)
        do {
            let img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil)
            let thumbnail = UIImage(cgImage: img)
            return thumbnail
        } catch {
          print(error.localizedDescription)
          return nil
        }
    }
    
    0 讨论(0)
  • 2021-02-05 09:27

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

    add

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

    Thanks

    0 讨论(0)
  • 2021-02-05 09:30

    Thank you for this. It was very helpful to me. Here is a version of Rhythmic Fistman's answer ported to Swift 3 with the required import statements and delegate methods.

    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)
        }
    }
    
    }
    
    0 讨论(0)
  • 2021-02-05 09:33

    you can use this code to save your videos in the photo library , You have to give the follwing parameters in which the most important is OutputURL.path which is filesystem path to the movie file you want to save to the Camera Roll album , For the rest of the parameters you can either pass there respective values or you can also assign nil that depends on your need

    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
    
    }
    
    0 讨论(0)
  • 2021-02-05 09:39

    You can save record your video to file by creating and adding an AVCaptureMovieFileOutput to your capture session, and making your ViewController conform to the AVCaptureFileOutputRecordingDelegate.

    This example records 5 seconds of video to a file called "output.mov" in the app's Documents directory.

    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)
            }
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题