以120/240fps保存视频 [英] Saving video at 120/240fps

查看:78
本文介绍了以120/240fps保存视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个应用,以设备的最大帧频(即iPhone 5s中的120fps和6s和6s中的240fps)录制视频.我已经成功配置了AVCaptureDevice来设置maxFrameRateDuration,我将currentDevice.activeFormat.videoSupportedFrameRateRanges打印到日志中,并且一切正常.

I'm making an app to record videos at the device maximum frame rate (i.e., 120fps in the iPhone 5s and 240 in the 6 and 6s). I've managed to configure the AVCaptureDevice to set the maxFrameRateDuration, I print to the logs the currentDevice.activeFormat.videoSupportedFrameRateRanges and everything works great.

但是当我尝试保存视频时,它确实以正常帧速率(而不是120或240fps)保存了视频.

But when I attempt to save the video, it does save it, but at normal frame rate, not at 120 or 240fps.

请,有人可以帮我吗?任何帮助将不胜感激.

Please, can anyone help me with this? Any help would be much appreciated.

谢谢.

P.S .:到目前为止,这是我的完整代码

P.S.: Here is my full code so far

import UIKit
import AVFoundation
import AVKit
import AssetsLibrary

class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate {

    @IBOutlet weak var cameraButton:UIButton!

    let captureSession = AVCaptureSession()
    var currentDevice:AVCaptureDevice?
    var videoFileOutput:AVCaptureMovieFileOutput?
    var cameraPreviewLayer:AVCaptureVideoPreviewLayer?
    var outputPath: String = ""
    var backgroundRecordId: UIBackgroundTaskIdentifier = UIBackgroundTaskInvalid

    var isRecording = false

    override func viewDidLoad() {
        super.viewDidLoad()

        // Preset the session for taking photo in full resolution
        captureSession.sessionPreset = AVCaptureSessionPresetHigh

        // Get the available devices that is capable of taking video
        let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! [AVCaptureDevice]

        // Get the back-facing camera for taking videos
        for device in devices {
            if device.position == AVCaptureDevicePosition.Back {
            currentDevice = device
                configureDevice()
            }
        }

        let captureDeviceInput:AVCaptureDeviceInput
        do {
            captureDeviceInput = try AVCaptureDeviceInput(device: currentDevice)
        } catch {
            print(error)
            return
        }

        // Configure the session with the output for capturing video
        videoFileOutput = AVCaptureMovieFileOutput()

        // Configure the session with the input and the output devices
        captureSession.addInput(captureDeviceInput)
        captureSession.addOutput(videoFileOutput)

        // Provide a camera preview
        cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        view.layer.addSublayer(cameraPreviewLayer!)
        cameraPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
        cameraPreviewLayer?.frame = view.layer.frame

        // Bring the camera button to front
        view.bringSubviewToFront(cameraButton)
        captureSession.startRunning()    
    }

    func configureDevice() {

        var bestFormat: AVCaptureDeviceFormat? = nil
        var bestFrameRateRange: AVFrameRateRange? = nil
        var bestPixelArea: Int32 = 0
        for format in currentDevice!.formats {
            let dims: CMVideoDimensions = CMVideoFormatDescriptionGetDimensions(format.formatDescription)
            let pixelArea: Int32 = dims.width * dims.height
            let ranges = format.videoSupportedFrameRateRanges as! [AVFrameRateRange];
            for range in ranges {
                //print ("[",dims.width,",",dims.width,"] : ",range.maxFrameRate);
                if bestFrameRateRange==nil || range.maxFrameRate > bestFrameRateRange!.maxFrameRate || ((range.maxFrameRate == bestFrameRateRange!.maxFrameRate) && (pixelArea > bestPixelArea)) {
                    bestFormat = format as? AVCaptureDeviceFormat
                    bestFrameRateRange = range
                    bestPixelArea = pixelArea
                }
            }
        }            

        do {

            try currentDevice!.lockForConfiguration() {

            currentDevice!.activeFormat = bestFormat
            currentDevice!.activeVideoMinFrameDuration = bestFrameRateRange!.minFrameDuration
            currentDevice!.activeVideoMaxFrameDuration = bestFrameRateRange!.minFrameDuration              

        }
        catch{}         

        print(currentDevice!.activeFormat.videoSupportedFrameRateRanges)

        currentDevice!.unlockForConfiguration()            
    }    


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - AVCaptureFileOutputRecordingDelegate methods

    func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) {


        if error != nil {
            print(error)
            return
        }

        let backgroundRecordId: UIBackgroundTaskIdentifier = self.backgroundRecordId
        self.backgroundRecordId = UIBackgroundTaskInvalid

        ALAssetsLibrary().writeVideoAtPathToSavedPhotosAlbum(outputFileURL, completionBlock: {
            (assetURL:NSURL!, error:NSError!) in
            if error != nil{
                print(error)

            }

            do {
                try NSFileManager.defaultManager().removeItemAtURL(outputFileURL)
            } catch _ {
            }

            if backgroundRecordId != UIBackgroundTaskInvalid {
                UIApplication.sharedApplication().endBackgroundTask(backgroundRecordId)
            }

        })
        performSegueWithIdentifier("playVideo", sender: outputFileURL)
    }

    // MARK: - Segue methods

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "playVideo" {
            let videoPlayerViewController = segue.destinationViewController as! AVPlayerViewController
            let videoFileURL = sender as! NSURL
            videoPlayerViewController.player = AVPlayer(URL: videoFileURL)

        }
    }


    // MARK: - Action methods

    @IBAction func unwindToCamera(segue:UIStoryboardSegue) {

    }

    @IBAction func capture(sender: AnyObject) {
        if !isRecording {
            isRecording = true

            UIView.animateWithDuration(0.5, delay: 0.0, options: [.Repeat, .Autoreverse, .AllowUserInteraction], animations: { () -> Void in
                self.cameraButton.transform = CGAffineTransformMakeScale(0.5, 0.5)
                }, completion: nil)

            let outputPath: String = NSTemporaryDirectory() + "output.mov"
            let outputFileURL = NSURL(fileURLWithPath: outputPath)
            videoFileOutput?.startRecordingToOutputFileURL(outputFileURL, recordingDelegate: self)
        } else {
            isRecording = false

            UIView.animateWithDuration(0.5, delay: 1.0, options: [], animations: { () -> Void in
                self.cameraButton.transform = CGAffineTransformMakeScale(1.0, 1.0)
                }, completion: nil)
            cameraButton.layer.removeAllAnimations()

            videoFileOutput?.stopRecording()

        }
    }        
}

推荐答案

您调用configDevice()的时间过早,并且您的配置已被替换.

You're calling configDevice() too early and your configuration is being replaced.

添加捕获设备的输入后,呼叫configDevice():

Call configDevice() after you've added the capture device's input:

// Configure the session with the input and the output devices
captureSession.addInput(captureDeviceInput)
configureDevice()

这篇关于以120/240fps保存视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