admin管理员组文章数量:1135644
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: [
'.mp4',
'.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!
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!
Share Improve this question edited Dec 23, 2016 at 16:10 Sherwood Callaway asked Dec 23, 2016 at 14:11 Sherwood CallawaySherwood Callaway 1,5581 gold badge14 silver badges18 bronze badges 1- Can you provide a jsfiddle? – simsketch Commented Dec 23, 2016 at 15:01
5 Answers
Reset to default 200Quick 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.
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>
)
}
You can use the key attribute :
<video key={videoUrl} autoPlay width="100%">
<source src={videoUrl} type="video/mp4"></source>
</video>
If the video's key attribute change, the video component will be re-mounted
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">
Add a parent div to second video
My code:
{isMobile ? (
<video
autoPlay={true}
loop
className="moviles"
muted
playsInline
poster="/totto/kids.png"
>
<source src="/totto/losmoviles.webm"></source>
<source src="/totto/losmoviles.mp4"></source>
</video>
) : (
<div>
<video
autoPlay={true}
loop
className="moviles2"
muted
playsInline
poster="/totto/portada.jpg"
>
<source src="/totto/moviles.webm"></source>
<source src="/totto/moviles.mp4"></source>
</video>
</div>
)}
本文标签: javascriptUpdating source URL on HTML5 video with ReactStack Overflow
版权声明:本文标题:javascript - Updating source URL on HTML5 video with React - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736927225a1956660.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论