import React , { useEffect , useCallback , useState , useRef , RefObject , useImperativeHandle , forwardRef , CanvasHTMLAttributes , useMemo } from 'react' ; import "./Video.scss" ; import { videoGroup } from 'src/utils/Http/HttpList/Video' ; import { GetVideoGroupType , GetVideoObjType } from './VideoInterface/VideoInterface' ; import { canvasRatio } from "src/utils/index" ; const Video = ( props , ref ) => { const [ getVideoGroup , setVideoGroup ] = useState < string > ( "" ) ; const [ getVideoObj , setVideoObj ] = useState < GetVideoObjType > ( { muted : false , poster : "" , preload : "auto" , } ) ; const [ playing , setPlaying ] = useState < boolean > ( false ) ; const [ canvasSize , setCanvasSize ] = useState < { width : string ; height : string ; } > ( { width : `400` , height : `225` } ) ; const videoRef = useRef ( null ) ; const canvasRef = useRef ( null ) ; const [ videoDuration , setVideoDuration ] = useState < string > ( '00:00' ) ; const [ videoTargetTime , setVideoTargetTime ] = useState < string > ( `00:00` ) ; const setVideoAttr = new Map ( [ [ "playbackRate" , ( speed ) => videoRef . current ! . playbackRate = speed ] , [ "duration" , ( ) => videoRef . current ! . duration ] , [ "networkState" , ( ) => videoRef . current ! . networkState ] , [ "duration" , ( ) => videoRef . current ! . duration ] , [ "currentTime" , ( ) => videoRef . current ! . currentTime ] , [ "nowDuration" , ( ) => videoRef . current ! . played . start ( 0 ) + videoRef . current ! . played . end ( 0 ) ] , [ "readyState" , ( ) => videoRef . current ! . readyState ] , ] ) ; const videoFn = new Map ( [ [ "onratechange" , ( ) => videoRef . current ! . onratechange = ( ) => { console . log ( `播放速度改变` ) ; } ] , [ "onvolumechange" , ( ) => videoRef . current ! . onvolumechange = ( ) => { console . log ( `音量改变` ) ; } ] , [ "play" , ( ) => videoRef . current ! . onplay = ( ) => { console . log ( `开始播放` ) ; } ] , [ "ended" , ( ) => videoRef . current ! . onended = ( ) => { console . log ( `播放结束` ) ; } ] , [ "onpause" , ( ) => videoRef . current ! . onpause = ( ) => { console . log ( `视频暂停` ) ; return true ; } ] , [ "onplaying" , ( ) => videoRef . current ! . onplaying = ( ) => { console . log ( `视频异常,暂停` ) ; } ] , [ "onwaiting" , ( ) => videoRef . current ! . onwaiting = ( ) => { console . log ( `视频需要缓冲到下一帧，可以做一些操作` ) ; } ] , [ "onseeking" , ( ) => videoRef . current ! . onseeking = ( ) => { console . log ( `移动视频播放位置` ) ; } ] , [ "onseeked" , ( ) => videoRef . current ! . onseeked = ( ) => { console . log ( `视频播放位置移动完成,可以做一些操作` ) ; } ] , [ "ontimeupdate" , ( ) => videoRef . current ! . ontimeupdate = ( ) => videoRef . current ! . currentTime ] , [ "onabort" , ( ) => videoRef . current ! . onabort = ( ) => { console . log ( `视频终止加载,提示信息` ) ; } ] , [ "onerror" , ( ) => videoRef . current ! . onerror = ( ) => { console . log ( `视频加载错误` ) ; } ] , [ "onstalled" , ( ) => videoRef . current ! . onstalled = ( ) => { console . log ( `当前视频格式不可用` ) ; } ] , [ "onsuspend" , ( ) => videoRef . current ! . onsuspend = ( ) => { console . log ( `媒体加载数据被阻止` ) ; } ] , ] ) ; useEffect ( ( ) => { const reqDefault = requestAnimationFrame ( requestAnimateFrameFn ) ; VideoGroup ( ) ; canvasDefault ( ) ; return ( ) => window . cancelAnimationFrame ( reqDefault ) ; } , [ ] ) ; useEffect ( ( ) => { console . log ( videoDuration , '---lll---' ) ; } , [ videoDuration ] ) ; const VideoGroup = useCallback ( async ( ) => { const data = await videoGroup ( ) ; console . log ( data [ 0 ] . data . urlInfo . url , `---data---` ) ; setVideoGroup ( data [ 0 ] . data . urlInfo . url ) ; await setTimeout ( ( ) => { console . log ( setVideoAttr . get ( "duration" ) ! ( 0 ) ) ; const time = setVideoAttr . get ( "duration" ) ! ( 0 ) . toFixed ( 2 ) ; const minute = time / 60 < 10 ? `0${ Math . floor ( time / 60 ) }` : `${ Math . floor ( time / 60 ) }` ; console . log ( minute , '---kk--- minute----' ) ; const second = `${ + ( time - parseInt ( minute , 10 ) * 60 ) . toFixed ( 2 ) < 10 ? ( time - parseInt ( minute , 10 ) * 60 ) . toFixed ( 0 ) : ( time - parseInt ( minute , 10 ) * 60 ) . toFixed ( 0 ) }` ; console . log ( second , '-----kk---second' ) ; setVideoDuration ( minute + ":" + second ) ; console . log ( videoDuration , '????' ) ; } , 200 ) ; } , [ getVideoGroup , videoDuration ] ) ; const requestAnimateFrameFn = useCallback ( ( ) => { let reqFnDefault = - 1 ; if ( canvasRef . current ) { const ctx = canvasRef . current ? canvasRef . current . getContext ( "2d" ) : null ; const ratio = canvasRatio ( ctx ) ; ctx ! . drawImage ( videoRef . current ! , 0 , 0 , 400 * ratio , 225 * ratio ) ; ctx ! . scale ( ratio , ratio ) ; reqFnDefault = requestAnimationFrame ( requestAnimateFrameFn ) ; } return ( ) => ( cancelAnimationFrame ( reqFnDefault ) ) ; } , [ ] ) ; const playAddEventListenerFn = useCallback ( ( ) => { const playDefault = requestAnimationFrame ( requestAnimateFrameFn ) ; console . log ( setVideoAttr . get ( "currentTime" ) ! ( 0 ) , '---kkk---- 获取当前播放位置' ) ; return ( ) => cancelAnimationFrame ( playDefault ) ; } , [ ] ) ; const canvasDefault = useCallback ( ( ) => { videoRef . current ! . addEventListener ( "play" , playAddEventListenerFn ) ; return ( ) => videoRef . current ! . removeEventListener ( "play" , playAddEventListenerFn ) ; } , [ ] ) ; useImperativeHandle ( ref , ( ) => ( { } ) ) ; const playVideo = ( ) : void => { videoRef . current ! . play ( ) ; } ; const pause = ( ) : void => { videoRef . current ! . pause ( ) ; } ; useEffect ( ( ) => { if ( playing ) { playVideo ( ) ; } else { pause ( ) ; } } , [ playing ] ) ; const changePlayStatus = useCallback ( ( ) => { setPlaying ( ! playing ) ; } , [ playing ] ) ; return ( < div className = "video" > < div className = "canvasBox" style = { { width : canvasSize . width + `px` , height : canvasSize . height + `px` } } > < canvas id = "videoCanvas" ref = { canvasRef } width = { canvasSize . width } height = { canvasSize . height } style = { { width : `${ canvasSize . width }px` , height : `${ canvasSize . height }px` } } > 您的浏览器不支持canvas < /canvas> < div className = "videoControls" > < i className = { [ "iconfont" , playing ? "icon-zanting-copy" : "icon-kaishi-copy" ] . join ( " " ) } onClick = { changePlayStatus } / > < i className = { [ "iconfont icon-yinliang" ] . join ( " " ) } /> < i className = { [ "iconfont icon-quanping" ] . join ( " " ) } / > < i /> < /div> { } < div className = "videoProgess" > < span className = "videoProgessCache" / > < /div> < div className = "videoTime" > { videoTargetTime } / { videoDuration } < /div> < /div> < video src = { getVideoGroup } controls = { true } ref = { videoRef } className = "videoRef" muted = { getVideoObj . muted } poster = { getVideoObj . poster } preload = { getVideoObj . preload } > 您的浏览器不支持video标签 < /video> < /div>); } ; const FinalVideo = forwardRef ( Video ) ; export default FinalVideo ;