仅在 iPhone 7 之前的设备上使用前置摄像头时崩溃
Crash when using front camera ONLY on pre-iPhone 7 devices
我最近在我的基于相机的应用程序上开始了 运行 测试版。除 iPhone 6 台设备外,一切都按预期工作。
会话从后置摄像头开始,每次 iPhone 6 用户切换到前置摄像头时,应用程序都会崩溃。 (要明确一点:在任何其他 iPhone 型号上都没有遇到此问题。)我已经拿到 6 进行测试,并且可以始终如一地重现错误,从而导致 libc++abi.dylib: terminating with uncaught exception of type NSException
.
我试过在前置摄像头上启动会话,但它立即崩溃了。
func initializeCamera() {
self.captureSession.sessionPreset = .hd1920x1080
let discovery = AVCaptureDevice.DiscoverySession.init(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],
mediaType: .video,
position: .unspecified) as AVCaptureDevice.DiscoverySession
for device in discovery.devices as [AVCaptureDevice] {
if device.hasMediaType(.video) {
if device.position == AVCaptureDevice.Position.front {
videoCaptureDevice = device
do {
try currentDeviceInput = AVCaptureDeviceInput(device: device)
} catch {
print("error: \(error.localizedDescription)")
}
}
}
}
if videoCaptureDevice != nil {
do {
let videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice!)
captureSession.addInput(videoInput)
if let audioInput = AVCaptureDevice.default(for: .audio) {
try captureSession.addInput(AVCaptureDeviceInput(device: audioInput))
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
guard let previewLayer = previewLayer else { return }
cameraPreviewView.frame = cameraContainer.frame
cameraPreviewView.layer.addSublayer(previewLayer)
previewLayer.frame = cameraPreviewView.frame
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
setVideoOrientation()
captureSession.addOutput(movieFileOutput)
if let movieFileOutputConnection = movieFileOutput.connection(with: .video) {
if movieFileOutputConnection.isVideoStabilizationSupported {
movieFileOutputConnection.preferredVideoStabilizationMode = .cinematic
}
}
captureSession.startRunning()
sessionIsReady(true)
} catch {
print("error: \(error.localizedDescription)")
}
}
}
func setVideoOrientation() {
if let connection = self.previewLayer?.connection {
if connection.isVideoOrientationSupported {
connection.videoOrientation = .portrait
previewLayer?.frame = cameraContainer.bounds
}
}
}
崩溃是在 captureSession.addInput(videoInput)
触发的。 videoInput
不是 nil
。相机的方向锁定为纵向。
任何人都可以提供任何见解吗?请让我知道是否有任何其他代码会有所帮助。提前致谢。
captureSession.addInput(videoInput)
导致崩溃。
所以你应该在canAddInput(_:)
之前使用以避免崩溃。
if captureSession.canAddInput(videoInput) {
captureSession.addInput(videoInput)
}
在你的情况下,captureSession.canAddInput(videoInput)
== false iPhone 6.
现在,你也在做self.captureSession.sessionPreset = .hd1920x1080
但是according to WikiPedia,iPhone6前置摄像头硬件支持
相机 1.2 MP(最大 1280×960 像素),720p 视频录制(30 fps)。似乎不适合 1920*1080 ("Full HD")。
你可以这样做检查你可以使用什么 "max" AVCaptureSession.Preset
。
func setSessionPreset(forDevice device: AVCaptureDevice) {
let videoPresets: [AVCaptureSession.Preset] = [.hd4K3840x2160, .hd1920x1080, .hd1280x720] //etc. Put them in order to "preferred" to "last preferred"
let preset = videoPresets.first(where: { device.supportsSessionPreset([=11=]) }) ?? .hd1280x720
captureSession.sessionPreset = preset
}
我最近在我的基于相机的应用程序上开始了 运行 测试版。除 iPhone 6 台设备外,一切都按预期工作。
会话从后置摄像头开始,每次 iPhone 6 用户切换到前置摄像头时,应用程序都会崩溃。 (要明确一点:在任何其他 iPhone 型号上都没有遇到此问题。)我已经拿到 6 进行测试,并且可以始终如一地重现错误,从而导致 libc++abi.dylib: terminating with uncaught exception of type NSException
.
我试过在前置摄像头上启动会话,但它立即崩溃了。
func initializeCamera() {
self.captureSession.sessionPreset = .hd1920x1080
let discovery = AVCaptureDevice.DiscoverySession.init(deviceTypes: [AVCaptureDevice.DeviceType.builtInWideAngleCamera],
mediaType: .video,
position: .unspecified) as AVCaptureDevice.DiscoverySession
for device in discovery.devices as [AVCaptureDevice] {
if device.hasMediaType(.video) {
if device.position == AVCaptureDevice.Position.front {
videoCaptureDevice = device
do {
try currentDeviceInput = AVCaptureDeviceInput(device: device)
} catch {
print("error: \(error.localizedDescription)")
}
}
}
}
if videoCaptureDevice != nil {
do {
let videoInput = try AVCaptureDeviceInput(device: videoCaptureDevice!)
captureSession.addInput(videoInput)
if let audioInput = AVCaptureDevice.default(for: .audio) {
try captureSession.addInput(AVCaptureDeviceInput(device: audioInput))
}
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
guard let previewLayer = previewLayer else { return }
cameraPreviewView.frame = cameraContainer.frame
cameraPreviewView.layer.addSublayer(previewLayer)
previewLayer.frame = cameraPreviewView.frame
previewLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
setVideoOrientation()
captureSession.addOutput(movieFileOutput)
if let movieFileOutputConnection = movieFileOutput.connection(with: .video) {
if movieFileOutputConnection.isVideoStabilizationSupported {
movieFileOutputConnection.preferredVideoStabilizationMode = .cinematic
}
}
captureSession.startRunning()
sessionIsReady(true)
} catch {
print("error: \(error.localizedDescription)")
}
}
}
func setVideoOrientation() {
if let connection = self.previewLayer?.connection {
if connection.isVideoOrientationSupported {
connection.videoOrientation = .portrait
previewLayer?.frame = cameraContainer.bounds
}
}
}
崩溃是在 captureSession.addInput(videoInput)
触发的。 videoInput
不是 nil
。相机的方向锁定为纵向。
任何人都可以提供任何见解吗?请让我知道是否有任何其他代码会有所帮助。提前致谢。
captureSession.addInput(videoInput)
导致崩溃。
所以你应该在canAddInput(_:)
之前使用以避免崩溃。
if captureSession.canAddInput(videoInput) {
captureSession.addInput(videoInput)
}
在你的情况下,captureSession.canAddInput(videoInput)
== false iPhone 6.
现在,你也在做self.captureSession.sessionPreset = .hd1920x1080
但是according to WikiPedia,iPhone6前置摄像头硬件支持 相机 1.2 MP(最大 1280×960 像素),720p 视频录制(30 fps)。似乎不适合 1920*1080 ("Full HD")。
你可以这样做检查你可以使用什么 "max" AVCaptureSession.Preset
。
func setSessionPreset(forDevice device: AVCaptureDevice) {
let videoPresets: [AVCaptureSession.Preset] = [.hd4K3840x2160, .hd1920x1080, .hd1280x720] //etc. Put them in order to "preferred" to "last preferred"
let preset = videoPresets.first(where: { device.supportsSessionPreset([=11=]) }) ?? .hd1280x720
captureSession.sessionPreset = preset
}