/** * camera 预览组件 * video 标签 * cordova-plugin-camera-preview 插件 */ import { useEffect, useMemo, useRef } from "react"; import CameraPreviewVideo, { IVideoConf } from "./common/CameraPreview/CameraPreviewVideo"; import CameraPreviewPlugin, { IPluginConf } from "./common/CameraPreview/CameraPreviewPlugin"; import { clientWidth, clientHeight, modeType } from "./common/constant"; import useVideo from "./useVideo"; import { ICameraPreviewerProps, IInitConf } from "./type"; import "./index.less"; /** * 摄像头预览组件 * @param props * @returns */ export const useCameraPreviewer = function (props: ICameraPreviewerProps) { const { autoStart = true, mode = modeType.video } = props || {}; const isPlugin = mode === modeType.pluginCameraPreview; /** 视频流处理工具函数 */ const playerRef = useRef(null); /** 视频流配置 */ const videoConf = useMemo(() => { const _videoConf: IVideoConf = { /** * 默认 user 前置摄像头 * user * environment */ facingMode: "user", ...props.videoConf, }; return _videoConf; }, [props.videoConf]); // 初始化 DOM 结构(video + children容器) const { videoRef, transform } = useVideo(props); useEffect(() => { init(); props.init && props.init({ onPlay, onClose, getPicImg, getPicCanvas, getPicBase64, videoRef, playerRef, init, }); if (autoStart) { onPlay(); } return () => { onClose(); }; }, []); /** * 初始化视频流 * @param videoConf * @param video */ function init(conf?: IInitConf) { const { videoConf: _videoConf, video } = conf || {}; if (playerRef.current) { return; } /** 视频流配置 */ const mergeVideoConf = { width: clientWidth, height: clientHeight, x: 0, y: 0, toBack: true, ...videoConf, ..._videoConf, }; // 视频流工具函数初始化 if (isPlugin) { playerRef.current = new CameraPreviewPlugin({ videoConf: mergeVideoConf, }); } else if (videoRef.current) { playerRef.current = new CameraPreviewVideo({ videoConf: videoConf, video: video || videoRef?.current, }); playerRef.current.video.style.left = typeof mergeVideoConf.x === "number" ? `${mergeVideoConf.x}px` : mergeVideoConf.x; playerRef.current.video.style.top = typeof mergeVideoConf.y === "number" ? `${mergeVideoConf.y}px` : mergeVideoConf.y; } } /** 开启视频流 */ function onPlay() { // video 情况下避免重复开启导致目标丢失 if (playerRef.current?.isPlaying) { return Promise.resolve(); } return playerRef.current?.start(); } /** 关闭视频流 */ function onClose() { playerRef.current?.close(); } /** 从视频流中获取图片 img 元素 */ function getPicImg(): Promise { return playerRef.current?.getSnapImg(); } /** 从视频流中获取 canvas 元素 */ function getPicCanvas(): Promise { return playerRef.current?.getSnap(); } /** 从视频流中获取图片 base64 字符串 */ function getPicBase64(): Promise { return playerRef.current?.getSnapBase64(); } return { onPlay, onClose, playerRef, videoRef, getPicImg, getPicCanvas, getPicBase64, isPlugin, transform, }; }; export { modeType }; export default useCameraPreviewer;