@e-group/material-lab
Version:
EGroup Team Lab - Incubator for EGroup Team experimental React components.
177 lines (153 loc) • 5.49 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _regeneratorRuntime from "@babel/runtime/regenerator";
import React, { useRef, useEffect, useCallback } from 'react';
import useInterval from '@e-group/hooks/useInterval';
import useTimeout from '@e-group/hooks/useTimeout';
import { createStyles, withStyles } from '@material-ui/core';
import clsx from 'clsx';
import useGetVideoSnapshot from './useGetVideoSnapshot';
const styles = () => createStyles({
mirrored: {
transform: 'rotateY(180deg)'
}
});
/**
* Use MediaStream to extends video and get screenshot interval when streaming open.
*/
const MediaStreamClipper = (_ref) => {
let classes = _ref.classes,
className = _ref.className,
_ref$facingMode = _ref.facingMode,
facingMode = _ref$facingMode === void 0 ? 'user' : _ref$facingMode,
onPlay = _ref.onPlay,
onTimeout = _ref.onTimeout,
onGetUserMediaFulfilled = _ref.onGetUserMediaFulfilled,
onGetUserMediaRejected = _ref.onGetUserMediaRejected,
onGetUserMediaError = _ref.onGetUserMediaError,
isStopSnapshot = _ref.isStopSnapshot,
isPause = _ref.isPause,
isStop = _ref.isStop,
_ref$intervalTime = _ref.intervalTime,
intervalTime = _ref$intervalTime === void 0 ? 200 : _ref$intervalTime,
pauseOnTimeout = _ref.pauseOnTimeout,
_ref$quality = _ref.quality,
quality = _ref$quality === void 0 ? 0.8 : _ref$quality,
handleGetIntervalShot = _ref.handleGetIntervalShot,
mirrored = _ref.mirrored,
other = _objectWithoutProperties(_ref, ["classes", "className", "facingMode", "onPlay", "onTimeout", "onGetUserMediaFulfilled", "onGetUserMediaRejected", "onGetUserMediaError", "isStopSnapshot", "isPause", "isStop", "intervalTime", "pauseOnTimeout", "quality", "handleGetIntervalShot", "mirrored"]);
const videoEl = useRef(null);
const _useGetVideoSnapshot = useGetVideoSnapshot(videoEl, {
mirrored
}),
_useGetVideoSnapshot2 = _slicedToArray(_useGetVideoSnapshot, 1),
getVideoSnapshot = _useGetVideoSnapshot2[0]; // Set min avoid frame lag.
const minIntervalTime = intervalTime < 100 ? 100 : intervalTime;
const handleTimeout = () => {
if (videoEl.current) {
videoEl.current.pause();
}
if (onTimeout) {
onTimeout();
}
};
const _useTimeout = useTimeout(handleTimeout, pauseOnTimeout !== null && pauseOnTimeout !== void 0 ? pauseOnTimeout : null),
_useTimeout2 = _slicedToArray(_useTimeout, 3),
reset = _useTimeout2[2];
useInterval( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var result, blob, canvas, ctx;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return getVideoSnapshot('image/jpeg', quality);
case 2:
result = _context.sent;
if (handleGetIntervalShot && result) {
blob = result.blob, canvas = result.canvas, ctx = result.ctx;
if (blob && canvas && ctx) {
handleGetIntervalShot(blob, canvas, ctx);
}
}
case 4:
case "end":
return _context.stop();
}
}, _callee);
})), isStopSnapshot ? null : minIntervalTime);
const startStreaming = useCallback(() => {
const constraints = {
audio: false,
video: {
facingMode
}
};
const onfulfilled = value => {
if (!videoEl.current) return;
if (onGetUserMediaFulfilled) {
onGetUserMediaFulfilled(videoEl.current);
}
if ('srcObject' in videoEl.current) {
videoEl.current.srcObject = value;
}
};
const onrejected = reason => {
if (onGetUserMediaRejected) {
onGetUserMediaRejected(reason);
}
};
try {
navigator.mediaDevices.getUserMedia(constraints).then(onfulfilled, onrejected);
} catch (error) {
if (onGetUserMediaError) {
onGetUserMediaError(error);
}
}
}, [facingMode, onGetUserMediaError, onGetUserMediaFulfilled, onGetUserMediaRejected]);
const stopStreaming = useCallback(() => {
if (videoEl.current && 'srcObject' in videoEl.current) {
const stream = videoEl.current.srcObject;
if (stream) {
const tracks = stream.getTracks();
tracks.forEach(track => track.stop());
}
}
}, []);
useEffect(() => () => {
stopStreaming();
}, [stopStreaming]);
useEffect(() => {
if (isStop) {
stopStreaming();
} else {
startStreaming();
}
}, [stopStreaming, startStreaming, isStop]);
useEffect(() => {
if (videoEl.current) {
if (isPause) {
videoEl.current.pause();
} else {
videoEl.current.play();
}
}
}, [isPause]);
const handlePlay = e => {
reset();
if (onPlay) {
onPlay(e);
}
};
return /*#__PURE__*/React.createElement("video", _extends({
className: clsx(className, {
[classes.mirrored]: mirrored
}),
ref: videoEl,
onPlay: handlePlay
}, other));
};
export default withStyles(styles, {
name: 'EgMediaStreamClipper'
})(MediaStreamClipper);