autoplayVideo.tsx 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import {useEffect, useRef} from 'react';
  2. import {useReducedMotion} from 'framer-motion';
  3. interface AutoplayVideoProps extends React.VideoHTMLAttributes<HTMLVideoElement> {
  4. 'aria-label': string;
  5. }
  6. /**
  7. * Wrapper for autoplaying video.
  8. *
  9. * Because of react limitations and browser controls we need to
  10. * use refs.
  11. *
  12. * Note, video needs `muted` for `autoplay` to work on Chrome
  13. * See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
  14. */
  15. function AutoplayVideo(props: AutoplayVideoProps) {
  16. const videoRef = useRef<HTMLVideoElement>(null);
  17. const prefersReducedMotion = useReducedMotion();
  18. useEffect(() => {
  19. if (videoRef.current) {
  20. // Set muted as more browsers allow autoplay with muted video.
  21. // We can't use the muted prop because of a react bug.
  22. // https://github.com/facebook/react/issues/10389
  23. // So we need to set the muted property then trigger play.
  24. videoRef.current.muted = true;
  25. if (!prefersReducedMotion) {
  26. // non-chromium Edge and jsdom don't return a promise.
  27. videoRef.current.play()?.catch(() => {
  28. // Do nothing. Interrupting this playback is fine.
  29. });
  30. }
  31. }
  32. }, [prefersReducedMotion]);
  33. return <video ref={videoRef} playsInline disablePictureInPicture loop {...props} />;
  34. }
  35. export {AutoplayVideo};