admin管理员组

文章数量:1421492

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

Share Improve this question edited Jan 9, 2020 at 18:11 Anatole Lucet asked Jan 9, 2020 at 17:37 Anatole LucetAnatole Lucet 1,8234 gold badges28 silver badges47 bronze badges 12
  • 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 an App ponents, App only contain <RawPlayer /> and finaly App is rendered using ReactDOM.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
 |  Show 7 more ments

2 Answers 2

Reset to default 3

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./documentation/mp4fragment/

For a full list of valid mime codecs, see:

https://cconcolato.github.io/media-mime-support/

本文标签: javascriptUsing MediaSource to stream a video file in a React componentStack Overflow