如何在不使用预设的情况下在iOS上录制视频? [英] How do I record a video on iOS without using a preset?

查看:212
本文介绍了如何在不使用预设的情况下在iOS上录制视频?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The simpler way to record a video on iOS is by setting a AVCaptureSession.sessionPreset.

但这对我不起作用,因为我想控制合并等参数,稳定(电影,标准或无)和ISO。

But that doesn't work for me since I want to control parameters like binning, stabilization (cinematic, standard, or none) and ISO.

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

I find the format I want and assign it to activeFormat, but when I try to start recording, I get an error:

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)")
  }
}

最后一个日志语句产生:

The last log statement produces:

<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 参考

This is indeed the format I want, so setFormatWithHighestIso() is working as expected. See the Apple reference.

我尝试过的其他操作:


  • 通过将== 875704422更改为!=,使用420v而不是420f。

  • 而不是在照片模式,以视频模式启动它,然后通过删除AVCapturePhotoOutput并添加AVCaptureMovieFileOutput将其更改为视频模式。

  • 验证是否已启用AVCaptureConnection。

  • 验证连接处于活动状态,但不是:

  • Using 420v instead of 420f, by changing the == 875704422 to !=.
  • Instead of starting the camera in photo mode, starting it in video mode, and then changing it to video mode by removing the AVCapturePhotoOutput and adding the AVCaptureMovieFileOutput.
  • Verifying that the AVCaptureConnection is enabled, and it is.
  • Verifying that the connection is active, but it's not:

let conn = output.connection(withMediaType:AVMediaTypeVideo)!
verify(conn.isActive)

let conn = output.connection(withMediaType: AVMediaTypeVideo)! verify(conn.isActive)

我也尝试使用其他一些 AVCaptureDeviceFormats ,并且它们起作用:

I also tried using some other AVCaptureDeviceFormats, and they work:

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的格式不起作用。这种格式有什么特别之处?

It's only the format with the highest ISO that doesn't work. What's special about this format?

我需要手动创建AVCaptureConnection吗?但是已经有了联系;

Do I need to manually create an AVCaptureConnection? But there's already a connection; it's just not active.

这是在运行iOS 10.3.3的iPhone 7 Plus上。如何通过设置activeFormat而不使用会话来以特定格式录制视频?

This is on the iPhone 7 Plus running iOS 10.3.3. How do I record video in a specific format by setting the activeFormat without using a session?

如果我不是使用分配给activeFormat的会话,而是使用sessionPreset录制了一个视频成功。

If, instead of assigning to activeFormat, I use a sessionPreset, it does record a video successfully.

还有其他关于此错误消息的问题,但这并不是我的错

There are other questions talking of this error message, but this isn't a dupe of them since I specifically need to capture video without using a preset.

推荐答案

该解决方案原来是在将AVCaptureDevice添加到会话之前对其进行配置的。而不是:

The solution turned out to be configuring the AVCaptureDevice before adding it to a session. Instead of:

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)

将设备添加到会话后,将以某种方式创建和配置AVCaptureConnection。如果稍后更改设备的分辨率,则配置将不再匹配,因此连接将被停用,并且视频也将无法录制。

When the device is added to the session, an AVCaptureConnection is created and configured in a certain way. If you change the device's resolution later, the configuration no longer matches, so the connection gets deactivated, and the video won't record.

这篇关于如何在不使用预设的情况下在iOS上录制视频?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