Thursday, April 25, 2024
 Popular · Latest · Hot · Upcoming
105
rated 0 times [  106] [ 1]  / answers: 1 / hits: 34797  / 8 Years ago, fri, december 23, 2016, 12:00:00

I want to update the source tag in a HTML5 video element so that when I click a button, whatever's playing switches to a new video.



I have a Clip component that returns an HTML5 video element, with the source URL provided via props.



function Clip(props) {
return (
<video width=320 height=240 controls autoPlay>
<source src={props.url} />
</video>
)
}


I also have a Movie component, which contains multiple URLs, each corresponding to a section of the movie. It also contains a position attribute, which acts like an iterator by remembering which section is currently playing.



class Movie extends Component {
constructor() {
super();
this.state = {
sections: [
'https://my-bucket.s3.amazonaws.com/vid1.mp4',
'https://my-bucket.s3.amazonaws.com/vid2.mp4'
],
position: 0
};
}
render() {
const sections = this.state.sections
const position = this.state.position

return (
<div>
{position}
<Clip url={sections[position]} />
<button onClick={() => this.updatePosition()}>Next</button>
</div>
)
}
updatePosition() {
const position = this.state.position + 1;
this.setState({ position: position });
}
}


The Movie component renders a Clip component and a Next button. When the Next button gets clicked, I want to update the position attribute and re-render the HTML5 video element using the next URL from sections.



As of now, when I hit Next the HTML5 video source tag updates, but the element continues playing the video from the previous URL. Can anyone help me figure out how to reset the video element?



Update: I created a JSFiddle, which you can see here.



Update 2: Updating the src attribute on the video element works!


More From » html

 Answers
99

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();

useEffect(() => {
videoRef.current?.load();
}, [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.


[#59587] Thursday, December 22, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
marcos

Total Points: 331
Total Questions: 106
Total Answers: 104

Location: Gabon
Member since Sat, Jul 25, 2020
4 Years ago
marcos questions
Thu, Feb 24, 22, 00:00, 2 Years ago
Sat, Apr 17, 21, 00:00, 3 Years ago
Mon, Feb 1, 21, 00:00, 3 Years ago
Tue, Jan 26, 21, 00:00, 3 Years ago
Wed, Jan 6, 21, 00:00, 3 Years ago
;