Когда устройство добавляется в сеанс, AVCaptureConnection создается и настраивается определенным образом. Если вы позже измените разрешение устройства, конфигурация больше не будет соответствовать, поэтому соединение будет деактивировано, и видео не будет записано.
простой способ записать видео на iOS - это установитьAVCaptureSession.sessionPreset
.
Но это не работает для меня, так как я хочу контролировать параметры, такие как биннинг, стабилизация (кинематографическая, стандартная или нет) и 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()
работает как положено. Увидеть яблокоссылка.
Некоторые другие вещи, которые я пробовал:
Используя 420v вместо 420f, изменив == 875704422 на! =.Вместо запуска камеры в режиме фото, запустите ее в режиме видео, а затем измените ее в режим видео, удалив AVCapturePhotoOutput и добавив AVCaptureMovieFileOutput.Проверка того, что AVCaptureConnection включен, и это так.Проверка того, что соединение активно, но это не так:
let conn = output.connection (withMediaType: AVMediaTypeVideo)! проверить (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? Но уже есть связь; это просто не активно.
Это на iPhone 7 Plus под управлением iOS 10.3.3. Как мне записать видео в определенном формате, установив activeFormat без использования сеанса?
Если вместо назначения activeFormat я использую sessionPreset, он успешно записывает видео.
Есть другие вопросы, говорящие об этом сообщении об ошибке, но это не заблуждение, так как мне специально нужно снимать видео без использования предустановки.