【问题标题】:Different errors on different browsers with Media Source Extension of HTML Video tag使用 HTML 视频标签的媒体源扩展在不同浏览器上出现不同错误
【发布时间】:2020-08-15 10:03:03
【问题描述】:

所以我试图在我的 HTML 页面中使用媒体源 API 播放视频。我有一个 NodeJS 服务器,可以为我提供大约 30MB 的视频文件。

下面是我的服务器代码:

const fileMap = {
    "1": "sample.mp4"
}

router.get("/", async (req, res) => {
    try {
        let range = req.headers.range;
        let fileName = fileMap[req.query.file];
        console.log("Range", range);
        console.log('Filename: ' + fileName);
        const movieSize = await movieService.getMovieSize(fileName);
        if (range) {
            console.info('Range Found');
            const parts = range.replace(/bytes=/, "").split("-");
            const start = parseInt(parts[0], 10);
            const end = parts[1] ? parseInt(parts[0], 10) : movieSize - 1;
            console.log("Start: ", start);
            console.log("End: ", end);
            let readStream = await movieService.getMovieFileReadStream(fileName, start, end);
            if (start >= movieSize) {
                res.status(416).send('Requested Range Not Satisfiable');
            }
            const chunkSize = (end - start) + 1;
            const head = {
                "Content-Range": `bytes ${start}-${end}/${movieSize}`,
                "Accept-Ranges": 'bytes',
                "Content-Length": chunkSize,
                "Content-Type": 'video/mp4'
            }
            res.writeHead(200, head);
            readStream.pipe(res);
        } else {
            console.log('No range received');
            const head = {
                "Content-Length": movieSize,
                "Content-Type": 'video/mp4'
            };
            res.writeHead(200, head);
            let readStream = await movieService.getMovieFileReadStream(fileName)
            readStream.pipe(res);
        }
    } catch (err) {
        console.error("Error while processing Movie request:\n", err);
        res.sendStatus(500);
    }
})

下面是我的 HTML 代码:

<!DOCTYPE html>
<html>

<head>
    <title>
        Sample Page
    </title>
</head>

<body>
    <video id="videoplayer" controls width="80%" muted="muted"></video>
</body>

<script type="text/javascript">

    console.log('In Here')

    let url = '/v1/movies?file=1';
    let sourceBuffer;
    let mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
    let video = document.querySelector('video');
    
    onLoad();

    function onLoad() {
        console.info('OnLoad called');

        if (!window.MediaSource) {
            let message = 'MediaSource not supported by current browser';
            console.error(message);
            return;
        }

        if (!window.MediaSource.isTypeSupported(mimeCodec)) {
            let message = 'Code not supported by MediaSource';
            console.error(message);
            return;
        }

        console.log('So FAr')
        let mediaSource = new MediaSource();
        video.src = URL.createObjectURL(mediaSource);
        mediaSource.addEventListener('sourceopen', handleOpen.bind(mediaSource));
    }

    function handleOpen() {
        let mediaSource = this;
        console.log("Open State");
        console.log('Ready: ', mediaSource.readyState);
        sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
        addToSourceBuffer(sourceBuffer, (err) => {
            if (err) {
                console.error('Whammy');
            }
            mediaSource.endOfStream();
            video.play().then(resolved => {
                console.log(resolved)
            }).catch(err => console.error(err))
        })
    }


    function addToSourceBuffer(sourceBuffer, callback) {
        getChunk(function(buff) {
            console.log("Received Buffer: ", buff);
            sourceBuffer.appendBuffer(buff);

            sourceBuffer.addEventListener('updateend', function() {
                console.log('Source Buffer Update has ended');
                callback();
            });

            sourceBuffer.addEventListener('error', function(err) {
                console.error('Error Ocurred')
                callback(err);
            })
        })
    }

    function getChunk(callback) {
        console.log("Calling URL: ", url)
        var xhr = new XMLHttpRequest();
        xhr.open('get', url);
        xhr.responseType = 'arraybuffer';
        xhr.onload = function() {
            callback(xhr.response);
        };
        xhr.send()
    }

</script>

</html>

当我使用 Firefox 79.0(64 位) 运行此程序时,我收到 Uncaught DOMException: The Quota has been exceeded 错误。

我不明白为什么会这样,因为根据日志,我已经在 Received Buffer: ArrayBuffer(31491130) {} 这一行收到了作为数组缓冲区的文件。

我是否一次输入了太多数据?根据this,Firefox 最多可以处理 100MB,而我的文件只有 30+ MB。

那为什么我的视频没有播放?

在 Chrome 84 上,我得到了不同的 DOMException

(index):57 DOMException: The element has no supported sources.

当我在 HTML 代码中尝试 video.play() 时会发生这种情况。

我哪里出错了?在这两种情况下,我都无法播放视频。我已经阅读了有关使用 DASH 将 MSE 与媒体片段一起使用的信息,但我现在只想尝试没有任何 DASH 的原始媒体源扩展,只是为了让它工作。

但是不同浏览器上的不同错误让我感到困惑。我跟着this教程

任何帮助将不胜感激

【问题讨论】:

    标签: javascript html node.js video-streaming html5-video


    【解决方案1】:

    我想第一个问题是你的视频。

    我使用 ffmpeg 重新编码我的视频:

    ffmpeg -i "v.mp4" -vcodec copy -c:a libfdk_aac -b:a 48k -movflags frag_keyframe+empty_moov+default_base_moof+omit_tfhd_offset "V2.mp4"
    

    重要的是-movflags frag_keyframe+empty_moov+default_base_moof+omit_tfhd_offset 我从https://developer.mozilla.org/en-US/docs/Web/API/Media_Source_Extensions_API/Transcoding_assets_for_MSE得到它

    这个chrome://media-internals/也有用,看看发生了什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-01
      • 2019-05-26
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 2014-06-30
      相关资源
      最近更新 更多