Socket
Socket
Sign inDemoInstall

@uppy/webcam

Package Overview
Dependencies
Maintainers
5
Versions
96
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@uppy/webcam - npm Package Compare versions

Comparing version 1.8.13 to 2.0.0-alpha.0

9

lib/CameraIcon.js

@@ -1,5 +0,8 @@

var _require = require('preact'),
h = _require.h;
"use strict";
module.exports = function (props) {
const {
h
} = require('preact');
module.exports = props => {
return h("svg", {

@@ -6,0 +9,0 @@ "aria-hidden": "true",

@@ -0,23 +1,22 @@

"use strict";
function _extends() { _extends = Object.assign || 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 _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
/* eslint-disable jsx-a11y/media-has-caption */
var _require = require('preact'),
h = _require.h,
Component = _require.Component;
const {
h,
Component
} = require('preact');
var SnapshotButton = require('./SnapshotButton');
const SnapshotButton = require('./SnapshotButton');
var RecordButton = require('./RecordButton');
const RecordButton = require('./RecordButton');
var RecordingLength = require('./RecordingLength');
const RecordingLength = require('./RecordingLength');
var VideoSourceSelect = require('./VideoSourceSelect');
const VideoSourceSelect = require('./VideoSourceSelect');
var SubmitButton = require('./SubmitButton');
const SubmitButton = require('./SubmitButton');
var DiscardButton = require('./DiscardButton');
const DiscardButton = require('./DiscardButton');

@@ -28,47 +27,42 @@ function isModeAvailable(modes, mode) {

var CameraScreen = /*#__PURE__*/function (_Component) {
_inheritsLoose(CameraScreen, _Component);
function CameraScreen() {
return _Component.apply(this, arguments) || this;
class CameraScreen extends Component {
componentDidMount() {
const {
onFocus
} = this.props;
onFocus();
}
var _proto = CameraScreen.prototype;
_proto.componentDidMount = function componentDidMount() {
var onFocus = this.props.onFocus;
onFocus();
};
_proto.componentWillUnmount = function componentWillUnmount() {
var onStop = this.props.onStop;
componentWillUnmount() {
const {
onStop
} = this.props;
onStop();
};
}
_proto.render = function render() {
var _this = this;
var _this$props = this.props,
src = _this$props.src,
recordedVideo = _this$props.recordedVideo,
recording = _this$props.recording,
modes = _this$props.modes,
supportsRecording = _this$props.supportsRecording,
videoSources = _this$props.videoSources,
showVideoSourceDropdown = _this$props.showVideoSourceDropdown,
showRecordingLength = _this$props.showRecordingLength,
onSubmit = _this$props.onSubmit,
i18n = _this$props.i18n,
mirror = _this$props.mirror,
onSnapshot = _this$props.onSnapshot,
onStartRecording = _this$props.onStartRecording,
onStopRecording = _this$props.onStopRecording,
onDiscardRecordedVideo = _this$props.onDiscardRecordedVideo,
recordingLengthSeconds = _this$props.recordingLengthSeconds;
var hasRecordedVideo = !!recordedVideo;
var shouldShowRecordButton = !hasRecordedVideo && supportsRecording && (isModeAvailable(modes, 'video-only') || isModeAvailable(modes, 'audio-only') || isModeAvailable(modes, 'video-audio'));
var shouldShowSnapshotButton = !hasRecordedVideo && isModeAvailable(modes, 'picture');
var shouldShowRecordingLength = supportsRecording && showRecordingLength;
var shouldShowVideoSourceDropdown = showVideoSourceDropdown && videoSources && videoSources.length > 1;
var videoProps = {
render() {
const {
src,
recordedVideo,
recording,
modes,
supportsRecording,
videoSources,
showVideoSourceDropdown,
showRecordingLength,
onSubmit,
i18n,
mirror,
onSnapshot,
onStartRecording,
onStopRecording,
onDiscardRecordedVideo,
recordingLengthSeconds
} = this.props;
const hasRecordedVideo = !!recordedVideo;
const shouldShowRecordButton = !hasRecordedVideo && supportsRecording && (isModeAvailable(modes, 'video-only') || isModeAvailable(modes, 'audio-only') || isModeAvailable(modes, 'video-audio'));
const shouldShowSnapshotButton = !hasRecordedVideo && isModeAvailable(modes, 'picture');
const shouldShowRecordingLength = supportsRecording && showRecordingLength;
const shouldShowVideoSourceDropdown = showVideoSourceDropdown && videoSources && videoSources.length > 1;
const videoProps = {
playsinline: true

@@ -97,6 +91,4 @@ };

/* eslint-disable-next-line no-return-assign */
ref: function ref(videoElement) {
return _this.videoElement = videoElement;
},
className: "uppy-Webcam-video " + (mirror ? 'uppy-Webcam-video--mirrored' : '')
ref: videoElement => this.videoElement = videoElement,
className: `uppy-Webcam-video ${mirror ? 'uppy-Webcam-video--mirrored' : ''}`
/* eslint-disable-next-line react/jsx-props-no-spreading */

@@ -130,7 +122,6 @@

}))));
};
}
return CameraScreen;
}(Component);
}
module.exports = CameraScreen;

@@ -1,7 +0,11 @@

var _require = require('preact'),
h = _require.h;
"use strict";
function DiscardButton(_ref) {
var onDiscard = _ref.onDiscard,
i18n = _ref.i18n;
const {
h
} = require('preact');
function DiscardButton({
onDiscard,
i18n
}) {
return h("button", {

@@ -8,0 +12,0 @@ className: "uppy-u-reset uppy-c-btn uppy-Webcam-button",

@@ -0,1 +1,3 @@

"use strict";
/**

@@ -9,3 +11,3 @@ * Takes an Integer value of seconds (e.g. 83) and converts it into a human-readable formatted string (e.g. '1:23').

module.exports = function formatSeconds(seconds) {
return Math.floor(seconds / 60) + ":" + String(seconds % 60).padStart(2, 0);
return `${Math.floor(seconds / 60)}:${String(seconds % 60).padStart(2, 0)}`;
};

@@ -0,1 +1,3 @@

"use strict";
var _class, _temp;

@@ -5,29 +7,25 @@

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
const {
h
} = require('preact');
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
const {
UIPlugin
} = require('@uppy/core');
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
const Translator = require('@uppy/utils/lib/Translator');
var _require = require('preact'),
h = _require.h;
const getFileTypeExtension = require('@uppy/utils/lib/getFileTypeExtension');
var _require2 = require('@uppy/core'),
Plugin = _require2.Plugin;
const mimeTypes = require('@uppy/utils/lib/mimeTypes');
var Translator = require('@uppy/utils/lib/Translator');
const canvasToBlob = require('@uppy/utils/lib/canvasToBlob');
var getFileTypeExtension = require('@uppy/utils/lib/getFileTypeExtension');
const supportsMediaRecorder = require('./supportsMediaRecorder');
var mimeTypes = require('@uppy/utils/lib/mimeTypes');
const CameraIcon = require('./CameraIcon');
var canvasToBlob = require('@uppy/utils/lib/canvasToBlob');
const CameraScreen = require('./CameraScreen');
var supportsMediaRecorder = require('./supportsMediaRecorder');
var CameraIcon = require('./CameraIcon');
var CameraScreen = require('./CameraScreen');
var PermissionsScreen = require('./PermissionsScreen');
const PermissionsScreen = require('./PermissionsScreen');
/**

@@ -70,28 +68,7 @@ * Normalize a MIME type or file extension into a MIME type.

}
/**
* Setup getUserMedia, with polyfill for older browsers
* Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
*/
function getMediaDevices() {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
// eslint-disable-next-line compat/compat
return navigator.mediaDevices;
}
var _getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
if (!_getUserMedia) {
return null;
}
return {
getUserMedia: function getUserMedia(opts) {
return new Promise(function (resolve, reject) {
_getUserMedia.call(navigator, opts, resolve, reject);
});
}
};
return navigator.mediaDevices;
}

@@ -103,44 +80,38 @@ /**

module.exports = (_temp = _class = /*#__PURE__*/function (_Plugin) {
_inheritsLoose(Webcam, _Plugin);
module.exports = (_temp = _class = class Webcam extends UIPlugin {
// eslint-disable-next-line global-require
function Webcam(uppy, opts) {
var _this;
constructor(uppy, opts) {
super(uppy, opts);
this.mediaDevices = getMediaDevices();
this.supportsUserMedia = !!this.mediaDevices; // eslint-disable-next-line no-restricted-globals
_this = _Plugin.call(this, uppy, opts) || this;
_this.mediaDevices = getMediaDevices();
_this.supportsUserMedia = !!_this.mediaDevices; // eslint-disable-next-line no-restricted-globals
this.protocol = location.protocol.match(/https/i) ? 'https' : 'http';
this.id = this.opts.id || 'Webcam';
this.type = 'acquirer';
this.capturedMediaFile = null;
_this.protocol = location.protocol.match(/https/i) ? 'https' : 'http';
_this.id = _this.opts.id || 'Webcam';
_this.title = _this.opts.title || 'Camera';
_this.type = 'acquirer';
_this.capturedMediaFile = null;
this.icon = () => h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#03BFEF",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M22 11c1.133 0 2 .867 2 2v7.333c0 1.134-.867 2-2 2H10c-1.133 0-2-.866-2-2V13c0-1.133.867-2 2-2h2.333l1.134-1.733C13.6 9.133 13.8 9 14 9h4c.2 0 .4.133.533.267L19.667 11H22zm-6 1.533a3.764 3.764 0 0 0-3.8 3.8c0 2.129 1.672 3.801 3.8 3.801s3.8-1.672 3.8-3.8c0-2.13-1.672-3.801-3.8-3.801zm0 6.261c-1.395 0-2.46-1.066-2.46-2.46 0-1.395 1.065-2.461 2.46-2.461s2.46 1.066 2.46 2.46c0 1.395-1.065 2.461-2.46 2.461z",
fill: "#FFF",
fillRule: "nonzero"
})));
_this.icon = function () {
return h("svg", {
"aria-hidden": "true",
focusable: "false",
width: "32",
height: "32",
viewBox: "0 0 32 32"
}, h("g", {
fill: "none",
fillRule: "evenodd"
}, h("rect", {
className: "uppy-ProviderIconBg",
fill: "#03BFEF",
width: "32",
height: "32",
rx: "16"
}), h("path", {
d: "M22 11c1.133 0 2 .867 2 2v7.333c0 1.134-.867 2-2 2H10c-1.133 0-2-.866-2-2V13c0-1.133.867-2 2-2h2.333l1.134-1.733C13.6 9.133 13.8 9 14 9h4c.2 0 .4.133.533.267L19.667 11H22zm-6 1.533a3.764 3.764 0 0 0-3.8 3.8c0 2.129 1.672 3.801 3.8 3.801s3.8-1.672 3.8-3.8c0-2.13-1.672-3.801-3.8-3.801zm0 6.261c-1.395 0-2.46-1.066-2.46-2.46 0-1.395 1.065-2.461 2.46-2.461s2.46 1.066 2.46 2.46c0 1.395-1.065 2.461-2.46 2.461z",
fill: "#FFF",
fillRule: "nonzero"
})));
};
_this.defaultLocale = {
this.defaultLocale = {
strings: {
pluginNameCamera: 'Camera',
smile: 'Smile!',

@@ -161,6 +132,4 @@ takePicture: 'Take a picture',

var defaultOptions = {
onBeforeSnapshot: function onBeforeSnapshot() {
return Promise.resolve();
},
const defaultOptions = {
onBeforeSnapshot: () => Promise.resolve(),
countdown: false,

@@ -175,27 +144,28 @@ modes: ['video-audio', 'video-only', 'audio-only', 'picture'],

};
_this.opts = _extends({}, defaultOptions, opts);
this.opts = { ...defaultOptions,
...opts
};
this.i18nInit();
this.title = this.i18n('pluginNameCamera');
this.install = this.install.bind(this);
this.setPluginState = this.setPluginState.bind(this);
this.render = this.render.bind(this); // Camera controls
_this.i18nInit();
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
this.takeSnapshot = this.takeSnapshot.bind(this);
this.startRecording = this.startRecording.bind(this);
this.stopRecording = this.stopRecording.bind(this);
this.discardRecordedVideo = this.discardRecordedVideo.bind(this);
this.submit = this.submit.bind(this);
this.oneTwoThreeSmile = this.oneTwoThreeSmile.bind(this);
this.focus = this.focus.bind(this);
this.changeVideoSource = this.changeVideoSource.bind(this);
this.webcamActive = false;
_this.install = _this.install.bind(_assertThisInitialized(_this));
_this.setPluginState = _this.setPluginState.bind(_assertThisInitialized(_this));
_this.render = _this.render.bind(_assertThisInitialized(_this)); // Camera controls
_this.start = _this.start.bind(_assertThisInitialized(_this));
_this.stop = _this.stop.bind(_assertThisInitialized(_this));
_this.takeSnapshot = _this.takeSnapshot.bind(_assertThisInitialized(_this));
_this.startRecording = _this.startRecording.bind(_assertThisInitialized(_this));
_this.stopRecording = _this.stopRecording.bind(_assertThisInitialized(_this));
_this.discardRecordedVideo = _this.discardRecordedVideo.bind(_assertThisInitialized(_this));
_this.submit = _this.submit.bind(_assertThisInitialized(_this));
_this.oneTwoThreeSmile = _this.oneTwoThreeSmile.bind(_assertThisInitialized(_this));
_this.focus = _this.focus.bind(_assertThisInitialized(_this));
_this.changeVideoSource = _this.changeVideoSource.bind(_assertThisInitialized(_this));
_this.webcamActive = false;
if (_this.opts.countdown) {
_this.opts.onBeforeSnapshot = _this.oneTwoThreeSmile;
if (this.opts.countdown) {
this.opts.onBeforeSnapshot = this.oneTwoThreeSmile;
}
_this.setPluginState({
this.setPluginState({
hasCamera: false,

@@ -208,24 +178,14 @@ cameraReady: false,

});
}
return _this;
setOptions(newOpts) {
super.setOptions({ ...newOpts,
videoConstraints: { // May be undefined but ... handles that
...this.opts.videoConstraints,
...(newOpts == null ? void 0 : newOpts.videoConstraints)
}
});
}
var _proto = Webcam.prototype;
_proto.setOptions = function setOptions(newOpts) {
_Plugin.prototype.setOptions.call(this, _extends({}, newOpts, {
videoConstraints: _extends({}, this.opts.videoConstraints, newOpts == null ? void 0 : newOpts.videoConstraints)
}));
this.i18nInit();
};
_proto.i18nInit = function i18nInit() {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale]);
this.i18n = this.translator.translate.bind(this.translator);
this.i18nArray = this.translator.translateArray.bind(this.translator);
this.setPluginState(); // so that UI re-renders and we see the updated locale
};
_proto.hasCameraCheck = function hasCameraCheck() {
hasCameraCheck() {
if (!this.mediaDevices) {

@@ -235,30 +195,24 @@ return Promise.resolve(false);

return this.mediaDevices.enumerateDevices().then(function (devices) {
return devices.some(function (device) {
return device.kind === 'videoinput';
});
return this.mediaDevices.enumerateDevices().then(devices => {
return devices.some(device => device.kind === 'videoinput');
});
};
}
_proto.isAudioOnly = function isAudioOnly() {
isAudioOnly() {
return this.opts.modes.length === 1 && this.opts.modes[0] === 'audio-only';
};
}
_proto.getConstraints = function getConstraints(deviceId) {
var _this$opts$videoConst;
if (deviceId === void 0) {
deviceId = null;
}
var acceptsAudio = this.opts.modes.indexOf('video-audio') !== -1 || this.opts.modes.indexOf('audio-only') !== -1;
var acceptsVideo = !this.isAudioOnly() && (this.opts.modes.indexOf('video-audio') !== -1 || this.opts.modes.indexOf('video-only') !== -1 || this.opts.modes.indexOf('picture') !== -1);
var videoConstraints = _extends({}, (_this$opts$videoConst = this.opts.videoConstraints) != null ? _this$opts$videoConst : {
facingMode: this.opts.facingMode
}, deviceId ? {
deviceId: deviceId,
facingMode: null
} : {});
getConstraints(deviceId = null) {
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 || {
facingMode: this.opts.facingMode
}),
// facingMode takes precedence over deviceId, and not needed
// when specific device is selected
...(deviceId ? {
deviceId,
facingMode: null
} : {})
};
return {

@@ -269,11 +223,5 @@ audio: acceptsAudio,

} // eslint-disable-next-line consistent-return
;
_proto.start = function start(options) {
var _this2 = this;
if (options === void 0) {
options = null;
}
start(options = null) {
if (!this.supportsUserMedia) {

@@ -285,18 +233,17 @@ return Promise.reject(new Error('Webcam access not supported'));

this.opts.mirror = true;
var constraints = this.getConstraints(options && options.deviceId ? options.deviceId : null);
this.hasCameraCheck().then(function (hasCamera) {
_this2.setPluginState({
hasCamera: hasCamera
const constraints = this.getConstraints(options && options.deviceId ? options.deviceId : null);
this.hasCameraCheck().then(hasCamera => {
this.setPluginState({
hasCamera
}); // ask user for access to their camera
return this.mediaDevices.getUserMedia(constraints).then(stream => {
this.stream = stream;
let currentDeviceId = null;
const tracks = this.isAudioOnly() ? stream.getAudioTracks() : stream.getVideoTracks();
return _this2.mediaDevices.getUserMedia(constraints).then(function (stream) {
_this2.stream = stream;
var currentDeviceId = null;
var tracks = _this2.isAudioOnly() ? stream.getAudioTracks() : stream.getVideoTracks();
if (!options || !options.deviceId) {
currentDeviceId = tracks[0].getSettings().deviceId;
} else {
tracks.forEach(function (track) {
tracks.forEach(track => {
if (track.getSettings().deviceId === options.deviceId) {

@@ -309,15 +256,13 @@ currentDeviceId = track.getSettings().deviceId;

_this2.updateVideoSources();
_this2.setPluginState({
currentDeviceId: currentDeviceId,
this.updateVideoSources();
this.setPluginState({
currentDeviceId,
cameraReady: true
});
}).catch(function (err) {
_this2.setPluginState({
}).catch(err => {
this.setPluginState({
cameraReady: false,
cameraError: err
});
_this2.uppy.info(err.message, 'error');
this.uppy.info(err.message, 'error');
});

@@ -329,6 +274,6 @@ });

*/
;
_proto.getMediaRecorderOptions = function getMediaRecorderOptions() {
var options = {}; // Try to use the `opts.preferredVideoMimeType` or one of the `allowedFileTypes` for the recording.
getMediaRecorderOptions() {
const options = {}; // 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.

@@ -338,4 +283,6 @@ // Safari doesn't have the `isTypeSupported` API.

if (MediaRecorder.isTypeSupported) {
var restrictions = this.uppy.opts.restrictions;
var preferredVideoMimeTypes = [];
const {
restrictions
} = this.uppy.opts;
let preferredVideoMimeTypes = [];

@@ -348,7 +295,5 @@ if (this.opts.preferredVideoMimeType) {

var filterSupportedTypes = function filterSupportedTypes(candidateType) {
return MediaRecorder.isTypeSupported(candidateType) && getFileTypeExtension(candidateType);
};
const filterSupportedTypes = candidateType => MediaRecorder.isTypeSupported(candidateType) && getFileTypeExtension(candidateType);
var acceptableMimeTypes = preferredVideoMimeTypes.filter(filterSupportedTypes);
const acceptableMimeTypes = preferredVideoMimeTypes.filter(filterSupportedTypes);

@@ -362,7 +307,5 @@ if (acceptableMimeTypes.length > 0) {

return options;
};
}
_proto.startRecording = function startRecording() {
var _this3 = this;
startRecording() {
// only used if supportsMediaRecorder() returned true

@@ -372,24 +315,20 @@ // eslint-disable-next-line compat/compat

this.recordingChunks = [];
var stoppingBecauseOfMaxSize = false;
this.recorder.addEventListener('dataavailable', function (event) {
_this3.recordingChunks.push(event.data);
let stoppingBecauseOfMaxSize = false;
this.recorder.addEventListener('dataavailable', event => {
this.recordingChunks.push(event.data);
const {
restrictions
} = this.uppy.opts;
var restrictions = _this3.uppy.opts.restrictions;
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
if (_this3.recordingChunks.length > 1 && restrictions.maxFileSize != null && !stoppingBecauseOfMaxSize) {
var totalSize = _this3.recordingChunks.reduce(function (acc, chunk) {
return 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);
var averageChunkSize = (totalSize - _this3.recordingChunks[0].size) / (_this3.recordingChunks.length - 1);
var expectedEndChunkSize = averageChunkSize * 3;
var maxSize = Math.max(0, restrictions.maxFileSize - expectedEndChunkSize);
if (totalSize > maxSize) {
stoppingBecauseOfMaxSize = true;
_this3.uppy.info(_this3.i18n('recordingStoppedMaxSize'), 'warning', 4000);
_this3.stopRecording();
this.uppy.info(this.i18n('recordingStoppedMaxSize'), 'warning', 4000);
this.stopRecording();
}

@@ -404,6 +343,5 @@ }

// Start the recordingLengthTimer if we are showing the recording length.
this.recordingLengthTimer = setInterval(function () {
var currentRecordingLength = _this3.getPluginState().recordingLengthSeconds;
_this3.setPluginState({
this.recordingLengthTimer = setInterval(() => {
const currentRecordingLength = this.getPluginState().recordingLengthSeconds;
this.setPluginState({
recordingLengthSeconds: currentRecordingLength + 1

@@ -417,19 +355,15 @@ });

});
};
}
_proto.stopRecording = function stopRecording() {
var _this4 = this;
var stopped = new Promise(function (resolve) {
_this4.recorder.addEventListener('stop', function () {
stopRecording() {
const stopped = new Promise(resolve => {
this.recorder.addEventListener('stop', () => {
resolve();
});
this.recorder.stop();
_this4.recorder.stop();
if (_this4.opts.showRecordingLength) {
if (this.opts.showRecordingLength) {
// Stop the recordingLengthTimer if we are showing the recording length.
clearInterval(_this4.recordingLengthTimer);
_this4.setPluginState({
clearInterval(this.recordingLengthTimer);
this.setPluginState({
recordingLengthSeconds: 0

@@ -439,35 +373,33 @@ });

});
return stopped.then(function () {
_this4.setPluginState({
return stopped.then(() => {
this.setPluginState({
isRecording: false
});
return _this4.getVideo();
}).then(function (file) {
return this.getVideo();
}).then(file => {
try {
_this4.capturedMediaFile = file; // create object url for capture result preview
this.capturedMediaFile = file; // create object url for capture result preview
_this4.setPluginState({
this.setPluginState({
// eslint-disable-next-line compat/compat
recordedVideo: URL.createObjectURL(file.data)
});
_this4.opts.mirror = false;
this.opts.mirror = false;
} catch (err) {
// Logging the error, exept restrictions, which is handled in Core
if (!err.isRestriction) {
_this4.uppy.log(err);
this.uppy.log(err);
}
}
}).then(function () {
_this4.recordingChunks = null;
_this4.recorder = null;
}, function (error) {
_this4.recordingChunks = null;
_this4.recorder = null;
}).then(() => {
this.recordingChunks = null;
this.recorder = null;
}, error => {
this.recordingChunks = null;
this.recorder = null;
throw error;
});
};
}
_proto.discardRecordedVideo = function discardRecordedVideo() {
discardRecordedVideo() {
this.setPluginState({

@@ -478,5 +410,5 @@ recordedVideo: null

this.capturedMediaFile = null;
};
}
_proto.submit = function submit() {
submit() {
try {

@@ -492,10 +424,10 @@ if (this.capturedMediaFile) {

}
};
}
_proto.stop = function stop() {
stop() {
if (this.stream) {
this.stream.getAudioTracks().forEach(function (track) {
this.stream.getAudioTracks().forEach(track => {
track.stop();
});
this.stream.getVideoTracks().forEach(function (track) {
this.stream.getVideoTracks().forEach(track => {
track.stop();

@@ -510,18 +442,16 @@ });

});
};
}
_proto.getVideoElement = function getVideoElement() {
getVideoElement() {
return this.el.querySelector('.uppy-Webcam-video');
};
}
_proto.oneTwoThreeSmile = function oneTwoThreeSmile() {
var _this5 = this;
oneTwoThreeSmile() {
return new Promise((resolve, reject) => {
let count = this.opts.countdown; // eslint-disable-next-line consistent-return
return new Promise(function (resolve, reject) {
var count = _this5.opts.countdown; // eslint-disable-next-line consistent-return
var countDown = setInterval(function () {
if (!_this5.webcamActive) {
const countDown = setInterval(() => {
if (!this.webcamActive) {
clearInterval(countDown);
_this5.captureInProgress = false;
this.captureInProgress = false;
return reject(new Error('Webcam is not active'));

@@ -531,53 +461,42 @@ }

if (count > 0) {
_this5.uppy.info(count + "...", 'warning', 800);
this.uppy.info(`${count}...`, 'warning', 800);
count--;
} else {
clearInterval(countDown);
_this5.uppy.info(_this5.i18n('smile'), 'success', 1500);
setTimeout(function () {
return resolve();
}, 1500);
this.uppy.info(this.i18n('smile'), 'success', 1500);
setTimeout(() => resolve(), 1500);
}
}, 1000);
});
};
}
_proto.takeSnapshot = function takeSnapshot() {
var _this6 = this;
takeSnapshot() {
if (this.captureInProgress) return;
this.captureInProgress = true;
this.opts.onBeforeSnapshot().catch(function (err) {
var message = typeof err === 'object' ? err.message : err;
this.opts.onBeforeSnapshot().catch(err => {
const message = typeof err === 'object' ? err.message : err;
this.uppy.info(message, 'error', 5000);
return Promise.reject(new Error(`onBeforeSnapshot: ${message}`));
}).then(() => {
return this.getImage();
}).then(tagFile => {
this.captureInProgress = false;
_this6.uppy.info(message, 'error', 5000);
return Promise.reject(new Error("onBeforeSnapshot: " + message));
}).then(function () {
return _this6.getImage();
}).then(function (tagFile) {
_this6.captureInProgress = false;
try {
_this6.uppy.addFile(tagFile);
this.uppy.addFile(tagFile);
} catch (err) {
// Logging the error, except restrictions, which is handled in Core
if (!err.isRestriction) {
_this6.uppy.log(err);
this.uppy.log(err);
}
}
}, function (error) {
_this6.captureInProgress = false;
}, error => {
this.captureInProgress = false;
throw error;
});
};
}
_proto.getImage = function getImage() {
var _this7 = this;
getImage() {
const video = this.getVideoElement();
var video = this.getVideoElement();
if (!video) {

@@ -587,11 +506,13 @@ return Promise.reject(new Error('No video element found, likely due to the Webcam tab being closed.'));

var width = video.videoWidth;
var height = video.videoHeight;
var canvas = document.createElement('canvas');
const width = video.videoWidth;
const height = video.videoHeight;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext('2d');
const ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0);
var restrictions = this.uppy.opts.restrictions;
var preferredImageMimeTypes = [];
const {
restrictions
} = this.uppy.opts;
let preferredImageMimeTypes = [];

@@ -604,9 +525,9 @@ if (this.opts.preferredImageMimeType) {

var mimeType = preferredImageMimeTypes[0] || 'image/jpeg';
var ext = getFileTypeExtension(mimeType) || 'jpg';
var name = "cam-" + Date.now() + "." + ext;
return canvasToBlob(canvas, mimeType).then(function (blob) {
const mimeType = preferredImageMimeTypes[0] || 'image/jpeg';
const ext = getFileTypeExtension(mimeType) || 'jpg';
const name = `cam-${Date.now()}.${ext}`;
return canvasToBlob(canvas, mimeType).then(blob => {
return {
source: _this7.id,
name: name,
source: this.id,
name,
data: new Blob([blob], {

@@ -618,9 +539,9 @@ type: mimeType

});
};
}
_proto.getVideo = function getVideo() {
getVideo() {
// Sometimes in iOS Safari, Blobs (especially the first Blob in the recordingChunks Array)
// have empty 'type' attributes (e.g. '') so we need to find a Blob that has a defined 'type'
// attribute in order to determine the correct MIME type.
var mimeType = this.recordingChunks.find(function (blob) {
const mimeType = this.recordingChunks.find(blob => {
var _blob$type;

@@ -630,15 +551,15 @@

}).type;
var fileExtension = getFileTypeExtension(mimeType);
const fileExtension = getFileTypeExtension(mimeType);
if (!fileExtension) {
return Promise.reject(new Error("Could not retrieve recording: Unsupported media type \"" + mimeType + "\""));
return Promise.reject(new Error(`Could not retrieve recording: Unsupported media type "${mimeType}"`));
}
var name = "webcam-" + Date.now() + "." + fileExtension;
var blob = new Blob(this.recordingChunks, {
const name = `webcam-${Date.now()}.${fileExtension}`;
const blob = new Blob(this.recordingChunks, {
type: mimeType
});
var file = {
const file = {
source: this.id,
name: name,
name,
data: new Blob([blob], {

@@ -650,33 +571,27 @@ type: mimeType

return Promise.resolve(file);
};
}
_proto.focus = function focus() {
var _this8 = this;
focus() {
if (!this.opts.countdown) return;
setTimeout(function () {
_this8.uppy.info(_this8.i18n('smile'), 'success', 1500);
setTimeout(() => {
this.uppy.info(this.i18n('smile'), 'success', 1500);
}, 1000);
};
}
_proto.changeVideoSource = function changeVideoSource(deviceId) {
changeVideoSource(deviceId) {
this.stop();
this.start({
deviceId: deviceId
deviceId
});
};
}
_proto.updateVideoSources = function updateVideoSources() {
var _this9 = this;
this.mediaDevices.enumerateDevices().then(function (devices) {
_this9.setPluginState({
videoSources: devices.filter(function (device) {
return device.kind === 'videoinput';
})
updateVideoSources() {
this.mediaDevices.enumerateDevices().then(devices => {
this.setPluginState({
videoSources: devices.filter(device => device.kind === 'videoinput')
});
});
};
}
_proto.render = function render() {
render() {
if (!this.webcamActive) {

@@ -686,3 +601,3 @@ this.start();

var webcamState = this.getPluginState();
const webcamState = this.getPluginState();

@@ -716,7 +631,5 @@ if (!webcamState.cameraReady || !webcamState.hasCamera) {

}));
};
}
_proto.install = function install() {
var _this10 = this;
install() {
this.setPluginState({

@@ -726,3 +639,5 @@ cameraReady: false,

});
var target = this.opts.target;
const {
target
} = this.opts;

@@ -736,13 +651,12 @@ if (target) {

this.mediaDevices.ondevicechange = function () {
_this10.updateVideoSources();
this.mediaDevices.ondevicechange = () => {
this.updateVideoSources();
if (_this10.stream) {
var restartStream = true;
var _this10$getPluginStat = _this10.getPluginState(),
videoSources = _this10$getPluginStat.videoSources,
currentDeviceId = _this10$getPluginStat.currentDeviceId;
videoSources.forEach(function (videoSource) {
if (this.stream) {
let restartStream = true;
const {
videoSources,
currentDeviceId
} = this.getPluginState();
videoSources.forEach(videoSource => {
if (currentDeviceId === videoSource.deviceId) {

@@ -754,5 +668,4 @@ restartStream = false;

if (restartStream) {
_this10.stop();
_this10.start();
this.stop();
this.start();
}

@@ -762,5 +675,5 @@ }

}
};
}
_proto.uninstall = function uninstall() {
uninstall() {
if (this.stream) {

@@ -771,5 +684,4 @@ this.stop();

this.unmount();
};
}
return Webcam;
}(Plugin), _class.VERSION = "1.8.13", _temp);
}, _class.VERSION = "2.0.0-alpha.0", _temp);

@@ -1,5 +0,8 @@

var _require = require('preact'),
h = _require.h;
"use strict";
module.exports = function (props) {
const {
h
} = require('preact');
module.exports = props => {
return h("div", {

@@ -6,0 +9,0 @@ className: "uppy-Webcam-permissons"

@@ -1,10 +0,13 @@

var _require = require('preact'),
h = _require.h;
"use strict";
module.exports = function RecordButton(_ref) {
var recording = _ref.recording,
onStartRecording = _ref.onStartRecording,
onStopRecording = _ref.onStopRecording,
i18n = _ref.i18n;
const {
h
} = require('preact');
module.exports = function RecordButton({
recording,
onStartRecording,
onStopRecording,
i18n
}) {
if (recording) {

@@ -11,0 +14,0 @@ return h("button", {

@@ -1,10 +0,14 @@

var _require = require('preact'),
h = _require.h;
"use strict";
var formatSeconds = require('./formatSeconds');
const {
h
} = require('preact');
module.exports = function RecordingLength(_ref) {
var recordingLengthSeconds = _ref.recordingLengthSeconds,
i18n = _ref.i18n;
var formattedRecordingLengthSeconds = formatSeconds(recordingLengthSeconds);
const formatSeconds = require('./formatSeconds');
module.exports = function RecordingLength({
recordingLengthSeconds,
i18n
}) {
const formattedRecordingLengthSeconds = formatSeconds(recordingLengthSeconds);
return h("span", {

@@ -11,0 +15,0 @@ "aria-label": i18n('recordingLength', {

@@ -1,9 +0,13 @@

var _require = require('preact'),
h = _require.h;
"use strict";
var CameraIcon = require('./CameraIcon');
const {
h
} = require('preact');
module.exports = function (_ref) {
var onSnapshot = _ref.onSnapshot,
i18n = _ref.i18n;
const CameraIcon = require('./CameraIcon');
module.exports = ({
onSnapshot,
i18n
}) => {
return h("button", {

@@ -10,0 +14,0 @@ className: "uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--picture",

@@ -1,7 +0,11 @@

var _require = require('preact'),
h = _require.h;
"use strict";
function SubmitButton(_ref) {
var onSubmit = _ref.onSubmit,
i18n = _ref.i18n;
const {
h
} = require('preact');
function SubmitButton({
onSubmit,
i18n
}) {
return h("button", {

@@ -8,0 +12,0 @@ className: "uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--submit",

@@ -0,1 +1,3 @@

"use strict";
module.exports = function supportsMediaRecorder() {

@@ -2,0 +4,0 @@ /* eslint-disable compat/compat */

@@ -1,8 +0,12 @@

var _require = require('preact'),
h = _require.h;
"use strict";
module.exports = function (_ref) {
var currentDeviceId = _ref.currentDeviceId,
videoSources = _ref.videoSources,
onChangeVideoSource = _ref.onChangeVideoSource;
const {
h
} = require('preact');
module.exports = ({
currentDeviceId,
videoSources,
onChangeVideoSource
}) => {
return h("div", {

@@ -12,12 +16,10 @@ className: "uppy-Webcam-videoSource"

className: "uppy-u-reset uppy-Webcam-videoSource-select",
onChange: function onChange(event) {
onChange: event => {
onChangeVideoSource(event.target.value);
}
}, videoSources.map(function (videoSource) {
return h("option", {
key: videoSource.deviceId,
value: videoSource.deviceId,
selected: videoSource.deviceId === currentDeviceId
}, videoSource.label);
})));
}, videoSources.map(videoSource => h("option", {
key: videoSource.deviceId,
value: videoSource.deviceId,
selected: videoSource.deviceId === currentDeviceId
}, videoSource.label))));
};
{
"name": "@uppy/webcam",
"description": "Uppy plugin that takes photos or records videos using the device's camera.",
"version": "1.8.13",
"version": "2.0.0-alpha.0",
"license": "MIT",

@@ -29,4 +29,4 @@ "main": "lib/index.js",

"dependencies": {
"@uppy/utils": "^3.6.2",
"preact": "8.2.9"
"@uppy/utils": "^4.0.0-alpha.0",
"preact": "^10.5.13"
},

@@ -36,3 +36,3 @@ "peerDependencies": {

},
"gitHead": "28997bc5c733e3f7ab7183d6cd61d2dfd74f71e4"
"gitHead": "113b627dd0ef5aa5d198dc309dda05da2117dfe5"
}

@@ -15,4 +15,4 @@ # @uppy/webcam

```js
const Uppy = require('@uppy/core')
const Webcam = require('@uppy/webcam')
import Uppy from '@uppy/core'
import Webcam from '@uppy/webcam'

@@ -23,3 +23,3 @@ const uppy = new Uppy()

facingMode: 'user',
showRecordingLength: true
showRecordingLength: true,
})

@@ -26,0 +26,0 @@ ```

const { h } = require('preact')
const { Plugin } = require('@uppy/core')
const { UIPlugin } = require('@uppy/core')
const Translator = require('@uppy/utils/lib/Translator')

@@ -45,25 +45,6 @@ const getFileTypeExtension = require('@uppy/utils/lib/getFileTypeExtension')

/**
* Setup getUserMedia, with polyfill for older browsers
* Adapted from: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
*/
function getMediaDevices () {
// bug in the compatibility data
// eslint-disable-next-line compat/compat
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
// eslint-disable-next-line compat/compat
return navigator.mediaDevices
}
const getUserMedia = navigator.mozGetUserMedia || navigator.webkitGetUserMedia
if (!getUserMedia) {
return null
}
return {
getUserMedia (opts) {
return new Promise((resolve, reject) => {
getUserMedia.call(navigator, opts, resolve, reject)
})
},
}
return navigator.mediaDevices
}

@@ -73,3 +54,3 @@ /**

*/
module.exports = class Webcam extends Plugin {
module.exports = class Webcam extends UIPlugin {
// eslint-disable-next-line global-require

@@ -85,3 +66,2 @@ static VERSION = require('../package.json').version

this.id = this.opts.id || 'Webcam'
this.title = this.opts.title || 'Camera'
this.type = 'acquirer'

@@ -100,2 +80,3 @@ this.capturedMediaFile = null

strings: {
pluginNameCamera: 'Camera',
smile: 'Smile!',

@@ -135,8 +116,7 @@ takePicture: 'Take a picture',

this.opts = { ...defaultOptions, ...opts }
this.i18nInit()
this.title = this.i18n('pluginNameCamera')
this.install = this.install.bind(this)
this.setPluginState = this.setPluginState.bind(this)
this.render = this.render.bind(this)

@@ -181,13 +161,4 @@

})
this.i18nInit()
}
i18nInit () {
this.translator = new Translator([this.defaultLocale, this.uppy.locale, this.opts.locale])
this.i18n = this.translator.translate.bind(this.translator)
this.i18nArray = this.translator.translateArray.bind(this.translator)
this.setPluginState() // so that UI re-renders and we see the updated locale
}
hasCameraCheck () {

@@ -216,3 +187,3 @@ if (!this.mediaDevices) {

const videoConstraints = {
...(this.opts.videoConstraints ?? { facingMode: this.opts.facingMode }),
...(this.opts.videoConstraints || { facingMode: this.opts.facingMode }),
// facingMode takes precedence over deviceId, and not needed

@@ -219,0 +190,0 @@ // when specific device is selected

@@ -1,18 +0,20 @@

import Uppy = require('@uppy/core')
/* eslint-disable */
import type { Locale } from '@uppy/core'
type WebcamLocale = Uppy.Locale<
| 'smile'
| 'takePicture'
| 'startRecording'
| 'stopRecording'
| 'allowAccessTitle'
| 'allowAccessDescription'
| 'noCameraTitle'
| 'noCameraDescription'
| 'recordingStoppedMaxSize'
| 'recordingLength'
| 'submitRecordedFile'
| 'discardRecordedFile'
>
type WebcamLocale = Locale<
| 'pluginNameCamera'
| 'smile'
| 'takePicture'
| 'startRecording'
| 'stopRecording'
| 'allowAccessTitle'
| 'allowAccessDescription'
| 'noCameraTitle'
| 'noCameraDescription'
| 'recordingStoppedMaxSize'
| 'recordingLength'
| 'submitRecordedFile'
| 'discardRecordedFile'
>
export = WebcamLocale
export default WebcamLocale

@@ -1,6 +0,5 @@

import Uppy = require('@uppy/core')
import WebcamLocale = require('./generatedLocale')
import type { PluginOptions, UIPlugin, PluginTarget } from '@uppy/core'
import WebcamLocale from './generatedLocale'
declare module Webcam {
export type WebcamMode =
export type WebcamMode =
| 'video-audio'

@@ -11,5 +10,5 @@ | 'video-only'

export interface WebcamOptions extends Uppy.PluginOptions {
export interface WebcamOptions extends PluginOptions {
replaceTargetContent?: boolean
target?: Uppy.PluginTarget
target?: PluginTarget
onBeforeSnapshot?: () => Promise<void>

@@ -24,7 +23,6 @@ countdown?: number | boolean

videoConstraints?: MediaTrackConstraints
}
}
declare class Webcam extends Uppy.Plugin<Webcam.WebcamOptions> {}
declare class Webcam extends UIPlugin<WebcamOptions> {}
export = Webcam
export default Webcam
import { expectError } from 'tsd'
import Uppy = require('@uppy/core')
import Webcam = require('../')
import Uppy from '@uppy/core'
import Webcam from '..'
{
Uppy<Uppy.StrictTypes>().use(Webcam, {
modes: ['video-only']
})
}
new Uppy().use(Webcam, {
modes: ['video-only'],
})
{
Uppy<Uppy.StrictTypes>().use(Webcam, {
modes: ['video-only'],
videoConstraints: {
width: { min: 420, ideal: 420, max: 1920 },
height: { min: 420, ideal: 420, max: 1080 }
}
})
}
new Uppy().use(Webcam, {
modes: ['video-only'],
videoConstraints: {
width: { min: 420, ideal: 420, max: 1920 },
height: { min: 420, ideal: 420, max: 1080 },
},
})
{
expectError(Uppy<Uppy.StrictTypes>().use(Webcam, {
modes: ['video-only'],
videoConstraints: {
width: 'not a number har har'
}
}))
}
expectError(new Uppy().use(Webcam, {
modes: ['video-only'],
videoConstraints: {
width: 'not a number har har',
},
}))

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
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc