Optimized Video: Fix exception on pause (#2109)

This commit is contained in:
Alexander Zinchuk 2022-11-07 23:00:42 +04:00
parent abd92f2ae8
commit b69d4ee2f1
2 changed files with 46 additions and 19 deletions

View File

@ -1,33 +1,31 @@
import { useCallback, useEffect, useRef } from '../../../../lib/teact/teact';
import { fastRaf } from '../../../../util/schedulers';
import safePlay from '../../../../util/safePlay';
import useBackgroundMode from '../../../../hooks/useBackgroundMode';
import useHeavyAnimationCheck from '../../../../hooks/useHeavyAnimationCheck';
import usePlayPause from '../../../../hooks/usePlayPause';
export default function useVideoAutoPause(playerRef: { current: HTMLVideoElement | null }, canPlay: boolean) {
const canPlayRef = useRef();
canPlayRef.current = canPlay;
const { play, pause } = usePlayPause(playerRef);
const isFrozenRef = useRef();
const freezePlaying = useCallback(() => {
isFrozenRef.current = true;
playerRef.current?.pause();
}, [playerRef]);
pause();
}, [pause]);
const unfreezePlaying = useCallback(() => {
isFrozenRef.current = false;
if (
playerRef.current && canPlayRef.current
// At this point `HTMLVideoElement` can be unmounted from the DOM
&& document.body.contains(playerRef.current)
) {
safePlay(playerRef.current);
if (canPlayRef.current) {
play();
}
}, [playerRef]);
}, [play]);
const unfreezePlayingOnRaf = useCallback(() => {
fastRaf(unfreezePlaying);
@ -38,23 +36,19 @@ export default function useVideoAutoPause(playerRef: { current: HTMLVideoElement
const handlePlaying = useCallback(() => {
if (!canPlayRef.current || isFrozenRef.current) {
playerRef.current!.pause();
pause();
}
}, [playerRef]);
}, [pause]);
useEffect(() => {
if (!playerRef.current) {
return;
}
if (canPlay) {
if (!isFrozenRef.current) {
safePlay(playerRef.current);
play();
}
} else {
playerRef.current!.pause();
pause();
}
}, [canPlay, playerRef]);
}, [canPlay, play, pause]);
return { handlePlaying };
}

33
src/hooks/usePlayPause.ts Normal file
View File

@ -0,0 +1,33 @@
import { useCallback, useRef } from '../lib/teact/teact';
export default function usePlayPause(mediaRef: React.RefObject<HTMLMediaElement>) {
const shouldPauseRef = useRef(false);
const isLoadingPlayRef = useRef(false);
const play = useCallback(() => {
shouldPauseRef.current = false;
if (mediaRef.current && !isLoadingPlayRef.current && document.body.contains(mediaRef.current)) {
isLoadingPlayRef.current = true;
mediaRef.current.play().then(() => {
isLoadingPlayRef.current = false;
if (shouldPauseRef.current) {
mediaRef.current?.pause();
shouldPauseRef.current = false;
}
}).catch((e) => {
// eslint-disable-next-line no-console
console.warn(e);
});
}
}, [mediaRef]);
const pause = useCallback(() => {
if (isLoadingPlayRef.current) {
shouldPauseRef.current = true;
} else {
mediaRef.current?.pause();
}
}, [mediaRef]);
return { play, pause };
}