import React, { useState, useEffect, useRef } from "react"; import { connect } from "react-redux"; import screenfull from 'screenfull'; import moment from "moment"; import request from 'superagent' import { VideoServeApi, IotVideoServerRequest, checkAudioVideo } from '$utils' import { Button, ToastFactory, } from '@douyinfe/semi-ui'; import VideoHeader from './voiceHeader' import VideoOperation from './videoOperation' import './videoPlay.less'; import EZUIKit from 'ezuikit-js' import { done } from "nprogress"; const timeFormat = 'YYYY-MM-DD HH:mm:ss' const yingshiUrl = 'https://open.ys7.com/ezopen/h5/iframe' const yingshiCloseSoundKey = 'closeSound' const yingshiOpenSoundKey = 'openSound' const VideoPlay = ({ height, width, containerId = 'myPlayer', // playUrl, name, global, videoStyle, changeData, videoObj, sizeWh, slideDown, //视频下方操作是否滑动 IsSize, //是否按照16:9的比例播放 // videoObj = { // type: 'yingshi', // audio: false, // serialNo: 'G75922040', // 设备序列号 必须 // channelNo: 1, // // yingshiToken: 'at.6nn6duwz8g8gbd919as9a6ea82bmn31x-709fnp7s3k-13q3v7e-mlov7lysf', // 萤石必须 // playUrlSd: 'ezopen://open.ys7.com/G75922040/1.live', // 必须 // // playUrl: 'ws://221.230.55.27:8081/jessica/34020000001110000077/34020000001310000003', // playUrlHd: 'ezopen://open.ys7.com/G75922040/1.hd.live', // replayUrl: 'ezopen://open.ys7.com/G75922040/1.hd.local.rec', // }, // videoObj = { // type: 'yingshi', // audio: false, // serialNo: 'G56385051', // 设备序列号 必须 // channelNo: 1, // // yingshiToken: 'at.6nn6duwz8g8gbd919as9a6ea82bmn31x-709fnp7s3k-13q3v7e-mlov7lysf', // 萤石必须 // playUrlSd: 'ezopen://open.ys7.com/G56384814/1.live', // 必须 // // playUrl: 'ws://221.230.55.27:8081/jessica/34020000001110000077/34020000001310000003', // playUrlHd: 'ezopen://open.ys7.com/G56384814/1.hd.live', // replayUrl: 'ezopen://open.ys7.com/G56384814/1.hd.local.rec', // }, // videoObj = { // type: 'cascade', // audio: false, // serialNo: '34020000001310000001', // 设备序列号 必须 // topSerialNo: '34020000001110000077', // 设备顶级序列号 必须 // playUrlSd: 'http://221.230.55.27:8081/jessica/34020000001110000077/34020000001310000001', // 必须 // // playUrlHd: 'ezopen://open.ys7.com/G75922040/1.hd.live', // // replayUrl: 'ezopen://open.ys7.com/G75922040/1.rec', // }, // iotVideoServer, local, //是否本地调用视频 }) => { if (videoObj.type == 'yingshi') { videoObj = { ...videoObj, playUrlSd: `ezopen://open.ys7.com/${videoObj.serialNo}/${videoObj.channelNo || '1'}.live`, playUrlHd: `ezopen://open.ys7.com/${videoObj.serialNo}/${videoObj.channelNo || '1'}.hd.live`, replayUrl: `ezopen://open.ys7.com/${videoObj.serialNo}/${videoObj.channelNo || '1'}.hd.local.rec`, } } const [jessibuca, setjessibuca] = useState(null) const [player, setPlayer] = useState(null) const [isPlaying, setIsPlaying] = useState(false) const [operationState, setoperationState] = useState() const [voiceDisY, setVoiceDisY] = useState(0) const [processDisX, setProcessDisX] = useState(0) const [isAdjustProcess, setIsAdjustProcess] = useState(false) const [histroyTime, setHistroyTime] = useState([]) const [histroyBegain, setHistroyBegain] = useState() const [roll, setRoll] = useState()//滚动备注 const [photo, setPhoto] = useState(1)//滚动备注 const [size, setSize] = useState({ parentWidth: sizeWh?.parentWidth, parentHeight: sizeWh?.parentHeight, width: width || sizeWh?.parentWidth, height: height || sizeWh?.parentHeight }) //视频本身和父级尺寸 const [resolution, setResolution] = useState('sd') // 标清 sd 高清 hd const [videoMask, setVideoMask] = useState(true) // 标清 sd 高清 hd // 标记萤石操作中,等待ifream返回信息后清空 const [yingshiPrepare, setYingshiPrepare] = useState('') const operationRef = useRef(null) const Begain = useRef() const playBackTime = useRef([]) const quanp = useRef() const processChangeTimeoutRef = useRef(null) // 标记萤石操作中,等待ifream返回信息后清空 const yingshiPrepareRef = useRef(null) const playState = useRef(false) //播放状态 const player_ = useRef(null) useEffect(() => { setRoll(false) }, [resolution]); useEffect(() => { setResolution(changeData?.hdChecked ? 'hd' : 'sd') if (player) { player.stop().then(() => { player.play({ url: changeData?.hdChecked ? videoObj.playUrlHd : videoObj.playUrlSd }) }) } }, [changeData?.hdChecked]) const changeSelectState = (key) => { // if (videoObj.type == 'yingshi' && yingshiPrepareRef.current) { // return // } const nextOperationState = JSON.parse(JSON.stringify(operationRef.current)) if (key == 'histroy' && nextOperationState.histroy.select) { // 取消历史播放 setProcessDisX(0) setHistroyTime([]) playBackTime.current = [] } for (let k in nextOperationState) { if (k == key) { nextOperationState[k].select = !nextOperationState[k].select } else if (k !== 'fullScreen') { nextOperationState[k].select = false } } operationRef.current = nextOperationState if (operationRef.current.histroy.select && histroyTime.length == 0) { setHistroyTime([moment().subtract(72, 'hours').format(timeFormat), moment().format(timeFormat)]) playBackTime.current = [moment().subtract(72, 'hours').format(timeFormat), moment().format(timeFormat)] } setoperationState(nextOperationState) } // 实时播放左下方操作栏内容 const operation = [{ key: 'control', click: () => { changeSelectState('control') } }, { key: 'talk', hide: !(videoObj.type == 'yingshi'), click: (e) => { console.log(e); changeSelectState('talk') } }, { key: 'fullScreen', click: () => { changeSelectState('fullScreen') let videoplay = document.getElementById('vcmp_videoplay') if (screenfull.isEnabled) { screenfull.toggle(videoplay); if (videoObj?.type == 'yingshi') { console.log(operationRef.current); if (operationRef.current?.fullScreen.select) { player.reSize(screen.width, screen.height); } else { player.reSize(size?.width, size?.height); } } } } }, { key: 'histroy', hide: !Boolean(videoObj.replayUrl), click: () => { changeSelectState('histroy') player.stop().then(() => { if (operationRef.current?.histroy?.select && Begain.current) { player.play({ url: `${videoObj.replayUrl}?begin=${moment(Begain.current).format("YYYYMMDDHHmmss")}&end=${moment(playBackTime.current[1]).format("YYYYMMDDHHmmss")}` }) } playState.current = false }) } },] // useEffect(() => { // createPlay() // }, [quanp.current]) useEffect(() => { createPlay() let nextOperationState = {} for (let p of operation) { nextOperationState[p.key] = { select: false } } setoperationState(nextOperationState) operationRef.current = nextOperationState // 全屏状态监听 screenfull.on('change', () => { if (screenfull.isFullscreen && operationRef.current && !operationRef.current['fullScreen'].select) { changeSelectState('fullScreen') } if (!screenfull.isFullscreen && operationRef.current && operationRef.current['fullScreen'].select) { changeSelectState('fullScreen') } }); // const resize_ = () => { // const VideoLocal = document.getElementById('vcmp_videoplay') // setSize({ parentWidth: VideoLocal?.clientWidth, parentHeight: VideoLocal?.clientHeight, width: VideoLocal?.clientWidth, height: VideoLocal?.clientHeight }) // } // if (local) { // window.addEventListener('resize', resize_); //只要窗口殴大小发生像素变化就会触发 // } return () => { if (jessibuca) { jessibuca.destroy() } if (player && videoObj.type == 'yingshi' && player) { console.log(11111111111); player.stop() } // if (local) { // window.removeEventListener('resize', resize_); // } } }, []) useEffect(() => { if (histroyTime.length) { setHistroyBegain(histroyTime[0]) Begain.current = histroyTime[0] document.getElementById('process_point').style.left = 0 + 'px'; // 重置进度条的位置 if (videoObj.type == 'yingshi') { // yingshiPrepareRef.current = 'play' // setYingshiPrepare('play') } } else { setHistroyBegain(null) Begain.current == null } }, [histroyTime]) useEffect(() => { if (operationState && operationState.histroy.select) { if (isAdjustProcess) { // 调整进度条 更新播放开始时间 if (processChangeTimeoutRef.current) { clearTimeout(processChangeTimeoutRef.current) } processChangeTimeoutRef.current = setTimeout(() => { setHistroyBegain( moment(histroyTime[0]) .add( Math.abs(moment(histroyTime[0]).diff(moment(histroyTime[1]), 'seconds')) * (processDisX / document.getElementById('process_point').parentElement.offsetWidth), 'second' ) .format(timeFormat) ) Begain.current = moment(histroyTime[0]) .add( Math.abs(moment(histroyTime[0]).diff(moment(histroyTime[1]), 'seconds')) * (processDisX / document.getElementById('process_point').parentElement.offsetWidth), 'second' ) .format(timeFormat) if (videoObj.type == 'yingshi') { // yingshiPrepareRef.current = 'play' // setYingshiPrepare('play') } }, 300) player.stop().then(() => { player.play({ url: `${videoObj.replayUrl}?begin=${moment(Begain.current).format("YYYYMMDDHHmmss")}&end=${moment(playBackTime.current[1]).format("YYYYMMDDHHmmss")}` }) playState.current = false }) } else { // 随播放时间变化更新进度条 document.getElementById('process_point').style.left = processDisX - 4.5 + 'px' } } }, [processDisX]) const createPlay = async () => { if (videoObj.type != 'yingshi') { try { // const inviteRes = await IotVideoServerRequest.get(VideoServeApi.invite, { // id: '36011200002002021114', // channel: '36011200581314002900' // }).then(res => { // console.log(res); // }, err => {. // console.log(err); // }) console.log(videoObj); const inviteRes_ = await request.get(`${iotVideoServer}/api/gb28181/invite?id=${videoObj.topSerialNo}&channel=${videoObj.serialNo}`) } catch (error) { console.log(error.response); } let $container = document.getElementById(containerId); const jessibuca = new window.Jessibuca({ container: $container, videoBuffer: 0.2, // 缓存时长 isResize: false, text: "", loadingText: "加载中", debug: true, showBandwidth: false, // 显示网速 operateBtns: { fullscreen: true, screenshot: false, play: false, audio: false, }, forceNoOffscreen: false, isNotMute: false, }); setjessibuca(jessibuca) play({ jessibuca }) } else { const player = new EZUIKit.EZUIKitPlayer({ id: containerId, // 视频容器ID accessToken: videoObj?.yingshiToken, url: videoObj.playUrlSd, width: setupSize('width'), height: setupSize('height'), handleSuccess: () => { //播放成功 setRoll(true) setVideoMask(false) playState.current = true }, handleError: (e) => { //播放失败 console.log(e, '播放失败'); }, }) setPlayer(player) player_.current = player } } const play = (params) => { if (videoObj.type == 'yingshi') { } else if ((params.jessibuca || jessibuca) && videoObj.playUrlSd) { const jes = params.jessibuca || jessibuca jes.play(videoObj.playUrlSd); setIsPlaying(true) } } const pause = () => { if (videoObj.type == 'yingshi' && player) { 5 } else if (jessibuca) { jessibuca.pause(); setIsPlaying(false) } } const closeSound = () => { if (videoObj.type == 'yingshi') { yingshiPrepareRef.current = yingshiCloseSoundKey setYingshiPrepare(yingshiCloseSoundKey) // yingshiOperation(yingshiCloseSoundKey) } } const openSound = () => { if (videoObj.type == 'yingshi') { yingshiPrepareRef.current = yingshiOpenSoundKey setYingshiPrepare(yingshiOpenSoundKey) // yingshiOperation(yingshiOpenSoundKey) } } const setupSize = (data) => { if (!operationRef.current?.fullScreen.select) { console.log(sizeWh); let containerWidth = sizeWh?.parentWidth //容器的宽高和视频的宽高 let containerHeight = sizeWh?.parentHeight let videoWidth = width || sizeWh?.width let videoHeight = height || sizeWh?.height if (IsSize == 'true') { if (containerWidth >= videoWidth && containerHeight >= videoHeight) { if (videoHeight / videoWidth >= 0.55 && videoHeight / videoWidth <= 0.57) { } else { console.warn('宽高不符合尺寸要求,故返回合适的尺寸') if (videoWidth / 16 > videoHeight / 9) { videoWidth = (videoHeight / 9) * 16 } else { videoHeight = (videoWidth / 16) * 9 } } } else { console.warn('传递宽高参数有误,请确认容器大小范围内') if (containerWidth / 16 > containerHeight / 9) { videoWidth = (containerHeight / 9) * 16 } else { videoHeight = (containerWidth / 16) * 9 } } if (videoObj.type == 'yingshi' && player) { player.reSize(videoWidth, videoHeight) } } else { if (videoObj.type == 'yingshi' && player) { player.reSize(width || sizeWh?.parentWidth, height || sizeWh?.parentHeight) } } setSize({ parentWidth: containerWidth, parentHeight: containerHeight, width: videoWidth, height: videoHeight }) return data == 'width' ? videoWidth : data == 'height' ? videoHeight : '' } } useEffect(() => { setupSize() }, [sizeWh]) return ( <>