I'm trying to stream a video file using Javascript's MediaSource API in a React component.
Here's my component:
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.com/AnatoleLucet/react-MediaSource
The code is in src/App.tsx
The 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.com/documentation/mp4fragment/
For a full list of valid mime codecs, see:
https://cconcolato.github.io/media-mime-support/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With