以120/240fps保存视频 [英] Saving video at 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屋!