@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.
Files changed (95) hide show
  1. package/CapacitorCommunityCameraPreview.podspec +3 -2
  2. package/LICENSE +21 -0
  3. package/README.md +46 -57
  4. package/android/build.gradle +4 -4
  5. package/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java +127 -118
  6. package/dist/esm/definitions.d.ts +9 -5
  7. package/dist/esm/definitions.js +1 -0
  8. package/dist/esm/index.d.ts +3 -1
  9. package/dist/esm/index.js +5 -1
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/web.d.ts +7 -1
  12. package/dist/esm/web.js +89 -77
  13. package/dist/esm/web.js.map +1 -1
  14. package/ios/Plugin/CameraController.swift +155 -48
  15. package/ios/Plugin/Plugin.m +3 -0
  16. package/ios/Plugin/Plugin.swift +125 -46
  17. package/ios/Plugin.xcodeproj/project.pbxproj +2 -6
  18. package/ios/Podfile +2 -2
  19. package/ios/Podfile.lock +4 -4
  20. package/package.json +7 -6
  21. package/android/local.properties +0 -8
  22. package/ios/Plugin.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  23. package/ios/Plugin.xcodeproj/xcuserdata/nielsvanharen.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  24. package/ios/Plugin.xcworkspace/xcuserdata/ahernandez.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  25. package/ios/Plugin.xcworkspace/xcuserdata/arielhernandezmusa.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  26. package/ios/Plugin.xcworkspace/xcuserdata/nielsvanharen.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  27. package/ios/Pods/CapacitorCordova/LICENSE +0 -23
  28. package/ios/Pods/CapacitorCordova/README.md +0 -39
  29. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/CapacitorCordova.h +0 -21
  30. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.h +0 -8
  31. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/AppDelegate.m +0 -5
  32. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDV.h +0 -28
  33. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVAvailability.h +0 -109
  34. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegate.h +0 -51
  35. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.h +0 -39
  36. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVCommandDelegateImpl.m +0 -154
  37. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.h +0 -31
  38. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVConfigParser.m +0 -81
  39. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.h +0 -52
  40. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVInvokedUrlCommand.m +0 -116
  41. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.h +0 -81
  42. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPlugin.m +0 -154
  43. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.h +0 -25
  44. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginManager.m +0 -77
  45. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.h +0 -82
  46. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVPluginResult.m +0 -216
  47. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVScreenOrientationDelegate.h +0 -33
  48. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUIWebViewDelegate.h +0 -41
  49. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUIWebViewDelegate.m +0 -399
  50. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.h +0 -27
  51. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVURLProtocol.m +0 -74
  52. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUserAgentUtil.h +0 -27
  53. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVUserAgentUtil.m +0 -156
  54. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.h +0 -30
  55. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/CDVViewController.m +0 -34
  56. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.h +0 -35
  57. package/ios/Pods/CapacitorCordova/ios/CapacitorCordova/CapacitorCordova/Classes/Public/NSDictionary+CordovaPreferences.m +0 -63
  58. package/ios/Pods/Local Podspecs/Capacitor.podspec.json +0 -31
  59. package/ios/Pods/Manifest.lock +0 -23
  60. package/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -1296
  61. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Capacitor.xcscheme +0 -60
  62. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/CapacitorCordova.xcscheme +0 -58
  63. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Pods-Plugin.xcscheme +0 -58
  64. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/Pods-PluginTests.xcscheme +0 -58
  65. package/ios/Pods/Pods.xcodeproj/xcuserdata/ahernandez.xcuserdatad/xcschemes/xcschememanagement.plist +0 -39
  66. package/ios/Pods/Target Support Files/Capacitor/Capacitor-Info.plist +0 -26
  67. package/ios/Pods/Target Support Files/Capacitor/Capacitor-dummy.m +0 -5
  68. package/ios/Pods/Target Support Files/Capacitor/Capacitor-prefix.pch +0 -12
  69. package/ios/Pods/Target Support Files/Capacitor/Capacitor.debug.xcconfig +0 -13
  70. package/ios/Pods/Target Support Files/Capacitor/Capacitor.modulemap +0 -7
  71. package/ios/Pods/Target Support Files/Capacitor/Capacitor.release.xcconfig +0 -13
  72. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-Info.plist +0 -26
  73. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-dummy.m +0 -5
  74. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-prefix.pch +0 -12
  75. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova-umbrella.h +0 -32
  76. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.debug.xcconfig +0 -12
  77. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.modulemap +0 -6
  78. package/ios/Pods/Target Support Files/CapacitorCordova/CapacitorCordova.release.xcconfig +0 -12
  79. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-Info.plist +0 -26
  80. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.markdown +0 -57
  81. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-acknowledgements.plist +0 -95
  82. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-dummy.m +0 -5
  83. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin-umbrella.h +0 -16
  84. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.debug.xcconfig +0 -13
  85. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.modulemap +0 -6
  86. package/ios/Pods/Target Support Files/Pods-Plugin/Pods-Plugin.release.xcconfig +0 -13
  87. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-Info.plist +0 -26
  88. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.markdown +0 -57
  89. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-acknowledgements.plist +0 -95
  90. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-dummy.m +0 -5
  91. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-frameworks.sh +0 -187
  92. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests-umbrella.h +0 -16
  93. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.debug.xcconfig +0 -14
  94. package/ios/Pods/Target Support Files/Pods-PluginTests/Pods-PluginTests.modulemap +0 -6
  95. 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
  }>;
