@e-group/material-lab
Version:
EGroup Team Lab - Incubator for EGroup Team experimental React components.
199 lines (161 loc) • 6.24 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _react = _interopRequireWildcard(require("react"));
var _useInterval = _interopRequireDefault(require("@e-group/hooks/useInterval"));
var _useTimeout3 = _interopRequireDefault(require("@e-group/hooks/useTimeout"));
var _core = require("@material-ui/core");
var _clsx = _interopRequireDefault(require("clsx"));
var _useGetVideoSnapshot3 = _interopRequireDefault(require("./useGetVideoSnapshot"));
const styles = () => (0, _core.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 = (0, _objectWithoutProperties2.default)(_ref, ["classes", "className", "facingMode", "onPlay", "onTimeout", "onGetUserMediaFulfilled", "onGetUserMediaRejected", "onGetUserMediaError", "isStopSnapshot", "isPause", "isStop", "intervalTime", "pauseOnTimeout", "quality", "handleGetIntervalShot", "mirrored"]);
const videoEl = (0, _react.useRef)(null);
const _useGetVideoSnapshot = (0, _useGetVideoSnapshot3.default)(videoEl, {
mirrored
}),
_useGetVideoSnapshot2 = (0, _slicedToArray2.default)(_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 = (0, _useTimeout3.default)(handleTimeout, pauseOnTimeout !== null && pauseOnTimeout !== void 0 ? pauseOnTimeout : null),
_useTimeout2 = (0, _slicedToArray2.default)(_useTimeout, 3),
reset = _useTimeout2[2];
(0, _useInterval.default)( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
var result, blob, canvas, ctx;
return _regenerator.default.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 = (0, _react.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 = (0, _react.useCallback)(() => {
if (videoEl.current && 'srcObject' in videoEl.current) {
const stream = videoEl.current.srcObject;
if (stream) {
const tracks = stream.getTracks();
tracks.forEach(track => track.stop());
}
}
}, []);
(0, _react.useEffect)(() => () => {
stopStreaming();
}, [stopStreaming]);
(0, _react.useEffect)(() => {
if (isStop) {
stopStreaming();
} else {
startStreaming();
}
}, [stopStreaming, startStreaming, isStop]);
(0, _react.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.default.createElement("video", (0, _extends2.default)({
className: (0, _clsx.default)(className, {
[classes.mirrored]: mirrored
}),
ref: videoEl,
onPlay: handlePlay
}, other));
};
var _default = (0, _core.withStyles)(styles, {
name: 'EgMediaStreamClipper'
})(MediaStreamClipper);
exports.default = _default;