@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,13 +1,14 @@
|
|
|
1
1
|
|
|
2
2
|
Pod::Spec.new do |s|
|
|
3
3
|
s.name = 'CapacitorCommunityCameraPreview'
|
|
4
|
-
s.version = '0.0
|
|
4
|
+
s.version = '2.0.0'
|
|
5
5
|
s.summary = 'Camera preview'
|
|
6
6
|
s.license = 'MIT'
|
|
7
7
|
s.homepage = 'https://github.com/capacitor-community/camera-preview.git'
|
|
8
8
|
s.author = 'Ariel Hernandez Musa'
|
|
9
9
|
s.source = { :git => 'https://github.com/capacitor-community/camera-preview.git', :tag => s.version.to_s }
|
|
10
10
|
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
11
|
-
s.ios.deployment_target = '
|
|
11
|
+
s.ios.deployment_target = '12.0'
|
|
12
12
|
s.dependency 'Capacitor'
|
|
13
|
+
s.swift_version = '5.1'
|
|
13
14
|
end
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Ariel Hernandez Musa.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
<p align="center"><br><img src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png" width="128" height="128" /></p>
|
|
2
|
+
<h3 align="center">Capacitor Camera Preview</h3>
|
|
3
|
+
<p align="center"><strong><code>@capacitor-community/camera-preview</code></strong></p>
|
|
4
|
+
<br>
|
|
5
|
+
<p align="center"><strong>CAPACITOR 3</strong></p><br>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
Capacitor plugin that allows camera interaction from Javascript and HTML<br>(based on cordova-plugin-camera-preview).
|
|
9
|
+
</p>
|
|
10
|
+
<br>
|
|
6
11
|
|
|
7
|
-
|
|
12
|
+
Version 2 of this plugin is compatible with Ionic 5 and Capacitor 3. If your project uses Capacitor 2, please make sure you install [version 1](https://github.com/capacitor-community/camera-preview/releases/tag/v1.2.1) of this plugin.
|
|
8
13
|
|
|
9
14
|
**PR's are greatly appreciated. Maintainer(s) wanted.**
|
|
10
15
|
|
|
@@ -25,22 +30,6 @@ Capacitor plugin that allows camera interaction from Javascript and HTML (based
|
|
|
25
30
|
|
|
26
31
|
# Installation
|
|
27
32
|
|
|
28
|
-
<!-- Use any one of the installation methods listed below depending on which framework you use. -->
|
|
29
|
-
|
|
30
|
-
<!-- To install the master version with latest fixes and features -->
|
|
31
|
-
|
|
32
|
-
<!-- ```
|
|
33
|
-
cordova plugin add https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git
|
|
34
|
-
|
|
35
|
-
ionic cordova plugin add https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git
|
|
36
|
-
|
|
37
|
-
meteor add cordova:cordova-plugin-camera-preview@https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git#[latest_commit_id]
|
|
38
|
-
|
|
39
|
-
<plugin spec="https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git" source="git" />
|
|
40
|
-
``` -->
|
|
41
|
-
|
|
42
|
-
<!-- or if you want to use the last released version on npm -->
|
|
43
|
-
|
|
44
33
|
```
|
|
45
34
|
yarn add @capacitor-community/camera-preview
|
|
46
35
|
|
|
@@ -53,44 +42,19 @@ Then run
|
|
|
53
42
|
npx cap sync
|
|
54
43
|
```
|
|
55
44
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
import com.ahm.capacitor.camera.preview.CameraPreview;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
|
|
64
|
-
// Additional plugins you've installed go here
|
|
65
|
-
// Ex: add(TotallyAwesomePlugin.class);
|
|
66
|
-
add(CameraPreview.class);
|
|
67
|
-
}});
|
|
45
|
+
## Extra Android installation steps
|
|
46
|
+
Open `android/app/src/main/AndroidManifest.xml` and above the closing `</manifest>` tag add this line to request the CAMERA permission:
|
|
47
|
+
```xml
|
|
48
|
+
<uses-permission android:name="android.permission.CAMERA" />
|
|
68
49
|
```
|
|
50
|
+
For more help consult the [Capacitor docs](https://capacitorjs.com/docs/android/configuration#configuring-androidmanifestxml).
|
|
69
51
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<!--
|
|
73
|
-
#### iOS Quirks
|
|
74
|
-
If you are developing for iOS 10+ you must also add the following to your config.xml
|
|
52
|
+
## Extra iOS installation steps
|
|
53
|
+
You will need to add two permissions to `Info.plist`. Follow the [Capacitor docs](https://capacitorjs.com/docs/ios/configuration#configuring-infoplist) and add permissions with the raw keys `NSCameraUsageDescription` and `NSMicrophoneUsageDescription`.
|
|
75
54
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
<string>Allow the app to use your camera</string>
|
|
79
|
-
</config-file> -->
|
|
80
|
-
|
|
81
|
-
<!-- or for Phonegap -->
|
|
55
|
+
## Extra Web installation steps
|
|
56
|
+
Add `import '@capacitor-community/camera-preview'` to you entry script in ionic on `app.module.ts`, so capacitor can register the web platform from the plugin
|
|
82
57
|
|
|
83
|
-
<!-- <gap:config-file platform="ios" target="*-Info.plist" parent="NSCameraUsageDescription" overwrite="true">
|
|
84
|
-
<string>Allow the app to use your camera</string>
|
|
85
|
-
</gap:config-file>
|
|
86
|
-
``` -->
|
|
87
|
-
<!--
|
|
88
|
-
#### Android Quirks (older devices)
|
|
89
|
-
When using the plugin for older devices, the camera preview will take the focus inside the app once initialized.
|
|
90
|
-
In order to prevent the app from closing when a user presses the back button, the event for the camera view is disabled.
|
|
91
|
-
If you still want the user to navigate, you can add a listener for the back event for the preview
|
|
92
|
-
(see <code>[onBackButton](#onBackButton)</code>)
|
|
93
|
-
-->
|
|
94
58
|
|
|
95
59
|
# Methods
|
|
96
60
|
|
|
@@ -112,6 +76,7 @@ Starts the camera preview instance.
|
|
|
112
76
|
| storeToFile | boolean | (optional) Capture images to a file and return back the file path instead of returning base64 encoded data, default false. |
|
|
113
77
|
| disableExifHeaderStripping | boolean | (optional) Disable automatic rotation of the image, and let the browser deal with it, default true (applicable to the android and ios platforms only) |
|
|
114
78
|
| disableAudio | boolean | (optional) Disables audio stream to prevent permission requests, default false. (applicable to web only) |
|
|
79
|
+
| lockAndroidOrientation | boolean | (optional) Locks device orientation when camer is showing, default false. (applicable to Android only) |
|
|
115
80
|
|
|
116
81
|
<!-- <strong>Options:</strong>
|
|
117
82
|
All options stated are optional and will default to values here
|
|
@@ -148,7 +113,7 @@ ion-content {
|
|
|
148
113
|
--background: transparent;
|
|
149
114
|
}
|
|
150
115
|
```
|
|
151
|
-
Take into account that this will make transparent all ion-content on application, if you want to show camera preview only in one page, just add a
|
|
116
|
+
Take into account that this will make transparent all ion-content on application, if you want to show camera preview only in one page, just add a custom class to your ion-content and make it transparent:
|
|
152
117
|
|
|
153
118
|
```css
|
|
154
119
|
.my-custom-camera-preview-content {
|
|
@@ -205,7 +170,7 @@ CameraPreview.hide();
|
|
|
205
170
|
<!-- <info>Take the picture. If width and height are not specified or are 0 it will use the defaults. If width and height are specified, it will choose a supported photo size that is closest to width and height specified and has closest aspect ratio to the preview. The argument `quality` defaults to `85` and specifies the quality/compression value: `0=max compression`, `100=max quality`.</info><br/> -->
|
|
206
171
|
|
|
207
172
|
```javascript
|
|
208
|
-
import { CameraPreviewFlashMode } from '
|
|
173
|
+
import { CameraPreviewFlashMode } from '@capacitor-community/camera-preview';
|
|
209
174
|
|
|
210
175
|
const cameraPreviewPictureOptions: CameraPreviewPictureOptions = {
|
|
211
176
|
quality: 50
|
|
@@ -218,6 +183,28 @@ const base64PictureData = result.value;
|
|
|
218
183
|
|
|
219
184
|
```
|
|
220
185
|
|
|
186
|
+
### captureSample(options)
|
|
187
|
+
|
|
188
|
+
| Option | values | descriptions |
|
|
189
|
+
|----------|---------------|----------------------------------------------------------------------|
|
|
190
|
+
| quality | number | (optional) The picture quality, 0 - 100, default 85 |
|
|
191
|
+
|
|
192
|
+
<info>Captures a sample image from the video stream. Only for Android and iOS, web implementation falls back to `capture` method. This can be used to perform real-time analysis on the current frame in the video. The argument `quality` defaults to `85` and specifies the quality/compression value: `0=max compression`, `100=max quality`.</info><br/>
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
import { CameraSampleOptions } from '@capacitor-community/camera-preview';
|
|
196
|
+
|
|
197
|
+
const cameraSampleOptions: CameraSampleOptions = {
|
|
198
|
+
quality: 50
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const result = await CameraPreview.captureSample(cameraSampleOptions);
|
|
202
|
+
const base64PictureData = result.value;
|
|
203
|
+
|
|
204
|
+
// do something with base64PictureData
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
|
|
221
208
|
### getSupportedFlashModes()
|
|
222
209
|
|
|
223
210
|
<info>Get the flash modes supported by the camera device currently started. Returns an array containing supported flash modes. See <code>[FLASH_MODE](#camera_Settings.FlashMode)</code> for possible values that can be returned</info><br/>
|
|
@@ -408,3 +395,5 @@ Created by Marcel Barbosa Pinto [@mbppower](https://github.com/mbppower)
|
|
|
408
395
|
# Demo
|
|
409
396
|
|
|
410
397
|
A working example can be found at [Demo](https://github.com/capacitor-community/camera-preview/tree/master/demo)
|
|
398
|
+
|
|
399
|
+
To run the demo on your local network and access media devices, a secure context is needed. Add an `.env` file at the root of the demo folder with `HTTPS=true` to start react with HTTPS.
|
package/android/build.gradle
CHANGED
|
@@ -11,10 +11,10 @@ buildscript {
|
|
|
11
11
|
apply plugin: 'com.android.library'
|
|
12
12
|
|
|
13
13
|
android {
|
|
14
|
-
compileSdkVersion
|
|
14
|
+
compileSdkVersion 30
|
|
15
15
|
defaultConfig {
|
|
16
16
|
minSdkVersion 21
|
|
17
|
-
targetSdkVersion
|
|
17
|
+
targetSdkVersion 30
|
|
18
18
|
versionCode 1
|
|
19
19
|
versionName "1.0"
|
|
20
20
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
|
@@ -40,8 +40,8 @@ repositories {
|
|
|
40
40
|
dependencies {
|
|
41
41
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
42
42
|
implementation project(':capacitor-android')
|
|
43
|
-
implementation 'androidx.appcompat:appcompat:1.
|
|
44
|
-
implementation 'androidx.exifinterface:exifinterface:1.
|
|
43
|
+
implementation 'androidx.appcompat:appcompat:1.3.0'
|
|
44
|
+
implementation 'androidx.exifinterface:exifinterface:1.3.2'
|
|
45
45
|
testImplementation 'junit:junit:4.12'
|
|
46
46
|
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
|
47
47
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
package com.ahm.capacitor.camera.preview;
|
|
2
2
|
|
|
3
|
-
import android.Manifest;
|
|
4
3
|
import android.app.FragmentManager;
|
|
5
4
|
import android.app.FragmentTransaction;
|
|
5
|
+
import android.content.pm.ActivityInfo;
|
|
6
6
|
import android.graphics.Color;
|
|
7
7
|
import android.graphics.Point;
|
|
8
8
|
import android.hardware.Camera;
|
|
@@ -13,33 +13,40 @@ import android.view.ViewGroup;
|
|
|
13
13
|
import android.widget.FrameLayout;
|
|
14
14
|
|
|
15
15
|
import com.getcapacitor.JSObject;
|
|
16
|
-
import com.getcapacitor.
|
|
16
|
+
import com.getcapacitor.Logger;
|
|
17
|
+
import com.getcapacitor.PermissionState;
|
|
17
18
|
import com.getcapacitor.Plugin;
|
|
18
19
|
import com.getcapacitor.PluginCall;
|
|
19
20
|
import com.getcapacitor.PluginMethod;
|
|
21
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
22
|
+
import com.getcapacitor.annotation.Permission;
|
|
23
|
+
import com.getcapacitor.annotation.PermissionCallback;
|
|
20
24
|
|
|
21
25
|
import org.json.JSONArray;
|
|
22
|
-
import org.json.JSONException;
|
|
23
|
-
import org.json.JSONObject;
|
|
24
26
|
|
|
25
|
-
import java.util.List;
|
|
26
27
|
import java.io.File;
|
|
28
|
+
import java.util.List;
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
import static android.Manifest.permission.CAMERA;
|
|
31
|
+
|
|
32
|
+
@CapacitorPlugin(
|
|
33
|
+
name = "CameraPreview",
|
|
29
34
|
permissions = {
|
|
30
|
-
|
|
31
|
-
Manifest.permission.RECORD_AUDIO,
|
|
32
|
-
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
|
33
|
-
Manifest.permission.READ_EXTERNAL_STORAGE
|
|
34
|
-
},
|
|
35
|
-
requestCodes = {
|
|
36
|
-
CameraPreview.REQUEST_CAMERA_PERMISSION
|
|
35
|
+
@Permission(strings = {CAMERA}, alias = CameraPreview.CAMERA_PERMISSION_ALIAS)
|
|
37
36
|
}
|
|
38
37
|
)
|
|
39
38
|
public class CameraPreview extends Plugin implements CameraActivity.CameraPreviewListener {
|
|
39
|
+
static final String CAMERA_PERMISSION_ALIAS = "camera";
|
|
40
|
+
|
|
40
41
|
private static String VIDEO_FILE_PATH = "";
|
|
41
42
|
private static String VIDEO_FILE_EXTENSION = ".mp4";
|
|
42
|
-
|
|
43
|
+
|
|
44
|
+
private String captureCallbackId = "";
|
|
45
|
+
private String snapshotCallbackId = "";
|
|
46
|
+
private String recordCallbackId = "";
|
|
47
|
+
|
|
48
|
+
// keep track of previously specified orientation to support locking orientation:
|
|
49
|
+
private int previousOrientationRequest = -1;
|
|
43
50
|
|
|
44
51
|
private CameraActivity fragment;
|
|
45
52
|
private int containerViewId = 20;
|
|
@@ -50,26 +57,19 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
50
57
|
|
|
51
58
|
JSObject ret = new JSObject();
|
|
52
59
|
ret.put("value", value);
|
|
53
|
-
call.
|
|
60
|
+
call.resolve(ret);
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
@PluginMethod()
|
|
57
64
|
public void start(PluginCall call) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (hasRequiredPermissions()) {
|
|
65
|
+
if (PermissionState.GRANTED.equals(getPermissionState(CAMERA_PERMISSION_ALIAS))) {
|
|
61
66
|
startCamera(call);
|
|
62
67
|
} else {
|
|
63
|
-
|
|
64
|
-
Manifest.permission.CAMERA,
|
|
65
|
-
Manifest.permission.RECORD_AUDIO,
|
|
66
|
-
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
|
67
|
-
Manifest.permission.READ_EXTERNAL_STORAGE
|
|
68
|
-
}, REQUEST_CAMERA_PERMISSION);
|
|
68
|
+
requestPermissionForAlias(CAMERA_PERMISSION_ALIAS, call, "handleCameraPermissionResult");
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
@PluginMethod
|
|
72
|
+
@PluginMethod()
|
|
73
73
|
public void flip(PluginCall call) {
|
|
74
74
|
try {
|
|
75
75
|
fragment.switchCamera();
|
|
@@ -82,11 +82,11 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
82
82
|
@PluginMethod()
|
|
83
83
|
public void capture(PluginCall call) {
|
|
84
84
|
if(this.hasCamera(call) == false){
|
|
85
|
-
call.
|
|
85
|
+
call.reject("Camera is not running");
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
bridge.saveCall(call);
|
|
89
|
+
captureCallbackId = call.getCallbackId();
|
|
90
90
|
|
|
91
91
|
Integer quality = call.getInt("quality", 85);
|
|
92
92
|
// Image Dimensions - Optional
|
|
@@ -95,6 +95,19 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
95
95
|
fragment.takePicture(width, height, quality);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
@PluginMethod()
|
|
99
|
+
public void captureSample(PluginCall call) {
|
|
100
|
+
if(this.hasCamera(call) == false){
|
|
101
|
+
call.reject("Camera is not running");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
bridge.saveCall(call);
|
|
105
|
+
snapshotCallbackId = call.getCallbackId();
|
|
106
|
+
|
|
107
|
+
Integer quality = call.getInt("quality", 85);
|
|
108
|
+
fragment.takeSnapshot(quality);
|
|
109
|
+
}
|
|
110
|
+
|
|
98
111
|
@PluginMethod()
|
|
99
112
|
public void stop(final PluginCall call) {
|
|
100
113
|
bridge.getActivity().runOnUiThread(new Runnable() {
|
|
@@ -102,6 +115,9 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
102
115
|
public void run() {
|
|
103
116
|
FrameLayout containerView = getBridge().getActivity().findViewById(containerViewId);
|
|
104
117
|
|
|
118
|
+
// allow orientation changes after closing camera:
|
|
119
|
+
getBridge().getActivity().setRequestedOrientation(previousOrientationRequest);
|
|
120
|
+
|
|
105
121
|
if (containerView != null) {
|
|
106
122
|
((ViewGroup)getBridge().getWebView().getParent()).removeView(containerView);
|
|
107
123
|
getBridge().getWebView().setBackgroundColor(Color.WHITE);
|
|
@@ -111,7 +127,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
111
127
|
fragmentTransaction.commit();
|
|
112
128
|
fragment = null;
|
|
113
129
|
|
|
114
|
-
call.
|
|
130
|
+
call.resolve();
|
|
115
131
|
} else {
|
|
116
132
|
call.reject("camera already stopped");
|
|
117
133
|
}
|
|
@@ -122,7 +138,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
122
138
|
@PluginMethod()
|
|
123
139
|
public void getSupportedFlashModes(PluginCall call) {
|
|
124
140
|
if(this.hasCamera(call) == false){
|
|
125
|
-
call.
|
|
141
|
+
call.reject("Camera is not running");
|
|
126
142
|
return;
|
|
127
143
|
}
|
|
128
144
|
|
|
@@ -140,20 +156,20 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
140
156
|
|
|
141
157
|
JSObject jsObject = new JSObject();
|
|
142
158
|
jsObject.put("result", jsonFlashModes);
|
|
143
|
-
call.
|
|
159
|
+
call.resolve(jsObject);
|
|
144
160
|
|
|
145
161
|
}
|
|
146
162
|
|
|
147
163
|
@PluginMethod()
|
|
148
164
|
public void setFlashMode(PluginCall call) {
|
|
149
165
|
if(this.hasCamera(call) == false){
|
|
150
|
-
call.
|
|
166
|
+
call.reject("Camera is not running");
|
|
151
167
|
return;
|
|
152
168
|
}
|
|
153
169
|
|
|
154
170
|
String flashMode = call.getString("flashMode");
|
|
155
171
|
if(flashMode == null || flashMode.isEmpty() == true) {
|
|
156
|
-
call.
|
|
172
|
+
call.reject("flashMode required parameter is missing");
|
|
157
173
|
return;
|
|
158
174
|
}
|
|
159
175
|
|
|
@@ -165,36 +181,75 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
165
181
|
if (supportedFlashModes.indexOf(flashMode) > -1) {
|
|
166
182
|
params.setFlashMode(flashMode);
|
|
167
183
|
} else {
|
|
168
|
-
call.
|
|
184
|
+
call.reject("Flash mode not recognised: " + flashMode);
|
|
169
185
|
return;
|
|
170
186
|
}
|
|
171
187
|
|
|
172
188
|
fragment.setCameraParameters(params);
|
|
173
189
|
|
|
174
|
-
call.
|
|
190
|
+
call.resolve();
|
|
175
191
|
}
|
|
176
192
|
|
|
177
|
-
@
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
}
|
|
193
|
+
@PluginMethod()
|
|
194
|
+
public void startRecordVideo(final PluginCall call) {
|
|
195
|
+
if(this.hasCamera(call) == false){
|
|
196
|
+
call.reject("Camera is not running");
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
final String filename = "videoTmp";
|
|
200
|
+
VIDEO_FILE_PATH = getActivity().getCacheDir().toString() + "/";
|
|
187
201
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
202
|
+
final String position = call.getString("position", "front");
|
|
203
|
+
final Integer width = call.getInt("width", 0);
|
|
204
|
+
final Integer height = call.getInt("height", 0);
|
|
205
|
+
final Boolean withFlash = call.getBoolean("withFlash", false);
|
|
206
|
+
final Integer maxDuration = call.getInt("maxDuration", 0);
|
|
207
|
+
// final Integer quality = call.getInt("quality", 0);
|
|
208
|
+
bridge.saveCall(call);
|
|
209
|
+
recordCallbackId = call.getCallbackId();
|
|
210
|
+
|
|
211
|
+
bridge.getActivity().runOnUiThread(new Runnable() {
|
|
212
|
+
@Override
|
|
213
|
+
public void run() {
|
|
214
|
+
// fragment.startRecord(getFilePath(filename), position, width, height, quality, withFlash);
|
|
215
|
+
fragment.startRecord(getFilePath(filename), position, width, height, 70, withFlash, maxDuration);
|
|
193
216
|
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
call.resolve();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
@PluginMethod()
|
|
223
|
+
public void stopRecordVideo(PluginCall call) {
|
|
224
|
+
if(this.hasCamera(call) == false){
|
|
225
|
+
call.reject("Camera is not running");
|
|
226
|
+
return;
|
|
194
227
|
}
|
|
195
228
|
|
|
229
|
+
System.out.println("stopRecordVideo - Callbackid=" + call.getCallbackId());
|
|
230
|
+
|
|
231
|
+
bridge.saveCall(call);
|
|
232
|
+
recordCallbackId = call.getCallbackId();
|
|
233
|
+
|
|
234
|
+
// bridge.getActivity().runOnUiThread(new Runnable() {
|
|
235
|
+
// @Override
|
|
236
|
+
// public void run() {
|
|
237
|
+
// fragment.stopRecord();
|
|
238
|
+
// }
|
|
239
|
+
// });
|
|
196
240
|
|
|
241
|
+
fragment.stopRecord();
|
|
242
|
+
// call.resolve();
|
|
243
|
+
}
|
|
197
244
|
|
|
245
|
+
@PermissionCallback
|
|
246
|
+
private void handleCameraPermissionResult(PluginCall call) {
|
|
247
|
+
if (PermissionState.GRANTED.equals(getPermissionState(CAMERA_PERMISSION_ALIAS))) {
|
|
248
|
+
startCamera(call);
|
|
249
|
+
} else {
|
|
250
|
+
Logger.debug(getLogTag(), "User denied camera permission: " + getPermissionState(CAMERA_PERMISSION_ALIAS).toString());
|
|
251
|
+
call.reject("Permission failed: user denied access to camera.");
|
|
252
|
+
}
|
|
198
253
|
}
|
|
199
254
|
|
|
200
255
|
private void startCamera(final PluginCall call) {
|
|
@@ -215,6 +270,8 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
215
270
|
final Boolean toBack = call.getBoolean("toBack", false);
|
|
216
271
|
final Boolean storeToFile = call.getBoolean("storeToFile", false);
|
|
217
272
|
final Boolean disableExifHeaderStripping = call.getBoolean("disableExifHeaderStripping", true);
|
|
273
|
+
final Boolean lockOrientation = call.getBoolean("lockAndroidOrientation", false);
|
|
274
|
+
previousOrientationRequest = getBridge().getActivity().getRequestedOrientation();
|
|
218
275
|
|
|
219
276
|
fragment = new CameraActivity();
|
|
220
277
|
fragment.setEventListener(this);
|
|
@@ -230,6 +287,11 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
230
287
|
@Override
|
|
231
288
|
public void run() {
|
|
232
289
|
DisplayMetrics metrics = getBridge().getActivity().getResources().getDisplayMetrics();
|
|
290
|
+
// lock orientation if specified in options:
|
|
291
|
+
if (lockOrientation) {
|
|
292
|
+
getBridge().getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
|
|
293
|
+
}
|
|
294
|
+
|
|
233
295
|
// offset
|
|
234
296
|
int computedX = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, x, metrics);
|
|
235
297
|
int computedY = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, y, metrics);
|
|
@@ -283,7 +345,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
283
345
|
fragmentTransaction.add(containerView.getId(), fragment);
|
|
284
346
|
fragmentTransaction.commit();
|
|
285
347
|
|
|
286
|
-
call.
|
|
348
|
+
call.resolve();
|
|
287
349
|
} else {
|
|
288
350
|
call.reject("camera already started");
|
|
289
351
|
}
|
|
@@ -291,7 +353,6 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
291
353
|
});
|
|
292
354
|
}
|
|
293
355
|
|
|
294
|
-
|
|
295
356
|
@Override
|
|
296
357
|
protected void handleOnResume() {
|
|
297
358
|
super.handleOnResume();
|
|
@@ -301,29 +362,24 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
301
362
|
public void onPictureTaken(String originalPicture) {
|
|
302
363
|
JSObject jsObject = new JSObject();
|
|
303
364
|
jsObject.put("value", originalPicture);
|
|
304
|
-
getSavedCall().
|
|
365
|
+
bridge.getSavedCall(captureCallbackId).resolve(jsObject);
|
|
305
366
|
}
|
|
306
367
|
|
|
307
368
|
@Override
|
|
308
369
|
public void onPictureTakenError(String message) {
|
|
309
|
-
getSavedCall().reject(message);
|
|
370
|
+
bridge.getSavedCall(captureCallbackId).reject(message);
|
|
310
371
|
}
|
|
311
372
|
|
|
312
373
|
@Override
|
|
313
374
|
public void onSnapshotTaken(String originalPicture) {
|
|
314
|
-
JSONArray data = new JSONArray();
|
|
315
|
-
data.put(originalPicture);
|
|
316
|
-
|
|
317
|
-
PluginCall call = getSavedCall();
|
|
318
|
-
|
|
319
375
|
JSObject jsObject = new JSObject();
|
|
320
|
-
jsObject.put("
|
|
321
|
-
|
|
376
|
+
jsObject.put("value", originalPicture);
|
|
377
|
+
bridge.getSavedCall(snapshotCallbackId).resolve(jsObject);
|
|
322
378
|
}
|
|
323
379
|
|
|
324
380
|
@Override
|
|
325
381
|
public void onSnapshotTakenError(String message) {
|
|
326
|
-
getSavedCall().reject(message);
|
|
382
|
+
bridge.getSavedCall(snapshotCallbackId).reject(message);
|
|
327
383
|
}
|
|
328
384
|
|
|
329
385
|
@Override
|
|
@@ -343,9 +399,7 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
343
399
|
|
|
344
400
|
@Override
|
|
345
401
|
public void onCameraStarted() {
|
|
346
|
-
PluginCall pluginCall = getSavedCall();
|
|
347
402
|
System.out.println("camera started");
|
|
348
|
-
pluginCall.success();
|
|
349
403
|
}
|
|
350
404
|
|
|
351
405
|
@Override
|
|
@@ -354,20 +408,22 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
354
408
|
}
|
|
355
409
|
@Override
|
|
356
410
|
public void onStartRecordVideoError(String message) {
|
|
357
|
-
getSavedCall().reject(message);
|
|
411
|
+
bridge.getSavedCall(recordCallbackId).reject(message);
|
|
358
412
|
}
|
|
359
413
|
@Override
|
|
360
414
|
public void onStopRecordVideo(String file) {
|
|
361
|
-
PluginCall pluginCall = getSavedCall();
|
|
415
|
+
PluginCall pluginCall = bridge.getSavedCall(recordCallbackId);
|
|
362
416
|
JSObject jsObject = new JSObject();
|
|
363
417
|
jsObject.put("videoFilePath", file);
|
|
364
|
-
pluginCall.
|
|
418
|
+
pluginCall.resolve(jsObject);
|
|
365
419
|
}
|
|
366
420
|
@Override
|
|
367
421
|
public void onStopRecordVideoError(String error) {
|
|
368
|
-
getSavedCall().reject(error);
|
|
422
|
+
bridge.getSavedCall(recordCallbackId).reject(error);
|
|
369
423
|
}
|
|
370
424
|
|
|
425
|
+
|
|
426
|
+
|
|
371
427
|
private boolean hasView(PluginCall call) {
|
|
372
428
|
if(fragment == null) {
|
|
373
429
|
return false;
|
|
@@ -388,62 +444,15 @@ public class CameraPreview extends Plugin implements CameraActivity.CameraPrevie
|
|
|
388
444
|
return true;
|
|
389
445
|
}
|
|
390
446
|
|
|
391
|
-
@PluginMethod()
|
|
392
|
-
public void startRecordVideo(final PluginCall call) {
|
|
393
|
-
if(this.hasCamera(call) == false){
|
|
394
|
-
call.error("Camera is not running");
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
final String filename = "videoTmp";
|
|
398
|
-
VIDEO_FILE_PATH = getActivity().getCacheDir().toString() + "/";
|
|
399
|
-
|
|
400
|
-
final String position = call.getString("position", "front");
|
|
401
|
-
final Integer width = call.getInt("width", 0);
|
|
402
|
-
final Integer height = call.getInt("height", 0);
|
|
403
|
-
final Boolean withFlash = call.getBoolean("withFlash", false);
|
|
404
|
-
final Integer maxDuration = call.getInt("maxDuration", 0);
|
|
405
|
-
// final Integer quality = call.getInt("quality", 0);
|
|
406
|
-
|
|
407
|
-
bridge.getActivity().runOnUiThread(new Runnable() {
|
|
408
|
-
@Override
|
|
409
|
-
public void run() {
|
|
410
|
-
// fragment.startRecord(getFilePath(filename), position, width, height, quality, withFlash);
|
|
411
|
-
fragment.startRecord(getFilePath(filename), position, width, height, 70, withFlash, maxDuration);
|
|
412
|
-
}
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
call.success();
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
@PluginMethod()
|
|
419
|
-
public void stopRecordVideo(PluginCall call) {
|
|
420
|
-
if(this.hasCamera(call) == false){
|
|
421
|
-
call.error("Camera is not running");
|
|
422
|
-
return;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
saveCall(call);
|
|
426
|
-
|
|
427
|
-
// bridge.getActivity().runOnUiThread(new Runnable() {
|
|
428
|
-
// @Override
|
|
429
|
-
// public void run() {
|
|
430
|
-
// fragment.stopRecord();
|
|
431
|
-
// }
|
|
432
|
-
// });
|
|
433
|
-
|
|
434
|
-
fragment.stopRecord();
|
|
435
|
-
// call.success();
|
|
436
|
-
}
|
|
437
|
-
|
|
438
447
|
private String getFilePath(String filename) {
|
|
439
448
|
String fileName = filename;
|
|
440
449
|
|
|
441
450
|
int i = 1;
|
|
442
451
|
|
|
443
452
|
while (new File(VIDEO_FILE_PATH + fileName + VIDEO_FILE_EXTENSION).exists()) {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
453
|
+
// Add number suffix if file exists
|
|
454
|
+
fileName = filename + '_' + i;
|
|
455
|
+
i++;
|
|
447
456
|
}
|
|
448
457
|
|
|
449
458
|
return VIDEO_FILE_PATH + fileName + VIDEO_FILE_EXTENSION;
|