Сбой при использовании ТОЛЬКО фронтальной камеры на устройствах до iPhone 7 - PullRequest
0 голосов
/ 08 ноября 2018

Я недавно запустил бета-версию своего приложения для камеры. Все работает, как и ожидалось, кроме устройств 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. Ориентация камеры зафиксирована на портретной.

Может ли кто-нибудь предложить какое-либо понимание? Пожалуйста, дайте мне знать, если какой-либо дополнительный код будет полезен. Заранее спасибо.

1 Ответ

0 голосов
/ 08 ноября 2018

captureSession.addInput(videoInput) вызывает сбой.

Таким образом, вы должны использовать canAddInput(_:) прежде, чтобы избежать сбоя.

if captureSession.canAddInput(videoInput) {
    captureSession.addInput(videoInput)
}

А в вашем случае captureSession.canAddInput(videoInput) == неверно с этим iPhone 6.

Теперь вы также делаете self.captureSession.sessionPreset = .hd1920x1080

Но в соответствии с WikiPedia , аппаратная часть передней камеры iPhone 6 поддерживает Камера 1,2 Мп (1280 × 960 пикселей макс.), Запись видео 720p (30 к / с) . Кажется, не подходит к 1920 * 1080 ("Full HD").

Вы можете сделать эту проверку, какую «макс» 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($0) }) ?? .hd1280x720
    captureSession.sessionPreset = preset
}
...