Socket
Socket
Sign inDemoInstall

@uppy/webcam

Package Overview
Dependencies
11
Maintainers
6
Versions
89
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.3.1 to 3.3.2

13

lib/CameraScreen.js
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
/* eslint-disable jsx-a11y/media-has-caption */

@@ -11,7 +10,5 @@ import { h, Component } from 'preact';

import DiscardButton from "./DiscardButton.js";
function isModeAvailable(modes, mode) {
return modes.includes(mode);
}
class CameraScreen extends Component {

@@ -24,3 +21,2 @@ componentDidMount() {

}
componentWillUnmount() {

@@ -32,3 +28,2 @@ const {

}
render() {

@@ -61,8 +56,8 @@ const {

};
if (recordedVideo) {
videoProps.muted = false;
videoProps.controls = true;
videoProps.src = recordedVideo; // reset srcObject in dom. If not resetted, stream sticks in element
videoProps.src = recordedVideo;
// reset srcObject in dom. If not resetted, stream sticks in element
if (this.videoElement) {

@@ -76,3 +71,2 @@ this.videoElement.srcObject = undefined;

}
return h("div", {

@@ -87,3 +81,2 @@ className: "uppy uppy-Webcam-container"

/* eslint-disable-next-line react/jsx-props-no-spreading */
}, videoProps))), h("div", {

@@ -116,5 +109,3 @@ className: "uppy-Webcam-footer"

}
}
export default CameraScreen;
import { h } from 'preact';
function DiscardButton(_ref) {

@@ -32,3 +31,2 @@ let {

}
export default DiscardButton;

@@ -9,3 +9,2 @@ import { h } from 'preact';

} = _ref;
if (recording) {

@@ -33,3 +32,2 @@ return h("button", {

}
return h("button", {

@@ -36,0 +34,0 @@ className: "uppy-u-reset uppy-c-btn uppy-Webcam-button",

import { h } from 'preact';
function SubmitButton(_ref) {

@@ -29,3 +28,2 @@ let {

}
export default SubmitButton;

153

lib/Webcam.js
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _classPrivateFieldLooseBase(receiver, privateKey) { if (!Object.prototype.hasOwnProperty.call(receiver, privateKey)) { throw new TypeError("attempted to use private field on non-instance"); } return receiver; }
var id = 0;
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
import { h } from 'preact';

@@ -20,5 +16,6 @@ import { UIPlugin } from '@uppy/core';

const packageJson = {
"version": "3.3.1"
"version": "3.3.2"
};
import locale from './locale.js';
/**

@@ -30,3 +27,2 @@ * Normalize a MIME type or file extension into a MIME type.

*/
function toMimeType(fileType) {

@@ -36,5 +32,5 @@ if (fileType[0] === '.') {

}
return fileType;
}
/**

@@ -46,7 +42,6 @@ * Is this MIME type a video?

*/
function isVideoMimeType(mimeType) {
return /^video\/[^*]+$/.test(mimeType);
}
/**

@@ -58,8 +53,5 @@ * Is this MIME type an image?

*/
function isImageMimeType(mimeType) {
return /^image\/[^*]+$/.test(mimeType);
}
function getMediaDevices() {

@@ -70,18 +62,15 @@ // bug in the compatibility data

}
function isModeAvailable(modes, mode) {
return modes.includes(mode);
}
/**
* Webcam
*/
var _enableMirror = /*#__PURE__*/_classPrivateFieldLooseKey("enableMirror");
export default class Webcam extends UIPlugin {
// enableMirror is used to toggle mirroring, for instance when discarding the video,
// while `opts.mirror` is used to remember the initial user setting
constructor(uppy, opts) {
super(uppy, opts);
// enableMirror is used to toggle mirroring, for instance when discarding the video,
// while `opts.mirror` is used to remember the initial user setting
Object.defineProperty(this, _enableMirror, {

@@ -92,4 +81,4 @@ writable: true,

this.mediaDevices = getMediaDevices();
this.supportsUserMedia = !!this.mediaDevices; // eslint-disable-next-line no-restricted-globals
this.supportsUserMedia = !!this.mediaDevices;
// eslint-disable-next-line no-restricted-globals
this.protocol = location.protocol.match(/https/i) ? 'https' : 'http';

@@ -99,3 +88,2 @@ this.id = this.opts.id || 'Webcam';

this.capturedMediaFile = null;
this.icon = () => h("svg", {

@@ -112,5 +100,5 @@ "aria-hidden": "true",

}));
this.defaultLocale = locale;
this.defaultLocale = locale; // set default options
// set default options
const defaultOptions = {

@@ -132,3 +120,4 @@ onBeforeSnapshot: () => Promise.resolve(),

};
this.opts = { ...defaultOptions,
this.opts = {
...defaultOptions,
...opts

@@ -141,4 +130,5 @@ };

this.setPluginState = this.setPluginState.bind(this);
this.render = this.render.bind(this); // Camera controls
this.render = this.render.bind(this);
// Camera controls
this.start = this.start.bind(this);

@@ -155,7 +145,5 @@ this.stop = this.stop.bind(this);

this.webcamActive = false;
if (this.opts.countdown) {
this.opts.onBeforeSnapshot = this.oneTwoThreeSmile;
}
this.setPluginState({

@@ -170,6 +158,7 @@ hasCamera: false,

}
setOptions(newOpts) {
super.setOptions({ ...newOpts,
videoConstraints: { // May be undefined but ... handles that
super.setOptions({
...newOpts,
videoConstraints: {
// May be undefined but ... handles that
...this.opts.videoConstraints,

@@ -180,3 +169,2 @@ ...(newOpts == null ? void 0 : newOpts.videoConstraints)

}
hasCameraCheck() {

@@ -186,3 +174,2 @@ if (!this.mediaDevices) {

}
return this.mediaDevices.enumerateDevices().then(devices => {

@@ -192,7 +179,5 @@ return devices.some(device => device.kind === 'videoinput');

}
isAudioOnly() {
return this.opts.modes.length === 1 && this.opts.modes[0] === 'audio-only';
}
getConstraints(deviceId) {

@@ -202,6 +187,6 @@ if (deviceId === void 0) {

}
const acceptsAudio = this.opts.modes.indexOf('video-audio') !== -1 || this.opts.modes.indexOf('audio-only') !== -1;
const acceptsVideo = !this.isAudioOnly() && (this.opts.modes.indexOf('video-audio') !== -1 || this.opts.modes.indexOf('video-only') !== -1 || this.opts.modes.indexOf('picture') !== -1);
const videoConstraints = { ...(this.opts.videoConstraints || {
const videoConstraints = {
...(this.opts.videoConstraints || {
facingMode: this.opts.facingMode

@@ -220,5 +205,5 @@ }),

};
} // eslint-disable-next-line consistent-return
}
// eslint-disable-next-line consistent-return
start(options) {

@@ -228,13 +213,9 @@ if (options === void 0) {

}
if (!this.supportsUserMedia) {
return Promise.reject(new Error('Webcam access not supported'));
}
this.webcamActive = true;
if (this.opts.mirror) {
_classPrivateFieldLooseBase(this, _enableMirror)[_enableMirror] = true;
}
const constraints = this.getConstraints(options && options.deviceId ? options.deviceId : null);

@@ -244,4 +225,5 @@ this.hasCameraCheck().then(hasCamera => {

hasCamera
}); // ask user for access to their camera
});
// ask user for access to their camera
return this.mediaDevices.getUserMedia(constraints).then(stream => {

@@ -251,3 +233,2 @@ this.stream = stream;

const tracks = this.isAudioOnly() ? stream.getAudioTracks() : stream.getVideoTracks();
if (!options || !options.deviceId) {

@@ -261,5 +242,5 @@ currentDeviceId = tracks[0].getSettings().deviceId;

});
} // Update the sources now, so we can access the names.
}
// Update the sources now, so we can access the names.
this.updateVideoSources();

@@ -279,12 +260,12 @@ this.setPluginState({

}
/**
* @returns {object}
*/
getMediaRecorderOptions() {
const options = {};
getMediaRecorderOptions() {
const options = {}; // Try to use the `opts.preferredVideoMimeType` or one of the `allowedFileTypes` for the recording.
// Try to use the `opts.preferredVideoMimeType` or one of the `allowedFileTypes` for the recording.
// If the browser doesn't support it, we'll fall back to the browser default instead.
// Safari doesn't have the `isTypeSupported` API.
if (MediaRecorder.isTypeSupported) {

@@ -295,3 +276,2 @@ const {

let preferredVideoMimeTypes = [];
if (this.opts.preferredVideoMimeType) {

@@ -302,7 +282,4 @@ preferredVideoMimeTypes = [this.opts.preferredVideoMimeType];

}
const filterSupportedTypes = candidateType => MediaRecorder.isTypeSupported(candidateType) && getFileTypeExtension(candidateType);
const acceptableMimeTypes = preferredVideoMimeTypes.filter(filterSupportedTypes);
if (acceptableMimeTypes.length > 0) {

@@ -313,6 +290,4 @@ // eslint-disable-next-line prefer-destructuring

}
return options;
}
startRecording() {

@@ -329,10 +304,8 @@ // only used if supportsMediaRecorder() returned true

} = this.uppy.opts;
if (this.recordingChunks.length > 1 && restrictions.maxFileSize != null && !stoppingBecauseOfMaxSize) {
const totalSize = this.recordingChunks.reduce((acc, chunk) => acc + chunk.size, 0); // Exclude the initial chunk from the average size calculation because it is likely to be a very small outlier
const totalSize = this.recordingChunks.reduce((acc, chunk) => acc + chunk.size, 0);
// Exclude the initial chunk from the average size calculation because it is likely to be a very small outlier
const averageChunkSize = (totalSize - this.recordingChunks[0].size) / (this.recordingChunks.length - 1);
const expectedEndChunkSize = averageChunkSize * 3;
const maxSize = Math.max(0, restrictions.maxFileSize - expectedEndChunkSize);
if (totalSize > maxSize) {

@@ -344,7 +317,7 @@ stoppingBecauseOfMaxSize = true;

}
}); // use a "time slice" of 500ms: ondataavailable will be called each 500ms
});
// use a "time slice" of 500ms: ondataavailable will be called each 500ms
// smaller time slices mean we can more accurately check the max file size restriction
this.recorder.start(500);
if (this.opts.showRecordingLength) {

@@ -359,3 +332,2 @@ // Start the recordingLengthTimer if we are showing the recording length.

}
this.setPluginState({

@@ -365,3 +337,2 @@ isRecording: true

}
stopRecording() {

@@ -373,3 +344,2 @@ const stopped = new Promise(resolve => {

this.recorder.stop();
if (this.opts.showRecordingLength) {

@@ -390,4 +360,4 @@ // Stop the recordingLengthTimer if we are showing the recording length.

try {
this.capturedMediaFile = file; // create object url for capture result preview
this.capturedMediaFile = file;
// create object url for capture result preview
this.setPluginState({

@@ -413,3 +383,2 @@ // eslint-disable-next-line compat/compat

}
discardRecordedVideo() {

@@ -419,10 +388,7 @@ this.setPluginState({

});
if (this.opts.mirror) {
_classPrivateFieldLooseBase(this, _enableMirror)[_enableMirror] = true;
}
this.capturedMediaFile = null;
}
submit() {

@@ -440,3 +406,2 @@ try {

}
async stop() {

@@ -448,3 +413,2 @@ if (this.stream) {

}
if (this.recorder) {

@@ -456,3 +420,2 @@ await new Promise(resolve => {

this.recorder.stop();
if (this.opts.showRecordingLength) {

@@ -463,3 +426,2 @@ clearInterval(this.recordingLengthTimer);

}
this.recordingChunks = null;

@@ -475,11 +437,10 @@ this.recorder = null;

}
getVideoElement() {
return this.el.querySelector('.uppy-Webcam-video');
}
oneTwoThreeSmile() {
return new Promise((resolve, reject) => {
let count = this.opts.countdown; // eslint-disable-next-line consistent-return
let count = this.opts.countdown;
// eslint-disable-next-line consistent-return
const countDown = setInterval(() => {

@@ -491,3 +452,2 @@ if (!this.webcamActive) {

}
if (count > 0) {

@@ -504,3 +464,2 @@ this.uppy.info(`${count}...`, 'warning', 800);

}
takeSnapshot() {

@@ -517,3 +476,2 @@ if (this.captureInProgress) return;

this.captureInProgress = false;
try {

@@ -532,10 +490,7 @@ this.uppy.addFile(tagFile);

}
getImage() {
const video = this.getVideoElement();
if (!video) {
return Promise.reject(new Error('No video element found, likely due to the Webcam tab being closed.'));
}
const width = video.videoWidth;

@@ -552,3 +507,2 @@ const height = video.videoHeight;

let preferredImageMimeTypes = [];
if (this.opts.preferredImageMimeType) {

@@ -559,3 +513,2 @@ preferredImageMimeTypes = [this.opts.preferredImageMimeType];

}
const mimeType = preferredImageMimeTypes[0] || 'image/jpeg';

@@ -575,3 +528,2 @@ const ext = getFileTypeExtension(mimeType) || 'jpg';

}
getVideo() {

@@ -583,11 +535,8 @@ // Sometimes in iOS Safari, Blobs (especially the first Blob in the recordingChunks Array)

var _blob$type;
return ((_blob$type = blob.type) == null ? void 0 : _blob$type.length) > 0;
}).type;
const fileExtension = getFileTypeExtension(mimeType);
if (!fileExtension) {
return Promise.reject(new Error(`Could not retrieve recording: Unsupported media type "${mimeType}"`));
}
const name = `webcam-${Date.now()}.${fileExtension}`;

@@ -607,3 +556,2 @@ const blob = new Blob(this.recordingChunks, {

}
focus() {

@@ -615,3 +563,2 @@ if (!this.opts.countdown) return;

}
changeVideoSource(deviceId) {

@@ -623,3 +570,2 @@ this.stop();

}
updateVideoSources() {

@@ -632,3 +578,2 @@ this.mediaDevices.enumerateDevices().then(devices => {

}
render() {

@@ -638,5 +583,3 @@ if (!this.webcamActive) {

}
const webcamState = this.getPluginState();
if (!webcamState.cameraReady || !webcamState.hasCamera) {

@@ -649,4 +592,4 @@ return h(PermissionsScreen, {

}
return h(CameraScreen // eslint-disable-next-line react/jsx-props-no-spreading
return h(CameraScreen
// eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, webcamState, {

@@ -671,3 +614,2 @@ onChangeVideoSource: this.changeVideoSource,

}
install() {

@@ -683,6 +625,4 @@ const {

} = this.opts;
if (mobileNativeCamera && target) {
var _this$getTargetPlugin;
(_this$getTargetPlugin = this.getTargetPlugin(target)) == null ? void 0 : _this$getTargetPlugin.setOptions({

@@ -695,3 +635,2 @@ showNativeVideoCameraButton: isModeAvailable(modes, 'video-only') || isModeAvailable(modes, 'video-audio'),

}
this.setPluginState({

@@ -701,13 +640,9 @@ cameraReady: false,

});
if (target) {
this.mount(target, this);
}
if (this.mediaDevices) {
this.updateVideoSources();
this.mediaDevices.ondevicechange = () => {
this.updateVideoSources();
if (this.stream) {

@@ -724,3 +659,2 @@ let restartStream = true;

});
if (restartStream) {

@@ -734,3 +668,2 @@ this.stop();

}
uninstall() {

@@ -740,8 +673,6 @@ this.stop();

}
onUnmount() {
this.stop();
}
}
Webcam.VERSION = packageJson.version;
{
"name": "@uppy/webcam",
"description": "Uppy plugin that takes photos or records videos using the device's camera.",
"version": "3.3.1",
"version": "3.3.2",
"license": "MIT",

@@ -30,3 +30,3 @@ "main": "lib/index.js",

"dependencies": {
"@uppy/utils": "^5.3.0",
"@uppy/utils": "^5.4.3",
"is-mobile": "^3.1.1",

@@ -39,4 +39,4 @@ "preact": "^10.5.13"

"peerDependencies": {
"@uppy/core": "^3.2.0"
"@uppy/core": "^3.4.0"
}
}

@@ -1,2 +0,2 @@

import type { PluginOptions, UIPlugin, PluginTarget } from '@uppy/core'
import type { PluginTarget, UIPlugin, UIPluginOptions } from '@uppy/core'
import WebcamLocale from './generatedLocale'

@@ -10,3 +10,3 @@

export interface WebcamOptions extends PluginOptions {
export interface WebcamOptions extends UIPluginOptions {
target?: PluginTarget

@@ -13,0 +13,0 @@ onBeforeSnapshot?: () => Promise<void>

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

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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc