Skip to content

Commit 20ba86b

Browse files
Handle video loading and play errors (#638)
Handle "AbortError: The play() request was interrupted by a call to pause()". Error can be reproduced by using Fast 4G network and continuously clicking on the area where the video would appear. Only shows playing UI if play (autoplay / resume playing) has been successful, otherwise shows paused UI.
1 parent be27446 commit 20ba86b

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

src/components/HomepageBannerVideo.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
Icon,
77
useDisclosure,
88
} from "@chakra-ui/react";
9-
import { useCallback, useRef, useState } from "react";
9+
import { useCallback, useEffect, useRef, useState } from "react";
1010
import { FormattedMessage, useIntl } from "react-intl";
1111
import HomepageBannerVideoTranscriptDialog from "./HomepageBannerVideoTranscriptDialog";
1212

@@ -17,13 +17,30 @@ export interface HomepageBannerVideoProps {
1717
const HomepageBannerVideo = ({ src }: HomepageBannerVideoProps) => {
1818
const intl = useIntl();
1919
const videoRef = useRef<HTMLVideoElement | null>(null);
20-
const [isPaused, setIsPaused] = useState<boolean>(false);
20+
const [isPaused, setIsPaused] = useState<boolean>(true);
2121
const textTranscriptDialog = useDisclosure();
2222

23+
useEffect(() => {
24+
const video = videoRef.current;
25+
const listener = () => setIsPaused(false);
26+
if (video) {
27+
// Fires when video playback starts or resumes (including autoplay).
28+
// Autoplay requires page permission, element creation, and sufficient buffering.
29+
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play_event
30+
video.addEventListener("play", listener);
31+
}
32+
return () => {
33+
if (video) {
34+
video.removeEventListener("play", listener);
35+
}
36+
};
37+
}, []);
38+
2339
const handleTogglePlayPause = useCallback(async () => {
2440
if (videoRef.current?.paused) {
25-
await videoRef.current?.play();
26-
setIsPaused(false);
41+
await videoRef.current.play().catch((_e) => {
42+
// Do nothing. Continue to show video as paused.
43+
});
2744
} else {
2845
videoRef.current?.pause();
2946
setIsPaused(true);

0 commit comments

Comments
 (0)