import React from 'react'; import videojs from 'video.js'; import 'video.js/dist/video-js.css'; import './index.scss'; import noVideo from './video-box.svg'; let statusChangeTimer = null; // 解决视频未加载完成时,双击视频之后,视频疯了一样播放暂停的问题 //引入videojs中文文件 import video_zhCN from 'video.js/dist/lang/zh-CN.json'; videojs.addLanguage('zh-CN', video_zhCN); //设置播放器的语言 export const VideoJS = (props: IVideoProps) => { const videoRef = React.useRef(null); const playerRef = React.useRef(null); const first = React.useRef(true); // 首次渲染 const tempRef = React.useRef(null); // 截视频的图 const statusChangeTimerRef = React.useRef(null); // 故事集一次控制两个 const { options, change, isPreviewShow = false, isScreening = false, width, height } = props; const { mixedmode, status, autoplay, controls, controlsAlwaysShow, muted, loop, sources, opacity } = options; React.useEffect(() => { // Make sure Video.js player is only initialized once if (!playerRef.current) { const videoElement = videoRef.current; if (!videoElement) return; const player = (playerRef.current = videojs(videoElement, options, () => { // videojs.log('player is ready'); })); first.current = false; // 渲染过后更新状态 player.on('play', function () { // 视频开始播放 change?.('play'); }); player.on('pause', function () { // 视频暂停播放 change?.('pause'); }); player.on('ended', function () { // 视频播放结束 change?.('ended'); }); player.on('volumechange', function () { // 视频播放结束 change?.('muted', player?.children_[0]?.hasAttribute('muted')); }); } else { const player = playerRef.current; if ((player && !sources[0]?.src) || isPreviewShow) { player.dispose(); playerRef.current = null; } else { player.src(sources); } } }, [sources[0]?.src]); React.useEffect(() => { // Make sure Video.js player is only initialized once if (!playerRef.current) { const videoElement = videoRef.current; if (!videoElement || first.current) return; const player = (playerRef.current = videojs(videoElement, options, () => { // videojs.log('player is ready'); })); status === '播放' ? player.pause() : player.play(); player.on('play', function () { // 视频开始播放 change?.('play'); }); player.on('pause', function () { // 视频暂停播放 change?.('pause'); }); player.on('ended', function () { // 视频播放结束 change?.('ended'); }); player.on('volumechange', function () { // 视频播放结束 change?.('muted', player?.children_[0]?.hasAttribute('muted')); }); } else { const player = playerRef.current; if (player && isPreviewShow) { player.dispose(); playerRef.current = null; } else { player.src(sources); } } }, [isPreviewShow]); React.useEffect(() => { // Make sure Video.js player is only initialized once if (!playerRef.current) { const videoElement = videoRef.current; if (!videoElement) return; const player = (playerRef.current = videojs(videoElement, options, () => { // videojs.log('player is ready'); // onReady && onReady(player); })); } else { const player = playerRef.current; if (player && !sources[0]?.src) { player.dispose(); playerRef.current = null; } else { if(!statusChangeTimerRef?.current){ statusChangeTimerRef.current = setTimeout(()=> { status === '播放' ? player.pause() : player.play(); player.controls(controls); player.loop(loop); player.muted(muted); player.autoplay(autoplay); statusChangeTimerRef.current = null; clearTimeout(statusChangeTimerRef?.current); },310) } } } }, [ mixedmode, status, controls, controlsAlwaysShow, muted, loop, autoplay, videoRef, opacity ]); // Dispose the Video.js player when the functional component unmounts React.useEffect(() => { const player = playerRef.current; return () => { if (player) { player.dispose(); playerRef.current = null; } }; }, [playerRef]); React.useEffect(() => { if (isScreening && sources[0]?.src) { // 把当前视频倾内容渲染到canvas上 //getContext方法返回一个用于在画布上绘图的环境 tempRef?.current?.setAttribute('crossOrigin', 'Anonymous'); let ctx = tempRef?.current?.getContext('2d'); ctx?.drawImage(videoRef?.current, 0, 0, width, height); //在画布上定位图像 } }, [isScreening]); return !sources[0]?.src || isPreviewShow ? ( 暂无视频 ) : (
); }; export default VideoJS; export interface IVideoProps { options: Ioptions; change?: Function; isPreviewShow?: boolean; isScreening?: boolean; width?: number; height?: number; } export interface Ioptions { mixedmode?: any; status?: string; autoplay?: boolean; controls?: boolean; controlsAlwaysShow?: string; muted?: boolean; loop?: boolean; sources?: ISources[]; opacity?: number; } export interface ISources { src?: string; type?: string; }