Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-record-webcam

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-record-webcam - npm Package Compare versions

Comparing version 0.0.14 to 0.0.15

LICENSE

18

dist/component/Controls.d.ts
import React from 'react';
import { CAMERA_STATUS } from '../constants';
import type { WebcamStatus } from '../types';
declare type ControlsProps = {
openCamera(): void;
closeCamera(): void;
start(): void;
stop(): void;
retake(): void;
download(): void;
getRecording(): void;
status: keyof typeof CAMERA_STATUS;
openCamera: () => void;
closeCamera: () => void;
start: () => void;
stop: () => void;
retake: () => void;
download: () => void;
getRecording: () => void;
status: WebcamStatus;
cssNamespace?: string;

@@ -13,0 +13,0 @@ labels?: {

@@ -11,11 +11,10 @@ "use strict";

var _a, _b, _c, _d, _e, _f;
var showOpenCamera = props.status !== constants_1.CAMERA_STATUS.OPEN &&
props.status !== constants_1.CAMERA_STATUS.RECORDING &&
props.status !== constants_1.CAMERA_STATUS.PREVIEW;
var showCloseCamera = props.status !== constants_1.CAMERA_STATUS.CLOSED &&
(props.status === constants_1.CAMERA_STATUS.OPEN || constants_1.CAMERA_STATUS.RECORDING);
var showStart = props.status === constants_1.CAMERA_STATUS.OPEN;
var showStop = props.status === constants_1.CAMERA_STATUS.RECORDING;
var showRetake = props.status === constants_1.CAMERA_STATUS.PREVIEW;
var showDownload = props.status === constants_1.CAMERA_STATUS.PREVIEW;
var showOpenCamera = props.status !== 'OPEN' &&
props.status !== 'RECORDING' &&
props.status !== 'PREVIEW';
var showCloseCamera = props.status !== 'CLOSED' && (props.status === 'OPEN' || 'RECORDING');
var showStart = props.status === 'OPEN';
var showStop = props.status === 'RECORDING';
var showRetake = props.status === 'PREVIEW';
var showDownload = props.status === 'PREVIEW';
return (react_1["default"].createElement(react_1["default"].Fragment, null,

@@ -22,0 +21,0 @@ react_1["default"].createElement("style", null, "\n ." + props.cssNamespace + "__controls {\n display: -webkit-box;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-orient: horizontal;\n -webkit-box-direction: normal;\n -ms-flex-flow: row nowrap;\n flex-flow: row nowrap;\n }\n "),

@@ -0,20 +1,21 @@

/// <reference types="recordrtc" />
import React from 'react';
import { RecordWebcamOptions, Recorder } from '../types';
import { CAMERA_STATUS } from '../constants';
declare type RenderControlsArgs = {
openCamera: () => void;
import type { Recorder } from '../mediaRecorder';
import type { RecordOptions, WebcamStatus } from '../types';
export declare type WebcamRenderProps = {
status: WebcamStatus;
closeCamera: () => void;
download: () => Promise<void>;
getRecording: () => Promise<Blob | null>;
openCamera: () => Promise<void>;
retake: () => void;
start: () => void;
stop: () => void;
retake: () => void;
download: () => void;
getRecording: () => void;
status: string;
};
declare type RecordWebcamProps = {
export declare type RecordWebcamProps = {
cssNamespace?: string;
downloadFileName?: string;
options?: RecordWebcamOptions;
getStatus?(status: string): void;
render?({}: RenderControlsArgs): void;
options?: RecordOptions;
getStatus?: (status: WebcamStatus) => void;
render?: (props: WebcamRenderProps) => void;
controlLabels?: {

@@ -29,21 +30,10 @@ CLOSE: string | number;

};
declare type RecordWebcamState = {
status: keyof typeof CAMERA_STATUS;
export declare type RecordWebcamState = {
status: WebcamStatus;
};
export declare class RecordWebcam extends React.PureComponent<RecordWebcamProps, RecordWebcamState> {
constructor(props: RecordWebcamProps);
state: {
status: "CLOSED";
};
state: RecordWebcamState;
recorder: Recorder;
recorderOptions: {
mimeType: string;
width: number;
height: number;
aspectRatio: number;
isNewSize: boolean;
type: "video";
mute?: boolean | undefined;
disableLogs?: boolean | undefined;
};
recorderOptions: RecordOptions;
webcamRef: React.RefObject<HTMLVideoElement>;

@@ -54,15 +44,76 @@ previewRef: React.RefObject<HTMLVideoElement>;

};
options: {
aspectRatio?: number | undefined;
fileName?: string | undefined;
frameRate?: number | undefined;
height?: number | undefined;
recordingLength?: number | undefined;
width?: number | undefined;
type?: "video" | "audio" | "canvas" | "gif" | undefined;
recorderType?: import("recordrtc").RecordRTCPromisesHandler | import("recordrtc").MediaStreamRecorder | import("recordrtc").StereoAudioRecorder | import("recordrtc").WebAssemblyRecorder | import("recordrtc").CanvasRecorder | import("recordrtc").GifRecorder | import("recordrtc").WhammyRecorder | import("recordrtc").MultiStreamsMixer | import("recordrtc").MultiStreamRecorder | undefined;
mimeType?: "audio/webm" | "audio/webm;codecs=pcm" | "video/mp4" | "video/webm" | "video/webm;codecs=vp9" | "video/webm;codecs=vp8" | "video/webm;codecs=h264" | "video/x-matroska;codecs=avc1" | "video/mpeg" | "audio/wav" | "audio/ogg" | undefined;
disableLogs?: boolean | undefined;
timeSlice?: number | undefined;
ondataavailable?: ((blob: Blob) => void) | undefined;
checkForInactiveTracks?: boolean | undefined;
onTimeStamp?: ((timestamp: number, timestamps: number[]) => void) | undefined;
bitsPerSecond?: number | undefined;
audioBitsPerSecond?: number | undefined;
videoBitsPerSecond?: number | undefined;
frameInterval?: number | undefined;
previewStream?: ((stream: MediaStream) => void) | undefined;
video?: HTMLVideoElement | undefined;
canvas?: {
width: number;
height: number;
} | undefined;
sampleRate?: number | undefined;
desiredSampRate?: number | undefined;
bufferSize?: 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 | undefined;
numberOfAudioChannels?: 2 | 1 | undefined;
bitrate?: number | undefined;
elementClass?: string | undefined;
} | {
aspectRatio?: number | undefined;
fileName?: string | undefined;
frameRate?: number | undefined;
height?: number | undefined;
recordingLength?: number | undefined;
width?: number | undefined;
type?: "video" | "audio" | "canvas" | "gif" | undefined;
recorderType?: import("recordrtc").RecordRTCPromisesHandler | import("recordrtc").MediaStreamRecorder | import("recordrtc").StereoAudioRecorder | import("recordrtc").WebAssemblyRecorder | import("recordrtc").CanvasRecorder | import("recordrtc").GifRecorder | import("recordrtc").WhammyRecorder | import("recordrtc").MultiStreamsMixer | import("recordrtc").MultiStreamRecorder | undefined;
mimeType?: "audio/webm" | "audio/webm;codecs=pcm" | "video/mp4" | "video/webm" | "video/webm;codecs=vp9" | "video/webm;codecs=vp8" | "video/webm;codecs=h264" | "video/x-matroska;codecs=avc1" | "video/mpeg" | "audio/wav" | "audio/ogg" | undefined;
disableLogs?: boolean | undefined;
timeSlice?: number | undefined;
ondataavailable?: ((blob: Blob) => void) | undefined;
checkForInactiveTracks?: boolean | undefined;
onTimeStamp?: ((timestamp: number, timestamps: number[]) => void) | undefined;
bitsPerSecond?: number | undefined;
audioBitsPerSecond?: number | undefined;
videoBitsPerSecond?: number | undefined;
frameInterval?: number | undefined;
previewStream?: ((stream: MediaStream) => void) | undefined;
video?: HTMLVideoElement | undefined;
canvas?: {
width: number;
height: number;
} | undefined;
sampleRate?: number | undefined;
desiredSampRate?: number | undefined;
bufferSize?: 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 | undefined;
numberOfAudioChannels?: 2 | 1 | undefined;
bitrate?: number | undefined;
elementClass?: string | undefined;
};
componentDidUpdate(_: RecordWebcamProps, prevState: RecordWebcamState): void;
handleError(error: unknown): void;
stopStream(): void;
close(): void;
openCamera(): Promise<void>;
closeCamera(): void;
handleCloseCamera(): void;
handleError(error: Error): void;
handleOpenCamera(): Promise<void>;
handleStartRecording(): Promise<void>;
handleStopRecording(): Promise<void>;
handleRetakeRecording(): Promise<void>;
start(): Promise<void>;
stop(): Promise<void>;
retake(): Promise<void>;
download(): Promise<void>;
getRecording(): Promise<Blob | undefined>;
getRecording(): Promise<Blob | null>;
render(): JSX.Element;
}
export {};

@@ -76,32 +76,18 @@ "use strict";

function RecordWebcam(props) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
var _this = _super.call(this, props) || this;
_this.state = {
status: constants_1.CAMERA_STATUS.CLOSED
status: 'CLOSED'
};
_this.recorderOptions = __assign(__assign({}, constants_1.RECORDER_OPTIONS), {
mimeType: "video/" + (((_a = _this.props.options) === null || _a === void 0 ? void 0 : _a.fileType) || 'mp4') + ";codecs=" + (((_c = (_b = _this.props.options) === null || _b === void 0 ? void 0 : _b.codec) === null || _c === void 0 ? void 0 : _c.video) ||
((_d = _this.props.options) === null || _d === void 0 ? void 0 : _d.fileType) === 'webm'
? 'vp8'
: 'avc') + "," + (((_f = (_e = _this.props.options) === null || _e === void 0 ? void 0 : _e.codec) === null || _f === void 0 ? void 0 : _f.audio) ||
((_g = _this.props.options) === null || _g === void 0 ? void 0 : _g.fileType) === 'webm'
? 'opus'
: 'aac'),
width: ((_h = _this.props.options) === null || _h === void 0 ? void 0 : _h.width) || constants_1.RECORDER_OPTIONS.width,
height: ((_j = _this.props.options) === null || _j === void 0 ? void 0 : _j.height) || constants_1.RECORDER_OPTIONS.height,
aspectRatio: ((_k = _this.props.options) === null || _k === void 0 ? void 0 : _k.aspectRatio) || constants_1.RECORDER_OPTIONS.aspectRatio,
isNewSize: Boolean(((_l = _this.props.options) === null || _l === void 0 ? void 0 : _l.width) || ((_m = _this.props.options) === null || _m === void 0 ? void 0 : _m.height))
});
_this.recorderOptions = __assign(__assign({}, constants_1.DEFAULT_OPTIONS), _this.props.options);
_this.webcamRef = react_1["default"].createRef();
_this.previewRef = react_1["default"].createRef();
_this.closeCamera = _this.closeCamera.bind(_this);
_this.options = __assign(__assign({}, _this.recorderOptions), _this.props.options);
_this.download = _this.download.bind(_this);
_this.getRecording = _this.getRecording.bind(_this);
_this.handleOpenCamera = _this.handleOpenCamera.bind(_this);
_this.openCamera = _this.openCamera.bind(_this);
_this.handleError = _this.handleError.bind(_this);
_this.handleCloseCamera = _this.handleCloseCamera.bind(_this);
_this.handleRetakeRecording = _this.handleRetakeRecording.bind(_this);
_this.handleStartRecording = _this.handleStartRecording.bind(_this);
_this.handleStopRecording = _this.handleStopRecording.bind(_this);
_this.openCamera = _this.openCamera.bind(_this);
_this.close = _this.close.bind(_this);
_this.retake = _this.retake.bind(_this);
_this.start = _this.start.bind(_this);
_this.stop = _this.stop.bind(_this);
return _this;

@@ -115,27 +101,15 @@ }

};
RecordWebcam.prototype.openCamera = function () {
return __awaiter(this, void 0, void 0, function () {
var recorderInit;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, mediaRecorder_1.mediaRecorder(this.recorderOptions)];
case 1:
recorderInit = _a.sent();
this.recorder = recorderInit;
if (this.webcamRef.current) {
this.webcamRef.current.srcObject = recorderInit.stream;
}
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 1700); })];
case 2:
_a.sent();
return [2 /*return*/];
}
});
RecordWebcam.prototype.handleError = function (error) {
this.setState({
status: 'ERROR'
});
console.error({ error: error });
};
RecordWebcam.prototype.closeCamera = function () {
if (this.recorder.stream.id)
RecordWebcam.prototype.stopStream = function () {
var _a;
if (this.recorder.stream.id && ((_a = this.recorder) === null || _a === void 0 ? void 0 : _a.stopRecording)) {
this.recorder.stream.stop();
}
};
RecordWebcam.prototype.handleCloseCamera = function () {
RecordWebcam.prototype.close = function () {
if (this.previewRef.current) {

@@ -145,33 +119,34 @@ this.previewRef.current.removeAttribute('src');

}
this.setState({ status: constants_1.CAMERA_STATUS.CLOSED });
this.closeCamera();
this.setState({ status: 'CLOSED' });
this.stopStream();
};
RecordWebcam.prototype.handleError = function (error) {
this.setState({
status: constants_1.CAMERA_STATUS.ERROR
});
console.error({ error: error });
};
RecordWebcam.prototype.handleOpenCamera = function () {
RecordWebcam.prototype.openCamera = function () {
return __awaiter(this, void 0, void 0, function () {
var error_1;
var recorderInit, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
_a.trys.push([0, 3, , 4]);
this.setState({
status: constants_1.CAMERA_STATUS.INIT
status: 'INIT'
});
return [4 /*yield*/, this.openCamera()];
return [4 /*yield*/, mediaRecorder_1.mediaRecorder(this.options)];
case 1:
recorderInit = _a.sent();
this.recorder = recorderInit;
if (this.webcamRef.current) {
this.webcamRef.current.srcObject = recorderInit.stream;
}
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 1700); })];
case 2:
_a.sent();
this.setState({
status: constants_1.CAMERA_STATUS.OPEN
status: 'OPEN'
});
return [3 /*break*/, 3];
case 2:
return [3 /*break*/, 4];
case 3:
error_1 = _a.sent();
this.handleError(error_1);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}

@@ -181,29 +156,30 @@ });

};
RecordWebcam.prototype.handleStartRecording = function () {
var _a;
RecordWebcam.prototype.start = function () {
var _a, _b;
return __awaiter(this, void 0, void 0, function () {
var length_1, error_2;
return __generator(this, function (_b) {
switch (_b.label) {
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_b.trys.push([0, 5, , 6]);
_c.trys.push([0, 5, , 6]);
if (!((_a = this.recorder) === null || _a === void 0 ? void 0 : _a.startRecording)) return [3 /*break*/, 4];
return [4 /*yield*/, this.recorder.startRecording()];
case 1:
_b.sent();
_c.sent();
this.setState({
status: constants_1.CAMERA_STATUS.RECORDING
status: 'RECORDING'
});
if (!((_a = this.props.options) === null || _a === void 0 ? void 0 : _a.recordingLength)) return [3 /*break*/, 4];
if (!((_b = this.props.options) === null || _b === void 0 ? void 0 : _b.recordingLength)) return [3 /*break*/, 4];
length_1 = this.props.options.recordingLength * 1000;
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, length_1); })];
case 2:
_b.sent();
return [4 /*yield*/, this.handleStopRecording()];
_c.sent();
return [4 /*yield*/, this.stop()];
case 3:
_b.sent();
this.closeCamera();
_b.label = 4;
_c.sent();
this.stop();
_c.label = 4;
case 4: return [3 /*break*/, 6];
case 5:
error_2 = _b.sent();
error_2 = _c.sent();
this.handleError(error_2);

@@ -216,15 +192,18 @@ return [3 /*break*/, 6];

};
RecordWebcam.prototype.handleStopRecording = function () {
RecordWebcam.prototype.stop = function () {
var _a, _b;
return __awaiter(this, void 0, void 0, function () {
var blob, preview, error_3;
return __generator(this, function (_a) {
switch (_a.label) {
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_a.trys.push([0, 3, , 4]);
_c.trys.push([0, 4, , 5]);
if (!(((_a = this.recorder) === null || _a === void 0 ? void 0 : _a.stopRecording) && ((_b = this.recorder) === null || _b === void 0 ? void 0 : _b.getBlob))) return [3 /*break*/, 3];
return [4 /*yield*/, this.recorder.stopRecording()];
case 1:
_a.sent();
_c.sent();
return [4 /*yield*/, this.recorder.getBlob()];
case 2:
blob = _a.sent();
blob = _c.sent();
console.log('**', { blob: blob });
preview = window.URL.createObjectURL(blob);

@@ -234,12 +213,13 @@ if (this.previewRef.current) {

}
this.closeCamera();
this.stopStream();
this.setState({
status: constants_1.CAMERA_STATUS.PREVIEW
status: 'PREVIEW'
});
return [3 /*break*/, 4];
case 3:
error_3 = _a.sent();
return [2 /*return*/];
case 3: throw new Error('Stop recording error!');
case 4:
error_3 = _c.sent();
this.handleError(error_3);
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}

@@ -249,3 +229,3 @@ });

};
RecordWebcam.prototype.handleRetakeRecording = function () {
RecordWebcam.prototype.retake = function () {
return __awaiter(this, void 0, void 0, function () {

@@ -257,3 +237,3 @@ var error_4;

_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, this.handleOpenCamera()];
return [4 /*yield*/, this.openCamera()];
case 1:

@@ -272,20 +252,25 @@ _a.sent();

RecordWebcam.prototype.download = function () {
var _a, _b;
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function () {
var blob, filename, error_5;
return __generator(this, function (_c) {
switch (_c.label) {
var blob, fileTypeFromMimeType, fileType, filename, error_5;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
_c.trys.push([0, 2, , 3]);
_d.trys.push([0, 3, , 4]);
if (!((_a = this.recorder) === null || _a === void 0 ? void 0 : _a.getBlob)) return [3 /*break*/, 2];
return [4 /*yield*/, this.recorder.getBlob()];
case 1:
blob = _c.sent();
filename = (((_a = this.props.options) === null || _a === void 0 ? void 0 : _a.filename) || new Date().getTime()) + "." + (((_b = this.props.options) === null || _b === void 0 ? void 0 : _b.fileType) || 'mp4');
blob = _d.sent();
fileTypeFromMimeType = ((_c = (_b = this.recorderOptions.mimeType) === null || _b === void 0 ? void 0 : _b.split('video/')[1]) === null || _c === void 0 ? void 0 : _c.split(';')[0]) ||
'mp4';
fileType = fileTypeFromMimeType === 'x-matroska' ? 'mkv' : fileTypeFromMimeType;
filename = this.recorderOptions.fileName + "." + fileType;
utils_1.saveFile(filename, blob);
return [3 /*break*/, 3];
case 2:
error_5 = _c.sent();
return [2 /*return*/];
case 2: throw new Error('Error downloading file!');
case 3:
error_5 = _d.sent();
this.handleError(error_5);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}

@@ -298,14 +283,18 @@ });

return __awaiter(this, void 0, void 0, function () {
var error_6;
var blob, error_6;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
return [4 /*yield*/, ((_a = this.recorder) === null || _a === void 0 ? void 0 : _a.getBlob())];
case 1: return [2 /*return*/, _b.sent()];
case 2:
_b.trys.push([0, 3, , 4]);
if (!((_a = this.recorder) === null || _a === void 0 ? void 0 : _a.getBlob)) return [3 /*break*/, 2];
return [4 /*yield*/, this.recorder.getBlob()];
case 1:
blob = _b.sent();
return [2 /*return*/, blob];
case 2: return [2 /*return*/, null];
case 3:
error_6 = _b.sent();
this.handleError(error_6);
return [2 /*return*/];
case 3: return [2 /*return*/];
return [2 /*return*/, null];
case 4: return [2 /*return*/];
}

@@ -321,7 +310,7 @@ });

_b.call(_a, {
openCamera: this.handleOpenCamera,
closeCamera: this.handleCloseCamera,
start: this.handleStartRecording,
stop: this.handleStopRecording,
retake: this.handleRetakeRecording,
openCamera: this.openCamera,
closeCamera: this.close,
start: this.start,
stop: this.stop,
retake: this.retake,
download: this.download,

@@ -332,7 +321,7 @@ getRecording: this.getRecording,

!this.props.render && (react_1["default"].createElement("div", { className: this.props.cssNamespace + "__status" }, "Status: " + this.state.status)),
!this.props.render && (react_1["default"].createElement(Controls_1.Controls, { closeCamera: this.handleCloseCamera, cssNamespace: this.props.cssNamespace, download: this.download, getRecording: this.getRecording, labels: this.props.controlLabels, openCamera: this.handleOpenCamera, retake: this.handleRetakeRecording, start: this.handleStartRecording, status: this.state.status, stop: this.handleStopRecording })),
!this.props.render && (react_1["default"].createElement(Controls_1.Controls, { closeCamera: this.close, cssNamespace: this.props.cssNamespace, download: this.download, getRecording: this.getRecording, labels: this.props.controlLabels, openCamera: this.openCamera, retake: this.retake, start: this.start, status: this.state.status, stop: this.stop })),
react_1["default"].createElement(Video_1.Video, { cssNamespace: this.props.cssNamespace, style: {
display: "" + (this.state.status !== constants_1.CAMERA_STATUS.CLOSED &&
(this.state.status === constants_1.CAMERA_STATUS.OPEN ||
this.state.status === constants_1.CAMERA_STATUS.RECORDING)
display: "" + (this.state.status !== 'CLOSED' &&
(this.state.status === 'OPEN' ||
this.state.status === 'RECORDING')
? 'block'

@@ -342,4 +331,4 @@ : 'none')

react_1["default"].createElement(Video_1.Video, { cssNamespace: this.props.cssNamespace, style: {
display: "" + (this.state.status !== constants_1.CAMERA_STATUS.CLOSED &&
this.state.status === constants_1.CAMERA_STATUS.PREVIEW
display: "" + (this.state.status !== 'CLOSED' &&
this.state.status === 'PREVIEW'
? 'block'

@@ -346,0 +335,0 @@ : 'none')

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

import { RecordWebcamOptions, RecorderOptions } from './types';
export declare const OPTIONS: RecordWebcamOptions;
export declare const RECORDER_OPTIONS: RecorderOptions;
export declare const CAMERA_STATUS: {
readonly INIT: "INIT";
readonly CLOSED: "CLOSED";
readonly OPEN: "OPEN";
readonly RECORDING: "RECORDING";
readonly PREVIEW: "PREVIEW";
readonly ERROR: "ERROR";
};
import { RecordOptions } from './types';
export declare const DEFAULT_OPTIONS: RecordOptions;
export declare const BUTTON_LABELS: {

@@ -13,0 +4,0 @@ readonly OPEN: "Open camera";

"use strict";
exports.__esModule = true;
exports.NAMESPACES = exports.BUTTON_LABELS = exports.CAMERA_STATUS = exports.RECORDER_OPTIONS = exports.OPTIONS = void 0;
exports.OPTIONS = {
filename: String(new Date().getTime()),
recordingLength: 3,
fileType: 'mp4',
width: 1920,
height: 1080,
aspectRatio: 1.777777778
};
exports.RECORDER_OPTIONS = {
exports.NAMESPACES = exports.BUTTON_LABELS = exports.DEFAULT_OPTIONS = void 0;
exports.DEFAULT_OPTIONS = {
type: 'video',
mimeType: 'video/mp4',
disableLogs: true,
mimeType: 'video/webm',
aspectRatio: 1.7,
fileName: String(new Date().getTime()),
width: 1280,
height: 720,
aspectRatio: 1.77,
isNewSize: false
height: 720
};
exports.CAMERA_STATUS = {
INIT: 'INIT',
CLOSED: 'CLOSED',
OPEN: 'OPEN',
RECORDING: 'RECORDING',
PREVIEW: 'PREVIEW',
ERROR: 'ERROR'
};
exports.BUTTON_LABELS = {

@@ -30,0 +13,0 @@ OPEN: 'Open camera',

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

import { RecordWebcamHook, RecordWebcamOptions } from '../types';
export declare function useRecordWebcam(options?: RecordWebcamOptions): RecordWebcamHook;
import React from 'react';
import type { RecordOptions, WebcamStatus } from '../types';
export declare type UseRecordWebcam = {
previewRef: React.RefObject<HTMLVideoElement>;
status: WebcamStatus;
webcamRef: React.RefObject<HTMLVideoElement>;
close: () => void;
download: () => void;
getRecording: () => void;
open: () => void;
retake: () => void;
start: () => void;
stop: () => void;
stopStream: () => void;
};
export declare function useRecordWebcam(options?: RecordOptions): UseRecordWebcam;

@@ -62,16 +62,12 @@ "use strict";

var previewRef = react_1["default"].useRef(null);
var _a = react_1["default"].useState(constants_1.CAMERA_STATUS.CLOSED), status = _a[0], setStatus = _a[1];
var _a = react_1["default"].useState('CLOSED'), status = _a[0], setStatus = _a[1];
var _b = react_1["default"].useState(null), recorder = _b[0], setRecorder = _b[1];
var _c = react_1["default"].useState(constants_1.RECORDER_OPTIONS), recorderOptions = _c[0], setRecorderOptions = _c[1];
react_1["default"].useEffect(function () {
var _a, _b;
if (options) {
setRecorderOptions(__assign(__assign({}, constants_1.RECORDER_OPTIONS), { mimeType: "video/" + (options.fileType || 'mp4') + ";codecs=" + (((_a = options === null || options === void 0 ? void 0 : options.codec) === null || _a === void 0 ? void 0 : _a.video) || options.fileType === 'webm' ? 'vp8' : 'avc') + "," + (((_b = options === null || options === void 0 ? void 0 : options.codec) === null || _b === void 0 ? void 0 : _b.audio) || options.fileType === 'webm' ? 'opus' : 'aac'), width: options.width || constants_1.RECORDER_OPTIONS.width, height: options.height || constants_1.RECORDER_OPTIONS.height, aspectRatio: (options === null || options === void 0 ? void 0 : options.aspectRatio) || constants_1.RECORDER_OPTIONS.aspectRatio, isNewSize: Boolean((options === null || options === void 0 ? void 0 : options.width) || (options === null || options === void 0 ? void 0 : options.height)) }));
}
}, []);
var recorderOptions = __assign(__assign({}, constants_1.DEFAULT_OPTIONS), options);
var openCamera = function () { return __awaiter(_this, void 0, void 0, function () {
var recorderInit;
var recorderInit, error_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, mediaRecorder_1.mediaRecorder(recorderOptions)];
case 0:
_a.trys.push([0, 3, , 4]);
return [4 /*yield*/, mediaRecorder_1.mediaRecorder(recorderOptions)];
case 1:

@@ -86,3 +82,9 @@ recorderInit = _a.sent();

_a.sent();
return [2 /*return*/];
return [3 /*break*/, 4];
case 3:
error_1 = _a.sent();
setStatus('ERROR');
console.error({ error: error_1 });
return [3 /*break*/, 4];
case 4: return [2 /*return*/];
}

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

var stopStream = function () {
if (recorder === null || recorder === void 0 ? void 0 : recorder.stream.id)
if ((recorder === null || recorder === void 0 ? void 0 : recorder.stream.id) && recorder.stopRecording)
recorder.stream.stop();

@@ -101,7 +103,7 @@ };

}
setStatus(constants_1.CAMERA_STATUS.CLOSED);
setStatus('CLOSED');
stopStream();
};
var open = function () { return __awaiter(_this, void 0, void 0, function () {
var error_1;
var error_2;
return __generator(this, function (_a) {

@@ -111,12 +113,12 @@ switch (_a.label) {

_a.trys.push([0, 2, , 3]);
setStatus(constants_1.CAMERA_STATUS.INIT);
setStatus('INIT');
return [4 /*yield*/, openCamera()];
case 1:
_a.sent();
setStatus(constants_1.CAMERA_STATUS.OPEN);
setStatus('OPEN');
return [3 /*break*/, 3];
case 2:
error_1 = _a.sent();
setStatus(constants_1.CAMERA_STATUS.ERROR);
console.error({ error: error_1 });
error_2 = _a.sent();
setStatus('ERROR');
console.error({ error: error_2 });
return [3 /*break*/, 3];

@@ -127,32 +129,2 @@ case 3: return [2 /*return*/];

}); };
var stop = function () { return __awaiter(_this, void 0, void 0, function () {
var blob, preview, error_2;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 4, , 5]);
if (!(recorder === null || recorder === void 0 ? void 0 : recorder.stopRecording)) return [3 /*break*/, 3];
return [4 /*yield*/, recorder.stopRecording()];
case 1:
_a.sent();
return [4 /*yield*/, recorder.getBlob()];
case 2:
blob = _a.sent();
preview = window.URL.createObjectURL(blob);
if (previewRef.current) {
previewRef.current.src = preview;
}
stopStream();
setStatus(constants_1.CAMERA_STATUS.PREVIEW);
return [2 /*return*/];
case 3: throw new Error('Stop recording error!');
case 4:
error_2 = _a.sent();
setStatus(constants_1.CAMERA_STATUS.ERROR);
console.error({ error: error_2 });
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
}); };
var start = function () { return __awaiter(_this, void 0, void 0, function () {

@@ -168,5 +140,5 @@ var length_1, error_3;

_a.sent();
setStatus(constants_1.CAMERA_STATUS.RECORDING);
if (!(options === null || options === void 0 ? void 0 : options.recordingLength)) return [3 /*break*/, 4];
length_1 = options.recordingLength * 1000;
setStatus('RECORDING');
if (!(recorderOptions === null || recorderOptions === void 0 ? void 0 : recorderOptions.recordingLength)) return [3 /*break*/, 4];
length_1 = recorderOptions.recordingLength * 1000;
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, length_1); })];

@@ -184,3 +156,3 @@ case 2:

error_3 = _a.sent();
setStatus(constants_1.CAMERA_STATUS.ERROR);
setStatus('ERROR');
console.error({ error: error_3 });

@@ -192,4 +164,34 @@ return [3 /*break*/, 7];

}); };
var stop = function () { return __awaiter(_this, void 0, void 0, function () {
var blob, preview, error_4;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 4, , 5]);
if (!((recorder === null || recorder === void 0 ? void 0 : recorder.stopRecording) && (recorder === null || recorder === void 0 ? void 0 : recorder.getBlob))) return [3 /*break*/, 3];
return [4 /*yield*/, recorder.stopRecording()];
case 1:
_a.sent();
return [4 /*yield*/, recorder.getBlob()];
case 2:
blob = _a.sent();
preview = window.URL.createObjectURL(blob);
if (previewRef.current) {
previewRef.current.src = preview;
}
stopStream();
setStatus('PREVIEW');
return [2 /*return*/];
case 3: throw new Error('Stop recording error!');
case 4:
error_4 = _a.sent();
setStatus('ERROR');
console.error({ error: error_4 });
return [3 /*break*/, 5];
case 5: return [2 /*return*/];
}
});
}); };
var retake = function () { return __awaiter(_this, void 0, void 0, function () {
var error_4;
var error_5;
return __generator(this, function (_a) {

@@ -204,5 +206,5 @@ switch (_a.label) {

case 2:
error_4 = _a.sent();
setStatus(constants_1.CAMERA_STATUS.ERROR);
console.error({ error: error_4 });
error_5 = _a.sent();
setStatus('ERROR');
console.error({ error: error_5 });
return [3 /*break*/, 3];

@@ -214,12 +216,15 @@ case 3: return [2 /*return*/];

var download = function () { return __awaiter(_this, void 0, void 0, function () {
var blob, filename, error_5;
return __generator(this, function (_a) {
switch (_a.label) {
var blob, fileTypeFromMimeType, fileType, filename, error_6;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
_a.trys.push([0, 3, , 4]);
_c.trys.push([0, 3, , 4]);
if (!(recorder === null || recorder === void 0 ? void 0 : recorder.getBlob)) return [3 /*break*/, 2];
return [4 /*yield*/, recorder.getBlob()];
case 1:
blob = _a.sent();
filename = ((options === null || options === void 0 ? void 0 : options.filename) || new Date().getTime()) + "." + ((options === null || options === void 0 ? void 0 : options.fileType) || 'mp4');
blob = _c.sent();
fileTypeFromMimeType = ((_b = (_a = recorderOptions.mimeType) === null || _a === void 0 ? void 0 : _a.split('video/')[1]) === null || _b === void 0 ? void 0 : _b.split(';')[0]) || 'mp4';
fileType = fileTypeFromMimeType === 'x-matroska' ? 'mkv' : fileTypeFromMimeType;
filename = recorderOptions.fileName + "." + fileType;
utils_1.saveFile(filename, blob);

@@ -229,5 +234,5 @@ return [2 /*return*/];

case 3:
error_5 = _a.sent();
setStatus(constants_1.CAMERA_STATUS.ERROR);
console.error({ error: error_5 });
error_6 = _c.sent();
setStatus('ERROR');
console.error({ error: error_6 });
return [3 /*break*/, 4];

@@ -239,15 +244,19 @@ case 4: return [2 /*return*/];

var getRecording = function () { return __awaiter(_this, void 0, void 0, function () {
var error_6;
var blob, error_7;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, (recorder === null || recorder === void 0 ? void 0 : recorder.getBlob())];
case 1: return [2 /*return*/, _a.sent()];
case 2:
error_6 = _a.sent();
setStatus(constants_1.CAMERA_STATUS.ERROR);
console.error({ error: error_6 });
return [2 /*return*/];
case 3: return [2 /*return*/];
_a.trys.push([0, 3, , 4]);
if (!(recorder === null || recorder === void 0 ? void 0 : recorder.getBlob)) return [3 /*break*/, 2];
return [4 /*yield*/, recorder.getBlob()];
case 1:
blob = _a.sent();
return [2 /*return*/, blob];
case 2: return [2 /*return*/, null];
case 3:
error_7 = _a.sent();
setStatus('ERROR');
console.error({ error: error_7 });
return [2 /*return*/, null];
case 4: return [2 /*return*/];
}

@@ -254,0 +263,0 @@ });

export * from './component';
export * from './hook';
export * from './types';
export * from './constants';

@@ -16,2 +16,1 @@ "use strict";

__exportStar(require("./types"), exports);
__exportStar(require("./constants"), exports);

@@ -1,8 +0,6 @@

import { RecorderOptions, Recorder } from './types';
declare type CaptureUserMedia = {
stream: MediaStream;
recordRtc: any;
};
export declare function captureUserMedia(options: RecorderOptions): Promise<CaptureUserMedia>;
export declare function mediaRecorder(options: RecorderOptions): Promise<Recorder>;
export {};
import { RecordRTCPromisesHandler } from 'recordrtc';
import type { RecordOptions } from './types';
export declare type Recorder = {
stream: MediaStream & MediaStreamTrack;
} & Partial<RecordRTCPromisesHandler>;
export declare function mediaRecorder(options: RecordOptions): Promise<Recorder>;

@@ -50,28 +50,9 @@ "use strict";

exports.__esModule = true;
exports.mediaRecorder = exports.captureUserMedia = void 0;
// @ts-ignore
exports.mediaRecorder = void 0;
var recordrtc_1 = require("recordrtc");
function captureUserMedia(options) {
function mediaRecorder(options) {
return __awaiter(this, void 0, void 0, function () {
var stream, recordRtc;
var stream, recordRtc, supported, tracks;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
video: true,
audio: true
})];
case 1:
stream = _a.sent();
recordRtc = new recordrtc_1.RecordRTCPromisesHandler(stream, __assign({}, options));
return [2 /*return*/, { stream: stream, recordRtc: recordRtc }];
}
});
});
}
exports.captureUserMedia = captureUserMedia;
function mediaRecorder(options) {
return __awaiter(this, void 0, void 0, function () {
var _a, stream, recordRtc, supported, tracks;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:

@@ -81,5 +62,9 @@ if (!navigator.mediaDevices.getUserMedia) {

}
return [4 /*yield*/, captureUserMedia(options)];
return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
video: true,
audio: true
})];
case 1:
_a = _b.sent(), stream = _a.stream, recordRtc = _a.recordRtc;
stream = (_a.sent());
recordRtc = new recordrtc_1.RecordRTCPromisesHandler(stream, __assign({}, options));
supported = navigator.mediaDevices.getSupportedConstraints();

@@ -89,3 +74,6 @@ if (!supported.width || !supported.height) {

}
if (options.isNewSize && supported.width && supported.height) {
if (!supported.frameRate) {
console.error('Media device does not support setting frameRate!');
}
if (supported.width || supported.height || supported.frameRate) {
tracks = stream.getTracks();

@@ -97,3 +85,4 @@ tracks.forEach(function (track) {

height: options.height,
aspectRatio: options.aspectRatio
aspectRatio: options.aspectRatio,
frameRate: options.frameRate
});

@@ -100,0 +89,0 @@ }

@@ -1,64 +0,10 @@

/// <reference types="react" />
declare type AudioCodec = 'aac' | 'opus';
declare type VideoCodec = 'av1' | 'avc' | 'vp8';
export declare type FileMimeType = 'video/mp4' | 'video/webm';
export declare type FileType = 'mp4' | 'webm';
export declare type RecordingOptions = {
mimeType: FileMimeType;
};
export declare type RecorderOptions = {
aspectRatio: number;
height: number;
type: 'video';
width: number;
isNewSize?: boolean;
mimeType?: string;
mute?: boolean;
disableLogs?: boolean;
};
export declare type RecordWebcamOptions = {
codec?: {
audio: AudioCodec;
video: VideoCodec;
};
filename?: string;
import type { Options } from 'recordrtc';
export declare type RecordOptions = {
aspectRatio?: number;
fileName?: string;
frameRate?: number;
height?: number;
recordingLength?: number;
fileType?: FileType;
width?: number;
height?: number;
aspectRatio?: number;
};
export declare type WebcamRenderProps = {
isPreview: boolean;
isRecording: boolean;
isWebcamOn: boolean;
status: string;
closeCamera(): void;
download(): void;
getRecording(): Blob | undefined;
openCamera(): void;
retake(): void;
start(): void;
stop(): void;
};
export declare type RecordWebcamHook = {
previewRef: React.RefObject<HTMLVideoElement>;
status: string | number;
webcamRef: React.RefObject<HTMLVideoElement>;
close(): void;
download(): void;
getRecording(): void;
open(): void;
retake(): void;
start(): void;
stop(): void;
stopStream(): void;
};
export declare type Recorder = {
stream: any;
getBlob(): Promise<Blob>;
getDataURL(): Promise<string>;
startRecording(): Promise<void>;
stopRecording(): Promise<void>;
};
export {};
} & Options;
export declare type WebcamStatus = 'INIT' | 'CLOSED' | 'OPEN' | 'RECORDING' | 'PREVIEW' | 'ERROR';
{
"name": "react-record-webcam",
"description": "A React webcam recording hook and component 🎬📹",
"version": "0.0.14",
"version": "0.0.15",
"main": "dist/index.js",

@@ -31,3 +31,6 @@ "files": [

"video"
]
],
"devDependencies": {
"@types/recordrtc": "^5.6.9"
}
}

@@ -16,6 +16,9 @@ <div align="center" style="width: 100%; background-color: white;">

## Add package
```
npm i react-record-webcam
```
<i>Or</i>
```

@@ -25,3 +28,2 @@ yarn add react-record-webcam

## Use hook

@@ -55,2 +57,3 @@

```
Import the hook and initialize it in your function. The hook returns refs for both preview and recording video elements, functions to control recording (open, start, stop, retake, download) and camera status.

@@ -65,2 +68,3 @@

Passing options:
```

@@ -72,3 +76,2 @@ const OPTIONS = { ... }

| Options ||

@@ -85,6 +88,4 @@ | ------------- | ------------- |

<br>
## Use component

@@ -103,2 +104,3 @@

```
You can include the component as is and it will render controls, video and preview elements. Alternatively you can use the render prop for more control:

@@ -130,5 +132,2 @@

<br>

@@ -169,3 +168,3 @@

You can use the below default class names or pass your own namespace to replace the default `react-record-webcam`.
You can use the below default class names or pass your own namespace to replace the default `react-record-webcam`.

@@ -178,2 +177,6 @@ | className |

|`react-record-webcam__controls`
|`react-record-webcam__controls-button`
|`react-record-webcam__controls-button`
## License
[MIT](LICENSE)
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