Closed ghost closed 6 years ago
I’d need your full code. Are you using <source>
and/or changing the src
after initialization?
I found it to not work with react when I tried it a while back, my solution was to create a div and manually create the video element and inserting it into the react div. It's a bit dirty but it did the trick just fine.
If anyone provides a repro I can look into it.
There are other issues opened by people trying it with react, maybe they have the solution.
I just remembered, I needed this workaround as React doesn't pass on the muted
prop as expected.
So this is what I did (simplified):
class Player extends React.Component {
// Dom References
video;
videoContainer;
addVideoToContainer = div => {
const { url, mutedDefault = true } = this.props;
// Doing the ref stuff unfortunately requires some workarounds
if (div === null) {
return;
}
this.videoContainer = div;
// Unfortunately we need to hack our way around React not passing on the "muted" prop as expected, without it iOS ( and Android ) won't allow autoplay at all
this.videoContainer.innerHTML = `
<video src="${url}" autoplay ${mutedDefault
? "muted"
: ""} playsinline id="video_1" style="width: 100%; height: 100%; z-index: 2; position: absolute; top: 0; left: 0;"></video>
`;
const video = this.videoContainer.querySelector("video");
if (!video || !(video instanceof HTMLVideoElement)) {
throw new Error("Expected Video Element");
}
this.video = video;
this.video.addEventListener("loadedmetadata", this.videoMetadata, false);
this.video.addEventListener("play", this.videoPlay, false);
this.video.addEventListener("timeupdate", this.videoTimeUpdate, false);
this.video.addEventListener("pause", this.videoPaused, false);
this.video.addEventListener("ended", this.videoEnded, false);
this.video.addEventListener("contextmenu", this.videoContextmenu, false);
this.video.addEventListener("click", this.videoContextmenu, false);
this.video.addEventListener("seeking", this.videoSeeking, false);
this.video.addEventListener("waiting", this.videoMetadata, false);
this.video.addEventListener("playing", this.videoMetadata, false);
};
videoMetadata = () => {};
videoPlay = () => {};
videoTimeUpdate = () => {};
videoPaused = () => {};
videoEnded = () => {};
videoContextmenu = () => {};
render() {
const { state, mutedDefault = true } = this.props;
return <div ref={this.addVideoToContainer} />;
}
}
This works perfectly fine for me in production
I’m sure that’s unnecessary, you need to IIV on the real dom element, not on the react component. IIV should not go through React so there’s no prop that it wouldn’t “pass”
We do it like this:
initPolyfill(this.video, {
iPad: true,
muted: this.state.muted
})
Where this.video
is a ref
A ref to what? I’d need more of the code to understand where it’s being called.
Muted isn’t a parameter anymore, it just reads the attribute.
@bfred-it https://reactjs.org/docs/refs-and-the-dom.html, I am not the original issue autor, just trying to help how to integrate your library with React.
@montogeek Thanks, the sounds like the correct way.
Hello mate. I am using react and I have this error. Does anyone know what is going on ?
:3000/#:1 Uncaught (in promise) DOMException: Failed to load because no supported source was found.