@@ -1 +1,2 @@
1
+ export {};
1
2
  //# sourceMappingURL=definitions.js.map
@@ -1,2 +1,4 @@
1
+ import { CameraPreviewPlugin } from './definitions';
2
+ declare const CameraPreview: CameraPreviewPlugin;
1
3
  export * from './definitions';
2
- export * from './web';
4
+ export { CameraPreview };
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 * from './web';
6
+ export { CameraPreview };
3
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,OAAO,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 __awaiter(this, void 0, void 0, function* () {
20
- return new Promise((resolve, reject) => {
21
- navigator.mediaDevices.getUserMedia({
22
- audio: !options.disableAudio,
23
- video: true
24
- });
25
- const video = document.getElementById("video");
26
- const parent = document.getElementById(options.parent);
27
- if (!video) {
28
- const videoElement = document.createElement("video");
29
- videoElement.id = "video";
30
- videoElement.setAttribute("class", options.className || "");
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
- else {
46
- reject({ message: "camera already started" });
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
- stop() {
52
- return __awaiter(this, void 0, void 0, function* () {
53
- const video = document.getElementById("video");
54
- if (video) {
55
- video.pause();
56
- const st = video.srcObject;
57
- const tracks = st.getTracks();
58
- for (var i = 0; i < tracks.length; i++) {
59
- var track = tracks[i];
60
- track.stop();
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
- video.remove();
61
+ }
62
+ else {
63
+ reject({ message: "camera already started" });
63
64
  }
64
65
  });
65
66
  }
66
- capture(_options) {
67
- return __awaiter(this, void 0, void 0, function* () {
68
- return new Promise((resolve, _) => {
69
- const video = document.getElementById("video");
70
- const canvas = document.createElement("canvas");
71
- // video.width = video.offsetWidth;
72
- const context = canvas.getContext("2d");
73
- canvas.width = video.videoWidth;
74
- canvas.height = video.videoHeight;
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
- context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
78
- resolve({
79
- value: canvas
80
- .toDataURL("image/png")
81
- .replace("data:image/png;base64,", ""),
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
- getSupportedFlashModes() {
87
- return __awaiter(this, void 0, void 0, function* () {
88
- throw new Error('getSupportedFlashModes not supported under the web platform');
89
- });
101
+ async captureSample(_options) {
102
+ return this.capture(_options);
90
103
  }
91
- setFlashMode(_options) {
92
- return __awaiter(this, void 0, void 0, function* () {
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
- flip() {
97
- return __awaiter(this, void 0, void 0, function* () {
98
- throw new Error('flip not supported under the web platform');
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();
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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"}
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
- let orientation: UIDeviceOrientation = UIDevice.current.orientation
123
- let statusBarOrientation = UIApplication.shared.statusBarOrientation
124
- switch (orientation) {
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
- self.previewLayer?.connection?.videoOrientation = .portrait
127
- case .landscapeRight:
128
- self.previewLayer?.connection?.videoOrientation = .landscapeLeft
171
+ videoOrientation = .portrait
129
172
  case .landscapeLeft:
130
- self.previewLayer?.connection?.videoOrientation = .landscapeRight
173
+ videoOrientation = .landscapeRight
174
+ case .landscapeRight:
175
+ videoOrientation = .landscapeLeft
131
176
  case .portraitUpsideDown:
132
- self.previewLayer?.connection?.videoOrientation = .portraitUpsideDown
133
- case .faceUp, .faceDown:
134
- switch (statusBarOrientation) {
177
+ videoOrientation = .portraitUpsideDown
178
+ case .faceUp, .faceDown, .unknown:
179
+ fallthrough
180
+ @unknown default:
181
+ switch UIApplication.shared.statusBarOrientation {
135
182
  case .portrait:
136
- self.previewLayer?.connection?.videoOrientation = .portrait
137
- case .landscapeRight:
138
- self.previewLayer?.connection?.videoOrientation = .landscapeRight
183
+ videoOrientation = .portrait
139
184
  case .landscapeLeft:
140
- self.previewLayer?.connection?.videoOrientation = .landscapeLeft
185
+ videoOrientation = .landscapeLeft
186
+ case .landscapeRight:
187
+ videoOrientation = .landscapeRight
141
188
  case .portraitUpsideDown:
142
- self.previewLayer?.connection?.videoOrientation = .portraitUpsideDown
143
- default:
144
- self.previewLayer?.connection?.videoOrientation = .portrait
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
- view.layer.insertSublayer(self.previewLayer!, at: 0)
151
- self.previewLayer?.frame = view.frame
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
+ }
@@ -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
  )