Когда устройство добавляется в сеанс, 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, он успешно записывает видео.

Есть другие вопросы, говорящие об этом сообщении об ошибке, но это не заблуждение, так как мне специально нужно снимать видео без использования предустановки.

Ответы на вопрос(1)

Ваш ответ на вопрос