html视频播放器无法播放gridfs流中的小视频,但可以播放大视频

问题描述 投票:0回答:1

我可以播放 1GB 和 500MB 等大型视频,但对于 60MB 或更小的视频大小,浏览器在收到内容时不会加载它们。 for small videos not able to load even metadata

对于大视频- loaded

视频 html-


<video src="${url}" style="width:100% !important; height: inherit; background: black;" controls autoplay muted preload="metadata"></video>

我尝试操纵响应内容范围、状态,但没有任何效果。

我的服务器代码用于响应范围请求-

route.get('/video/:id', async (req, res) => {
const { id } = req.params;`your text`
const range = req.headers.range;`your text`
    console.log(range);
    if (!range || range === undefined) {
    res.writeHead(416,{
        "Content-Range":`bytes */*`
    }).send("Requires Range header");
    return;
    }
    try {
        const cursor = await bucket.find({ "_id": id });
        let size, type;
        await cursor.forEach(document => {
        size = document.length;
        type = document.metadata.mimeType;
        });
        let CHUNK_SIZE = 1024 *1024 ; // 1MB
        let start = Number(range.replace(/\D/g, ""));
        const end = Math.min(start + CHUNK_SIZE, size-1);
        if(start>=size || start===end){
        res.writeHead(416,{
            "Content-Range":`bytes */${size}`
        })
        return res.end();
        }
        try {
        const downloadStream = await bucket.openDownloadStream(id, {
            start: start,
            end: end
        });
        const contentLength = end - start;
        const headers = {
            "Content-Range": `bytes ${start}-${end}/${size}`,
            "Accept-Ranges": "bytes",
            "Content-Length": contentLength,
            "Content-Type": "video/mp4",
        };
        res.writeHead(206, headers);
        downloadStream.pipe(res);
        } catch (err) {
        console.log('Error: ' + err);
        res.status(416).send();
        }
    } catch (err) {
        console.log('Error: ' + err);
        res.status(416).send();
    }
});
node.js video-streaming html5-video gridfs range-header
1个回答
0
投票

问题解决了!!!
当范围请求接近文件末尾或此代码最小条件达到大小 -1 时,就会出现问题

const end = Math.min(start + CHUNK_SIZE, **size-1**);

这里的问题是流大小:

const downloadStream = await bucket.openDownloadStream(id, {
  start: start,
  **end: end**
});

流永远不会到达终点

因此,如果我们将端点配置为实际端点,就可以解决问题

最终代码 -

route.get('/video/:id', async (req, res) => {
  const { id } = req.params;
  const range = req.headers.range;
  try {
    const cursor = await bucket.find({ "_id": id }).toArray();
    const document = cursor[0];
    const size = document.length;
    const type = document.metadata.mimeType;
    if (range) {
      let CHUNK_SIZE = 5 * 1024 * 1024; // 5MB
      var parts = range.replace(/bytes=/, "").split("-");
      var partialstart = parts[0];
      var partialend = parts[1];
      var start = parseInt(partialstart, 10);
      var end = partialend ? parseInt(partialend, 10) : Math.min(start + CHUNK_SIZE, size - 1);
      if (start >= size) {
        res.writeHead(416, {
          "Content-Range": `bytes */${size}`
        })
        return res.end();
      }
      try {

        const downloadStream = await bucket.openDownloadStream(id, {
          start: start,
          end: end == size - 1 ? size : end
        });
        const contentLength = end - start + 1;
        const headers = {
          "Content-Range": `bytes ${start}-${end}/${size}`,
          "Accept-Ranges": "bytes",
          "Content-Length": `${contentLength}`,
          "Content-Type": type,
        };
        res.writeHead(206, headers);
        console.info('Satisfied Range: ' + `${start}-${end}/${size}`);

        downloadStream.pipe(res);
      } catch (err) {
        console.log('Error: ' + err);
        res.status(416).send();
      }
    } else {
      const downloadStream = await bucket.openDownloadStream(id);
      res.setHeader('Cache-Control', 'private, max-age=0, must-revalidate');
      res.setHeader('Content-Length', size.toString());
      res.setHeader('Content-Type', type);
      res.writeHead(200);
      res.end(downloadStream);
    }
  } catch (err) {
    console.log('Error: ' + err);
    res.status(416).send();
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.