3

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()、期待どおりに機能しています。Appleリファレンスを参照してください。


私が試した他のいくつかのこと:

  • == 875704422 を != に変更して、420f の代わりに 420v を使用します。
  • カメラを写真モードで起動する代わりに、ビデオ モードで起動してから、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 を手動で作成する必要がありますか? しかし、すでに接続があります。アクティブではないだけです。

これは、iOS 10.3.3 を実行している iPhone 7 Plus にあります。セッションを使用せずに activeFormat を設定して特定の形式でビデオを録画するにはどうすればよいですか?

activeFormat に割り当てる代わりに、sessionPreset を使用すると、ビデオが正常に記録されます。


このエラー メッセージについては他にも質問がありますが、特にプリセットを使用せずにビデオをキャプチャする必要があるため、これは間違いではありません。

4

1 に答える 1