首页 > 解决方案 > HTML5 视频在播放时没有缓冲足够的数据

问题描述

编辑

在最初的问题和测试中,所有这些都使用了 Chrome。似乎使用 Firefox 和一些小测试现在可以产生比 Chrome 更一致的加载体验,即使在搜索时,视频的缓冲部分也会始终保持在更大的块上。添加它以防其他人发现它有用或可以验证结果(也许还有更多浏览器)。

TL;博士:

如何让视频在播放时缓冲更多数据?最好我也希望它即使在暂停时也能保持缓冲数据。

所以我从运行在 Node.js 上的 Express 服务器提供了这个非常基本的视频内容。关键是用户使用 ID 请求特定视频,然后服务器将 mp4 文件流式传输到前端的 HTML5 视频标签。这一切都完美无缺,除了一个小抱怨。

最初,当用户加载视频时,视频的缓冲部分明显大于之后的任何时间(较浅的灰色是 HTML5Video.buffered 范围的视觉表示)。

缓冲的初始视频

现在,如果视频继续播放超过这个初始加载点,它只会从服务器加载非常小的块,即使块大小设置为 10MB 并且整个测试视频只有 30MB!(缓冲部分现在将在整个播放过程中始终保持该数量)。

较小的缓冲部分

一个明显的问题是,在较慢的网络上它经常停止播放,因为当网络突然允许更多带宽时,我的播放器不会利用这一点,并且视频不会缓冲超过前面这个非常小的部分当前时间标记的。如果视频暂停,它也不会保留缓冲数据。

以下是允许流式传输视频文件的特定代码:

app.get("/source", (req, res) => {
    ...

    if (!req.headers.range) {
        return res.sendStatus(416);
    }
    
    ...

    const sourcePath = getSourcePath();
    const sourceSize = fs.statSync(sourcePath).size;

    const CHUNK_SIZE = 10000000; // 10M bytes / 10MB
    const start = Number(req.headers.range.replace(/\D/g, ""));
    const end = Math.min(start + CHUNK_SIZE, sourceSize - 1);
  
    const contentLength = (end - start) + 1;
    const headers = {
        "Accept-Ranges": "bytes",
        "Connection": "keep-alive",
        "Content-Length": contentLength,
        "Content-Range": `bytes ${start}-${end}/${sourceSize}`,
        "Content-Type": "video/mp4",
    };
  
    res.writeHead(206, headers);
    fs.createReadStream(sourcePath, { start, end }).pipe(res);
});

并且使用简单的 HTML5 视频元素从 Express 请求数据:

<video id="videoPlayer" class="video">
    <source src="/source<%= src %>" type="video/mp4" />
</video>

这里的 src 是在一个 .ejs 模板文件中获得的,对整个代码来说并不重要。

标签: javascripthtmlnode.jsexpressvideo-streaming

解决方案


推荐阅读