How to activate preferredVideoStabilizationMode for AVCaptureSessionPresetPhoto

149 views Asked by At

I am working to capture photo with 4:3 ratios like in iOS's default camera app with lens stabilization mode enabled. But lens are not stabilizing.

preferredVideoStabilizationMode with .photo (AVCaptureSessionPresetPhoto) does not activated even though i set. But when I set the present type to .high (AVCaptureSessionPresetMedium), the lens stabilizer starts to work.

I don't understand why and how can i set for .photo preset. Because i need vertical FOV on taken photo but .high (16:9) and .photos (4:3) presents ratios are different. I can get less vertical FOV with .high present type. AVCaptureSessionPresetPhoto present give me more Vertical FOV value.

When I use the iOS camera, I can take 4:3 lens stabilized photos. However, to be frank, I could not see this feature in 3rd camera applications.

    func startCamera(){

        self.capturePhotoOutput = AVCapturePhotoOutput.init()
        self.captureDevice = AVCaptureDevice.default(AVCaptureDevice.DeviceType.builtInWideAngleCamera
                                                     , for: AVMediaType.video, position: .back)
        do {
            
            let input = try AVCaptureDeviceInput(device: self.captureDevice!)
            
            self.captureSession = AVCaptureSession()
            self.captureSession?.sessionPreset = .high
            /**
             self.captureSession?.sessionPreset = .high
             Resolation: 1920 x 1080
             Ratio: (16:9)
             */
            
            /**
             self.captureSession?.sessionPreset = .photo
             Resolation: 4032 x 3024
             Ratio: (4:3 )
             */
            
            self.captureSession?.addInput(input)
            
            videoDataOutput = AVCaptureVideoDataOutput()
            videoDataOutput?.setSampleBufferDelegate(self, queue: DispatchQueue(label: "videoQueue"))
            
            self.captureSession?.addOutput(self.capturePhotoOutput!)
            if ((captureSession?.canAddOutput(videoDataOutput!)) != nil) {
                captureSession?.addOutput(videoDataOutput!)
            }
            
            self.capturePhotoOutput?.isHighResolutionCaptureEnabled = true
            self.videoPreviewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession!)
            self.videoPreviewLayer?.videoGravity = .resizeAspect
            
            self.videoPreviewLayer?.connection?.videoOrientation = .portrait
            self.videoPreviewLayer?.connection?.preferredVideoStabilizationMode = .cinematicExtended
            self.videoPreviewLayer?.frame = self.previewView.layer.frame
            
            self.previewView.layer.insertSublayer(self.videoPreviewLayer!, at: 0)
            
            DispatchQueue.global(qos: .background).async {
                self.captureSession?.startRunning()
            }
            
        } catch {
            print(error)
        }
    }

When I triggered the function to try the stabilization types by changing preferredVideoStabilizationMode in live camera, I saw that it works in video presentations, but not in photo presentations, it doesn't even respond.

@objc func changeVideoStabilizationMode(){
        
        print(print("\(vSModesInt)"))
        guard let mode = AVCaptureVideoStabilizationMode.init(rawValue: vSModesInt) else { return }
        
        switch mode {
        case .off:
            videoStabilizationModeLabel.text = "off"
        case .standard:
            videoStabilizationModeLabel.text = "standart"
        case .cinematic:
            videoStabilizationModeLabel.text = "cinematic"
        case .cinematicExtended:
            videoStabilizationModeLabel.text = "cinematic extended"
        case .auto:
            videoStabilizationModeLabel.text = "auto"
        @unknown default:
            videoStabilizationModeLabel.text = "unknow"
        }        
        
        vSModesInt+=1
        
        if vSModesInt > 3 {
            vSModesInt = -1
        }
        
        
        if let videoDataOutput = videoDataOutput {
            if let connection = videoDataOutput.connection(with: .video) {
                connection.preferredVideoStabilizationMode = mode
            }
        }
    }
0

There are 0 answers