@capacitor-community/camera-preview
Advanced tools
Comparing version 2.0.0-beta.0 to 2.0.0-beta.2
@@ -1,6 +0,1 @@ | ||
declare module "@capacitor/core" { | ||
interface PluginRegistry { | ||
CameraPreview: CameraPreviewPlugin; | ||
} | ||
} | ||
export declare type CameraPosition = 'rear' | 'front'; | ||
@@ -36,2 +31,4 @@ export interface CameraPreviewOptions { | ||
disableAudio?: boolean; | ||
/** Defaults to false - Android Only - Locks device orientation when camera is showing. */ | ||
lockAndroidOrientation?: boolean; | ||
} | ||
@@ -46,2 +43,6 @@ export interface CameraPreviewPictureOptions { | ||
} | ||
export interface CameraSampleOptions { | ||
/** The picture quality, 0 - 100, default 85 */ | ||
quality?: number; | ||
} | ||
export declare type CameraPreviewFlashMode = 'off' | 'on' | 'auto' | 'red-eye' | 'torch'; | ||
@@ -54,2 +55,5 @@ export interface CameraPreviewPlugin { | ||
}>; | ||
captureSample(options: CameraSampleOptions): Promise<{ | ||
value: string; | ||
}>; | ||
getSupportedFlashModes(): Promise<{ | ||
@@ -56,0 +60,0 @@ result: CameraPreviewFlashMode[]; |
@@ -0,1 +1,2 @@ | ||
export {}; | ||
//# sourceMappingURL=definitions.js.map |
@@ -0,2 +1,4 @@ | ||
import { CameraPreviewPlugin } from './definitions'; | ||
declare const CameraPreview: CameraPreviewPlugin; | ||
export * from './definitions'; | ||
export * from './web'; | ||
export { CameraPreview }; |
@@ -0,3 +1,7 @@ | ||
import { registerPlugin } from '@capacitor/core'; | ||
const CameraPreview = registerPlugin('CameraPreview', { | ||
web: () => import('./web').then(m => new m.CameraPreviewWeb()), | ||
}); | ||
export * from './definitions'; | ||
export * from './web'; | ||
export { CameraPreview }; | ||
//# sourceMappingURL=index.js.map |
import { WebPlugin } from "@capacitor/core"; | ||
import { CameraPreviewOptions, CameraPreviewPictureOptions, CameraPreviewPlugin, CameraPreviewFlashMode } from "./definitions"; | ||
import { CameraPreviewOptions, CameraPreviewPictureOptions, CameraPreviewPlugin, CameraPreviewFlashMode, CameraSampleOptions } from "./definitions"; | ||
export declare class CameraPreviewWeb extends WebPlugin implements CameraPreviewPlugin { | ||
/** | ||
* track which camera is used based on start options | ||
* used in capture | ||
*/ | ||
private isBackCamera; | ||
constructor(); | ||
@@ -8,2 +13,3 @@ start(options: CameraPreviewOptions): Promise<{}>; | ||
capture(_options: CameraPreviewPictureOptions): Promise<any>; | ||
captureSample(_options: CameraSampleOptions): Promise<any>; | ||
getSupportedFlashModes(): Promise<{ | ||
@@ -10,0 +16,0 @@ result: CameraPreviewFlashMode[]; |
@@ -1,10 +0,1 @@ | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
import { WebPlugin } from "@capacitor/core"; | ||
@@ -18,85 +9,106 @@ export class CameraPreviewWeb extends WebPlugin { | ||
} | ||
start(options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return new Promise((resolve, reject) => { | ||
navigator.mediaDevices.getUserMedia({ | ||
audio: !options.disableAudio, | ||
video: true | ||
}); | ||
const video = document.getElementById("video"); | ||
const parent = document.getElementById(options.parent); | ||
if (!video) { | ||
const videoElement = document.createElement("video"); | ||
videoElement.id = "video"; | ||
videoElement.setAttribute("class", options.className || ""); | ||
async start(options) { | ||
return new Promise(async (resolve, reject) => { | ||
await navigator.mediaDevices.getUserMedia({ | ||
audio: !options.disableAudio, | ||
video: true | ||
}).then((stream) => { | ||
// Stop any existing stream so we can request media with different constraints based on user input | ||
stream.getTracks().forEach((track) => track.stop()); | ||
}).catch(error => { | ||
reject(error); | ||
}); | ||
const video = document.getElementById("video"); | ||
const parent = document.getElementById(options.parent); | ||
if (!video) { | ||
const videoElement = document.createElement("video"); | ||
videoElement.id = "video"; | ||
videoElement.setAttribute("class", options.className || ""); | ||
// Don't flip video feed if camera is rear facing | ||
if (options.position !== 'rear') { | ||
videoElement.setAttribute("style", "-webkit-transform: scaleX(-1); transform: scaleX(-1);"); | ||
parent.appendChild(videoElement); | ||
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { | ||
// Not adding `{ audio: true }` since we only want video now | ||
navigator.mediaDevices.getUserMedia({ video: true }).then(function (stream) { | ||
//video.src = window.URL.createObjectURL(stream); | ||
videoElement.srcObject = stream; | ||
videoElement.play(); | ||
resolve({}); | ||
}, (err) => { | ||
reject(err); | ||
}); | ||
} | ||
} | ||
else { | ||
reject({ message: "camera already started" }); | ||
const userAgent = navigator.userAgent.toLowerCase(); | ||
const isSafari = userAgent.includes('safari') && !userAgent.includes('chrome'); | ||
// Safari on iOS needs to have the autoplay, muted and playsinline attributes set for video.play() to be successful | ||
// Without these attributes videoElement.play() will throw a NotAllowedError | ||
// https://developer.apple.com/documentation/webkit/delivering_video_content_for_safari | ||
if (isSafari) { | ||
videoElement.setAttribute('autoplay', 'true'); | ||
videoElement.setAttribute('muted', 'true'); | ||
videoElement.setAttribute('playsinline', 'true'); | ||
} | ||
}); | ||
}); | ||
} | ||
stop() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const video = document.getElementById("video"); | ||
if (video) { | ||
video.pause(); | ||
const st = video.srcObject; | ||
const tracks = st.getTracks(); | ||
for (var i = 0; i < tracks.length; i++) { | ||
var track = tracks[i]; | ||
track.stop(); | ||
parent.appendChild(videoElement); | ||
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { | ||
const constraints = { | ||
video: true, | ||
}; | ||
if (options.position === 'rear') { | ||
constraints.video = { facingMode: 'environment' }; | ||
this.isBackCamera = true; | ||
} | ||
else { | ||
this.isBackCamera = false; | ||
} | ||
navigator.mediaDevices.getUserMedia(constraints).then(function (stream) { | ||
//video.src = window.URL.createObjectURL(stream); | ||
videoElement.srcObject = stream; | ||
videoElement.play(); | ||
resolve({}); | ||
}, (err) => { | ||
reject(err); | ||
}); | ||
} | ||
video.remove(); | ||
} | ||
else { | ||
reject({ message: "camera already started" }); | ||
} | ||
}); | ||
} | ||
capture(_options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return new Promise((resolve, _) => { | ||
const video = document.getElementById("video"); | ||
const canvas = document.createElement("canvas"); | ||
// video.width = video.offsetWidth; | ||
const context = canvas.getContext("2d"); | ||
canvas.width = video.videoWidth; | ||
canvas.height = video.videoHeight; | ||
async stop() { | ||
const video = document.getElementById("video"); | ||
if (video) { | ||
video.pause(); | ||
const st = video.srcObject; | ||
const tracks = st.getTracks(); | ||
for (var i = 0; i < tracks.length; i++) { | ||
var track = tracks[i]; | ||
track.stop(); | ||
} | ||
video.remove(); | ||
} | ||
} | ||
async capture(_options) { | ||
return new Promise((resolve, _) => { | ||
const video = document.getElementById("video"); | ||
const canvas = document.createElement("canvas"); | ||
// video.width = video.offsetWidth; | ||
const context = canvas.getContext("2d"); | ||
canvas.width = video.videoWidth; | ||
canvas.height = video.videoHeight; | ||
// flip horizontally back camera isn't used | ||
if (!this.isBackCamera) { | ||
context.translate(video.videoWidth, 0); | ||
context.scale(-1, 1); | ||
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); | ||
resolve({ | ||
value: canvas | ||
.toDataURL("image/png") | ||
.replace("data:image/png;base64,", ""), | ||
}); | ||
} | ||
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); | ||
resolve({ | ||
value: canvas | ||
.toDataURL("image/png") | ||
.replace("data:image/png;base64,", ""), | ||
}); | ||
}); | ||
} | ||
getSupportedFlashModes() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
throw new Error('getSupportedFlashModes not supported under the web platform'); | ||
}); | ||
async captureSample(_options) { | ||
return this.capture(_options); | ||
} | ||
setFlashMode(_options) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
throw new Error('setFlashMode not supported under the web platform'); | ||
}); | ||
async getSupportedFlashModes() { | ||
throw new Error('getSupportedFlashModes not supported under the web platform'); | ||
} | ||
flip() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
throw new Error('flip not supported under the web platform'); | ||
}); | ||
async setFlashMode(_options) { | ||
throw new Error('setFlashMode not supported under the web platform'); | ||
} | ||
async flip() { | ||
throw new Error('flip not supported under the web platform'); | ||
} | ||
} | ||
@@ -103,0 +115,0 @@ const CameraPreview = new CameraPreviewWeb(); |
{ | ||
"name": "@capacitor-community/camera-preview", | ||
"version": "2.0.0-beta.0", | ||
"version": "2.0.0-beta.2", | ||
"description": "Camera preview", | ||
@@ -9,3 +9,3 @@ "main": "dist/esm/index.js", | ||
"build": "npm run clean && tsc", | ||
"clean": "rm -rf ./dist", | ||
"clean": "rimraf './dist'", | ||
"watch": "tsc --watch", | ||
@@ -18,8 +18,9 @@ "prepublishOnly": "npm run build", | ||
"dependencies": { | ||
"@capacitor/core": "^3.0.0-beta.1" | ||
"@capacitor/core": "latest" | ||
}, | ||
"devDependencies": { | ||
"@capacitor/android": "^3.0.0-beta.1", | ||
"@capacitor/ios": "^3.0.0-beta.1", | ||
"typescript": "^3.2.4" | ||
"@capacitor/android": "latest", | ||
"@capacitor/ios": "latest", | ||
"rimraf": "^3.0.2", | ||
"typescript": "^4.3.2" | ||
}, | ||
@@ -26,0 +27,0 @@ "files": [ |
103
README.md
@@ -1,9 +0,14 @@ | ||
# Beta version with initial support for capacitor 3 | ||
<p align="center"><br><img src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png" width="128" height="128" /></p> | ||
<h3 align="center">Capacitor Camera Preview</h3> | ||
<p align="center"><strong><code>@capacitor-community/camera-preview</code></strong></p> | ||
<br> | ||
<p align="center"><strong>CAPACITOR 3</strong></p><br> | ||
# Capacitor Camera Preview | ||
<p align="center"> | ||
Capacitor plugin that allows camera interaction from Javascript and HTML<br>(based on cordova-plugin-camera-preview). | ||
</p> | ||
<br> | ||
Capacitor plugin that allows camera interaction from Javascript and HTML (based on cordova-plugin-camera-preview) | ||
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. | ||
**Releases are being kept up to date when appropriate. However, this plugin is under constant development. As such it is recommended to use master to always have the latest fixes & features.** | ||
**PR's are greatly appreciated. Maintainer(s) wanted.** | ||
@@ -28,18 +33,2 @@ | ||
<!-- Use any one of the installation methods listed below depending on which framework you use. --> | ||
<!-- To install the master version with latest fixes and features --> | ||
<!-- ``` | ||
cordova plugin add https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git | ||
ionic cordova plugin add https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git | ||
meteor add cordova:cordova-plugin-camera-preview@https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git#[latest_commit_id] | ||
<plugin spec="https://github.com/cordova-plugin-camera-preview/cordova-plugin-camera-preview.git" source="git" /> | ||
``` --> | ||
<!-- or if you want to use the last released version on npm --> | ||
``` | ||
@@ -57,41 +46,16 @@ yarn add @capacitor-community/camera-preview | ||
#### Android Quirks | ||
## Extra Android installation steps | ||
Open `android/app/src/main/AndroidManifest.xml` and above the closing `</manifest>` tag add this line to request the CAMERA permission: | ||
```xml | ||
<uses-permission android:name="android.permission.CAMERA" /> | ||
``` | ||
For more help consult the [Capacitor docs](https://capacitorjs.com/docs/android/configuration#configuring-androidmanifestxml). | ||
On Android remember to add the plugin to `MainActivity` | ||
```java | ||
import com.ahm.capacitor.camera.preview.CameraPreview; | ||
## Extra iOS installation steps | ||
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`. | ||
this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{ | ||
// Additional plugins you've installed go here | ||
// Ex: add(TotallyAwesomePlugin.class); | ||
add(CameraPreview.class); | ||
}}); | ||
``` | ||
#### Web Quirks | ||
## Extra Web installation steps | ||
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 | ||
<!-- | ||
#### iOS Quirks | ||
If you are developing for iOS 10+ you must also add the following to your config.xml | ||
```xml | ||
<config-file platform="ios" target="*-Info.plist" parent="NSCameraUsageDescription" overwrite="true"> | ||
<string>Allow the app to use your camera</string> | ||
</config-file> --> | ||
<!-- or for Phonegap --> | ||
<!-- <gap:config-file platform="ios" target="*-Info.plist" parent="NSCameraUsageDescription" overwrite="true"> | ||
<string>Allow the app to use your camera</string> | ||
</gap:config-file> | ||
``` --> | ||
<!-- | ||
#### Android Quirks (older devices) | ||
When using the plugin for older devices, the camera preview will take the focus inside the app once initialized. | ||
In order to prevent the app from closing when a user presses the back button, the event for the camera view is disabled. | ||
If you still want the user to navigate, you can add a listener for the back event for the preview | ||
(see <code>[onBackButton](#onBackButton)</code>) | ||
--> | ||
# Methods | ||
@@ -117,2 +81,3 @@ | ||
| disableAudio | boolean | (optional) Disables audio stream to prevent permission requests, default false. (applicable to web only) | | ||
| lockAndroidOrientation | boolean | (optional) Locks device orientation when camer is showing, default false. (applicable to Android only) | | ||
@@ -154,3 +119,3 @@ <!-- <strong>Options:</strong> | ||
``` | ||
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 cutom class to your ion-content and make it transparent: | ||
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: | ||
@@ -212,3 +177,3 @@ ```css | ||
```javascript | ||
import { CameraPreviewFlashMode } from 'c@capacitor-community/camera-preview'; | ||
import { CameraPreviewFlashMode } from '@capacitor-community/camera-preview'; | ||
@@ -226,2 +191,24 @@ const cameraPreviewPictureOptions: CameraPreviewPictureOptions = { | ||
### captureSample(options) | ||
| Option | values | descriptions | | ||
|----------|---------------|----------------------------------------------------------------------| | ||
| quality | number | (optional) The picture quality, 0 - 100, default 85 | | ||
<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/> | ||
```javascript | ||
import { CameraSampleOptions } from '@capacitor-community/camera-preview'; | ||
const cameraSampleOptions: CameraSampleOptions = { | ||
quality: 50 | ||
}; | ||
const result = await CameraPreview.captureSample(cameraSampleOptions); | ||
const base64PictureData = result.value; | ||
// do something with base64PictureData | ||
``` | ||
### getSupportedFlashModes() | ||
@@ -417,1 +404,3 @@ | ||
A working example can be found at [Demo](https://github.com/capacitor-community/camera-preview/tree/master/demo) | ||
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. |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 3 instances in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
0
0
228405
4
50
214
399
+ Added@capacitor/core@6.2.0(transitive)
- Removed@capacitor/core@3.9.0(transitive)
Updated@capacitor/core@latest