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 { ToastFactory, } from '@douyinfe/semi-ui'; import VideoHeader from './voiceHeader' import VideoOperation from './videoOperation' import './videoPlay.less'; 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, videoObj, // videoObj = { // type: 'yingshi', // audio: false, // serialNo: 'G75922040', // 设备序列号 必须 // channelNo: 1, // // yingshiToken: 'at.3j6eyqbn0g5xvcut73v0rzdu1nh0gnxx-4ua03m82o9-12u1t9g-rtzndpyds', // 萤石必须 // 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.rec', // }, // videoObj = { // type: 'cascade', // audio: false, // serialNo: '34020000001310000001', // 设备序列号 必须 // topSerialNo: '34020000001110000077', // 设备顶级序列号 必须 // playUrlSd: 'ws://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 }) => { const [jessibuca, setjessibuca] = 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 [resolution, setResolution] = useState('sd') // 标清 sd 高清 hd // 标记萤石操作中,等待ifream返回信息后清空 const [yingshiPrepare, setYingshiPrepare] = useState('') const operationRef = useRef(null) const processChangeTimeoutRef = useRef(null) // 标记萤石操作中,等待ifream返回信息后清空 const yingshiPrepareRef = useRef(null) useEffect(() => { setRoll(false) }, [resolution]); 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([]) } 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)]) } setoperationState(nextOperationState) } // 实时播放左下方操作栏内容 const operation = [{ key: 'control', click: () => { changeSelectState('control') } }, { key: 'talk', hide: !(videoObj.type == 'yingshi'), click: () => { changeSelectState('talk') } }, { key: 'fullScreen', click: () => { if (yingshiPrepareRef.current) { return } changeSelectState('fullScreen') let player = document.getElementById('vcmp_videoplay') if (screenfull.isEnabled) { screenfull.toggle(player); } } }, { key: 'histroy', hide: !Boolean(videoObj.replayUrl), click: () => { changeSelectState('histroy') yingshiPrepareRef.current = 'play' setYingshiPrepare('play') } },] useEffect(() => { if (videoObj.type == 'yingshi') { yingshiPrepareRef.current = 'play' setYingshiPrepare('play') } else { createJessibuca() } 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') } }); // 萤石 ifream 信息监听 const listenYingshiMessage = async (e) => { const { data, origin } = e console.log(e); if (origin !== 'https://open.ys7.com') return if (data.type == "handleSuccess") { setRoll(true) if (yingshiPrepareRef.current == 'play') { setIsPlaying(true) } } else if (data.type == yingshiOpenSoundKey && data.code == 0) { if (yingshiPrepareRef.current == yingshiOpenSoundKey) { setVoiceDisY(30) } } if (data.type == yingshiCloseSoundKey && data.code == 0) { if (yingshiPrepareRef.current == yingshiCloseSoundKey) { setVoiceDisY(0) } } yingshiPrepareRef.current = null setYingshiPrepare(null) } if (videoObj.type == 'yingshi') { window.addEventListener('message', listenYingshiMessage); } return () => { window.removeEventListener('message', listenYingshiMessage); } }, []) useEffect(() => { if (histroyTime.length) { setHistroyBegain(histroyTime[0]) document.getElementById('process_point').style.left = 0 + 'px'; // 重置进度条的位置 if (videoObj.type == 'yingshi') { yingshiPrepareRef.current = 'play' setYingshiPrepare('play') } } else { setHistroyBegain(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) ) if (videoObj.type == 'yingshi') { yingshiPrepareRef.current = 'play' setYingshiPrepare('play') } }, 300) } else { // 随播放时间变化更新进度条 document.getElementById('process_point').style.left = processDisX - 4.5 + 'px' } } }, [processDisX]) const createJessibuca = 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); // }) 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: false, screenshot: false, play: false, audio: false, }, forceNoOffscreen: false, isNotMute: false, }); setjessibuca(jessibuca) play({ jessibuca }) } } const yingshiOperation = (operation) => { document.getElementById(containerId).contentWindow.postMessage(operation, yingshiUrl) // setIsPlaying(operation == 'play') } const play = (params) => { if (videoObj.type == 'yingshi') { yingshiOperation('play') } else if ((params.jessibuca || jessibuca) && videoObj.playUrlSd) { const jes = params.jessibuca || jessibuca jes.play(videoObj.playUrlSd); setIsPlaying(true) } } const pause = () => { if (videoObj.type == 'yingshi') { // yingshiOperation('stop') } 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) } } return ( <>
{/* 顶部信息 */} {/* 视频内容 */} { videoObj.type == 'yingshi' ?