我正在尝试从代理服务器流式传输视频,代理服务器和流媒体服务器都在同一主机中,但流媒体服务器不向公众公开,因此我必须通过代理(客户端和客户端)调用它代理服务器在同一端口运行:
客户端(端口3000):
<video src="/stream"></video>
代理服务器(端口3000):
router.get('/stream', async (req, res) => {
try {
const stream = await axios.get('/getstream', {
responseType: 'stream'
});
res.writeHead(stream.status, stream.headers)
stream.data.pipe(res)
} catch (err) {
...
}
})
流媒体服务器(端口3001,不对外公开):
app.get('/getstream', async (req, res) => {
console.log('conection is working!')
try {
const { headers, videoStream } = await streamVideo(req);
res.writeHead(206, headers)
videoStream.pipe(res)
} catch (err) {
...
}
})
三者之间的连接工作正常,没有错误(我在流服务器日志中看到“连接正在工作!”),但如果我从浏览器检查网络选项卡,我没有在客户端中获取视频块可以找到对代理服务器的调用,但所有选项卡(标头、cookie、请求、响应、计时)都是空的。
在开发中(我的本地电脑),如果我直接从客户端本身调用流媒体服务器,它工作得很好,并且视频流传输没有问题,但这在生产中不起作用,因为正如我所说,流媒体服务器不向公众公开.
尽管已经建立了与流媒体服务器(通过代理)的连接,但为什么我没有在客户端中获取视频块,有什么线索吗?
我发现了问题,代理服务器没有将范围标头发送到流媒体服务器。我没有意识到这一点,因为我没有正确处理流服务器上的错误,我什至为这种情况设置了一个特定的错误,但我没有对相应的 catch 块执行任何操作,因此该错误从未找到解决方法代理服务器。
现在,我可以很好地传输视频,客户端直接调用流媒体服务器,因为这样客户端将发送范围标头,流媒体服务器将采取相应的行动。
但是,如果客户端首先向代理服务器发出请求,那么我必须手动发送范围标头,而我没有。
所以,使用 axios 将会是:
router.get('/stream', async (req, res) => {
try {
const stream = await axios.get('/getstream', {
responseType: 'stream',
headers: {
range: req.headers.range // <------
}
});
...
} catch (err) {
...
}
})