UNPKG

@e-group/material-lab

Version:

EGroup Team Lab - Incubator for EGroup Team experimental React components.

177 lines (153 loc) 5.49 kB
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);