问题
I've recently started running beta on my camera-based app. Everything is working as expected except on iPhone 6 devices.
The session starts on the back camera, and each time an iPhone 6 user switches to the front camera the app crashes. (And just to be really clear: no one on any other iPhone model is experiencing the issue.) I've gotten my hands on a 6 to test and can consistently reproduce the error, resulting in libc++abi.dylib: terminating with uncaught exception of type NSException
.
I've tried starting the session on the front camera and it crashes immediately.
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
}
}
}
The crash is triggered at captureSession.addInput(videoInput)
. videoInput
is not nil
. The camera's orientation is locked to portrait.
Can anyone offer any insight? Please let me know if any additional code would be helpful. Thanks in advance.
回答1:
captureSession.addInput(videoInput)
is causing the crash.
So you should use canAddInput(_:)
before to avoid the crash.
if captureSession.canAddInput(videoInput) {
captureSession.addInput(videoInput)
}
And in your case, captureSession.canAddInput(videoInput)
== false with that iPhone 6.
Now, you are also doing self.captureSession.sessionPreset = .hd1920x1080
But according to WikiPedia, the iPhone 6 Front Camera hardware supports camera 1.2 MP (1280×960 px max.), 720p video recording (30 fps). Doesn't seem to fit the 1920*1080 ("Full HD").
You could do this check what the "max" AVCaptureSession.Preset you can use.
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($0) }) ?? .hd1280x720
captureSession.sessionPreset = preset
}
来源:https://stackoverflow.com/questions/53213054/crash-when-using-front-camera-only-on-pre-iphone-7-devices