react-use#useRafLoop TypeScript Examples
The following examples show how to use
react-use#useRafLoop.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: MediaStream.tsx From back-home-safe with GNU General Public License v3.0 | 4 votes |
MediaStream = ({ onFrame, suppressError = false }: Props) => {
const { t } = useTranslation("qr_reader");
const { preferredCameraId } = useCamera();
const [showUnSupportErrorModal, setShowUnSupportErrorModal] = useState(false);
const [showCameraActivationErrorModal, setShowCameraActivationErrorModal] =
useState(false);
const videoRef = useRef<HTMLVideoElement>(null);
const canvasRef = useRef<HTMLCanvasElement>(null);
const [loopStop, loopStart] = useRafLoop(() => {
const canvasElement = canvasRef.current;
const videoElement = videoRef.current;
if (
canvasElement &&
videoElement &&
videoElement.readyState === videoElement.HAVE_ENOUGH_DATA
) {
const canvas = canvasElement.getContext("2d");
if (!canvas) return;
canvasElement.height = videoElement.videoHeight;
canvasElement.width = videoElement.videoWidth;
canvas.drawImage(
videoElement,
0,
0,
canvasElement.width,
canvasElement.height
);
const imageData = canvas.getImageData(
0,
0,
canvasElement.width,
canvasElement.height
);
onFrame && onFrame(imageData);
}
}, false);
const initMediaStream = useCallback(async () => {
const videoElement = videoRef.current;
if (!videoElement) return;
try {
const stream = await getMediaStream(
preferredCameraId === "AUTO" ? undefined : preferredCameraId
);
if (!stream) return;
videoElement.srcObject = stream;
videoElement.play();
loopStart();
} catch (e) {
if (e instanceof Error) {
switch (e.message) {
case mediaStreamErrorType.GET_USER_MEDIA_NOT_FOUND:
setShowUnSupportErrorModal(true);
break;
case mediaStreamErrorType.CAMERA_ACTIVATE_ERROR:
if (suppressError) return;
setShowCameraActivationErrorModal(true);
break;
default:
console.error(e);
}
}
}
}, [loopStart, preferredCameraId, suppressError]);
useEffect(() => {
const videoElement = videoRef.current;
initMediaStream();
return () => {
loopStop();
if (videoElement) {
const stream = videoElement.srcObject as MediaStream | null;
if (!stream) return;
const tracks = stream.getTracks();
tracks.forEach((track) => {
track.stop();
});
videoElement.srcObject = null;
}
};
}, [loopStart, loopStop, videoRef, initMediaStream, preferredCameraId]);
return (
<>
<Video ref={videoRef} playsInline />
<Canvas ref={canvasRef} />
<Dialog
open={showUnSupportErrorModal}
keepMounted
aria-labelledby="unsupported-device-title"
aria-describedby="unsupported-device-description"
>
<DialogTitle id="unsupported-device-title">不支援的裝置</DialogTitle>
<DialogContent>
<DialogContentText id="unsupported-device-description">
{t("message.doesnt_support_get_user_media")}
{isIOS && <>{t("message.sure_latest_ios")}</>}
</DialogContentText>
</DialogContent>
<DialogActions>
<Link to="/">
<Button color="primary">{t("button.back_home")}</Button>
</Link>
</DialogActions>
</Dialog>
<Dialog
open={showCameraActivationErrorModal}
keepMounted
aria-labelledby="camera-activation-title"
aria-describedby="camera-activation-description"
>
<DialogTitle id="camera-activation-title">
{t("dialog.cannot_open_camera.title")}
</DialogTitle>
<DialogContent>
<DialogContentText id="camera-activation-description">
{t("dialog.cannot_open_camera.content")}
</DialogContentText>
</DialogContent>
<DialogActions>
<Link to="/">
<Button color="primary">{t("button.back_home")}</Button>
</Link>
<Link to="/cameraSetting">
<Button color="primary">{t("button.camera_setting")}</Button>
</Link>
</DialogActions>
</Dialog>
</>
);
}