components/IntroLoopVideo.jsxjavascript
import React, { useState } from "react";
import PropTypes from "prop-types";
import { CacheableVideo } from "./CacheableVideo";
/**
* Plays `intro` once, then switches to `loop` playing forever. Both videos
* are mounted from the start - the loop is fetched, decoded and paused at
* its first frame in the background while the intro plays, so the switch is
* just an opacity swap instead of a `src` change that would force a fresh
* fetch/decode at the exact moment of the handoff (visible as a stutter).
*
* @param {string} intro - URL of the video played once at the start.
* @param {string} loop - URL of the video played on loop afterwards.
* @param {...*} props - Passed through to both underlying `<video>` elements.
*/
export const IntroLoopVideo = ({ intro, loop, ...props }) => {
const [looping, setLooping] = useState(false);
return (
<>
<CacheableVideo
src={intro}
autoPlay
fallback={null}
onEnded={() => setLooping(true)}
{...props}
style={{ opacity: looping ? 0 : 1 }}
/>
<CacheableVideo
src={loop}
loop
playing={looping}
fallback={null}
{...props}
style={{ opacity: looping ? 1 : 0 }}
/>
</>
);
};
IntroLoopVideo.propTypes = {
intro: PropTypes.string.isRequired,
loop: PropTypes.string.isRequired,
};