Updating source URL on HTML5 video with React
Quick and dirty awnser: Add a key
prop to <Clip>
or <video>
, e.g.:
function Clip({ url }) { return ( <video key={url}> <source src={url} /> </video> );}
Recommended awnser: Trigger a load
event for the video element whenever there's a new URL, e.g.:
function Clip({ url }) { const videoRef = useRef(); const previousUrl = useRef(url); useEffect(() => { if (previousUrl.current === url) { return; } if (videoRef.current) { videoRef.current.load(); } previousUrl.current = url; }, [url]); return ( <video ref={videoRef}> <source src={url} /> </video> );}
Explanation: The video initially doesn't change because in essence you're only modifying the <source>
element and React understands that <video>
should remain unchanged, so it does not update it on the DOM and doesn't trigger a new load
event for that source. A new load
event should be triggered for <video>
.
The dirty answer works because when you change the key
of a React element, React understands that's a whole new element. It then creates a new element in the DOM which naturally will have its own load event triggered on mount.
Changing the src of <source />
doesn't seem to switch the video for some reason. This isn't a react issue I don't think. Probably just how <source />
works. Maybe you have to call .load()
on the element again. But it's just easier to set it directly on the element itself.
See the comment to the top answer: Can I use javascript to dynamically change a video's source?
You can set src
directly on element instead:
function Clip(props) { return ( <video width="320" height="240" src={props.url} controls autoPlay> </video> )}
Bind the URL in the src property of Video tag and not Source Tag
<video autoplay loop muted playsinline="true" webkit-playsinline="true" [src]="videoSrc" type="video/mp4">