生产中的视频流 500 错误 (NextJS)
Video Streaming 500 error in production (NextJS)
我一直在开发这个网站: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>
在本地,当我导航到根 localhost:3000/
时,它按我预期的那样工作,
但是当我尝试以不同的方式打开 /api/video
api 时,例如,当我导航到 localhost:3000/api/video
或在 Postman 中调用它时,出现错误 Cannot read property 'replace' of undefined
,我不明白req.headers.range
是 undefined
。同样在生产中,api 出现 500 错误,并且没有显示视频,正如您在上面的网站 link 中看到的那样。
我试过了:
if(!req.headers.range) // send the whole video at one
else ...
但在这种情况下,这不是我想要的流媒体,而且这导致 Exceeding Serverless Function Payload Size Limit
请问这是什么问题,我该怎么办?提前致谢!
正如错误所解释的那样,您 运行 限制了一个免费的 vercel 函数可以执行多少 - 视频流最好用可以处理该传输的主机或桶来处理 - 我建议托管它其他地方 https://cloudinary.com/pricing 有免费计划
从这个 post 开始,免费计划可以满足您的需求
25K transformations or
25 GB of managed storage or
25 GB of net viewing bandwidth
开发流式视频解决方案需要相关资源,您部署代码的主机不应该解决免费版本中的视频流。
我找到了答案,将其张贴给遇到同样问题的人。
根据我的理解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)
成功了!
我一直在开发这个网站: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>
在本地,当我导航到根 localhost:3000/
时,它按我预期的那样工作,
但是当我尝试以不同的方式打开 /api/video
api 时,例如,当我导航到 localhost:3000/api/video
或在 Postman 中调用它时,出现错误 Cannot read property 'replace' of undefined
,我不明白req.headers.range
是 undefined
。同样在生产中,api 出现 500 错误,并且没有显示视频,正如您在上面的网站 link 中看到的那样。
我试过了:
if(!req.headers.range) // send the whole video at one
else ...
但在这种情况下,这不是我想要的流媒体,而且这导致 Exceeding Serverless Function Payload Size Limit
请问这是什么问题,我该怎么办?提前致谢!
正如错误所解释的那样,您 运行 限制了一个免费的 vercel 函数可以执行多少 - 视频流最好用可以处理该传输的主机或桶来处理 - 我建议托管它其他地方 https://cloudinary.com/pricing 有免费计划
从这个 post 开始,免费计划可以满足您的需求
25K transformations or 25 GB of managed storage or 25 GB of net viewing bandwidth
开发流式视频解决方案需要相关资源,您部署代码的主机不应该解决免费版本中的视频流。
我找到了答案,将其张贴给遇到同样问题的人。
根据我的理解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)
成功了!