【问题标题】:video streaming in nodejs through fs module通过 fs 模块在 nodejs 中流式传输视频
【发布时间】:2020-01-15 12:43:27
【问题描述】:

我想通过 fs 模块在 node.js 中流式传输视频,我已经尝试了以下代码。

app.get('/video', function(req, res) {
  const path = 'assets/sample.mp4'
  const stat = fs.statSync(path)
  const fileSize = stat.size
  const range = req.headers.range
  if (range) {
    const parts = range.replace(/bytes=/, "").split("-")
    const start = parseInt(parts[0],10);
    const end = parts[1] ? parseInt(parts[1],10) : fileSize-1
    const chunksize = (end-start)+1
    const file = fs.createReadStream(path, {start, end})
    const head = {
      'Content-Range': `bytes ${start}-${end}/${fileSize}`,
      'Accept-Ranges': 'bytes',
      'Content-Length': chunksize,
      'Content-Type': 'video/mp4',
    }
    res.writeHead(206, head)
    file.pipe(res)
  } else {
       const head = {
         'Content-Length': fileSize,
         'Content-Type': 'video/mp4',
       }
       res.writeHead(200, head)
       fs.createReadStream(path).pipe(res)
  }
})

我的视频“sample.mp4”大小为:1055736 字节,即 1 MB。但是当我运行代码时,我发现在启动时 start 变量是 0,end 变量是 1055735 & chunksize 是 1055736。如果你查看 Content-Range 标题,这将等于开始时的低于值。

内容范围:'字节 0-1055735/1055736'

我想一个接一个地流式传输我的视频,而不是等待整个视频加载。但我认为上面的代码不会做同样的事情。

谁能告诉我,这段代码对于视频流是否正确?

提前致谢!

【问题讨论】:

  • 我想req.headers.range === "bytes=0-" ?
  • 对不起?你的回答不够清楚。
  • 这不是答案。也许是一个提示,但不是答案。这是一个问题。那么请求头Range等于"bytes=0-"吗?

标签: javascript node.js


【解决方案1】:

您的代码没有问题,除了一件事:通常浏览器会在视频请求中向您发送Range: bytes=0-。从这个标题你的代码

const start = parseInt(parts[0],10);
const end = parts[1] ? parseInt(parts[1],10) : fileSize-1

为您提供文件大小的start === 0end === fileSize-1chunksize。因为parts[1] 总是虚假的。所以是决定以一大块发送文件,而不是浏览器。浏览器已准备好接收206 Partial Content,但您没有发送它。试试

const preferred_chunksize = 100000
let end = parts[1] ? parseInt(parts[1],10) : start + preferred_chunksize
if( end > fileSize-1 ) end = fileSize-1
const chunksize = end-start+1

preferred_chunksize 可以是从 1 到 fileSize 的任何值,具体取决于您的网络状况。我试过preferred_chunksize = 1000 - 它很慢。我没有尝试preferred_chunksize = 1 - 因为它会非常缓慢并且会导致数百万个请求。 preferred_chunksize 在 100 000 和 10 000 000 之间看起来可以接受。

但是,实际上,如果你在一个大文件上尝试你的代码,你会注意到没有过多的内存使用,并且浏览器会立即开始播放你的视频文件,而无需等待

加载整个视频

即使您将一起跳过end 部分(因为它已经在您的代码版本中完成),并使用以下方法简化您的代码:

const end = fileSize-1
const chunksize = end-start+1

会的。
而且,正如我从你的问题的原始版本中知道的那样,你正在写一个教程,所以为了你的目的,它会做得很好。

PS。当然,在生产代码中,您最好检查 Range 标头是否格式错误

【讨论】:

  • 谢谢你的回答,但我不知道我应该使用什么preferred_chunksize。你能编辑你的答案并告诉我吗?
猜你喜欢
  • 1970-01-01
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多