Socket
Socket
Sign inDemoInstall

@uppy/webcam

Package Overview
Dependencies
11
Maintainers
5
Versions
93
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.8.8 to 1.8.9

lib/DiscardButton.js

96

lib/CameraScreen.js

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

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); }

@@ -5,2 +7,3 @@

/* eslint-disable jsx-a11y/media-has-caption */
var _require = require('preact'),

@@ -18,2 +21,6 @@ h = _require.h,

var SubmitButton = require('./SubmitButton');
var DiscardButton = require('./DiscardButton');
function isModeAvailable(modes, mode) {

@@ -33,14 +40,54 @@ return modes.indexOf(mode) !== -1;

_proto.componentDidMount = function componentDidMount() {
this.props.onFocus();
var onFocus = this.props.onFocus;
onFocus();
};
_proto.componentWillUnmount = function componentWillUnmount() {
this.props.onStop();
var onStop = this.props.onStop;
onStop();
};
_proto.render = function render() {
var shouldShowRecordButton = this.props.supportsRecording && (isModeAvailable(this.props.modes, 'video-only') || isModeAvailable(this.props.modes, 'audio-only') || isModeAvailable(this.props.modes, 'video-audio'));
var shouldShowSnapshotButton = isModeAvailable(this.props.modes, 'picture');
var shouldShowRecordingLength = this.props.supportsRecording && this.props.showRecordingLength;
var shouldShowVideoSourceDropdown = this.props.showVideoSourceDropdown && this.props.videoSources && this.props.videoSources.length > 1;
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 = {
playsinline: true
};
if (recordedVideo) {
videoProps.muted = false;
videoProps.controls = true;
videoProps.src = recordedVideo; // reset srcObject in dom. If not resetted, stream sticks in element
if (this.videoElement) {
this.videoElement.srcObject = undefined;
}
} else {
videoProps.muted = true;
videoProps.autoplay = true;
videoProps.srcObject = src;
}
return h("div", {

@@ -50,9 +97,11 @@ className: "uppy uppy-Webcam-container"

className: "uppy-Webcam-videoContainer"
}, h("video", {
className: "uppy-Webcam-video " + (this.props.mirror ? 'uppy-Webcam-video--mirrored' : ''),
autoPlay: true,
muted: true,
playsinline: true,
srcObject: this.props.src || ''
})), h("div", {
}, h("video", _extends({
/* eslint-disable-next-line no-return-assign */
ref: function ref(videoElement) {
return _this.videoElement = videoElement;
},
className: "uppy-Webcam-video " + (mirror ? 'uppy-Webcam-video--mirrored' : '')
/* eslint-disable-next-line react/jsx-props-no-spreading */
}, videoProps))), h("div", {
className: "uppy-Webcam-footer"

@@ -63,5 +112,22 @@ }, h("div", {

className: "uppy-Webcam-buttonContainer"
}, shouldShowSnapshotButton ? SnapshotButton(this.props) : null, ' ', shouldShowRecordButton ? RecordButton(this.props) : null), h("div", {
}, shouldShowSnapshotButton && h(SnapshotButton, {
onSnapshot: onSnapshot,
i18n: i18n
}), shouldShowRecordButton && h(RecordButton, {
recording: recording,
onStartRecording: onStartRecording,
onStopRecording: onStopRecording,
i18n: i18n
}), hasRecordedVideo && h(SubmitButton, {
onSubmit: onSubmit,
i18n: i18n
}), hasRecordedVideo && h(DiscardButton, {
onDiscard: onDiscardRecordedVideo,
i18n: i18n
})), shouldShowRecordingLength && h("div", {
className: "uppy-Webcam-recordingLength"
}, shouldShowRecordingLength ? RecordingLength(this.props) : null)));
}, h(RecordingLength, {
recordingLengthSeconds: recordingLengthSeconds,
i18n: i18n
}))));
};

@@ -68,0 +134,0 @@

153

lib/index.js

@@ -32,2 +32,4 @@ var _class, _temp;

