@capacitor-community/camera-preview 2.0.0-beta.0 → 2.0.0-beta.2
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 +3 -2
- package/LICENSE +21 -0
- package/README.md +46 -57
- package/android/build.gradle +4 -4
- package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +127 -118
- package/dist/esm/definitions.d.ts +9 -5
- package/dist/esm/definitions.js +1 -0
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +5 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +7 -1
- package/dist/esm/web.js +89 -77
- package/dist/esm/web.js.map +1 -1
- package/ios/Plugin/CameraController.swift +155 -48
- package/ios/Plugin/Plugin.m +3 -0
- package/ios/Plugin/Plugin.swift +125 -46
- package/ios/Plugin.xcodeproj/project.pbxproj +2 -6
- package/ios/Podfile +2 -2
- package/ios/Podfile.lock +4 -4
- package/package.json +7 -6
- package/android/local.properties +0 -8
- package/ios/Plugin.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/ios/Plugin.xcodeproj/xcuserdata/nielsvanharen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/ios/Plugin.xcworkspace/xcuserdata/ahernandez.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Plugin.xcworkspace/xcuserdata/arielhernandezmusa.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Plugin.xcworkspace/xcuserdata/nielsvanharen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/Pods/CapacitorCordova/LICENSE +0 -23
- package/ios/Pods/CapacitorCordova/README.md +0 -39
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/CapacitorCordova.h +0 -21
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.h +0 -8
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.m +0 -5
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDV.h +0 -28
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailability.h +0 -109
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegate.h +0 -51
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.h +0 -39
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.m +0 -154
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.h +0 -31
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.m +0 -81
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.h +0 -52
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.m +0 -116
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.h +0 -81
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.m +0 -154
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.h +0 -25
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.m +0 -77
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.h +0 -82
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.m +0 -216
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVScreenOrientationDelegate.h +0 -33
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUIWebViewDelegate.h +0 -41
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUIWebViewDelegate.m +0 -399
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.h +0 -27
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.m +0 -74
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUserAgentUtil.h +0 -27
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUserAgentUtil.m +0 -156
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.h +0 -30
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.m +0 -34
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.h +0 -35
- package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.m +0 -63
- package/ios/Pods/Local Podspecs/Capacitor.podspec.json +0 -31
- package/ios/Pods/Manifest.lock +0 -23
- package/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -1296
- package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Capacitor.xcscheme +0 -60
- package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/CapacitorCordova.xcscheme +0 -58
- package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Pods-Plugin.xcscheme +0 -58
- package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Pods-PluginTests.xcscheme +0 -58
- package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/xcschememanagement.plist +0 -39
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-Info.plist +0 -26
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-dummy.m +0 -5
- package/ios/Pods/Target Support Files/Capacitor/Capacitor-prefix.pch +0 -12
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.debug.xcconfig +0 -13
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.modulemap +0 -7
- package/ios/Pods/Target Support Files/Capacitor/Capacitor.release.xcconfig +0 -13
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-Info.plist +0 -26
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-dummy.m +0 -5
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-prefix.pch +0 -12
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-umbrella.h +0 -32
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.debug.xcconfig +0 -12
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.modulemap +0 -6
- package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.release.xcconfig +0 -12
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-Info.plist +0 -26
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.markdown +0 -57
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.plist +0 -95
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-dummy.m +0 -5
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-umbrella.h +0 -16
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.debug.xcconfig +0 -13
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.modulemap +0 -6
- package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.release.xcconfig +0 -13
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-Info.plist +0 -26
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.markdown +0 -57
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.plist +0 -95
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-dummy.m +0 -5
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh +0 -187
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-umbrella.h +0 -16
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.debug.xcconfig +0 -14
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.modulemap +0 -6
- package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.release.xcconfig +0 -14
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
declare module "@capacitor/core" {
|
|
2
|
-
interface PluginRegistry {
|
|
3
|
-
CameraPreview: CameraPreviewPlugin;
|
|
4
|
-
}
|
|
5
|
-
}
|
|
6
1
|
export declare type CameraPosition = 'rear' | 'front';
|
|
7
2
|
export interface CameraPreviewOptions {
|
|
8
3
|
/** Parent element to attach the video preview element to (applicable to the web platform only) */
|
|
@@ -33,6 +28,8 @@ export interface CameraPreviewOptions {
|
|
|
33
28
|
enableHighResolution?: boolean;
|
|
34
29
|
/** Defaults to false - Web only - Disables audio stream to prevent permission requests and output switching */
|
|
35
30
|
disableAudio?: boolean;
|
|
31
|
+
/** Defaults to false - Android Only - Locks device orientation when camera is showing. */
|
|
32
|
+
lockAndroidOrientation?: boolean;
|
|
36
33
|
}
|
|
37
34
|
export interface CameraPreviewPictureOptions {
|
|
38
35
|
/** The picture height, optional, default 0 (Device default) */
|
|
@@ -42,6 +39,10 @@ export interface CameraPreviewPictureOptions {
|
|
|
42
39
|
/** The picture quality, 0 - 100, default 85 */
|
|
43
40
|
quality?: number;
|
|
44
41
|
}
|
|
42
|
+
export interface CameraSampleOptions {
|
|
43
|
+
/** The picture quality, 0 - 100, default 85 */
|
|
44
|
+
quality?: number;
|
|
45
|
+
}
|
|
45
46
|
export declare type CameraPreviewFlashMode = 'off' | 'on' | 'auto' | 'red-eye' | 'torch';
|
|
46
47
|
export interface CameraPreviewPlugin {
|
|
47
48
|
start(options: CameraPreviewOptions): Promise<{}>;
|
|
@@ -49,6 +50,9 @@ export interface CameraPreviewPlugin {
|
|
|
49
50
|
capture(options: CameraPreviewPictureOptions): Promise<{
|
|
50
51
|
value: string;
|
|
51
52
|
}>;
|
|
53
|
+
captureSample(options: CameraSampleOptions): Promise<{
|
|
54
|
+
value: string;
|
|
55
|
+
}>;
|
|
52
56
|
getSupportedFlashModes(): Promise<{
|
|
53
57
|
result: CameraPreviewFlashMode[];
|
|
54
58
|
}>;
|
package/dist/esm/definitions.js
CHANGED
package/dist/esm/index.d.ts
CHANGED
package/dist/esm/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { registerPlugin } from '@capacitor/core';
|
|
2
|
+
const CameraPreview = registerPlugin('CameraPreview', {
|
|
3
|
+
web: () => import('./web').then(m => new m.CameraPreviewWeb()),
|
|
4
|
+
});
|
|
1
5
|
export * from './definitions';
|
|
2
|
-
export
|
|
6
|
+
export { CameraPreview };
|
|
3
7
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAG/C,MAAM,aAAa,GAAG,cAAc,CAAsB,eAAe,EAAE;IACzE,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;CAC/D,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAC,aAAa,EAAC,CAAC"}
|
package/dist/esm/web.d.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { WebPlugin } from "@capacitor/core";
|
|
2
|
-
import { CameraPreviewOptions, CameraPreviewPictureOptions, CameraPreviewPlugin, CameraPreviewFlashMode } from "./definitions";
|
|
2
|
+
import { CameraPreviewOptions, CameraPreviewPictureOptions, CameraPreviewPlugin, CameraPreviewFlashMode, CameraSampleOptions } from "./definitions";
|
|
3
3
|
export declare class CameraPreviewWeb extends WebPlugin implements CameraPreviewPlugin {
|
|
4
|
+
/**
|
|
5
|
+
* track which camera is used based on start options
|
|
6
|
+
* used in capture
|
|
7
|
+
*/
|
|
8
|
+
private isBackCamera;
|
|
4
9
|
constructor();
|
|
5
10
|
start(options: CameraPreviewOptions): Promise<{}>;
|
|
6
11
|
stop(): Promise<any>;
|
|
7
12
|
capture(_options: CameraPreviewPictureOptions): Promise<any>;
|
|
13
|
+
captureSample(_options: CameraSampleOptions): Promise<any>;
|
|
8
14
|
getSupportedFlashModes(): Promise<{
|
|
9
15
|
result: CameraPreviewFlashMode[];
|
|
10
16
|
}>;
|
package/dist/esm/web.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
1
|
import { WebPlugin } from "@capacitor/core";
|
|
11
2
|
export class CameraPreviewWeb extends WebPlugin {
|
|
12
3
|
constructor() {
|
|
@@ -15,88 +6,109 @@ export class CameraPreviewWeb extends WebPlugin {
|
|
|
15
6
|
platforms: ["web"],
|
|
16
7
|
});
|
|
17
8
|
}
|
|
18
|
-
start(options) {
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
9
|
+
async start(options) {
|
|
10
|
+
return new Promise(async (resolve, reject) => {
|
|
11
|
+
await navigator.mediaDevices.getUserMedia({
|
|
12
|
+
audio: !options.disableAudio,
|
|
13
|
+
video: true
|
|
14
|
+
}).then((stream) => {
|
|
15
|
+
// Stop any existing stream so we can request media with different constraints based on user input
|
|
16
|
+
stream.getTracks().forEach((track) => track.stop());
|
|
17
|
+
}).catch(error => {
|
|
18
|
+
reject(error);
|
|
19
|
+
});
|
|
20
|
+
const video = document.getElementById("video");
|
|
21
|
+
const parent = document.getElementById(options.parent);
|
|
22
|
+
if (!video) {
|
|
23
|
+
const videoElement = document.createElement("video");
|
|
24
|
+
videoElement.id = "video";
|
|
25
|
+
videoElement.setAttribute("class", options.className || "");
|
|
26
|
+
// Don't flip video feed if camera is rear facing
|
|
27
|
+
if (options.position !== 'rear') {
|
|
31
28
|
videoElement.setAttribute("style", "-webkit-transform: scaleX(-1); transform: scaleX(-1);");
|
|
32
|
-
parent.appendChild(videoElement);
|
|
33
|
-
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
|
34
|
-
// Not adding `{ audio: true }` since we only want video now
|
|
35
|
-
navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) {
|
|
36
|
-
//video.src = window.URL.createObjectURL(stream);
|
|
37
|
-
videoElement.srcObject = stream;
|
|
38
|
-
videoElement.play();
|
|
39
|
-
resolve({});
|
|
40
|
-
}, (err) => {
|
|
41
|
-
reject(err);
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
29
|
}
|
|
45
|
-
|
|
46
|
-
|
|
30
|
+
const userAgent = navigator.userAgent.toLowerCase();
|
|
31
|
+
const isSafari = userAgent.includes('safari') && !userAgent.includes('chrome');
|
|
32
|
+
// Safari on iOS needs to have the autoplay, muted and playsinline attributes set for video.play() to be successful
|
|
33
|
+
// Without these attributes videoElement.play() will throw a NotAllowedError
|
|
34
|
+
// https://developer.apple.com/documentation/webkit/delivering_video_content_for_safari
|
|
35
|
+
if (isSafari) {
|
|
36
|
+
videoElement.setAttribute('autoplay', 'true');
|
|
37
|
+
videoElement.setAttribute('muted', 'true');
|
|
38
|
+
videoElement.setAttribute('playsinline', 'true');
|
|
47
39
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
40
|
+
parent.appendChild(videoElement);
|
|
41
|
+
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
|
42
|
+
const constraints = {
|
|
43
|
+
video: true,
|
|
44
|
+
};
|
|
45
|
+
if (options.position === 'rear') {
|
|
46
|
+
constraints.video = { facingMode: 'environment' };
|
|
47
|
+
this.isBackCamera = true;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.isBackCamera = false;
|
|
51
|
+
}
|
|
52
|
+
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) {
|
|
53
|
+
//video.src = window.URL.createObjectURL(stream);
|
|
54
|
+
videoElement.srcObject = stream;
|
|
55
|
+
videoElement.play();
|
|
56
|
+
resolve({});
|
|
57
|
+
}, (err) => {
|
|
58
|
+
reject(err);
|
|
59
|
+
});
|
|
61
60
|
}
|
|
62
|
-
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
reject({ message: "camera already started" });
|
|
63
64
|
}
|
|
64
65
|
});
|
|
65
66
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
67
|
+
async stop() {
|
|
68
|
+
const video = document.getElementById("video");
|
|
69
|
+
if (video) {
|
|
70
|
+
video.pause();
|
|
71
|
+
const st = video.srcObject;
|
|
72
|
+
const tracks = st.getTracks();
|
|
73
|
+
for (var i = 0; i < tracks.length; i++) {
|
|
74
|
+
var track = tracks[i];
|
|
75
|
+
track.stop();
|
|
76
|
+
}
|
|
77
|
+
video.remove();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async capture(_options) {
|
|
81
|
+
return new Promise((resolve, _) => {
|
|
82
|
+
const video = document.getElementById("video");
|
|
83
|
+
const canvas = document.createElement("canvas");
|
|
84
|
+
// video.width = video.offsetWidth;
|
|
85
|
+
const context = canvas.getContext("2d");
|
|
86
|
+
canvas.width = video.videoWidth;
|
|
87
|
+
canvas.height = video.videoHeight;
|
|
88
|
+
// flip horizontally back camera isn't used
|
|
89
|
+
if (!this.isBackCamera) {
|
|
75
90
|
context.translate(video.videoWidth, 0);
|
|
76
91
|
context.scale(-1, 1);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
92
|
+
}
|
|
93
|
+
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
|
|
94
|
+
resolve({
|
|
95
|
+
value: canvas
|
|
96
|
+
.toDataURL("image/png")
|
|
97
|
+
.replace("data:image/png;base64,", ""),
|
|
83
98
|
});
|
|
84
99
|
});
|
|
85
100
|
}
|
|
86
|
-
|
|
87
|
-
return
|
|
88
|
-
throw new Error('getSupportedFlashModes not supported under the web platform');
|
|
89
|
-
});
|
|
101
|
+
async captureSample(_options) {
|
|
102
|
+
return this.capture(_options);
|
|
90
103
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
throw new Error('setFlashMode not supported under the web platform');
|
|
94
|
-
});
|
|
104
|
+
async getSupportedFlashModes() {
|
|
105
|
+
throw new Error('getSupportedFlashModes not supported under the web platform');
|
|
95
106
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
107
|
+
async setFlashMode(_options) {
|
|
108
|
+
throw new Error('setFlashMode not supported under the web platform');
|
|
109
|
+
}
|
|
110
|
+
async flip() {
|
|
111
|
+
throw new Error('flip not supported under the web platform');
|
|
100
112
|
}
|
|
101
113
|
}
|
|
102
114
|
const CameraPreview = new CameraPreviewWeb();
|
package/dist/esm/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,7 @@ class CameraController: NSObject {
|
|
|
17
17
|
var frontCamera: AVCaptureDevice?
|
|
18
18
|
var frontCameraInput: AVCaptureDeviceInput?
|
|
19
19
|
|
|
20
|
+
var dataOutput: AVCaptureVideoDataOutput?
|
|
20
21
|
var photoOutput: AVCapturePhotoOutput?
|
|
21
22
|
|
|
22
23
|
var rearCamera: AVCaptureDevice?
|
|
@@ -27,7 +28,12 @@ class CameraController: NSObject {
|
|
|
27
28
|
var flashMode = AVCaptureDevice.FlashMode.off
|
|
28
29
|
var photoCaptureCompletionBlock: ((UIImage?, Error?) -> Void)?
|
|
29
30
|
|
|
31
|
+
var sampleBufferCaptureCompletionBlock: ((UIImage?, Error?) -> Void)?
|
|
32
|
+
|
|
30
33
|
var highResolutionOutput: Bool = false
|
|
34
|
+
|
|
35
|
+
var audioDevice: AVCaptureDevice?
|
|
36
|
+
var audioInput: AVCaptureDeviceInput?
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
extension CameraController {
|
|
@@ -56,6 +62,7 @@ extension CameraController {
|
|
|
56
62
|
camera.unlockForConfiguration()
|
|
57
63
|
}
|
|
58
64
|
}
|
|
65
|
+
self.audioDevice = AVCaptureDevice.default(for: AVMediaType.audio)
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
func configureDeviceInputs() throws {
|
|
@@ -79,6 +86,16 @@ extension CameraController {
|
|
|
79
86
|
self.currentCameraPosition = .front
|
|
80
87
|
}
|
|
81
88
|
} else { throw CameraControllerError.noCamerasAvailable }
|
|
89
|
+
|
|
90
|
+
// Add audio input
|
|
91
|
+
if let audioDevice = self.audioDevice {
|
|
92
|
+
self.audioInput = try AVCaptureDeviceInput(device: audioDevice)
|
|
93
|
+
if captureSession.canAddInput(self.audioInput!) {
|
|
94
|
+
captureSession.addInput(self.audioInput!)
|
|
95
|
+
} else {
|
|
96
|
+
throw CameraControllerError.inputsAreInvalid
|
|
97
|
+
}
|
|
98
|
+
}
|
|
82
99
|
}
|
|
83
100
|
|
|
84
101
|
func configurePhotoOutput() throws {
|
|
@@ -91,12 +108,32 @@ extension CameraController {
|
|
|
91
108
|
captureSession.startRunning()
|
|
92
109
|
}
|
|
93
110
|
|
|
111
|
+
func configureDataOutput() throws {
|
|
112
|
+
guard let captureSession = self.captureSession else { throw CameraControllerError.captureSessionIsMissing }
|
|
113
|
+
|
|
114
|
+
self.dataOutput = AVCaptureVideoDataOutput()
|
|
115
|
+
self.dataOutput?.videoSettings = [
|
|
116
|
+
(kCVPixelBufferPixelFormatTypeKey as String): NSNumber(value: kCVPixelFormatType_32BGRA as UInt32)
|
|
117
|
+
]
|
|
118
|
+
self.dataOutput?.alwaysDiscardsLateVideoFrames = true
|
|
119
|
+
if captureSession.canAddOutput(self.dataOutput!) {
|
|
120
|
+
captureSession.addOutput(self.dataOutput!)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
captureSession.commitConfiguration()
|
|
124
|
+
|
|
125
|
+
let queue = DispatchQueue(label: "DataOutput", attributes: [])
|
|
126
|
+
self.dataOutput?.setSampleBufferDelegate(self, queue: queue)
|
|
127
|
+
}
|
|
128
|
+
|
|
94
129
|
DispatchQueue(label: "prepare").async {
|
|
95
130
|
do {
|
|
96
131
|
createCaptureSession()
|
|
97
132
|
try configureCaptureDevices()
|
|
98
133
|
try configureDeviceInputs()
|
|
99
134
|
try configurePhotoOutput()
|
|
135
|
+
try configureDataOutput()
|
|
136
|
+
//try configureVideoOutput()
|
|
100
137
|
}
|
|
101
138
|
|
|
102
139
|
catch {
|
|
@@ -108,6 +145,8 @@ extension CameraController {
|
|
|
108
145
|
}
|
|
109
146
|
|
|
110
147
|
DispatchQueue.main.async {
|
|
148
|
+
self.updateVideoOrientation()
|
|
149
|
+
|
|
111
150
|
completionHandler(nil)
|
|
112
151
|
}
|
|
113
152
|
}
|
|
@@ -119,36 +158,44 @@ extension CameraController {
|
|
|
119
158
|
self.previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
|
|
120
159
|
self.previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
|
|
121
160
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
161
|
+
view.layer.insertSublayer(self.previewLayer!, at: 0)
|
|
162
|
+
self.previewLayer?.frame = view.frame
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
func updateVideoOrientation() {
|
|
166
|
+
assert(Thread.isMainThread) // UIApplication.statusBarOrientation requires the main thread.
|
|
167
|
+
|
|
168
|
+
let videoOrientation: AVCaptureVideoOrientation
|
|
169
|
+
switch UIDevice.current.orientation {
|
|
125
170
|
case .portrait:
|
|
126
|
-
|
|
127
|
-
case .landscapeRight:
|
|
128
|
-
self.previewLayer?.connection?.videoOrientation = .landscapeLeft
|
|
171
|
+
videoOrientation = .portrait
|
|
129
172
|
case .landscapeLeft:
|
|
130
|
-
|
|
173
|
+
videoOrientation = .landscapeRight
|
|
174
|
+
case .landscapeRight:
|
|
175
|
+
videoOrientation = .landscapeLeft
|
|
131
176
|
case .portraitUpsideDown:
|
|
132
|
-
|
|
133
|
-
case .faceUp, .faceDown:
|
|
134
|
-
|
|
177
|
+
videoOrientation = .portraitUpsideDown
|
|
178
|
+
case .faceUp, .faceDown, .unknown:
|
|
179
|
+
fallthrough
|
|
180
|
+
@unknown default:
|
|
181
|
+
switch UIApplication.shared.statusBarOrientation {
|
|
135
182
|
case .portrait:
|
|
136
|
-
|
|
137
|
-
case .landscapeRight:
|
|
138
|
-
self.previewLayer?.connection?.videoOrientation = .landscapeRight
|
|
183
|
+
videoOrientation = .portrait
|
|
139
184
|
case .landscapeLeft:
|
|
140
|
-
|
|
185
|
+
videoOrientation = .landscapeLeft
|
|
186
|
+
case .landscapeRight:
|
|
187
|
+
videoOrientation = .landscapeRight
|
|
141
188
|
case .portraitUpsideDown:
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
189
|
+
videoOrientation = .portraitUpsideDown
|
|
190
|
+
case .unknown:
|
|
191
|
+
fallthrough
|
|
192
|
+
@unknown default:
|
|
193
|
+
videoOrientation = .portrait
|
|
145
194
|
}
|
|
146
|
-
default:
|
|
147
|
-
self.previewLayer?.connection?.videoOrientation = .portrait
|
|
148
195
|
}
|
|
149
196
|
|
|
150
|
-
|
|
151
|
-
|
|
197
|
+
previewLayer?.connection?.videoOrientation = videoOrientation
|
|
198
|
+
dataOutput?.connections.forEach { $0.videoOrientation = videoOrientation }
|
|
152
199
|
}
|
|
153
200
|
|
|
154
201
|
func switchCameras() throws {
|
|
@@ -212,36 +259,19 @@ extension CameraController {
|
|
|
212
259
|
settings.flashMode = self.flashMode
|
|
213
260
|
settings.isHighResolutionPhotoEnabled = self.highResolutionOutput;
|
|
214
261
|
|
|
215
|
-
let currentDevice: UIDevice = .current
|
|
216
|
-
let deviceOrientation: UIDeviceOrientation = currentDevice.orientation
|
|
217
|
-
let statusBarOrientation = UIApplication.shared.statusBarOrientation
|
|
218
|
-
if deviceOrientation == .portrait {
|
|
219
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.portrait
|
|
220
|
-
}else if (deviceOrientation == .landscapeLeft){
|
|
221
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.landscapeRight
|
|
222
|
-
}else if (deviceOrientation == .landscapeRight){
|
|
223
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.landscapeLeft
|
|
224
|
-
}else if (deviceOrientation == .portraitUpsideDown){
|
|
225
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.portraitUpsideDown
|
|
226
|
-
}else if (deviceOrientation == .faceUp || deviceOrientation == .faceDown){
|
|
227
|
-
switch (statusBarOrientation) {
|
|
228
|
-
case .portrait:
|
|
229
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.portrait
|
|
230
|
-
case .landscapeRight:
|
|
231
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.landscapeRight
|
|
232
|
-
case .landscapeLeft:
|
|
233
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.landscapeLeft
|
|
234
|
-
case .portraitUpsideDown:
|
|
235
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.portraitUpsideDown
|
|
236
|
-
default:
|
|
237
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.portrait
|
|
238
|
-
}
|
|
239
|
-
}else {
|
|
240
|
-
self.photoOutput?.connection(with: AVMediaType.video)?.videoOrientation = AVCaptureVideoOrientation.portrait
|
|
241
|
-
}
|
|
242
262
|
self.photoOutput?.capturePhoto(with: settings, delegate: self)
|
|
243
263
|
self.photoCaptureCompletionBlock = completion
|
|
244
264
|
}
|
|
265
|
+
|
|
266
|
+
func captureSample(completion: @escaping (UIImage?, Error?) -> Void) {
|
|
267
|
+
guard let captureSession = captureSession,
|
|
268
|
+
captureSession.isRunning else {
|
|
269
|
+
completion(nil, CameraControllerError.captureSessionIsMissing)
|
|
270
|
+
return
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
self.sampleBufferCaptureCompletionBlock = completion
|
|
274
|
+
}
|
|
245
275
|
|
|
246
276
|
func getSupportedFlashModes() throws -> [String] {
|
|
247
277
|
var currentCamera: AVCaptureDevice?
|
|
@@ -359,6 +389,31 @@ extension CameraController {
|
|
|
359
389
|
}
|
|
360
390
|
|
|
361
391
|
}
|
|
392
|
+
|
|
393
|
+
func captureVideo(completion: @escaping (URL?, Error?) -> Void) {
|
|
394
|
+
guard let captureSession = self.captureSession, captureSession.isRunning else {
|
|
395
|
+
completion(nil, CameraControllerError.captureSessionIsMissing)
|
|
396
|
+
return
|
|
397
|
+
}
|
|
398
|
+
let path = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
|
|
399
|
+
let identifier = UUID()
|
|
400
|
+
let randomIdentifier = identifier.uuidString.replacingOccurrences(of: "-", with: "")
|
|
401
|
+
let finalIdentifier = String(randomIdentifier.prefix(8))
|
|
402
|
+
let fileName="cpcp_video_"+finalIdentifier+".mp4"
|
|
403
|
+
|
|
404
|
+
let fileUrl = path.appendingPathComponent(fileName)
|
|
405
|
+
try? FileManager.default.removeItem(at: fileUrl)
|
|
406
|
+
/*videoOutput!.startRecording(to: fileUrl, recordingDelegate: self)
|
|
407
|
+
self.videoRecordCompletionBlock = completion*/
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
func stopRecording(completion: @escaping (Error?) -> Void) {
|
|
411
|
+
guard let captureSession = self.captureSession, captureSession.isRunning else {
|
|
412
|
+
completion(CameraControllerError.captureSessionIsMissing)
|
|
413
|
+
return
|
|
414
|
+
}
|
|
415
|
+
//self.videoOutput?.stopRecording()
|
|
416
|
+
}
|
|
362
417
|
}
|
|
363
418
|
|
|
364
419
|
extension CameraController: AVCapturePhotoCaptureDelegate {
|
|
@@ -377,6 +432,48 @@ extension CameraController: AVCapturePhotoCaptureDelegate {
|
|
|
377
432
|
}
|
|
378
433
|
}
|
|
379
434
|
|
|
435
|
+
extension CameraController: AVCaptureVideoDataOutputSampleBufferDelegate {
|
|
436
|
+
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
|
|
437
|
+
guard let completion = sampleBufferCaptureCompletionBlock else { return }
|
|
438
|
+
|
|
439
|
+
guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else {
|
|
440
|
+
completion(nil, CameraControllerError.unknown)
|
|
441
|
+
return
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
CVPixelBufferLockBaseAddress(imageBuffer, .readOnly)
|
|
445
|
+
defer { CVPixelBufferUnlockBaseAddress(imageBuffer, .readOnly) }
|
|
446
|
+
|
|
447
|
+
let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer)
|
|
448
|
+
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
|
|
449
|
+
let width = CVPixelBufferGetWidth(imageBuffer)
|
|
450
|
+
let height = CVPixelBufferGetHeight(imageBuffer)
|
|
451
|
+
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
|
452
|
+
let bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Little.rawValue |
|
|
453
|
+
CGImageAlphaInfo.premultipliedFirst.rawValue
|
|
454
|
+
|
|
455
|
+
let context = CGContext(
|
|
456
|
+
data: baseAddress,
|
|
457
|
+
width: width,
|
|
458
|
+
height: height,
|
|
459
|
+
bitsPerComponent: 8,
|
|
460
|
+
bytesPerRow: bytesPerRow,
|
|
461
|
+
space: colorSpace,
|
|
462
|
+
bitmapInfo: bitmapInfo
|
|
463
|
+
)
|
|
464
|
+
|
|
465
|
+
guard let cgImage = context?.makeImage() else {
|
|
466
|
+
completion(nil, CameraControllerError.unknown)
|
|
467
|
+
return
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
let image = UIImage(cgImage: cgImage)
|
|
471
|
+
completion(image.fixedOrientation(), nil)
|
|
472
|
+
|
|
473
|
+
sampleBufferCaptureCompletionBlock = nil
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
380
477
|
|
|
381
478
|
|
|
382
479
|
|
|
@@ -479,3 +576,13 @@ extension UIImage {
|
|
|
479
576
|
return UIImage.init(cgImage: newCGImage, scale: 1, orientation: .up)
|
|
480
577
|
}
|
|
481
578
|
}
|
|
579
|
+
|
|
580
|
+
extension CameraController: AVCaptureFileOutputRecordingDelegate {
|
|
581
|
+
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
|
|
582
|
+
/*if error == nil {
|
|
583
|
+
self.videoRecordCompletionBlock?(outputFileURL, nil)
|
|
584
|
+
} else {
|
|
585
|
+
self.videoRecordCompletionBlock?(nil, error)
|
|
586
|
+
}*/
|
|
587
|
+
}
|
|
588
|
+
}
|
package/ios/Plugin/Plugin.m
CHANGED
|
@@ -7,7 +7,10 @@ CAP_PLUGIN(CameraPreview, "CameraPreview",
|
|
|
7
7
|
CAP_PLUGIN_METHOD(start, CAPPluginReturnPromise);
|
|
8
8
|
CAP_PLUGIN_METHOD(stop, CAPPluginReturnPromise);
|
|
9
9
|
CAP_PLUGIN_METHOD(capture, CAPPluginReturnPromise);
|
|
10
|
+
CAP_PLUGIN_METHOD(captureSample, CAPPluginReturnPromise);
|
|
10
11
|
CAP_PLUGIN_METHOD(flip, CAPPluginReturnPromise);
|
|
11
12
|
CAP_PLUGIN_METHOD(getSupportedFlashModes, CAPPluginReturnPromise);
|
|
12
13
|
CAP_PLUGIN_METHOD(setFlashMode, CAPPluginReturnPromise);
|
|
14
|
+
CAP_PLUGIN_METHOD(startRecordVideo, CAPPluginReturnPromise);
|
|
15
|
+
CAP_PLUGIN_METHOD(stopRecordVideo, CAPPluginReturnPromise);
|
|
13
16
|
)
|