@capacitor-community/camera-preview 2.1.0 → 4.0.0-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapacitorCommunityCameraPreview.podspec +1 -1
- package/README.md +5 -3
- package/android/build.gradle +16 -11
- package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/gradlew +182 -108
- package/android/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.java +3 -3
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraActivity.java +835 -799
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +184 -173
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomSurfaceView.java +12 -14
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomTextureView.java +16 -18
- package/android/src/main/java/com/ahm/capacitor/camera/preview/Preview.java +327 -323
- package/android/src/main/java/com/ahm/capacitor/camera/preview/TapGestureDetector.java +15 -14
- package/android/src/test/java/com/getcapacitor/ExampleUnitTest.java +4 -3
- package/dist/esm/definitions.d.ts +10 -8
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +3 -3
- package/dist/esm/web.js +36 -25
- package/dist/esm/web.js.map +1 -1
- package/ios/Plugin/CameraController.swift +106 -129
- package/ios/Plugin/Plugin.swift +76 -90
- package/ios/Plugin.xcodeproj/project.pbxproj +6 -4
- package/ios/PluginTests/PluginTests.swift +8 -8
- package/ios/Podfile +1 -1
- package/package.json +31 -6
- package/android/.gradle/4.10.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/4.10.1/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/4.10.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/4.10.1/gc.properties +0 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/.idea/compiler.xml +0 -6
- package/android/.idea/gradle.xml +0 -20
- package/android/.idea/jarRepositories.xml +0 -45
- package/android/.idea/libraries/Gradle__androidx_activity_activity_1_2_0_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_activity_activity_1_2_3_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_annotation_annotation_1_1_0.xml +0 -9
- package/android/.idea/libraries/Gradle__androidx_annotation_annotation_1_2_0.xml +0 -9
- package/android/.idea/libraries/Gradle__androidx_annotation_annotation_experimental_1_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_2_0_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_1_3_0_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_2_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_appcompat_appcompat_resources_1_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_arch_core_core_common_2_1_0.xml +0 -9
- package/android/.idea/libraries/Gradle__androidx_arch_core_core_runtime_2_1_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_collection_collection_1_1_0.xml +0 -9
- package/android/.idea/libraries/Gradle__androidx_coordinatorlayout_coordinatorlayout_1_1_0_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_core_core_1_3_2_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_core_core_1_5_0_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_cursoradapter_cursoradapter_1_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_customview_customview_1_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_drawerlayout_drawerlayout_1_0_0_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_exifinterface_exifinterface_1_3_2_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_fragment_fragment_1_3_0_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_fragment_fragment_1_3_4_aar.xml +0 -14
- package/android/.idea/libraries/Gradle__androidx_interpolator_interpolator_1_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_3_0.xml +0 -9
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_common_2_3_1.xml +0 -9
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_2_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_livedata_core_2_3_1_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_runtime_2_3_1_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_2_3_1_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_savedstate_2_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_lifecycle_lifecycle_viewmodel_savedstate_2_3_1_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_loader_loader_1_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_savedstate_savedstate_1_1_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_core_1_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_1_0_alpha3_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_espresso_espresso_core_3_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_1_0_alpha3_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_espresso_espresso_idling_resource_3_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_ext_junit_1_1_2_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_monitor_1_1_0_alpha3_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_monitor_1_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_runner_1_1_0_alpha3_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_test_runner_1_3_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_tracing_tracing_1_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_1_1_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_vectordrawable_vectordrawable_animated_1_1_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_versionedparcelable_versionedparcelable_1_1_1_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__androidx_viewpager_viewpager_1_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__com_google_code_findbugs_jsr305_2_0_1.xml +0 -9
- package/android/.idea/libraries/Gradle__com_squareup_javawriter_2_1_1.xml +0 -9
- package/android/.idea/libraries/Gradle__javax_inject_javax_inject_1.xml +0 -9
- package/android/.idea/libraries/Gradle__junit_junit_4_12.xml +0 -9
- package/android/.idea/libraries/Gradle__junit_junit_4_13_1.xml +0 -9
- package/android/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_1_10_18.xml +0 -9
- package/android/.idea/libraries/Gradle__net_bytebuddy_byte_buddy_agent_1_10_18.xml +0 -9
- package/android/.idea/libraries/Gradle__net_sf_kxml_kxml2_2_3_0.xml +0 -9
- package/android/.idea/libraries/Gradle__org_apache_cordova_framework_7_0_0_aar.xml +0 -11
- package/android/.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3.xml +0 -9
- package/android/.idea/libraries/Gradle__org_hamcrest_hamcrest_integration_1_3.xml +0 -9
- package/android/.idea/libraries/Gradle__org_hamcrest_hamcrest_library_1_3.xml +0 -9
- package/android/.idea/libraries/Gradle__org_json_json_20140107.xml +0 -9
- package/android/.idea/libraries/Gradle__org_mockito_mockito_core_3_6_28.xml +0 -9
- package/android/.idea/libraries/Gradle__org_mockito_mockito_inline_3_6_28.xml +0 -9
- package/android/.idea/libraries/Gradle__org_objenesis_objenesis_3_1.xml +0 -9
- package/android/.idea/misc.xml +0 -9
- package/android/.idea/modules/1419750366/android.capacitor-android.iml +0 -92
- package/android/.idea/modules/android.iml +0 -87
- package/android/.idea/modules.xml +0 -9
- package/android/.idea/vcs.xml +0 -6
|
@@ -11,20 +11,20 @@ import UIKit
|
|
|
11
11
|
|
|
12
12
|
class CameraController: NSObject {
|
|
13
13
|
var captureSession: AVCaptureSession?
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
var currentCameraPosition: CameraPosition?
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
var frontCamera: AVCaptureDevice?
|
|
18
18
|
var frontCameraInput: AVCaptureDeviceInput?
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
var dataOutput: AVCaptureVideoDataOutput?
|
|
21
21
|
var photoOutput: AVCapturePhotoOutput?
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
var rearCamera: AVCaptureDevice?
|
|
24
24
|
var rearCameraInput: AVCaptureDeviceInput?
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
var previewLayer: AVCaptureVideoPreviewLayer?
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
var flashMode = AVCaptureDevice.FlashMode.off
|
|
29
29
|
var photoCaptureCompletionBlock: ((UIImage?, Error?) -> Void)?
|
|
30
30
|
|
|
@@ -34,12 +34,12 @@ class CameraController: NSObject {
|
|
|
34
34
|
|
|
35
35
|
var audioDevice: AVCaptureDevice?
|
|
36
36
|
var audioInput: AVCaptureDeviceInput?
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
var zoomFactor: CGFloat = 1.0
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
extension CameraController {
|
|
42
|
-
func prepare(cameraPosition: String, completionHandler: @escaping (Error?) -> Void) {
|
|
42
|
+
func prepare(cameraPosition: String, disableAudio: Bool, completionHandler: @escaping (Error?) -> Void) {
|
|
43
43
|
func createCaptureSession() {
|
|
44
44
|
self.captureSession = AVCaptureSession()
|
|
45
45
|
}
|
|
@@ -64,7 +64,9 @@ extension CameraController {
|
|
|
64
64
|
camera.unlockForConfiguration()
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
|
|
67
|
+
if disableAudio == false {
|
|
68
|
+
self.audioDevice = AVCaptureDevice.default(for: AVMediaType.audio)
|
|
69
|
+
}
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
func configureDeviceInputs() throws {
|
|
@@ -82,20 +84,21 @@ extension CameraController {
|
|
|
82
84
|
if let frontCamera = self.frontCamera {
|
|
83
85
|
self.frontCameraInput = try AVCaptureDeviceInput(device: frontCamera)
|
|
84
86
|
|
|
85
|
-
if captureSession.canAddInput(self.frontCameraInput!) { captureSession.addInput(self.frontCameraInput!) }
|
|
86
|
-
else { throw CameraControllerError.inputsAreInvalid }
|
|
87
|
+
if captureSession.canAddInput(self.frontCameraInput!) { captureSession.addInput(self.frontCameraInput!) } else { throw CameraControllerError.inputsAreInvalid }
|
|
87
88
|
|
|
88
89
|
self.currentCameraPosition = .front
|
|
89
90
|
}
|
|
90
91
|
} else { throw CameraControllerError.noCamerasAvailable }
|
|
91
92
|
|
|
92
93
|
// Add audio input
|
|
93
|
-
if
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
captureSession.
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
if disableAudio == false {
|
|
95
|
+
if let audioDevice = self.audioDevice {
|
|
96
|
+
self.audioInput = try AVCaptureDeviceInput(device: audioDevice)
|
|
97
|
+
if captureSession.canAddInput(self.audioInput!) {
|
|
98
|
+
captureSession.addInput(self.audioInput!)
|
|
99
|
+
} else {
|
|
100
|
+
throw CameraControllerError.inputsAreInvalid
|
|
101
|
+
}
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
104
|
}
|
|
@@ -104,7 +107,7 @@ extension CameraController {
|
|
|
104
107
|
guard let captureSession = self.captureSession else { throw CameraControllerError.captureSessionIsMissing }
|
|
105
108
|
|
|
106
109
|
self.photoOutput = AVCapturePhotoOutput()
|
|
107
|
-
self.photoOutput!.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey
|
|
110
|
+
self.photoOutput!.setPreparedPhotoSettingsArray([AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])], completionHandler: nil)
|
|
108
111
|
self.photoOutput?.isHighResolutionCaptureEnabled = self.highResolutionOutput
|
|
109
112
|
if captureSession.canAddOutput(self.photoOutput!) { captureSession.addOutput(self.photoOutput!) }
|
|
110
113
|
captureSession.startRunning()
|
|
@@ -135,10 +138,8 @@ extension CameraController {
|
|
|
135
138
|
try configureDeviceInputs()
|
|
136
139
|
try configurePhotoOutput()
|
|
137
140
|
try configureDataOutput()
|
|
138
|
-
//try configureVideoOutput()
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
catch {
|
|
141
|
+
// try configureVideoOutput()
|
|
142
|
+
} catch {
|
|
142
143
|
DispatchQueue.main.async {
|
|
143
144
|
completionHandler(error)
|
|
144
145
|
}
|
|
@@ -147,8 +148,6 @@ extension CameraController {
|
|
|
147
148
|
}
|
|
148
149
|
|
|
149
150
|
DispatchQueue.main.async {
|
|
150
|
-
self.updateVideoOrientation()
|
|
151
|
-
|
|
152
151
|
completionHandler(nil)
|
|
153
152
|
}
|
|
154
153
|
}
|
|
@@ -162,21 +161,23 @@ extension CameraController {
|
|
|
162
161
|
|
|
163
162
|
view.layer.insertSublayer(self.previewLayer!, at: 0)
|
|
164
163
|
self.previewLayer?.frame = view.frame
|
|
164
|
+
|
|
165
|
+
updateVideoOrientation()
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
func setupGestures(target: UIView, enableZoom: Bool) {
|
|
168
169
|
setupTapGesture(target: target, selector: #selector(handleTap(_:)), delegate: self)
|
|
169
|
-
if
|
|
170
|
+
if enableZoom {
|
|
170
171
|
setupPinchGesture(target: target, selector: #selector(handlePinch(_:)), delegate: self)
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
|
-
|
|
174
|
+
|
|
174
175
|
func setupTapGesture(target: UIView, selector: Selector, delegate: UIGestureRecognizerDelegate?) {
|
|
175
176
|
let tapGesture = UITapGestureRecognizer(target: self, action: selector)
|
|
176
177
|
tapGesture.delegate = delegate
|
|
177
178
|
target.addGestureRecognizer(tapGesture)
|
|
178
179
|
}
|
|
179
|
-
|
|
180
|
+
|
|
180
181
|
func setupPinchGesture(target: UIView, selector: Selector, delegate: UIGestureRecognizerDelegate?) {
|
|
181
182
|
let pinchGesture = UIPinchGestureRecognizer(target: self, action: selector)
|
|
182
183
|
pinchGesture.delegate = delegate
|
|
@@ -187,32 +188,19 @@ extension CameraController {
|
|
|
187
188
|
assert(Thread.isMainThread) // UIApplication.statusBarOrientation requires the main thread.
|
|
188
189
|
|
|
189
190
|
let videoOrientation: AVCaptureVideoOrientation
|
|
190
|
-
switch
|
|
191
|
+
switch UIApplication.shared.statusBarOrientation {
|
|
191
192
|
case .portrait:
|
|
192
193
|
videoOrientation = .portrait
|
|
193
194
|
case .landscapeLeft:
|
|
194
|
-
videoOrientation = .landscapeRight
|
|
195
|
-
case .landscapeRight:
|
|
196
195
|
videoOrientation = .landscapeLeft
|
|
196
|
+
case .landscapeRight:
|
|
197
|
+
videoOrientation = .landscapeRight
|
|
197
198
|
case .portraitUpsideDown:
|
|
198
199
|
videoOrientation = .portraitUpsideDown
|
|
199
|
-
case .
|
|
200
|
+
case .unknown:
|
|
200
201
|
fallthrough
|
|
201
202
|
@unknown default:
|
|
202
|
-
|
|
203
|
-
case .portrait:
|
|
204
|
-
videoOrientation = .portrait
|
|
205
|
-
case .landscapeLeft:
|
|
206
|
-
videoOrientation = .landscapeLeft
|
|
207
|
-
case .landscapeRight:
|
|
208
|
-
videoOrientation = .landscapeRight
|
|
209
|
-
case .portraitUpsideDown:
|
|
210
|
-
videoOrientation = .portraitUpsideDown
|
|
211
|
-
case .unknown:
|
|
212
|
-
fallthrough
|
|
213
|
-
@unknown default:
|
|
214
|
-
videoOrientation = .portrait
|
|
215
|
-
}
|
|
203
|
+
videoOrientation = .portrait
|
|
216
204
|
}
|
|
217
205
|
|
|
218
206
|
previewLayer?.connection?.videoOrientation = videoOrientation
|
|
@@ -227,7 +215,7 @@ extension CameraController {
|
|
|
227
215
|
func switchToFrontCamera() throws {
|
|
228
216
|
|
|
229
217
|
guard let rearCameraInput = self.rearCameraInput, captureSession.inputs.contains(rearCameraInput),
|
|
230
|
-
|
|
218
|
+
let frontCamera = self.frontCamera else { throw CameraControllerError.invalidOperation }
|
|
231
219
|
|
|
232
220
|
self.frontCameraInput = try AVCaptureDeviceInput(device: frontCamera)
|
|
233
221
|
|
|
@@ -237,9 +225,7 @@ extension CameraController {
|
|
|
237
225
|
captureSession.addInput(self.frontCameraInput!)
|
|
238
226
|
|
|
239
227
|
self.currentCameraPosition = .front
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
else {
|
|
228
|
+
} else {
|
|
243
229
|
throw CameraControllerError.invalidOperation
|
|
244
230
|
}
|
|
245
231
|
}
|
|
@@ -247,7 +233,7 @@ extension CameraController {
|
|
|
247
233
|
func switchToRearCamera() throws {
|
|
248
234
|
|
|
249
235
|
guard let frontCameraInput = self.frontCameraInput, captureSession.inputs.contains(frontCameraInput),
|
|
250
|
-
|
|
236
|
+
let rearCamera = self.rearCamera else { throw CameraControllerError.invalidOperation }
|
|
251
237
|
|
|
252
238
|
self.rearCameraInput = try AVCaptureDeviceInput(device: rearCamera)
|
|
253
239
|
|
|
@@ -257,9 +243,7 @@ extension CameraController {
|
|
|
257
243
|
captureSession.addInput(self.rearCameraInput!)
|
|
258
244
|
|
|
259
245
|
self.currentCameraPosition = .rear
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
else { throw CameraControllerError.invalidOperation }
|
|
246
|
+
} else { throw CameraControllerError.invalidOperation }
|
|
263
247
|
}
|
|
264
248
|
|
|
265
249
|
switch currentCameraPosition {
|
|
@@ -278,7 +262,7 @@ extension CameraController {
|
|
|
278
262
|
let settings = AVCapturePhotoSettings()
|
|
279
263
|
|
|
280
264
|
settings.flashMode = self.flashMode
|
|
281
|
-
settings.isHighResolutionPhotoEnabled = self.highResolutionOutput
|
|
265
|
+
settings.isHighResolutionPhotoEnabled = self.highResolutionOutput
|
|
282
266
|
|
|
283
267
|
self.photoOutput?.capturePhoto(with: settings, delegate: self)
|
|
284
268
|
self.photoCaptureCompletionBlock = completion
|
|
@@ -293,23 +277,23 @@ extension CameraController {
|
|
|
293
277
|
|
|
294
278
|
self.sampleBufferCaptureCompletionBlock = completion
|
|
295
279
|
}
|
|
296
|
-
|
|
280
|
+
|
|
297
281
|
func getSupportedFlashModes() throws -> [String] {
|
|
298
282
|
var currentCamera: AVCaptureDevice?
|
|
299
283
|
switch currentCameraPosition {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
284
|
+
case .front:
|
|
285
|
+
currentCamera = self.frontCamera!
|
|
286
|
+
case .rear:
|
|
287
|
+
currentCamera = self.rearCamera!
|
|
288
|
+
default: break
|
|
305
289
|
}
|
|
306
|
-
|
|
290
|
+
|
|
307
291
|
guard
|
|
308
292
|
let device = currentCamera
|
|
309
293
|
else {
|
|
310
294
|
throw CameraControllerError.noCamerasAvailable
|
|
311
295
|
}
|
|
312
|
-
|
|
296
|
+
|
|
313
297
|
var supportedFlashModesAsStrings: [String] = []
|
|
314
298
|
if device.hasFlash {
|
|
315
299
|
guard let supportedFlashModes: [AVCaptureDevice.FlashMode] = self.photoOutput?.supportedFlashModes else {
|
|
@@ -319,13 +303,13 @@ extension CameraController {
|
|
|
319
303
|
for flashMode in supportedFlashModes {
|
|
320
304
|
var flashModeValue: String?
|
|
321
305
|
switch flashMode {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
306
|
+
case AVCaptureDevice.FlashMode.off:
|
|
307
|
+
flashModeValue = "off"
|
|
308
|
+
case AVCaptureDevice.FlashMode.on:
|
|
309
|
+
flashModeValue = "on"
|
|
310
|
+
case AVCaptureDevice.FlashMode.auto:
|
|
311
|
+
flashModeValue = "auto"
|
|
312
|
+
default: break
|
|
329
313
|
}
|
|
330
314
|
if flashModeValue != nil {
|
|
331
315
|
supportedFlashModesAsStrings.append(flashModeValue!)
|
|
@@ -336,38 +320,38 @@ extension CameraController {
|
|
|
336
320
|
supportedFlashModesAsStrings.append("torch")
|
|
337
321
|
}
|
|
338
322
|
return supportedFlashModesAsStrings
|
|
339
|
-
|
|
323
|
+
|
|
340
324
|
}
|
|
341
|
-
|
|
325
|
+
|
|
342
326
|
func setFlashMode(flashMode: AVCaptureDevice.FlashMode) throws {
|
|
343
327
|
var currentCamera: AVCaptureDevice?
|
|
344
328
|
switch currentCameraPosition {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
329
|
+
case .front:
|
|
330
|
+
currentCamera = self.frontCamera!
|
|
331
|
+
case .rear:
|
|
332
|
+
currentCamera = self.rearCamera!
|
|
333
|
+
default: break
|
|
350
334
|
}
|
|
351
|
-
|
|
335
|
+
|
|
352
336
|
guard let device = currentCamera else {
|
|
353
337
|
throw CameraControllerError.noCamerasAvailable
|
|
354
338
|
}
|
|
355
|
-
|
|
339
|
+
|
|
356
340
|
guard let supportedFlashModes: [AVCaptureDevice.FlashMode] = self.photoOutput?.supportedFlashModes else {
|
|
357
341
|
throw CameraControllerError.invalidOperation
|
|
358
342
|
}
|
|
359
343
|
if supportedFlashModes.contains(flashMode) {
|
|
360
344
|
do {
|
|
361
345
|
try device.lockForConfiguration()
|
|
362
|
-
|
|
363
|
-
if
|
|
346
|
+
|
|
347
|
+
if device.hasTorch && device.isTorchAvailable && device.torchMode == AVCaptureDevice.TorchMode.on {
|
|
364
348
|
device.torchMode = AVCaptureDevice.TorchMode.off
|
|
365
349
|
}
|
|
366
350
|
self.flashMode = flashMode
|
|
367
351
|
let photoSettings = AVCapturePhotoSettings()
|
|
368
352
|
photoSettings.flashMode = flashMode
|
|
369
353
|
self.photoOutput?.photoSettingsForSceneMonitoring = photoSettings
|
|
370
|
-
|
|
354
|
+
|
|
371
355
|
device.unlockForConfiguration()
|
|
372
356
|
} catch {
|
|
373
357
|
throw CameraControllerError.invalidOperation
|
|
@@ -376,17 +360,17 @@ extension CameraController {
|
|
|
376
360
|
throw CameraControllerError.invalidOperation
|
|
377
361
|
}
|
|
378
362
|
}
|
|
379
|
-
|
|
363
|
+
|
|
380
364
|
func setTorchMode() throws {
|
|
381
365
|
var currentCamera: AVCaptureDevice?
|
|
382
366
|
switch currentCameraPosition {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
367
|
+
case .front:
|
|
368
|
+
currentCamera = self.frontCamera!
|
|
369
|
+
case .rear:
|
|
370
|
+
currentCamera = self.rearCamera!
|
|
371
|
+
default: break
|
|
388
372
|
}
|
|
389
|
-
|
|
373
|
+
|
|
390
374
|
guard
|
|
391
375
|
let device = currentCamera,
|
|
392
376
|
device.hasTorch,
|
|
@@ -397,9 +381,9 @@ extension CameraController {
|
|
|
397
381
|
|
|
398
382
|
do {
|
|
399
383
|
try device.lockForConfiguration()
|
|
400
|
-
if
|
|
384
|
+
if device.isTorchModeSupported(AVCaptureDevice.TorchMode.on) {
|
|
401
385
|
device.torchMode = AVCaptureDevice.TorchMode.on
|
|
402
|
-
} else if
|
|
386
|
+
} else if device.isTorchModeSupported(AVCaptureDevice.TorchMode.auto) {
|
|
403
387
|
device.torchMode = AVCaptureDevice.TorchMode.auto
|
|
404
388
|
} else {
|
|
405
389
|
device.torchMode = AVCaptureDevice.TorchMode.off
|
|
@@ -408,7 +392,7 @@ extension CameraController {
|
|
|
408
392
|
} catch {
|
|
409
393
|
throw CameraControllerError.invalidOperation
|
|
410
394
|
}
|
|
411
|
-
|
|
395
|
+
|
|
412
396
|
}
|
|
413
397
|
|
|
414
398
|
func captureVideo(completion: @escaping (URL?, Error?) -> Void) {
|
|
@@ -422,10 +406,10 @@ extension CameraController {
|
|
|
422
406
|
let finalIdentifier = String(randomIdentifier.prefix(8))
|
|
423
407
|
let fileName="cpcp_video_"+finalIdentifier+".mp4"
|
|
424
408
|
|
|
425
|
-
|
|
409
|
+
let fileUrl = path.appendingPathComponent(fileName)
|
|
426
410
|
try? FileManager.default.removeItem(at: fileUrl)
|
|
427
411
|
/*videoOutput!.startRecording(to: fileUrl, recordingDelegate: self)
|
|
428
|
-
|
|
412
|
+
self.videoRecordCompletionBlock = completion*/
|
|
429
413
|
}
|
|
430
414
|
|
|
431
415
|
func stopRecording(completion: @escaping (Error?) -> Void) {
|
|
@@ -433,32 +417,32 @@ extension CameraController {
|
|
|
433
417
|
completion(CameraControllerError.captureSessionIsMissing)
|
|
434
418
|
return
|
|
435
419
|
}
|
|
436
|
-
//self.videoOutput?.stopRecording()
|
|
420
|
+
// self.videoOutput?.stopRecording()
|
|
437
421
|
}
|
|
438
422
|
}
|
|
439
423
|
|
|
440
424
|
extension CameraController: UIGestureRecognizerDelegate {
|
|
441
425
|
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
|
442
|
-
return true
|
|
426
|
+
return true
|
|
443
427
|
}
|
|
444
|
-
|
|
428
|
+
|
|
445
429
|
@objc
|
|
446
430
|
func handleTap(_ tap: UITapGestureRecognizer) {
|
|
447
431
|
guard let device = self.currentCameraPosition == .rear ? rearCamera : frontCamera else { return }
|
|
448
|
-
|
|
432
|
+
|
|
449
433
|
let point = tap.location(in: tap.view)
|
|
450
434
|
let devicePoint = self.previewLayer?.captureDevicePointConverted(fromLayerPoint: point)
|
|
451
|
-
|
|
435
|
+
|
|
452
436
|
do {
|
|
453
437
|
try device.lockForConfiguration()
|
|
454
438
|
defer { device.unlockForConfiguration() }
|
|
455
|
-
|
|
439
|
+
|
|
456
440
|
let focusMode = AVCaptureDevice.FocusMode.autoFocus
|
|
457
441
|
if device.isFocusPointOfInterestSupported && device.isFocusModeSupported(focusMode) {
|
|
458
442
|
device.focusPointOfInterest = CGPoint(x: CGFloat(devicePoint?.x ?? 0), y: CGFloat(devicePoint?.y ?? 0))
|
|
459
443
|
device.focusMode = focusMode
|
|
460
444
|
}
|
|
461
|
-
|
|
445
|
+
|
|
462
446
|
let exposureMode = AVCaptureDevice.ExposureMode.autoExpose
|
|
463
447
|
if device.isExposurePointOfInterestSupported && device.isExposureModeSupported(exposureMode) {
|
|
464
448
|
device.exposurePointOfInterest = CGPoint(x: CGFloat(devicePoint?.x ?? 0), y: CGFloat(devicePoint?.y ?? 0))
|
|
@@ -468,24 +452,24 @@ extension CameraController: UIGestureRecognizerDelegate {
|
|
|
468
452
|
debugPrint(error)
|
|
469
453
|
}
|
|
470
454
|
}
|
|
471
|
-
|
|
455
|
+
|
|
472
456
|
@objc
|
|
473
457
|
private func handlePinch(_ pinch: UIPinchGestureRecognizer) {
|
|
474
458
|
guard let device = self.currentCameraPosition == .rear ? rearCamera : frontCamera else { return }
|
|
475
|
-
|
|
459
|
+
|
|
476
460
|
func minMaxZoom(_ factor: CGFloat) -> CGFloat { return max(1.0, min(factor, device.activeFormat.videoMaxZoomFactor)) }
|
|
477
|
-
|
|
461
|
+
|
|
478
462
|
func update(scale factor: CGFloat) {
|
|
479
463
|
do {
|
|
480
464
|
try device.lockForConfiguration()
|
|
481
465
|
defer { device.unlockForConfiguration() }
|
|
482
|
-
|
|
466
|
+
|
|
483
467
|
device.videoZoomFactor = factor
|
|
484
468
|
} catch {
|
|
485
469
|
debugPrint(error)
|
|
486
470
|
}
|
|
487
471
|
}
|
|
488
|
-
|
|
472
|
+
|
|
489
473
|
switch pinch.state {
|
|
490
474
|
case .began: fallthrough
|
|
491
475
|
case .changed:
|
|
@@ -501,14 +485,10 @@ extension CameraController: UIGestureRecognizerDelegate {
|
|
|
501
485
|
extension CameraController: AVCapturePhotoCaptureDelegate {
|
|
502
486
|
public func photoOutput(_ captureOutput: AVCapturePhotoOutput, didFinishProcessingPhoto photoSampleBuffer: CMSampleBuffer?, previewPhoto previewPhotoSampleBuffer: CMSampleBuffer?,
|
|
503
487
|
resolvedSettings: AVCaptureResolvedPhotoSettings, bracketSettings: AVCaptureBracketedStillImageSettings?, error: Swift.Error?) {
|
|
504
|
-
if let error = error { self.photoCaptureCompletionBlock?(nil, error) }
|
|
505
|
-
|
|
506
|
-
else if let buffer = photoSampleBuffer, let data = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: buffer, previewPhotoSampleBuffer: nil),
|
|
507
|
-
let image = UIImage(data: data) {
|
|
488
|
+
if let error = error { self.photoCaptureCompletionBlock?(nil, error) } else if let buffer = photoSampleBuffer, let data = AVCapturePhotoOutput.jpegPhotoDataRepresentation(forJPEGSampleBuffer: buffer, previewPhotoSampleBuffer: nil),
|
|
489
|
+
let image = UIImage(data: data) {
|
|
508
490
|
self.photoCaptureCompletionBlock?(image.fixedOrientation(), nil)
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
else {
|
|
491
|
+
} else {
|
|
512
492
|
self.photoCaptureCompletionBlock?(nil, CameraControllerError.unknown)
|
|
513
493
|
}
|
|
514
494
|
}
|
|
@@ -556,9 +536,6 @@ extension CameraController: AVCaptureVideoDataOutputSampleBufferDelegate {
|
|
|
556
536
|
}
|
|
557
537
|
}
|
|
558
538
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
539
|
enum CameraControllerError: Swift.Error {
|
|
563
540
|
case captureSessionAlreadyRunning
|
|
564
541
|
case captureSessionIsMissing
|
|
@@ -596,21 +573,21 @@ extension CameraControllerError: LocalizedError {
|
|
|
596
573
|
extension UIImage {
|
|
597
574
|
|
|
598
575
|
func fixedOrientation() -> UIImage? {
|
|
599
|
-
|
|
576
|
+
|
|
600
577
|
guard imageOrientation != UIImage.Orientation.up else {
|
|
601
|
-
//This is default orientation, don't need to do anything
|
|
578
|
+
// This is default orientation, don't need to do anything
|
|
602
579
|
return self.copy() as? UIImage
|
|
603
580
|
}
|
|
604
|
-
|
|
581
|
+
|
|
605
582
|
guard let cgImage = self.cgImage else {
|
|
606
|
-
//CGImage is not available
|
|
583
|
+
// CGImage is not available
|
|
607
584
|
return nil
|
|
608
585
|
}
|
|
609
586
|
|
|
610
587
|
guard let colorSpace = cgImage.colorSpace, let ctx = CGContext(data: nil, width: Int(size.width), height: Int(size.height), bitsPerComponent: cgImage.bitsPerComponent, bytesPerRow: 0, space: colorSpace, bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else {
|
|
611
|
-
return nil //Not able to create CGContext
|
|
588
|
+
return nil // Not able to create CGContext
|
|
612
589
|
}
|
|
613
|
-
|
|
590
|
+
|
|
614
591
|
var transform: CGAffineTransform = CGAffineTransform.identity
|
|
615
592
|
switch imageOrientation {
|
|
616
593
|
case .down, .downMirrored:
|
|
@@ -631,8 +608,8 @@ extension UIImage {
|
|
|
631
608
|
case .up, .upMirrored:
|
|
632
609
|
break
|
|
633
610
|
}
|
|
634
|
-
|
|
635
|
-
//Flip image one more time if needed to, this is to prevent flipped image
|
|
611
|
+
|
|
612
|
+
// Flip image one more time if needed to, this is to prevent flipped image
|
|
636
613
|
switch imageOrientation {
|
|
637
614
|
case .upMirrored, .downMirrored:
|
|
638
615
|
transform.translatedBy(x: size.width, y: 0)
|
|
@@ -644,9 +621,9 @@ extension UIImage {
|
|
|
644
621
|
case .up, .down, .left, .right:
|
|
645
622
|
break
|
|
646
623
|
}
|
|
647
|
-
|
|
624
|
+
|
|
648
625
|
ctx.concatenate(transform)
|
|
649
|
-
|
|
626
|
+
|
|
650
627
|
switch imageOrientation {
|
|
651
628
|
case .left, .leftMirrored, .right, .rightMirrored:
|
|
652
629
|
ctx.draw(self.cgImage!, in: CGRect(x: 0, y: 0, width: size.height, height: size.width))
|
|
@@ -662,9 +639,9 @@ extension UIImage {
|
|
|
662
639
|
extension CameraController: AVCaptureFileOutputRecordingDelegate {
|
|
663
640
|
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
|
|
664
641
|
/*if error == nil {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
642
|
+
self.videoRecordCompletionBlock?(outputFileURL, nil)
|
|
643
|
+
} else {
|
|
644
|
+
self.videoRecordCompletionBlock?(nil, error)
|
|
645
|
+
}*/
|
|
669
646
|
}
|
|
670
647
|
}
|