import React, { Component } from 'react'; import { Slider } from 'antd'; import './index.less'; import videojs from 'video.js'; import Assets from '@src/components/Assets'; import { generateUUID, formatSecondAuto } 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, progress: 0, speed: 1 }; } componentDidMount() { this.player = videojs( this.videoNode, { controls: true, sources: [ { src: this.props.src, type: 'video/mp4', }, ], width: this.props.width, height: this.props.height, }, () => { this.ready = true; }, ); } componentWillUnmount() { if (this.player) { this.player.dispose(); } } clearTimeUpdate() { if (this.timeInterval) { clearInterval(this.timeInterval); this.timeInterval = null; } } refreshTimeUpdate() { if (this.timeInterval) { clearInterval(this.timeInterval); this.timeInterval = null; } this.timeInterval = setInterval(() => { const { onTimeUpdate } = this.props; if (onTimeUpdate) onTimeUpdate(this.player.currentTime()); this.setState({ progress: this.player.currentTime() * 100 / this.player.duration() }); }, 1000); } onChangeProgress(value) { if (!this.ready) return; this.player.currentTime((this.player.duration() * value) / 100); this.setState({ progress: (this.player.currentTime() * 100) / this.player.duration() }); const { onChangeProgress } = this.props; const { playing } = this.state; if (!playing) { this.player.pause(); } if (onChangeProgress) onChangeProgress(this.player.currentTime()); } onPlay() { if (!this.ready) return; const { onPlay } = this.props; this.player.play(); this.setState({ playing: true }); if (onPlay) onPlay(this.player.currentTime()); this.refreshTimeUpdate(); } onPause() { if (!this.ready) return; const { onPause } = this.props; this.player.pause(); this.setState({ playing: false }); if (onPause) onPause(this.player.currentTime()); this.clearTimeUpdate(); } onNext() { const { onNext } = this.props; this.player.pause(); this.clearTimeUpdate(); this.setState({ playing: false }); if (onNext) onNext(); } onSpeed(speed) { this.player.playbackRate(speed); this.setState({ selectSpeed: false, speed }); } selectSpeed(value) { this.setState({ selectSpeed: value }); } onFullChange() { this.setState({ fulling: !this.state.fulling }); if (this.props.onFullChange) this.props.onFullChange(); } onFull() { fullAgent = () => this.onFullChange(); fullScreen(this.state.id); } onExitFull() { exitFullscreen(); } showProgressTip(e) { let x = e.clientX; const percent = x * 100 / this.progress.clientWidth; const text = percent > 0 ? formatSecondAuto(percent * this.player.duration() / 100) : '00:00'; const width = text.length > 5 ? 67.8 : 47.3; x += 1; x -= width / 2; if (x < 0) { x = 0; } else if (x + width > this.progress.clientWidth) { x = this.progress.clientWidth - width; } this.setState({ pt: { left: x, display: 'block', text, width } }); } hideProgressTip() { this.setState({ pt: {} }); } render() { const { btnList = [], children, onAction, hideAction, water } = this.props; const { playing, fulling, id, selectSpeed, speed } = this.state; return (
{ return playing ? this.onPause() : this.onPlay(); }}>
{/*
*/} {this.renderProgress()} {!hideAction && (
(playing ? this.onPause() : this.onPlay())} /> {/* {playing && this.onPause()} />} */}
this.onNext()} />
{this.ready ? (formatSecondAuto(this.player.currentTime())) : ('00:00')}
/
{this.ready ? (formatSecondAuto(this.player.duration())) : ('00:00')}
{btnList.map(btn => { if (btn.full && !fulling) return ''; if (!btn.show) return ''; return (
{btn.render ? (
{ if (btn.pause) this.onPause(); if (onAction) onAction(btn.key); }} > {btn.render(btn.active)}
) : (
onAction && onAction(btn.key)} >{btn.title}
)}
); })}
this.selectSpeed(!selectSpeed)}> 倍速
{!fulling && this.onFull()} />} {fulling && this.onExitFull()} />}
)}
{selectSpeed && (
this.onSpeed(0.5)}> 0.5
this.onSpeed(0.75)}> 0.75
this.onSpeed(1)}> 正常
this.onSpeed(1.25)}> 1.25
this.onSpeed(1.5)}> 1.5
this.onSpeed(2)}> 2.0
)} {children}
); } renderProgress() { const { hideProgress } = this.props; const { progress, pt = {} } = this.state; return ( !hideProgress && (
{ if (ref) this.progress = ref; }} onMouseMove={(e) => this.showProgressTip(e)} onMouseLeave={() => this.hideProgressTip()}> this.onChangeProgress(value)} />
{pt.text}
) ); } }