react-native-vision-camera/ios/CameraView+TakePhoto.swift
Marc Rousavy 72a1fad78e
feat: Separate usecases (decouple microphone, video, photo) (#168)
* Add props

* add props (iOS)

* Add use-cases conditionally

* Update CameraView+RecordVideo.swift

* Update RecordingSession.swift

* reconfigure on change

* Throw correct errors

* Check for audio permission

* Move `#if` outward

* Throw appropriate errors

* Update CameraView+RecordVideo.swift

* fix Splashscreen

* Dynamic filePath

* Fix video extension

* add `avci` and `m4v` file types

* Fix RecordVideo errors

* Fix audio setup

* Enable `photo`, `video` and `audio`

* Check for `video={true}` in frameProcessor

* format

* Remove unused DispatchQueue

* Update docs

* Add `supportsPhotoAndVideoCapture`

* Fix view manager

* Fix error not being propagated

* Catch normal errors too

* Update DEVICES.mdx

* Update CAPTURING.mdx

* Update classdocs
2021-06-07 13:08:40 +02:00

91 lines
4.1 KiB
Swift

//
// CameraView+TakePhoto.swift
// Cuvent
//
// Created by Marc Rousavy on 16.12.20.
// Copyright © 2020 mrousavy. All rights reserved.
//
import AVFoundation
// MARK: - TakePhotoOptions
struct TakePhotoOptions {
init(fromDictionary dictionary: NSDictionary) {
if let videoCodec = dictionary.value(forKey: "videoCodec") as? String {
self.videoCodec = AVVideoCodecType(withString: videoCodec)
}
qualityPrioritization = dictionary.value(forKey: "qualityPrioritization") as? String
}
var videoCodec: AVVideoCodecType?
var qualityPrioritization: String?
}
extension CameraView {
func takePhoto(options: NSDictionary, promise: Promise) {
cameraQueue.async {
guard let photoOutput = self.photoOutput,
let videoDeviceInput = self.videoDeviceInput else {
if self.photo?.boolValue == true {
return promise.reject(error: .session(.cameraNotReady))
} else {
return promise.reject(error: .capture(.photoNotEnabled))
}
}
var photoSettings = AVCapturePhotoSettings()
if let photoCodecString = options["photoCodec"] as? String {
guard let photoCodec = AVVideoCodecType(withString: photoCodecString) else {
return promise.reject(error: .capture(.invalidPhotoCodec))
}
if photoOutput.availablePhotoCodecTypes.contains(photoCodec) {
photoSettings = AVCapturePhotoSettings(format: [AVVideoCodecKey: photoCodec])
} else {
return promise.reject(error: .parameter(.invalid(unionName: "PhotoCodec", receivedValue: photoCodecString)))
}
}
if videoDeviceInput.device.isFlashAvailable, let flash = options["flash"] as? String {
guard let flashMode = AVCaptureDevice.FlashMode(withString: flash) else {
return promise.reject(error: .parameter(.invalid(unionName: "FlashMode", receivedValue: flash)))
}
photoSettings.flashMode = flashMode
}
photoSettings.isHighResolutionPhotoEnabled = photoOutput.isHighResolutionCaptureEnabled
if !photoSettings.__availablePreviewPhotoPixelFormatTypes.isEmpty {
photoSettings.previewPhotoFormat = [kCVPixelBufferPixelFormatTypeKey as String: photoSettings.__availablePreviewPhotoPixelFormatTypes.first!]
}
photoSettings.isDepthDataDeliveryEnabled = photoOutput.isDepthDataDeliveryEnabled
photoSettings.embedsDepthDataInPhoto = photoSettings.isDepthDataDeliveryEnabled
if #available(iOS 12.0, *) {
photoSettings.isPortraitEffectsMatteDeliveryEnabled = photoOutput.isPortraitEffectsMatteDeliveryEnabled
photoSettings.embedsPortraitEffectsMatteInPhoto = photoSettings.isPortraitEffectsMatteDeliveryEnabled
}
if #available(iOS 13.0, *), let qualityPrioritization = options["qualityPrioritization"] as? String {
guard let photoQualityPrioritization = AVCapturePhotoOutput.QualityPrioritization(withString: qualityPrioritization) else {
return promise.reject(error: .parameter(.invalid(unionName: "QualityPrioritization", receivedValue: qualityPrioritization)))
}
photoSettings.photoQualityPrioritization = photoQualityPrioritization
}
if #available(iOS 12.0, *), let autoRedEyeReduction = options["enableAutoRedEyeReduction"] as? Bool {
photoSettings.isAutoRedEyeReductionEnabled = autoRedEyeReduction
}
if let enableVirtualDeviceFusion = options["enableVirtualDeviceFusion"] as? Bool {
if #available(iOS 13.0, *) {
photoSettings.isAutoVirtualDeviceFusionEnabled = enableVirtualDeviceFusion
} else {
photoSettings.isAutoDualCameraFusionEnabled = enableVirtualDeviceFusion
}
}
if let enableAutoStabilization = options["enableAutoStabilization"] as? Bool {
photoSettings.isAutoStillImageStabilizationEnabled = enableAutoStabilization
}
if #available(iOS 14.1, *), let enableAutoDistortionCorrection = options["enableAutoDistortionCorrection"] as? Bool {
photoSettings.isAutoContentAwareDistortionCorrectionEnabled = enableAutoDistortionCorrection
}
photoOutput.capturePhoto(with: photoSettings, delegate: PhotoCaptureDelegate(promise: promise))
}
}
}