diff --git a/src/components/DriveVideo/index.jsx b/src/components/DriveVideo/index.jsx index b35f95b7..5334763e 100644 --- a/src/components/DriveVideo/index.jsx +++ b/src/components/DriveVideo/index.jsx @@ -2,7 +2,6 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { CircularProgress, Typography } from '@material-ui/core'; -import debounce from 'debounce'; import Obstruction from 'obstruction'; import ReactPlayer from 'react-player/file'; @@ -64,10 +63,11 @@ class DriveVideo extends Component { this.onHlsError = this.onHlsError.bind(this); this.onVideoError = this.onVideoError.bind(this); this.onVideoResume = this.onVideoResume.bind(this); - this.syncVideo = debounce(this.syncVideo.bind(this), 200, true); + this.syncVideo = this.syncVideo.bind(this); this.firstSeek = true; this.videoPlayer = React.createRef(); + this.internalPlayer = null; this.state = { src: null, @@ -82,7 +82,6 @@ class DriveVideo extends Component { } this.updateVideoSource({}); this.syncVideo(); - this.videoSyncIntv = setInterval(this.syncVideo, 500); } componentDidUpdate(prevProps) { @@ -91,9 +90,10 @@ class DriveVideo extends Component { } componentWillUnmount() { - if (this.videoSyncIntv) { - clearTimeout(this.videoSyncIntv); - this.videoSyncIntv = null; + if (this.internalPlayer) { + this.internalPlayer.removeEventListener('timeupdate', this.syncVideo); + this.internalPlayer.removeEventListener('seeked', this.syncVideo); + this.internalPlayer.removeEventListener('canplay', this.syncVideo); } } @@ -179,8 +179,12 @@ class DriveVideo extends Component { } onVideoResume() { + const { dispatch, isBufferingVideo } = this.props; const { videoError } = this.state; if (videoError) this.setState({ videoError: null }); + if (isBufferingVideo) { + dispatch(bufferVideo(false)); + } } updateVideoSource(prevProps) { @@ -194,6 +198,12 @@ class DriveVideo extends Component { } if (src === '' || !prevProps.currentRoute || prevProps.currentRoute?.fullname !== currentRoute.fullname) { + if (this.internalPlayer) { + this.internalPlayer.removeEventListener('timeupdate', this.syncVideo); + this.internalPlayer.removeEventListener('seeked', this.syncVideo); + this.internalPlayer.removeEventListener('canplay', this.syncVideo); + this.internalPlayer = null; + } src = Video.getQcameraStreamUrl(currentRoute.fullname, currentRoute.share_exp, currentRoute.share_sig); this.setState({ src, videoError: null }); this.syncVideo(); @@ -227,13 +237,12 @@ class DriveVideo extends Component { const internalPlayer = videoPlayer.getInternalPlayer(); - const { hasLoaded } = getVideoState(videoPlayer); - if (isBufferingVideo && internalPlayer.readyState >= 4) { + if (internalPlayer.readyState >= 3 && isBufferingVideo) { dispatch(bufferVideo(false)); - } else if (isBufferingVideo || !hasLoaded || internalPlayer.readyState < 2) { + } else if (internalPlayer.readyState < 2) { if (!isBufferingVideo) { dispatch(bufferVideo(true)); - } + } newPlaybackRate = 0; // in some circumstances, iOS won't update readyState unless temporarily paused } @@ -275,8 +284,20 @@ class DriveVideo extends Component { const { src, videoError } = this.state; const onPlayerReady = (player) => { + const videoElement = player.getInternalPlayer(); + if (videoElement) { + if (this.internalPlayer) { + this.internalPlayer.removeEventListener('timeupdate', this.syncVideo); + this.internalPlayer.removeEventListener('seeked', this.syncVideo); + this.internalPlayer.removeEventListener('canplay', this.syncVideo); + } + this.internalPlayer = videoElement; + videoElement.addEventListener('timeupdate', this.syncVideo); + videoElement.addEventListener('seeked', this.syncVideo); + videoElement.addEventListener('canplay', this.syncVideo); + } + if (isIos()) { // ios does not support hls.js and on other browsers hls.js does not directly play the m3u8 so audioTracks are not visible - const videoElement = player.getInternalPlayer(); if (videoElement && videoElement.audioTracks && videoElement.audioTracks.length > 0) { if (onAudioStatusChange) { onAudioStatusChange(true);