var PermissionsScreen = require('./PermissionsScreen');
var packageJsonVersion = "1.8.9";
/**

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

function toMimeType(fileType) {

@@ -111,3 +112,4 @@ if (fileType[0] === '.') {

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

@@ -117,2 +119,3 @@ _this.id = _this.opts.id || 'Webcam';

_this.type = 'acquirer';
_this.capturedMediaFile = null;

@@ -153,3 +156,5 @@ _this.icon = function () {

recordingStoppedMaxSize: 'Recording stopped because the file size is about to exceed the limit',
recordingLength: 'Recording length %{recording_length}'
recordingLength: 'Recording length %{recording_length}',
submitRecordedFile: 'Submit recorded file',
discardRecordedFile: 'Discard recorded file'
}

@@ -179,14 +184,16 @@ }; // set default options

_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._oneTwoThreeSmile = _this._oneTwoThreeSmile.bind(_assertThisInitialized(_this));
_this._focus = _this._focus.bind(_assertThisInitialized(_this));
_this._changeVideoSource = _this._changeVideoSource.bind(_assertThisInitialized(_this));
_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;
_this.opts.onBeforeSnapshot = _this.oneTwoThreeSmile;
}

@@ -260,5 +267,6 @@

};
};
} // eslint-disable-next-line consistent-return
;
_proto._start = function _start(options) {
_proto.start = function start(options) {
var _this2 = this;

@@ -275,2 +283,3 @@

this.webcamActive = true;
this.opts.mirror = true;
var constraints = this.getConstraints(options && options.deviceId ? options.deviceId : null);

@@ -320,3 +329,3 @@ this.hasCameraCheck().then(function (hasCamera) {

_proto._getMediaRecorderOptions = function _getMediaRecorderOptions() {
_proto.getMediaRecorderOptions = function getMediaRecorderOptions() {
var options = {}; // Try to use the `opts.preferredVideoMimeType` or one of the `allowedFileTypes` for the recording.

@@ -336,7 +345,10 @@ // If the browser doesn't support it, we'll fall back to the browser default instead.

var acceptableMimeTypes = preferredVideoMimeTypes.filter(function (candidateType) {
var filterSupportedTypes = function filterSupportedTypes(candidateType) {
return MediaRecorder.isTypeSupported(candidateType) && getFileTypeExtension(candidateType);
});
};
var acceptableMimeTypes = preferredVideoMimeTypes.filter(filterSupportedTypes);
if (acceptableMimeTypes.length > 0) {
// eslint-disable-next-line prefer-destructuring
options.mimeType = acceptableMimeTypes[0];

@@ -349,3 +361,3 @@ }

_proto._startRecording = function _startRecording() {
_proto.startRecording = function startRecording() {
var _this3 = this;

@@ -355,3 +367,3 @@

// eslint-disable-next-line compat/compat
this.recorder = new MediaRecorder(this.stream, this._getMediaRecorderOptions());
this.recorder = new MediaRecorder(this.stream, this.getMediaRecorderOptions());
this.recordingChunks = [];

@@ -379,3 +391,3 @@ var stoppingBecauseOfMaxSize = false;

_this3._stopRecording();
_this3.stopRecording();
}

@@ -404,6 +416,6 @@ }

_proto._stopRecording = function _stopRecording() {
_proto.stopRecording = function stopRecording() {
var _this4 = this;
var stopped = new Promise(function (resolve, reject) {
var stopped = new Promise(function (resolve) {
_this4.recorder.addEventListener('stop', function () {

@@ -432,3 +444,10 @@ resolve();

try {
_this4.uppy.addFile(file);
_this4.capturedMediaFile = file; // create object url for capture result preview
_this4.setPluginState({
// eslint-disable-next-line compat/compat
recordedVideo: URL.createObjectURL(file.data)
});
_this4.opts.mirror = false;
} catch (err) {

@@ -450,3 +469,24 @@ // Logging the error, exept restrictions, which is handled in Core

_proto._stop = function _stop() {
_proto.discardRecordedVideo = function discardRecordedVideo() {
this.setPluginState({
recordedVideo: null
});
this.opts.mirror = true;
this.capturedMediaFile = null;
};
_proto.submit = function submit() {
try {
if (this.capturedMediaFile) {
this.uppy.addFile(this.capturedMediaFile);
}
} catch (err) {
// Logging the error, exept restrictions, which is handled in Core
if (!err.isRestriction) {
this.uppy.log(err, 'error');
}
}
};
_proto.stop = function stop() {
if (this.stream) {

@@ -463,13 +503,17 @@ this.stream.getAudioTracks().forEach(function (track) {

this.stream = null;
this.setPluginState({
recordedVideo: null
});
};
_proto._getVideoElement = function _getVideoElement() {
_proto.getVideoElement = function getVideoElement() {
return this.el.querySelector('.uppy-Webcam-video');
};
_proto._oneTwoThreeSmile = function _oneTwoThreeSmile() {
_proto.oneTwoThreeSmile = function oneTwoThreeSmile() {
var _this5 = this;
return new Promise(function (resolve, reject) {
var count = _this5.opts.countdown;
var count = _this5.opts.countdown; // eslint-disable-next-line consistent-return
var countDown = setInterval(function () {

@@ -499,3 +543,3 @@ if (!_this5.webcamActive) {

_proto._takeSnapshot = function _takeSnapshot() {
_proto.takeSnapshot = function takeSnapshot() {
var _this6 = this;

@@ -512,3 +556,3 @@

}).then(function () {
return _this6._getImage();
return _this6.getImage();
}).then(function (tagFile) {

@@ -531,6 +575,6 @@ _this6.captureInProgress = false;

_proto._getImage = function _getImage() {
_proto.getImage = function getImage() {
var _this7 = this;
var video = this._getVideoElement();
var video = this.getVideoElement();

@@ -573,3 +617,10 @@ if (!video) {

_proto.getVideo = function getVideo() {
var mimeType = this.recordingChunks[0].type;
// 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) {
var _blob$type;
return ((_blob$type = blob.type) == null ? void 0 : _blob$type.length) > 0;
}).type;
var fileExtension = getFileTypeExtension(mimeType);

@@ -596,3 +647,3 @@

_proto._focus = function _focus() {
_proto.focus = function focus() {
var _this8 = this;

@@ -606,6 +657,5 @@

_proto._changeVideoSource = function _changeVideoSource(deviceId) {
this._stop();
this._start({
_proto.changeVideoSource = function changeVideoSource(deviceId) {
this.stop();
this.start({
deviceId: deviceId

@@ -629,3 +679,3 @@ });

if (!this.webcamActive) {
this._start();
this.start();
}

@@ -643,9 +693,12 @@

return h(CameraScreen, _extends({}, webcamState, {
onChangeVideoSource: this._changeVideoSource,
onSnapshot: this._takeSnapshot,
onStartRecording: this._startRecording,
onStopRecording: this._stopRecording,
onFocus: this._focus,
onStop: this._stop,
return h(CameraScreen // eslint-disable-next-line react/jsx-props-no-spreading
, _extends({}, webcamState, {
onChangeVideoSource: this.changeVideoSource,
onSnapshot: this.takeSnapshot,
onStartRecording: this.startRecording,
onStopRecording: this.stopRecording,
onDiscardRecordedVideo: this.discardRecordedVideo,
onSubmit: this.submit,
onFocus: this.focus,
onStop: this.stop,
i18n: this.i18n,

@@ -678,3 +731,3 @@ modes: this.opts.modes,

this.mediaDevices.ondevicechange = function (event) {
this.mediaDevices.ondevicechange = function () {
_this10.updateVideoSources();

@@ -696,5 +749,5 @@

if (restartStream) {
_this10._stop();
_this10.stop();
_this10._start();
_this10.start();
}

@@ -708,3 +761,3 @@ }

if (this.stream) {
this._stop();
this.stop();
}

@@ -716,2 +769,2 @@

return Webcam;
}(Plugin), _class.VERSION = "1.8.8", _temp);
}(Plugin), _class.VERSION = packageJsonVersion, _temp);

@@ -12,3 +12,3 @@ var _require = require('preact'),

return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--video",
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button",
type: "button",

@@ -35,3 +35,3 @@ title: i18n('stopRecording'),

return h("button", {
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--video",
className: "uppy-u-reset uppy-c-btn uppy-Webcam-button",
type: "button",

@@ -38,0 +38,0 @@ title: i18n('startRecording'),

{
"name": "@uppy/webcam",
"description": "Uppy plugin that takes photos or records videos using the device's camera.",
"version": "1.8.8",
"version": "1.8.9",
"license": "MIT",

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

},
"gitHead": "6771545fe70134088a5441ef5c2f7b872e32d812"
"gitHead": "209a0079d3ced4e20c5ef3e44582c2d82ad2e60c"
}

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

/* eslint-disable jsx-a11y/media-has-caption */
const { h, Component } = require('preact')

