I'm trying to stream a video file using Javascript's MediaSource API in a React ponent.
Here's my ponent:
const RawPlayer: React.FC= () => {
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
const mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if (videoRef.current && MediaSource.isTypeSupported(mimeCodec)) {
const myMediaSource = new MediaSource();
const url = URL.createObjectURL(myMediaSource);
videoRef.current.src = url;
myMediaSource.addEventListener('sourceopen', () => {
const videoSourceBuffer = myMediaSource.addSourceBuffer(mimeCodec);
videoSourceBuffer.addEventListener('error', console.log);
// this is just an express route that return an mp4 file using `res.sendFile`
fetch('http://localhost:3001/video/bC4Zud78/raw').then((response) => {
return response.arrayBuffer();
}).then((videoData) => {
videoSourceBuffer.appendBuffer(videoData);
});
});
}
});
return (
<video ref={videoRef} controls />
);
};
Strangely it doesn't work. When I go on the page, there's a spinner on the video, the spinner disappear then nothing happens.
This error listener:
videoSourceBuffer.addEventListener('error', console.log);
Log this:
Which is not really an error.
Here's a reproduction:
The code is in src/App.tsx
I'm trying to stream a video file using Javascript's MediaSource API in a React ponent.
Here's my ponent:
const RawPlayer: React.FC= () => {
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
const mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
if (videoRef.current && MediaSource.isTypeSupported(mimeCodec)) {
const myMediaSource = new MediaSource();
const url = URL.createObjectURL(myMediaSource);
videoRef.current.src = url;
myMediaSource.addEventListener('sourceopen', () => {
const videoSourceBuffer = myMediaSource.addSourceBuffer(mimeCodec);
videoSourceBuffer.addEventListener('error', console.log);
// this is just an express route that return an mp4 file using `res.sendFile`
fetch('http://localhost:3001/video/bC4Zud78/raw').then((response) => {
return response.arrayBuffer();
}).then((videoData) => {
videoSourceBuffer.appendBuffer(videoData);
});
});
}
});
return (
<video ref={videoRef} controls />
);
};
Strangely it doesn't work. When I go on the page, there's a spinner on the video, the spinner disappear then nothing happens.
This error listener:
videoSourceBuffer.addEventListener('error', console.log);
Log this:
Which is not really an error.
Here's a reproduction: https://github./AnatoleLucet/react-MediaSource
The code is in src/App.tsx
- can we get some screenshots of the console log, the webpage and your ponents source code plz? – X3R0 Commented Jan 9, 2020 at 17:40
-
Shure, but what do you mean with "my ponents source code"? The
RawPlayer
onent is directly used in anApp
ponents,App
only contain<RawPlayer />
and finalyApp
is rendered usingReactDOM.render()
– Anatole Lucet Commented Jan 9, 2020 at 17:42 - @DeanVanGreunen Edited. – Anatole Lucet Commented Jan 9, 2020 at 17:48
-
1
@DeanVanGreunen Well that doesn't really do what I want. I need to self manage the buffer so I can change the quality, the language, manage my segments and more... Without reloading the whole
Video
ponent. – Anatole Lucet Commented Jan 9, 2020 at 18:03 - 1 @DeanVanGreunen Thanks you for helping anyway! – Anatole Lucet Commented Jan 10, 2020 at 12:58
2 Answers
Reset to default 3The issue was the file format I recieve from the api. If I try with this file in my fetch
it works perfectly!
A note on the file format: I struggled with this as well. The mp4 has to be fragmented for it to work with MediaSource (in my tests, please offer any corrections). You can use this utility to create a fragmented mp4 from an unfragmented one:
https://www.bento4./documentation/mp4fragment/
For a full list of valid mime codecs, see:
https://cconcolato.github.io/media-mime-support/