From 6969321745f6e97c92321084dab492f07fd68821 Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Wed, 10 Apr 2024 12:45:16 -0500 Subject: [PATCH 1/3] fix: prevent AVCaptureSession from starting during session configuration --- .../AV/LivenessCaptureSession.swift | 19 +++++++++++-------- .../FaceLivenessDetectionViewModel.swift | 7 +++++-- .../Liveness/LivenessViewController.swift | 8 ++++---- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/Sources/FaceLiveness/AV/LivenessCaptureSession.swift b/Sources/FaceLiveness/AV/LivenessCaptureSession.swift index 8aee097a..b15d1f25 100644 --- a/Sources/FaceLiveness/AV/LivenessCaptureSession.swift +++ b/Sources/FaceLiveness/AV/LivenessCaptureSession.swift @@ -24,8 +24,8 @@ class LivenessCaptureSession { self.outputDelegate = outputDelegate } - func startSession(frame: CGRect) throws -> CALayer { - try startSession() + func configureCamera(frame: CGRect) throws -> CALayer { + try configureCamera() guard let captureSession = captureSession else { throw LivenessCaptureSessionError.captureSessionUnavailable @@ -39,7 +39,7 @@ class LivenessCaptureSession { return previewLayer } - func startSession() throws { + func configureCamera() throws { guard let camera = captureDevice.avCaptureDevice else { throw LivenessCaptureSessionError.cameraUnavailable } @@ -58,19 +58,22 @@ class LivenessCaptureSession { try setupOutput(videoOutput, for: captureSession) try captureDevice.configure() - configurationQueue.async { - captureSession.startRunning() - } - videoOutput.setSampleBufferDelegate( outputDelegate, queue: captureQueue ) } - func stopRunning() { + func startSession() { guard let session = captureSession else { return } + configurationQueue.async { + session.startRunning() + } + } + func stopRunning() { + guard let session = captureSession else { return } + print("*** Stop running") defer { captureSession = nil } diff --git a/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel.swift b/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel.swift index db1c2b87..b1a95f36 100644 --- a/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel.swift +++ b/Sources/FaceLiveness/Views/Liveness/FaceLivenessDetectionViewModel.swift @@ -122,14 +122,17 @@ class FaceLivenessDetectionViewModel: ObservableObject { } } + func startSession() { + captureSession.startSession() + } func stopRecording() { captureSession.stopRunning() } - func startCamera(withinFrame frame: CGRect) -> CALayer? { + func configureCamera(withinFrame frame: CGRect) -> CALayer? { do { - let avLayer = try captureSession.startSession(frame: frame) + let avLayer = try captureSession.configureCamera(frame: frame) DispatchQueue.main.async { self.livenessState.checkIsFacePrepared() } diff --git a/Sources/FaceLiveness/Views/Liveness/LivenessViewController.swift b/Sources/FaceLiveness/Views/Liveness/LivenessViewController.swift index b50a8e82..5e698f23 100644 --- a/Sources/FaceLiveness/Views/Liveness/LivenessViewController.swift +++ b/Sources/FaceLiveness/Views/Liveness/LivenessViewController.swift @@ -49,9 +49,6 @@ final class _LivenessViewController: UIViewController { super.viewDidLoad() view.backgroundColor = .black layoutSubviews() - } - - override func viewDidAppear(_ animated: Bool) { setupAVLayer() } @@ -69,13 +66,14 @@ final class _LivenessViewController: UIViewController { } private func setupAVLayer() { + guard previewLayer == nil else { return } let x = view.frame.minX let y = view.frame.minY let width = view.frame.width let height = width / 3 * 4 let cameraFrame = CGRect(x: x, y: y, width: width, height: height) - guard let avLayer = viewModel.startCamera(withinFrame: cameraFrame) else { + guard let avLayer = viewModel.configureCamera(withinFrame: cameraFrame) else { DispatchQueue.main.async { self.viewModel.livenessState .unrecoverableStateEncountered(.missingVideoPermission) @@ -92,6 +90,8 @@ final class _LivenessViewController: UIViewController { DispatchQueue.main.async { self.view.layer.insertSublayer(avLayer, at: 0) self.view.layoutIfNeeded() + + self.viewModel.startSession() } } From 4d65c247c534872604479dca96feda8074b842ec Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Wed, 10 Apr 2024 14:23:14 -0500 Subject: [PATCH 2/3] chore: remove debug code --- Sources/FaceLiveness/AV/LivenessCaptureSession.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/FaceLiveness/AV/LivenessCaptureSession.swift b/Sources/FaceLiveness/AV/LivenessCaptureSession.swift index b15d1f25..ee8db673 100644 --- a/Sources/FaceLiveness/AV/LivenessCaptureSession.swift +++ b/Sources/FaceLiveness/AV/LivenessCaptureSession.swift @@ -73,7 +73,6 @@ class LivenessCaptureSession { func stopRunning() { guard let session = captureSession else { return } - print("*** Stop running") defer { captureSession = nil } From 1b02cc7c269dc197ba2c76bb2018ca74ffe4b454 Mon Sep 17 00:00:00 2001 From: Tuan Pham Date: Thu, 11 Apr 2024 10:12:20 -0500 Subject: [PATCH 3/3] fix: update preview screen to configure and start camera session --- .../Views/GetReadyPage/CameraPreviewViewModel.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/FaceLiveness/Views/GetReadyPage/CameraPreviewViewModel.swift b/Sources/FaceLiveness/Views/GetReadyPage/CameraPreviewViewModel.swift index 5a9bcbc8..db408664 100644 --- a/Sources/FaceLiveness/Views/GetReadyPage/CameraPreviewViewModel.swift +++ b/Sources/FaceLiveness/Views/GetReadyPage/CameraPreviewViewModel.swift @@ -33,7 +33,8 @@ class CameraPreviewViewModel: NSObject, ObservableObject { ) do { - try previewCaptureSession?.startSession() + try previewCaptureSession?.configureCamera() + previewCaptureSession?.startSession() } catch { Amplify.Logging.default.error("Error starting preview capture session with error: \(error)") }