@@ -6,2 +7,4 @@ const SnapshotButton = require('./SnapshotButton')

const VideoSourceSelect = require('./VideoSourceSelect')
const SubmitButton = require('./SubmitButton')
const DiscardButton = require('./DiscardButton')

@@ -14,36 +17,99 @@ function isModeAvailable (modes, mode) {

componentDidMount () {
this.props.onFocus()
const { onFocus } = this.props
onFocus()
}
componentWillUnmount () {
this.props.onStop()
const { onStop } = this.props
onStop()
}
render () {
const shouldShowRecordButton = this.props.supportsRecording && (
isModeAvailable(this.props.modes, 'video-only')
|| isModeAvailable(this.props.modes, 'audio-only')
|| isModeAvailable(this.props.modes, 'video-audio')
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 = isModeAvailable(this.props.modes, 'picture')
const shouldShowRecordingLength = this.props.supportsRecording && this.props.showRecordingLength
const shouldShowVideoSourceDropdown = this.props.showVideoSourceDropdown && this.props.videoSources && this.props.videoSources.length > 1
const shouldShowSnapshotButton = !hasRecordedVideo && isModeAvailable(modes, 'picture')
const shouldShowRecordingLength = supportsRecording && showRecordingLength
const shouldShowVideoSourceDropdown = showVideoSourceDropdown && videoSources && videoSources.length > 1
const videoProps = {
playsinline: true,
}
if (recordedVideo) {
videoProps.muted = false
videoProps.controls = true
videoProps.src = recordedVideo
// reset srcObject in dom. If not resetted, stream sticks in element
if (this.videoElement) {
this.videoElement.srcObject = undefined
}
} else {
videoProps.muted = true
videoProps.autoplay = true
videoProps.srcObject = src
}
return (
<div className="uppy uppy-Webcam-container">
<div className="uppy-Webcam-videoContainer">
<video className={`uppy-Webcam-video ${this.props.mirror ? 'uppy-Webcam-video--mirrored' : ''}`} autoPlay muted playsinline srcObject={this.props.src || ''} />
<video
/* eslint-disable-next-line no-return-assign */
ref={(videoElement) => (this.videoElement = videoElement)}
className={`uppy-Webcam-video ${mirror ? 'uppy-Webcam-video--mirrored' : ''}`}
/* eslint-disable-next-line react/jsx-props-no-spreading */
{...videoProps}
/>
</div>
<div className="uppy-Webcam-footer">
<div className="uppy-Webcam-videoSourceContainer">
{shouldShowVideoSourceDropdown ? VideoSourceSelect(this.props) : null}
{shouldShowVideoSourceDropdown
? VideoSourceSelect(this.props)
: null}
</div>
<div className="uppy-Webcam-buttonContainer">
{shouldShowSnapshotButton ? SnapshotButton(this.props) : null}
{' '}
{shouldShowRecordButton ? RecordButton(this.props) : null}
{shouldShowSnapshotButton && <SnapshotButton onSnapshot={onSnapshot} i18n={i18n} />}
{shouldShowRecordButton && (
<RecordButton
recording={recording}
onStartRecording={onStartRecording}
onStopRecording={onStopRecording}
i18n={i18n}
/>
)}
{hasRecordedVideo && <SubmitButton onSubmit={onSubmit} i18n={i18n} />}
{hasRecordedVideo && <DiscardButton onDiscard={onDiscardRecordedVideo} i18n={i18n} />}
</div>
<div className="uppy-Webcam-recordingLength">
{shouldShowRecordingLength ? RecordingLength(this.props) : null}
</div>
{shouldShowRecordingLength && (
<div className="uppy-Webcam-recordingLength">
<RecordingLength recordingLengthSeconds={recordingLengthSeconds} i18n={i18n} />
</div>
)}
</div>

@@ -50,0 +116,0 @@ </div>

@@ -11,2 +11,3 @@ const { h } = require('preact')

const PermissionsScreen = require('./PermissionsScreen')
const packageJsonVersion = require('../package.json').version

@@ -74,3 +75,3 @@ /**

module.exports = class Webcam extends Plugin {
static VERSION = require('../package.json').version
static VERSION = packageJsonVersion

@@ -81,2 +82,3 @@ constructor (uppy, opts) {

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

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

this.type = 'acquirer'
this.capturedMediaFile = null
this.icon = () => (

@@ -108,2 +111,4 @@ <svg aria-hidden="true" focusable="false" width="32" height="32" viewBox="0 0 32 32">

recordingLength: 'Recording length %{recording_length}',
submitRecordedFile: 'Submit recorded file',
discardRecordedFile: 'Discard recorded file',
},

@@ -140,10 +145,12 @@ }

// Camera controls
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._oneTwoThreeSmile = this._oneTwoThreeSmile.bind(this)
this._focus = this._focus.bind(this)
this._changeVideoSource = this._changeVideoSource.bind(this)
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)

@@ -153,3 +160,3 @@ this.webcamActive = false

if (this.opts.countdown) {
this.opts.onBeforeSnapshot = this._oneTwoThreeSmile
this.opts.onBeforeSnapshot = this.oneTwoThreeSmile
}

@@ -222,3 +229,4 @@

_start (options = null) {
// eslint-disable-next-line consistent-return
start (options = null) {
if (!this.supportsUserMedia) {

@@ -229,2 +237,3 @@ return Promise.reject(new Error('Webcam access not supported'))

this.webcamActive = true
this.opts.mirror = true

@@ -277,3 +286,3 @@ const constraints = this.getConstraints(options && options.deviceId ? options.deviceId : null)

*/
_getMediaRecorderOptions () {
getMediaRecorderOptions () {
const options = {}

@@ -293,5 +302,8 @@

const acceptableMimeTypes = preferredVideoMimeTypes.filter((candidateType) => MediaRecorder.isTypeSupported(candidateType)
&& getFileTypeExtension(candidateType))
const filterSupportedTypes = (candidateType) => MediaRecorder.isTypeSupported(candidateType)
&& getFileTypeExtension(candidateType)
const acceptableMimeTypes = preferredVideoMimeTypes.filter(filterSupportedTypes)
if (acceptableMimeTypes.length > 0) {
// eslint-disable-next-line prefer-destructuring
options.mimeType = acceptableMimeTypes[0]

@@ -304,6 +316,6 @@ }

_startRecording () {
startRecording () {
// only used if supportsMediaRecorder() returned true
// eslint-disable-next-line compat/compat
this.recorder = new MediaRecorder(this.stream, this._getMediaRecorderOptions())
this.recorder = new MediaRecorder(this.stream, this.getMediaRecorderOptions())
this.recordingChunks = []

@@ -327,3 +339,3 @@ let stoppingBecauseOfMaxSize = false

this.uppy.info(this.i18n('recordingStoppedMaxSize'), 'warning', 4000)
this._stopRecording()
this.stopRecording()
}

@@ -350,4 +362,4 @@ }

_stopRecording () {
const stopped = new Promise((resolve, reject) => {
stopRecording () {
const stopped = new Promise((resolve) => {
this.recorder.addEventListener('stop', () => {

@@ -372,3 +384,9 @@ resolve()

try {
this.uppy.addFile(file)
this.capturedMediaFile = file
// create object url for capture result preview
this.setPluginState({
// eslint-disable-next-line compat/compat
recordedVideo: URL.createObjectURL(file.data),
})
this.opts.mirror = false
} catch (err) {

@@ -390,3 +408,22 @@ // Logging the error, exept restrictions, which is handled in Core

_stop () {
discardRecordedVideo () {
this.setPluginState({ recordedVideo: null })
this.opts.mirror = true
this.capturedMediaFile = null
}
submit () {
try {
if (this.capturedMediaFile) {
this.uppy.addFile(this.capturedMediaFile)
}
} catch (err) {
// Logging the error, exept restrictions, which is handled in Core
if (!err.isRestriction) {
this.uppy.log(err, 'error')
}
}
}
stop () {
if (this.stream) {

@@ -402,12 +439,16 @@ this.stream.getAudioTracks().forEach((track) => {

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

@@ -432,4 +473,5 @@ if (!this.webcamActive) {

_takeSnapshot () {
takeSnapshot () {
if (this.captureInProgress) return
this.captureInProgress = true

@@ -442,3 +484,3 @@

}).then(() => {
return this._getImage()
return this.getImage()
}).then((tagFile) => {

@@ -460,4 +502,4 @@ this.captureInProgress = false

_getImage () {
const video = this._getVideoElement()
getImage () {
const video = this.getVideoElement()
if (!video) {

@@ -499,3 +541,7 @@ return Promise.reject(new Error('No video element found, likely due to the Webcam tab being closed.'))

getVideo () {
const mimeType = this.recordingChunks[0].type
// 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.
const mimeType = this.recordingChunks.find(blob => blob.type?.length > 0).type
const fileExtension = getFileTypeExtension(mimeType)

@@ -519,3 +565,3 @@

_focus () {
focus () {
if (!this.opts.countdown) return

@@ -527,5 +573,5 @@ setTimeout(() => {

_changeVideoSource (deviceId) {
this._stop()
this._start({ deviceId })
changeVideoSource (deviceId) {
this.stop()
this.start({ deviceId })
}

@@ -543,3 +589,3 @@

if (!this.webcamActive) {
this._start()
this.start()
}

@@ -561,9 +607,12 @@

<CameraScreen
// eslint-disable-next-line react/jsx-props-no-spreading
{...webcamState}
onChangeVideoSource={this._changeVideoSource}
onSnapshot={this._takeSnapshot}
onStartRecording={this._startRecording}
onStopRecording={this._stopRecording}
onFocus={this._focus}
onStop={this._stop}
onChangeVideoSource={this.changeVideoSource}
onSnapshot={this.takeSnapshot}
onStartRecording={this.startRecording}
onStopRecording={this.stopRecording}
onDiscardRecordedVideo={this.discardRecordedVideo}
onSubmit={this.submit}
onFocus={this.focus}
onStop={this.stop}
i18n={this.i18n}

@@ -595,3 +644,3 @@ modes={this.opts.modes}

this.mediaDevices.ondevicechange = (event) => {
this.mediaDevices.ondevicechange = () => {
this.updateVideoSources()

@@ -611,4 +660,4 @@

if (restartStream) {
this._stop()
this._start()
this.stop()
this.start()
}

@@ -622,3 +671,3 @@ }

if (this.stream) {
this._stop()
this.stop()
}

@@ -625,0 +674,0 @@

@@ -13,3 +13,3 @@ const Uppy = require('@uppy/core')

expect(
uppy.getPlugin('Webcam')._getMediaRecorderOptions().mimeType
uppy.getPlugin('Webcam').getMediaRecorderOptions().mimeType
).not.toBeDefined()

@@ -25,3 +25,3 @@ })

expect(
uppy.getPlugin('Webcam')._getMediaRecorderOptions().mimeType
uppy.getPlugin('Webcam').getMediaRecorderOptions().mimeType
).toEqual('video/webm')

@@ -37,3 +37,3 @@ })

expect(
uppy.getPlugin('Webcam')._getMediaRecorderOptions().mimeType
uppy.getPlugin('Webcam').getMediaRecorderOptions().mimeType
).not.toBeDefined()

@@ -51,3 +51,3 @@ })

expect(
uppy.getPlugin('Webcam')._getMediaRecorderOptions().mimeType
uppy.getPlugin('Webcam').getMediaRecorderOptions().mimeType
).toEqual('video/mp4')

@@ -65,3 +65,3 @@ })

expect(
uppy.getPlugin('Webcam')._getMediaRecorderOptions().mimeType
uppy.getPlugin('Webcam').getMediaRecorderOptions().mimeType
).toEqual('video/webm')

@@ -80,3 +80,3 @@ })

expect(
uppy.getPlugin('Webcam')._getMediaRecorderOptions().mimeType
uppy.getPlugin('Webcam').getMediaRecorderOptions().mimeType
).toEqual('video/webm')

@@ -94,3 +94,3 @@ })

expect(
uppy.getPlugin('Webcam')._getMediaRecorderOptions().mimeType
uppy.getPlugin('Webcam').getMediaRecorderOptions().mimeType
).toEqual(undefined)

@@ -97,0 +97,0 @@ })

@@ -7,3 +7,3 @@ const { h } = require('preact')

<button
className="uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--video"
className="uppy-u-reset uppy-c-btn uppy-Webcam-button"
type="button"

@@ -24,3 +24,3 @@ title={i18n('stopRecording')}

<button
className="uppy-u-reset uppy-c-btn uppy-Webcam-button uppy-Webcam-button--video"
className="uppy-u-reset uppy-c-btn uppy-Webcam-button"
type="button"

@@ -27,0 +27,0 @@ title={i18n('startRecording')}

@@ -14,4 +14,6 @@ import Uppy = require('@uppy/core')

| 'recordingLength'
| 'submitRecordedFile'
| 'discardRecordedFile'
>
export = WebcamLocale

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