如何在不使用预设的情况下在iOS上录制video?

在iOS上录制video更简单的方法是设置AVCaptureSession.sessionPreset

但是,这并不适合我,因为我想控制像binning,稳定(电影,标准,或无)和ISO参数。

我find了我想要的格式并将其分配给activeFormat ,但是当我尝试开始录制时,出现错误:

 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVCaptureMovieFileOutput startRecordingToOutputFileURL:recordingDelegate:] No active/enabled connections' 

这是我的初始化代码:

 let device = AVCaptureDevice.defaultDevice( withDeviceType: .builtInWideAngleCamera, mediaType: AVMediaTypeVideo, position: .back)! let session = AVCaptureSession() session.addInput(try! AVCaptureDeviceInput(device: device)) output = AVCaptureMovieFileOutput() session.addOutput(output) device.setFormatWithHighestIso() session.startRunning() 

setFormatWithHighestIso()被定义为:

 extension AVCaptureDevice { var goodVideoFormats: [AVCaptureDeviceFormat] { return (formats as! [AVCaptureDeviceFormat]) .filter { CMFormatDescriptionGetMediaSubType($0.formatDescription) != 875704422 } // 420f .filter { $0.autoFocusSystem == .phaseDetection } } func setFormatWithHighestIso() { let format = goodVideoFormats .filter { $0.maxISO > 1759 } .filter { $0.height < 1937 } .first! try! lockForConfiguration() defer { unlockForConfiguration() } activeFormat = format NSLog("\(format)") } } 

最后的日志语句产生:

 <AVCaptureDeviceFormat: 0x1702027d0 'vide'/'420f' 2592x1936, { 3- 30 fps}, HRSI:4032x3024, fov:58.986, max zoom:189.00 (upscales @1.56), AF System:2, ISO:22.0-1760.0, SS:0.000005-0.333333, supports wide color> 

这确实是我想要的格式,所以setFormatWithHighestIso()按预期工作。 请参阅Apple 参考 。


我尝试了一些其他的东西:

  • 使用420v而不是420f,将== 875704422更改为!=。
  • 而不是在照片模式下启动相机,在video模式下启动相机,然后通过删除AVCapturePhotoOutput并添加AVCaptureMovieFileOutput将其更改为video模式。
  • validation是否启用了AVCaptureConnection,并且是。
  • validation连接是否处于活动状态,但不是:

    让conn = output.connection(withMediaType:AVMediaTypeVideo)! validation(conn.isActive)

我也尝试使用一些其他的AVCaptureDeviceFormats ,他们的工作:

 extension AVCaptureDevice { func setFormatWithCinematicVS() { let format = goodVideoFormats .filter { $0.isVideoStabilizationModeSupported(.cinematic) } .filter { $0.height == 720 } .first! try! lockForConfiguration() defer { unlockForConfiguration() } activeFormat = format } func setFormatWithStandardVS() { let format = goodVideoFormats .filter { $0.isVideoStabilizationModeSupported(.standard) } .filter { $0.height == 540 } .first! try! lockForConfiguration() defer { unlockForConfiguration() } activeFormat = format } } 

这只是具有最高ISO的格式不起作用。 这种格式有什么特别之处?

我是否需要手动创build一个AVCaptureConnection? 但是已经有了联系。 它只是不活跃。

这是运行iOS 10.3.3的iPhone 7 Plus。 如何通过在不使用会话的情况下设置activeFormat来以特定格式loggingvideo?

如果不是分配给activeFormat,而是使用sessionPreset,它会成功录制video。


还有其他的问题在谈论这个错误信息,但这不是一个愚蠢的事情,因为我特别需要捕捉video而不使用预设。

解决scheme原来是在将AVCaptureDevice添加到会话之前configuration的。 代替:

 session.addInput(try! AVCaptureDeviceInput(device: device)) output = AVCaptureMovieFileOutput() session.addOutput(output) device.setFormatWithHighestIso() 

你应该做:

 device.setFormatWithHighestIso() // Do this first! session.addInput(try! AVCaptureDeviceInput(device: device)) output = AVCaptureMovieFileOutput() session.addOutput(output) 

当设备被添加到会话中时,将以某种方式创build和configurationAVCaptureConnection。 如果稍后更改设备的分辨率,则configuration不再匹配,因此连接将被停用,并且video将不会被logging。