Video: Fix auto-pausing during heavy animation and when in background

This commit is contained in:
Alexander Zinchuk 2021-11-27 17:41:04 +01:00
parent eed0934c0a
commit 40930e07dc
4 changed files with 23 additions and 51 deletions

View File

@ -22,9 +22,8 @@ import useShowTransition from '../../../hooks/useShowTransition';
import useMediaTransition from '../../../hooks/useMediaTransition';
import usePrevious from '../../../hooks/usePrevious';
import useBuffering from '../../../hooks/useBuffering';
import useHeavyAnimationCheckForVideo from '../../../hooks/useHeavyAnimationCheckForVideo';
import useVideoCleanup from '../../../hooks/useVideoCleanup';
import usePauseOnInactive from './hooks/usePauseOnInactive';
import useVideoAutoPause from './hooks/useVideoAutoPause';
import useBlurredMediaThumbRef from './hooks/useBlurredMediaThumbRef';
import ProgressSpinner from '../../ui/ProgressSpinner';
@ -155,8 +154,7 @@ const RoundVideo: FC<OwnProps> = ({
}
}, [shouldPlay]);
useHeavyAnimationCheckForVideo(playerRef, shouldPlay);
usePauseOnInactive(playerRef, Boolean(mediaData));
useVideoAutoPause(playerRef, shouldPlay);
useVideoCleanup(playerRef, [mediaData]);
const handleClick = useCallback(() => {

View File

@ -24,9 +24,8 @@ import useMedia from '../../../hooks/useMedia';
import useShowTransition from '../../../hooks/useShowTransition';
import usePrevious from '../../../hooks/usePrevious';
import useBuffering from '../../../hooks/useBuffering';
import useHeavyAnimationCheckForVideo from '../../../hooks/useHeavyAnimationCheckForVideo';
import useVideoCleanup from '../../../hooks/useVideoCleanup';
import usePauseOnInactive from './hooks/usePauseOnInactive';
import useVideoAutoPause from './hooks/useVideoAutoPause';
import useBlurredMediaThumbRef from './hooks/useBlurredMediaThumbRef';
import ProgressSpinner from '../../ui/ProgressSpinner';
@ -132,8 +131,7 @@ const Video: FC<OwnProps> = ({
const isForwarded = isForwardedMessage(message);
const { width, height } = dimensions || calculateVideoDimensions(video, isOwn, isForwarded, noAvatars);
useHeavyAnimationCheckForVideo(videoRef, Boolean(isInline && canAutoPlay));
usePauseOnInactive(videoRef, isPlayAllowed);
useVideoAutoPause(videoRef, isInline);
useVideoCleanup(videoRef, [isInline]);
const handleClick = useCallback(() => {

View File

@ -1,16 +1,17 @@
import { useCallback, useRef } from '../../../../lib/teact/teact';
import { fastRaf } from '../../../../util/schedulers';
import useBackgroundMode from '../../../../hooks/useBackgroundMode';
import safePlay from '../../../../util/safePlay';
export default (playerRef: { current: HTMLVideoElement | null }, isPlayAllowed = false) => {
const wasPlaying = useRef(false);
const isFrozen = useRef(false);
import { fastRaf } from '../../../../util/schedulers';
import safePlay from '../../../../util/safePlay';
import useBackgroundMode from '../../../../hooks/useBackgroundMode';
import useHeavyAnimationCheck from '../../../../hooks/useHeavyAnimationCheck';
export default function useVideoAutoPause(playerRef: { current: HTMLVideoElement | null }, canPlay: boolean) {
const wasPlaying = useRef(playerRef.current?.paused);
const canPlayRef = useRef();
canPlayRef.current = canPlay;
const freezePlaying = useCallback(() => {
isFrozen.current = true;
if (!isPlayAllowed || !playerRef.current) {
if (!playerRef.current) {
return;
}
@ -19,25 +20,24 @@ export default (playerRef: { current: HTMLVideoElement | null }, isPlayAllowed =
}
playerRef.current.pause();
}, [isPlayAllowed, playerRef]);
}, [playerRef]);
const unfreezePlaying = useCallback(() => {
if (
playerRef.current && wasPlaying.current && canPlayRef.current
// At this point HTMLVideoElement can be unmounted from the DOM
if (isPlayAllowed && playerRef.current && wasPlaying.current && document.body.contains(playerRef.current)) {
&& document.body.contains(playerRef.current)
) {
safePlay(playerRef.current);
}
wasPlaying.current = false;
isFrozen.current = false;
}, [isPlayAllowed, playerRef]);
}, [playerRef]);
const unfreezePlayingOnRaf = useCallback(() => {
fastRaf(unfreezePlaying);
}, [unfreezePlaying]);
if (!document.hasFocus()) {
freezePlaying();
}
useBackgroundMode(freezePlaying, unfreezePlayingOnRaf);
};
useHeavyAnimationCheck(freezePlaying, unfreezePlaying);
}

View File

@ -1,24 +0,0 @@
import { RefObject } from 'react';
import { useCallback, useRef } from '../lib/teact/teact';
import useHeavyAnimationCheck from './useHeavyAnimationCheck';
import safePlay from '../util/safePlay';
export default function useHeavyAnimationCheckForVideo(playerRef: RefObject<HTMLVideoElement>, shouldPlay: boolean) {
const shouldPlayRef = useRef();
shouldPlayRef.current = shouldPlay;
const pause = useCallback(() => {
if (playerRef.current) {
playerRef.current.pause();
}
}, [playerRef]);
const play = useCallback(() => {
if (playerRef.current && shouldPlayRef.current) {
safePlay(playerRef.current);
}
}, [playerRef]);
useHeavyAnimationCheck(pause, play);
}