在iOS上记录视频的简单方法是设置AVCaptureSession.sessionPreset
。
但对我来说这并不适用,因为我想要控制诸如binning、稳定性(电影、标准或无)和ISO之类的参数。
我找到了想要的格式并将其分配给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()
按预期工作。请参阅苹果公司参考文献。
我尝试过的其他方法:
- 通过将 == 875704422 更改为 !=,使用 420v 而不是 420f。
- 不是从照片模式开始启动相机,而是从视频模式开始启动,然后通过删除 AVCapturePhotoOutput 并添加 AVCaptureMovieFileOutput 来将其更改为视频模式。
- 验证 AVCaptureConnection 已启用,确实如此。
验证连接已激活,但事实并非如此:
let conn = output.connection(withMediaType: AVMediaTypeVideo)! verify(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格式不起作用,这种格式有什么特殊之处?
我需要手动创建AVCaptureConnection吗?但已经有一个连接了;它只是没有激活。
这是在运行iOS 10.3.3的iPhone 7 Plus上。如何通过设置activeFormat来录制特定格式的视频而不使用会话?
如果我使用sessionPreset而不是分配给activeFormat,则可以成功记录视频。
有其他问题谈论这个错误信息,但这不是它们的重复,因为我需要特别捕获视频而不使用预设。