import * as React from 'react' import { VideoPlayer } from '@popcorn-video/react-video' import { createHTML5Decoder } from '@popcorn-video/html5-decoder' import { isLofter, isAndroid } from 'nw-detect' import { BaseComponent } from '../base-component' import { navigate } from '../utils/navigate' import { Props, State, } from './type' import * as Styled from './index.style' export class Video extends React.Component { static defaultProps = new Props() state = new State() videoRef: VideoPlayer componentDidMount() { const { videoObj, poster, } = this.props const { url } = videoObj || {} const posterUrl = poster?.url || `${url}?vframe&offset=1` this.setState({ posterUrl }) if (this.videoRef) { // 修复 某些 ios 在微信下封面不生效的问题 // 不能立马设置,否则还是无效果 setTimeout(() => { (this.videoRef._videoPlayer.decoder as any)._el.setAttribute("poster", posterUrl) if (isAndroid() && isLofter()) { this.addEvent() } }, 50) } } componentWillUnmount() { this.removeEvent() } handleAllEvent = (event: any) => { if ( event.type === 'progress' || event.type === 'timeupdate' ) return if (this.videoRef._videoPlayer.state === 'playing') { this.setState({ isVideoPlaying: true, isFirstPlay: false }) } else { this.setState({ isVideoPlaying: false }) } } addEvent = () => { this.videoRef._videoPlayer.addAllListener(this.handleAllEvent) } removeEvent = () => { this.videoRef._videoPlayer.removeAllListener(this.handleAllEvent) } handleNavi = () => { if (isAndroid() && isLofter() && this.props.postUrl) { this.videoRef._videoPlayer.pause() navigate(this.props.postUrl) } } handlePlay = (e: any) => { if (isAndroid() && isLofter()) { e.preventDefault() if (this.videoRef._videoPlayer.state !== 'playing') { this.videoRef._videoPlayer.play() } else { this.videoRef._videoPlayer.pause() } } } render() { const { style: oriStyle, videoObj, postUrl } = this.props const style = { ...oriStyle } const containerWidth = parseFloat(style.width as any) const { width, height, url } = videoObj || {} const { posterUrl, isVideoPlaying, isFirstPlay } = this.state style.height = width ? `${containerWidth * height / width}rem` : 'auto' const controlsAttr = isAndroid() && isLofter() ? null : { controls: 'true' } return (
{/* 不要小看这个多此一举的 div, 去掉会导致无法 resize 模块 */} { if (videoPlayer) { this.videoRef = videoPlayer } }} key={url + posterUrl} decoders={[ createHTML5Decoder({ htmlAttributes: { preload: isAndroid() ? 'metadata' : 'none', style: 'object-fit: cover;object-position: center center;', playsinline: 'true', 'webkit-playsinline': 'true', poster: posterUrl, ...controlsAttr } }) ]} sources={[{ src: url, type: 'video/mp4' }]} /> { isAndroid() && isLofter() && !isVideoPlaying ? ( play { postUrl && !isFirstPlay ? (
完整视频
) : null }
) : null }
) } }