@capgo/camera-preview 7.3.12 → 7.4.0-beta.10
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/CapgoCameraPreview.podspec +16 -13
- package/README.md +467 -73
- package/android/.gradle/8.14.2/checksums/checksums.lock +0 -0
- package/android/.gradle/8.14.2/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.14.2/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.14.2/executionHistory/executionHistory.bin +0 -0
- package/android/.gradle/8.14.2/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.14.2/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.14.2/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/8.14.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.14.2/fileHashes/resourceHashesCache.bin +0 -0
- package/android/.gradle/8.14.2/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +2 -0
- package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/android/.gradle/file-system.probe +0 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/build.gradle +11 -0
- package/android/gradle/wrapper/gradle-wrapper.properties +1 -1
- package/android/src/main/AndroidManifest.xml +5 -3
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +472 -541
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraXView.java +1648 -0
- package/android/src/main/java/com/ahm/capacitor/camera/preview/GridOverlayView.java +82 -0
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraDevice.java +54 -0
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraLens.java +70 -0
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/CameraSessionConfiguration.java +79 -0
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/LensInfo.java +34 -0
- package/android/src/main/java/com/ahm/capacitor/camera/preview/model/ZoomFactors.java +34 -0
- package/dist/docs.json +934 -154
- package/dist/esm/definitions.d.ts +445 -83
- package/dist/esm/definitions.js +10 -1
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +73 -3
- package/dist/esm/web.js +492 -68
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +498 -68
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +498 -68
- package/dist/plugin.js.map +1 -1
- package/ios/{Plugin → Sources/CapgoCameraPreview}/CameraController.swift +601 -59
- package/ios/Sources/CapgoCameraPreview/GridOverlayView.swift +65 -0
- package/ios/Sources/CapgoCameraPreview/Plugin.swift +1369 -0
- package/ios/Tests/CameraPreviewPluginTests/CameraPreviewPluginTests.swift +15 -0
- package/package.json +1 -1
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraActivity.java +0 -1279
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomSurfaceView.java +0 -29
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CustomTextureView.java +0 -39
- package/android/src/main/java/com/ahm/capacitor/camera/preview/Preview.java +0 -461
- package/android/src/main/java/com/ahm/capacitor/camera/preview/TapGestureDetector.java +0 -24
- package/ios/Plugin/Info.plist +0 -24
- package/ios/Plugin/Plugin.h +0 -10
- package/ios/Plugin/Plugin.m +0 -18
- package/ios/Plugin/Plugin.swift +0 -511
- package/ios/Plugin.xcodeproj/project.pbxproj +0 -593
- package/ios/Plugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/ios/Plugin.xcworkspace/contents.xcworkspacedata +0 -10
- package/ios/Plugin.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/ios/PluginTests/Info.plist +0 -22
- package/ios/PluginTests/PluginTests.swift +0 -83
- package/ios/Podfile +0 -13
- package/ios/Podfile.lock +0 -23
package/ios/Plugin/Plugin.swift
DELETED
|
@@ -1,511 +0,0 @@
|
|
|
1
|
-
import Foundation
|
|
2
|
-
import Capacitor
|
|
3
|
-
import AVFoundation
|
|
4
|
-
|
|
5
|
-
extension UIWindow {
|
|
6
|
-
static var isLandscape: Bool {
|
|
7
|
-
if #available(iOS 13.0, *) {
|
|
8
|
-
return UIApplication.shared.windows
|
|
9
|
-
.first?
|
|
10
|
-
.windowScene?
|
|
11
|
-
.interfaceOrientation
|
|
12
|
-
.isLandscape ?? false
|
|
13
|
-
} else {
|
|
14
|
-
return UIApplication.shared.statusBarOrientation.isLandscape
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
static var isPortrait: Bool {
|
|
18
|
-
if #available(iOS 13.0, *) {
|
|
19
|
-
return UIApplication.shared.windows
|
|
20
|
-
.first?
|
|
21
|
-
.windowScene?
|
|
22
|
-
.interfaceOrientation
|
|
23
|
-
.isPortrait ?? false
|
|
24
|
-
} else {
|
|
25
|
-
return UIApplication.shared.statusBarOrientation.isPortrait
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Please read the Capacitor iOS Plugin Development Guide
|
|
32
|
-
* here: https://capacitor.ionicframework.com/docs/plugins/ios
|
|
33
|
-
*/
|
|
34
|
-
@objc(CameraPreview)
|
|
35
|
-
public class CameraPreview: CAPPlugin, CAPBridgedPlugin {
|
|
36
|
-
public let identifier = "CameraPreviewPlugin"
|
|
37
|
-
public let jsName = "CameraPreview"
|
|
38
|
-
public let pluginMethods: [CAPPluginMethod] = [
|
|
39
|
-
CAPPluginMethod(name: "start", returnType: CAPPluginReturnPromise),
|
|
40
|
-
CAPPluginMethod(name: "flip", returnType: CAPPluginReturnPromise),
|
|
41
|
-
CAPPluginMethod(name: "stop", returnType: CAPPluginReturnPromise),
|
|
42
|
-
CAPPluginMethod(name: "capture", returnType: CAPPluginReturnPromise),
|
|
43
|
-
CAPPluginMethod(name: "captureSample", returnType: CAPPluginReturnPromise),
|
|
44
|
-
CAPPluginMethod(name: "getSupportedFlashModes", returnType: CAPPluginReturnPromise),
|
|
45
|
-
CAPPluginMethod(name: "getHorizontalFov", returnType: CAPPluginReturnPromise),
|
|
46
|
-
CAPPluginMethod(name: "setFlashMode", returnType: CAPPluginReturnPromise),
|
|
47
|
-
CAPPluginMethod(name: "startRecordVideo", returnType: CAPPluginReturnPromise),
|
|
48
|
-
CAPPluginMethod(name: "stopRecordVideo", returnType: CAPPluginReturnPromise),
|
|
49
|
-
CAPPluginMethod(name: "getTempFilePath", returnType: CAPPluginReturnPromise),
|
|
50
|
-
CAPPluginMethod(name: "getSupportedPictureSizes", returnType: CAPPluginReturnPromise)
|
|
51
|
-
]
|
|
52
|
-
// Camera state tracking
|
|
53
|
-
private var isInitializing: Bool = false
|
|
54
|
-
private var isInitialized: Bool = false
|
|
55
|
-
|
|
56
|
-
var previewView: UIView!
|
|
57
|
-
var cameraPosition = String()
|
|
58
|
-
let cameraController = CameraController()
|
|
59
|
-
var posX: CGFloat?
|
|
60
|
-
var posY: CGFloat?
|
|
61
|
-
var width: CGFloat?
|
|
62
|
-
var height: CGFloat?
|
|
63
|
-
var paddingBottom: CGFloat?
|
|
64
|
-
var rotateWhenOrientationChanged: Bool?
|
|
65
|
-
var toBack: Bool?
|
|
66
|
-
var storeToFile: Bool?
|
|
67
|
-
var enableZoom: Bool?
|
|
68
|
-
var highResolutionOutput: Bool = false
|
|
69
|
-
var disableAudio: Bool = false
|
|
70
|
-
|
|
71
|
-
@objc func rotated() {
|
|
72
|
-
guard let previewView = self.previewView,
|
|
73
|
-
let posX = self.posX,
|
|
74
|
-
let posY = self.posY,
|
|
75
|
-
let width = self.width,
|
|
76
|
-
let heightValue = self.height else {
|
|
77
|
-
return
|
|
78
|
-
}
|
|
79
|
-
let paddingBottom = self.paddingBottom ?? 0
|
|
80
|
-
let height = heightValue - paddingBottom
|
|
81
|
-
|
|
82
|
-
if UIWindow.isLandscape {
|
|
83
|
-
previewView.frame = CGRect(x: posY, y: posX, width: max(height, width), height: min(height, width))
|
|
84
|
-
self.cameraController.previewLayer?.frame = previewView.frame
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if UIWindow.isPortrait {
|
|
88
|
-
previewView.frame = CGRect(x: posX, y: posY, width: min(height, width), height: max(height, width))
|
|
89
|
-
self.cameraController.previewLayer?.frame = previewView.frame
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if let connection = self.cameraController.fileVideoOutput?.connection(with: .video) {
|
|
93
|
-
switch UIDevice.current.orientation {
|
|
94
|
-
case .landscapeRight:
|
|
95
|
-
connection.videoOrientation = .landscapeLeft
|
|
96
|
-
case .landscapeLeft:
|
|
97
|
-
connection.videoOrientation = .landscapeRight
|
|
98
|
-
case .portrait:
|
|
99
|
-
connection.videoOrientation = .portrait
|
|
100
|
-
case .portraitUpsideDown:
|
|
101
|
-
connection.videoOrientation = .portraitUpsideDown
|
|
102
|
-
default:
|
|
103
|
-
connection.videoOrientation = .portrait
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
cameraController.updateVideoOrientation()
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
struct CameraInfo {
|
|
111
|
-
let deviceID: String
|
|
112
|
-
let position: String
|
|
113
|
-
let pictureSizes: [CGSize]
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
func getSupportedPictureSizes() -> [CameraInfo] {
|
|
117
|
-
var cameraInfos = [CameraInfo]()
|
|
118
|
-
|
|
119
|
-
// Discover all available cameras
|
|
120
|
-
let deviceTypes: [AVCaptureDevice.DeviceType] = [
|
|
121
|
-
.builtInWideAngleCamera,
|
|
122
|
-
.builtInTelephotoCamera,
|
|
123
|
-
.builtInUltraWideCamera,
|
|
124
|
-
.builtInTrueDepthCamera
|
|
125
|
-
]
|
|
126
|
-
|
|
127
|
-
let session = AVCaptureDevice.DiscoverySession(
|
|
128
|
-
deviceTypes: deviceTypes,
|
|
129
|
-
mediaType: .video,
|
|
130
|
-
position: .unspecified
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
let devices = session.devices
|
|
134
|
-
|
|
135
|
-
for device in devices {
|
|
136
|
-
// Determine the position of the camera
|
|
137
|
-
var position = "Unknown"
|
|
138
|
-
switch device.position {
|
|
139
|
-
case .front:
|
|
140
|
-
position = "Front"
|
|
141
|
-
case .back:
|
|
142
|
-
position = "Back"
|
|
143
|
-
case .unspecified:
|
|
144
|
-
position = "Unspecified"
|
|
145
|
-
@unknown default:
|
|
146
|
-
position = "Unknown"
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
var pictureSizes = [CGSize]()
|
|
150
|
-
|
|
151
|
-
// Get supported formats
|
|
152
|
-
for format in device.formats {
|
|
153
|
-
let description = format.formatDescription
|
|
154
|
-
let dimensions = CMVideoFormatDescriptionGetDimensions(description)
|
|
155
|
-
let size = CGSize(width: CGFloat(dimensions.width), height: CGFloat(dimensions.height))
|
|
156
|
-
if !pictureSizes.contains(size) {
|
|
157
|
-
pictureSizes.append(size)
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// Sort sizes in descending order (largest to smallest)
|
|
162
|
-
pictureSizes.sort { $0.width * $0.height > $1.width * $1.height }
|
|
163
|
-
|
|
164
|
-
let cameraInfo = CameraInfo(deviceID: device.uniqueID, position: position, pictureSizes: pictureSizes)
|
|
165
|
-
cameraInfos.append(cameraInfo)
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return cameraInfos
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
@objc func getSupportedPictureSizes(_ call: CAPPluginCall) {
|
|
172
|
-
let cameraInfos = getSupportedPictureSizes()
|
|
173
|
-
call.resolve([
|
|
174
|
-
"supportedPictureSizes": cameraInfos.map {
|
|
175
|
-
return [
|
|
176
|
-
"facing": $0.position,
|
|
177
|
-
"supportedPictureSizes": $0.pictureSizes.map { size in
|
|
178
|
-
return [
|
|
179
|
-
"width": String(describing: size.width),
|
|
180
|
-
"height": String(describing: size.height)
|
|
181
|
-
]
|
|
182
|
-
}
|
|
183
|
-
]
|
|
184
|
-
}
|
|
185
|
-
])
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
@objc func start(_ call: CAPPluginCall) {
|
|
189
|
-
if self.isInitializing {
|
|
190
|
-
call.reject("camera initialization in progress")
|
|
191
|
-
return
|
|
192
|
-
}
|
|
193
|
-
if self.isInitialized {
|
|
194
|
-
call.reject("camera already started")
|
|
195
|
-
return
|
|
196
|
-
}
|
|
197
|
-
self.isInitializing = true
|
|
198
|
-
|
|
199
|
-
self.cameraPosition = call.getString("position") ?? "rear"
|
|
200
|
-
let cameraMode = call.getBool("cameraMode") ?? false
|
|
201
|
-
self.highResolutionOutput = call.getBool("enableHighResolution") ?? false
|
|
202
|
-
self.cameraController.highResolutionOutput = self.highResolutionOutput
|
|
203
|
-
|
|
204
|
-
if call.getInt("width") != nil {
|
|
205
|
-
self.width = CGFloat(call.getInt("width")!)
|
|
206
|
-
} else {
|
|
207
|
-
self.width = UIScreen.main.bounds.size.width
|
|
208
|
-
}
|
|
209
|
-
if call.getInt("height") != nil {
|
|
210
|
-
self.height = CGFloat(call.getInt("height")!)
|
|
211
|
-
} else {
|
|
212
|
-
self.height = UIScreen.main.bounds.size.height
|
|
213
|
-
}
|
|
214
|
-
self.posX = call.getInt("x") != nil ? CGFloat(call.getInt("x")!)/UIScreen.main.scale: 0
|
|
215
|
-
self.posY = call.getInt("y") != nil ? CGFloat(call.getInt("y")!) / (call.getBool("includeSafeAreaInsets") ?? false ? 1.0 : UIScreen.main.scale) + (call.getBool("includeSafeAreaInsets") ?? false ? UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0 : 0) : 0
|
|
216
|
-
if call.getInt("paddingBottom") != nil {
|
|
217
|
-
self.paddingBottom = CGFloat(call.getInt("paddingBottom")!)
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
self.rotateWhenOrientationChanged = call.getBool("rotateWhenOrientationChanged") ?? true
|
|
221
|
-
self.toBack = call.getBool("toBack") ?? false
|
|
222
|
-
self.storeToFile = call.getBool("storeToFile") ?? false
|
|
223
|
-
self.enableZoom = call.getBool("enableZoom") ?? false
|
|
224
|
-
self.disableAudio = call.getBool("disableAudio") ?? false
|
|
225
|
-
|
|
226
|
-
AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) in
|
|
227
|
-
guard granted else {
|
|
228
|
-
call.reject("permission failed")
|
|
229
|
-
return
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
DispatchQueue.main.async {
|
|
233
|
-
if self.cameraController.captureSession?.isRunning ?? false {
|
|
234
|
-
call.reject("camera already started")
|
|
235
|
-
} else {
|
|
236
|
-
self.cameraController.prepare(cameraPosition: self.cameraPosition, disableAudio: self.disableAudio, cameraMode: cameraMode) {error in
|
|
237
|
-
if let error = error {
|
|
238
|
-
print(error)
|
|
239
|
-
call.reject(error.localizedDescription)
|
|
240
|
-
return
|
|
241
|
-
}
|
|
242
|
-
let height = self.paddingBottom != nil ? self.height! - self.paddingBottom!: self.height!
|
|
243
|
-
self.previewView = UIView(frame: CGRect(x: self.posX ?? 0, y: self.posY ?? 0, width: self.width!, height: height))
|
|
244
|
-
self.webView?.isOpaque = false
|
|
245
|
-
self.webView?.backgroundColor = UIColor.clear
|
|
246
|
-
self.webView?.scrollView.backgroundColor = UIColor.clear
|
|
247
|
-
self.webView?.superview?.addSubview(self.previewView)
|
|
248
|
-
if self.toBack! {
|
|
249
|
-
self.webView?.superview?.bringSubviewToFront(self.webView!)
|
|
250
|
-
}
|
|
251
|
-
try? self.cameraController.displayPreview(on: self.previewView)
|
|
252
|
-
|
|
253
|
-
let frontView = self.toBack! ? self.webView : self.previewView
|
|
254
|
-
self.cameraController.setupGestures(target: frontView ?? self.previewView, enableZoom: self.enableZoom!)
|
|
255
|
-
|
|
256
|
-
if self.rotateWhenOrientationChanged == true {
|
|
257
|
-
NotificationCenter.default.addObserver(self, selector: #selector(CameraPreview.rotated), name: UIDevice.orientationDidChangeNotification, object: nil)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
self.isInitializing = false
|
|
261
|
-
self.isInitialized = true
|
|
262
|
-
call.resolve()
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
})
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
@objc func flip(_ call: CAPPluginCall) {
|
|
272
|
-
guard isInitialized else {
|
|
273
|
-
call.reject("Camera not initialized")
|
|
274
|
-
return
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
DispatchQueue.main.async { [weak self] in
|
|
278
|
-
guard let self = self else {
|
|
279
|
-
call.reject("Camera controller deallocated")
|
|
280
|
-
return
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// Disable user interaction during flip
|
|
284
|
-
self.previewView.isUserInteractionEnabled = false
|
|
285
|
-
|
|
286
|
-
// Perform camera switch on background thread
|
|
287
|
-
DispatchQueue.global(qos: .userInitiated).async {
|
|
288
|
-
var retryCount = 0
|
|
289
|
-
let maxRetries = 3
|
|
290
|
-
|
|
291
|
-
func attemptFlip() {
|
|
292
|
-
do {
|
|
293
|
-
try self.cameraController.switchCameras()
|
|
294
|
-
|
|
295
|
-
DispatchQueue.main.async {
|
|
296
|
-
self.cameraController.previewLayer?.frame = self.previewView.bounds
|
|
297
|
-
self.cameraController.previewLayer?.videoGravity = .resizeAspectFill
|
|
298
|
-
self.previewView.isUserInteractionEnabled = true
|
|
299
|
-
call.resolve()
|
|
300
|
-
}
|
|
301
|
-
} catch {
|
|
302
|
-
retryCount += 1
|
|
303
|
-
|
|
304
|
-
if retryCount < maxRetries {
|
|
305
|
-
DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 0.5) {
|
|
306
|
-
attemptFlip()
|
|
307
|
-
}
|
|
308
|
-
} else {
|
|
309
|
-
DispatchQueue.main.async {
|
|
310
|
-
self.previewView.isUserInteractionEnabled = true
|
|
311
|
-
print("Failed to flip camera after \(maxRetries) attempts: \(error.localizedDescription)")
|
|
312
|
-
call.reject("Failed to flip camera: \(error.localizedDescription)")
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
attemptFlip()
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
@objc func stop(_ call: CAPPluginCall) {
|
|
324
|
-
DispatchQueue.main.async {
|
|
325
|
-
if self.isInitializing {
|
|
326
|
-
call.reject("cannot stop camera while initialization is in progress")
|
|
327
|
-
return
|
|
328
|
-
}
|
|
329
|
-
if !self.isInitialized {
|
|
330
|
-
call.reject("camera not initialized")
|
|
331
|
-
return
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// Always attempt to stop and clean up, regardless of captureSession state
|
|
335
|
-
if let previewView = self.previewView {
|
|
336
|
-
previewView.removeFromSuperview()
|
|
337
|
-
self.previewView = nil
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
self.webView?.isOpaque = true
|
|
341
|
-
self.isInitialized = false
|
|
342
|
-
self.isInitializing = false
|
|
343
|
-
self.cameraController.cleanup()
|
|
344
|
-
|
|
345
|
-
call.resolve()
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
// Get user's cache directory path
|
|
349
|
-
@objc func getTempFilePath() -> URL {
|
|
350
|
-
let path = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
|
|
351
|
-
let identifier = UUID()
|
|
352
|
-
let randomIdentifier = identifier.uuidString.replacingOccurrences(of: "-", with: "")
|
|
353
|
-
let finalIdentifier = String(randomIdentifier.prefix(8))
|
|
354
|
-
let fileName="cpcp_capture_"+finalIdentifier+".jpg"
|
|
355
|
-
let fileUrl=path.appendingPathComponent(fileName)
|
|
356
|
-
return fileUrl
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
@objc func capture(_ call: CAPPluginCall) {
|
|
360
|
-
DispatchQueue.main.async {
|
|
361
|
-
|
|
362
|
-
let quality: Int? = call.getInt("quality", 85)
|
|
363
|
-
|
|
364
|
-
self.cameraController.captureImage { (image, error) in
|
|
365
|
-
|
|
366
|
-
guard let image = image else {
|
|
367
|
-
print(error ?? "Image capture error")
|
|
368
|
-
guard let error = error else {
|
|
369
|
-
call.reject("Image capture error")
|
|
370
|
-
return
|
|
371
|
-
}
|
|
372
|
-
call.reject(error.localizedDescription)
|
|
373
|
-
return
|
|
374
|
-
}
|
|
375
|
-
let imageData: Data?
|
|
376
|
-
if self.cameraController.currentCameraPosition == .front {
|
|
377
|
-
let flippedImage = image.withHorizontallyFlippedOrientation()
|
|
378
|
-
imageData = flippedImage.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
379
|
-
} else {
|
|
380
|
-
imageData = image.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if self.storeToFile == false {
|
|
384
|
-
let imageBase64 = imageData?.base64EncodedString()
|
|
385
|
-
call.resolve(["value": imageBase64!])
|
|
386
|
-
} else {
|
|
387
|
-
do {
|
|
388
|
-
let fileUrl=self.getTempFilePath()
|
|
389
|
-
try imageData?.write(to: fileUrl)
|
|
390
|
-
call.resolve(["value": fileUrl.absoluteString])
|
|
391
|
-
} catch {
|
|
392
|
-
call.reject("error writing image to file")
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
@objc func captureSample(_ call: CAPPluginCall) {
|
|
400
|
-
DispatchQueue.main.async {
|
|
401
|
-
let quality: Int? = call.getInt("quality", 85)
|
|
402
|
-
|
|
403
|
-
self.cameraController.captureSample { image, error in
|
|
404
|
-
guard let image = image else {
|
|
405
|
-
print("Image capture error: \(String(describing: error))")
|
|
406
|
-
call.reject("Image capture error: \(String(describing: error))")
|
|
407
|
-
return
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
let imageData: Data?
|
|
411
|
-
if self.cameraPosition == "front" {
|
|
412
|
-
let flippedImage = image.withHorizontallyFlippedOrientation()
|
|
413
|
-
imageData = flippedImage.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
414
|
-
} else {
|
|
415
|
-
imageData = image.jpegData(compressionQuality: CGFloat(quality!/100))
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
if self.storeToFile == false {
|
|
419
|
-
let imageBase64 = imageData?.base64EncodedString()
|
|
420
|
-
call.resolve(["value": imageBase64!])
|
|
421
|
-
} else {
|
|
422
|
-
do {
|
|
423
|
-
let fileUrl = self.getTempFilePath()
|
|
424
|
-
try imageData?.write(to: fileUrl)
|
|
425
|
-
call.resolve(["value": fileUrl.absoluteString])
|
|
426
|
-
} catch {
|
|
427
|
-
call.reject("Error writing image to file")
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
@objc func getSupportedFlashModes(_ call: CAPPluginCall) {
|
|
435
|
-
do {
|
|
436
|
-
let supportedFlashModes = try self.cameraController.getSupportedFlashModes()
|
|
437
|
-
call.resolve(["result": supportedFlashModes])
|
|
438
|
-
} catch {
|
|
439
|
-
call.reject("failed to get supported flash modes")
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
@objc func getHorizontalFov(_ call: CAPPluginCall) {
|
|
444
|
-
do {
|
|
445
|
-
let horizontalFov = try self.cameraController.getHorizontalFov()
|
|
446
|
-
call.resolve(["result": horizontalFov])
|
|
447
|
-
} catch {
|
|
448
|
-
call.reject("failed to get FOV")
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
@objc func setFlashMode(_ call: CAPPluginCall) {
|
|
453
|
-
guard let flashMode = call.getString("flashMode") else {
|
|
454
|
-
call.reject("failed to set flash mode. required parameter flashMode is missing")
|
|
455
|
-
return
|
|
456
|
-
}
|
|
457
|
-
do {
|
|
458
|
-
var flashModeAsEnum: AVCaptureDevice.FlashMode?
|
|
459
|
-
switch flashMode {
|
|
460
|
-
case "off":
|
|
461
|
-
flashModeAsEnum = AVCaptureDevice.FlashMode.off
|
|
462
|
-
case "on":
|
|
463
|
-
flashModeAsEnum = AVCaptureDevice.FlashMode.on
|
|
464
|
-
case "auto":
|
|
465
|
-
flashModeAsEnum = AVCaptureDevice.FlashMode.auto
|
|
466
|
-
default: break
|
|
467
|
-
}
|
|
468
|
-
if flashModeAsEnum != nil {
|
|
469
|
-
try self.cameraController.setFlashMode(flashMode: flashModeAsEnum!)
|
|
470
|
-
} else if flashMode == "torch" {
|
|
471
|
-
try self.cameraController.setTorchMode()
|
|
472
|
-
} else {
|
|
473
|
-
call.reject("Flash Mode not supported")
|
|
474
|
-
return
|
|
475
|
-
}
|
|
476
|
-
call.resolve()
|
|
477
|
-
} catch {
|
|
478
|
-
call.reject("failed to set flash mode")
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
@objc func startRecordVideo(_ call: CAPPluginCall) {
|
|
483
|
-
DispatchQueue.main.async {
|
|
484
|
-
do {
|
|
485
|
-
try self.cameraController.captureVideo()
|
|
486
|
-
call.resolve()
|
|
487
|
-
} catch {
|
|
488
|
-
call.reject(error.localizedDescription)
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
@objc func stopRecordVideo(_ call: CAPPluginCall) {
|
|
494
|
-
DispatchQueue.main.async {
|
|
495
|
-
self.cameraController.stopRecording { (fileURL, error) in
|
|
496
|
-
guard let fileURL = fileURL else {
|
|
497
|
-
print(error ?? "Video capture error")
|
|
498
|
-
guard let error = error else {
|
|
499
|
-
call.reject("Video capture error")
|
|
500
|
-
return
|
|
501
|
-
}
|
|
502
|
-
call.reject(error.localizedDescription)
|
|
503
|
-
return
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
call.resolve(["videoFilePath": fileURL.absoluteString])
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
}
|