【问题标题】:Video Streaming 500 error in production (NextJS)生产中的视频流 500 错误(NextJS)
【发布时间】:2022-01-26 11:32:11
【问题描述】:

我一直在开发这个网站:https://mirobod-tumani.vercel.app。主页上有视频背景。为了优化初始负载,我优化了视频本身并决定将其流式传输。 这是代码:

// pages/api/video

import fs from 'fs'

export default function handler(req, res) {
if (req.method === 'GET') {
    const range = req.headers.range
    const videoPath = 'public/assets/mirobod.webm'
    const videoSize = fs.statSync(videoPath).size
    const chunkSize = 1 * 1e6
    const start = Number(range.replace(/\D/g, ''))
    const end = Math.min(start + chunkSize, videoSize - 1)
    const contentLength = end - start + 1
    const headers = {
      'Content-Range': `bytes ${start}-${end}/${videoSize}`,
      'Accept-Ranges': 'bytes',
      'Content-Length': contentLength,
      'Content-Type': 'video/webm',
    }
    res.writeHead(206, headers)
    const stream = fs.createReadStream(videoPath, { start, end })
    stream.pipe(res)
}

// pages/index.js

<video autoPlay muted loop>
 <source src='/api/video' type='video/webm' />
</video>

在本地,当我导航到 root localhost:3000/ 时,它按我的预期工作, 但是当我尝试以不同的方式打开该/api/video api 时,例如,当我导航到localhost:3000/api/video 或在邮递员中调用它时,出现Cannot read property 'replace' of undefined 的错误,我不明白req.headers.range 是undefined。同样在生产中,该 api 存在 500 错误,并且没有显示视频,如您从上面的站点链接中看到的那样。

我试过了:

if(!req.headers.range) // send the whole video at one

else ...

但在这种情况下,这不是我想要的流媒体,这也导致Exceeding Serverless Function Payload Size Limit

那么问题出在哪里,我该怎么办?提前谢谢!

【问题讨论】:

    标签: node.js video next.js video-streaming


    【解决方案1】:

    正如错误所解释的那样,您遇到了免费 vercel 函数可以执行多少的限制 - 使用可以处理该传输的主机或存储桶更好地处理视频流 - 我建议将其托管在其他地方,例如 https://cloudinary.com/pricing免费计划

    在这篇文章中,免费计划可以满足您的需求

    25K 转换或 25 GB 托管存储或 25 GB 的净观看带宽

    开发流媒体视频解决方案需要相关资源,您部署代码的主机不应该解决免费版本中的视频流。

    【讨论】:

      【解决方案2】:

      我找到了答案,将其发布给遇到相同问题的任何人。

      对于我所理解的https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.27

      req.headers.range 可能未针对初始请求设置,并且在流传输期间可用。
      实际上,初始范围等于 'bytes=0-',并在流期间根据您定义的块大小进行更新

      确实如此:

      let range = req.headers.range
      if(!range) range = 'bytes=0-'
      
      ...
      
      

      但还是有问题 我以为是关于路径的,然后我改变了这个:

      const videoPath = 'public/assets/mirobod.webm'
      

      到这里:

      const videoName = 'mirobod.webm'
      const videoPath = path.resolve('public/assets/', videoName)
      

      它成功了!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-13
        • 1970-01-01
        • 2023-02-16
        • 2018-08-31
        相关资源
        最近更新 更多