Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using MediaSource to stream a video file in a React component

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

like image 202
Anatole Lucet Avatar asked Nov 15 '25 14:11

Anatole Lucet


2 Answers

The issue was the file format I recieve from the api. If I try with this file in my fetch it works perfectly!

like image 193
Anatole Lucet Avatar answered Nov 18 '25 05:11

Anatole Lucet


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/

like image 23
Hari Avatar answered Nov 18 '25 05:11

Hari



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!