import React, { Component } from 'react'; import './index.less'; import videojs from 'video.js'; import Assets from '@src/components/Assets'; import { generateUUID } from '@src/services/Tools'; function fullScreen(id) { const element = document.getElementById(id); if (element.requestFullscreen) { element.requestFullscreen(); } else if (element.msRequestFullscreen) { element.msRequestFullscreen(); } else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if (element.webkitRequestFullscreen) { element.webkitRequestFullscreen(); } } function exitFullscreen() { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } } let fullAgent = null; document.addEventListener('fullscreenchange', () => { if (fullAgent) fullAgent(); }); /* Firefox */ document.addEventListener('mozfullscreenchange', () => { if (fullAgent) fullAgent(); }); /* Chrome, Safari and Opera */ document.addEventListener('webkitfullscreenchange', () => { if (fullAgent) fullAgent(); }); /* IE / Edge */ document.addEventListener('msfullscreenchange', () => { if (fullAgent) fullAgent(); }); export default class Video extends Component { constructor(props) { super(props); this.ready = false; this.state = { id: generateUUID(8), playing: false, fulling: false }; } componentDidMount() { this.player = videojs( this.videoNode, { controls: false, sources: [ { src: this.props.src, type: 'video/mp4', }, ], }, () => { this.ready = true; }, ); } componentWillUnmount() { if (this.player) { this.player.dispose(); } } refreshTimeUpdate() { if (this.timeInterval) { clearInterval(this.timeInterval); this.timeInterval = null; } this.timeInterval = setInterval(() => { const { onTimeUpdate } = this.props; if (onTimeUpdate) onTimeUpdate(this.player.currentTime()); }, this.props.duration ? this.props.duration * 1000 : 1000); } onPlay() { if (!this.ready) return; const { onPlay } = this.props; this.player.play(); this.setState({ playing: true }); if (onPlay) onPlay(); } onPause() { if (!this.ready) return; const { onPause } = this.props; this.player.pause(); this.setState({ playing: false }); if (onPause) onPause(); } onNext() { const { onNext } = this.props; this.player.pause(); this.setState({ playing: false }); if (onNext) onNext(); } onSpeed(speed) { this.player.playbackRate(speed); } onFullChange() { this.setState({ fulling: !this.state.fulling }); if (this.props.onFullChange) this.props.onFullChange(); } onFull() { fullAgent = () => this.onFullChange(); fullScreen(this.state.id); } onExitFull() { exitFullscreen(); } render() { const { action = true, btnList = [], children, onAction, hideAction } = this.props; const { playing, fulling, id } = this.state; return ( <div id={id} className={`video-item ${action ? 'action' : ''} ${fulling ? 'full' : ''}`}> <div className="video-wrapper"> <video ref={node => { this.videoNode = node; }} /> {!playing && <Assets className="play" name="play" onClick={() => this.onPlay()} />} {playing && <Assets className="stop" name="stop" onClick={() => this.onPuase()} />} </div> {!hideAction && <div className="video-bottom"> <div className="progress" /> {action && ( <div className="action-bar"> <div className="d-i-b m-r-1"> {!playing && <Assets name="play2" onClick={() => this.onPlay()} />} {playing && <Assets name="stop2" onClick={() => this.onPause()} />} </div> <div className="d-i-b m-r-1"> <Assets name="next2" onClick={() => this.onNext()} /> </div> <div className="flex-block" /> {btnList.map(btn => { if (btn.full && !fulling) return ''; if (!btn.show) return ''; return ( <div className="d-i-b m-r-1"> {btn.render ? ( <div className="fix-btn d-i-b" onClick={() => { if (btn.pause) this.onPause(); if (onAction) onAction(btn.key); }}> {btn.render(btn.active)} </div> ) : (<div className={`btn ${btn.active ? 'active' : ''}`} onClick={() => onAction && onAction(btn.key)} > {btn.title} </div>)} </div> ); })} <div className="d-i-b m-r-1"> <div className="btn">倍速</div> </div> <div className="d-i-b"> {!fulling && <Assets name="full2" onClick={() => this.onFull()} />} {fulling && <Assets name="reduction2" onClick={() => this.onExitFull()} />} </div> </div> )} </div>} {children} </div> ); } }