很抱歉有这样的问题,但我遇到了一个非常奇怪的问题,我不知道为什么会发生这种情况。
我正在编写一个Node应用程序,它获取Youtube视频ID,然后将音频流式传输给请求者。这是代码。
router.get('/video/:videoId', function(req, res, next) {
console.log('requested ' + req.params.videoId);
var filename = req.params.videoId + ".mp3";
youtubeDL.exec(req.params.videoId, ['-x', '--audio-format', 'mp3', '-o', filename], {}, function(err, output) {
if (err){
res.send("bad request");
return;
}else{
console.log("exec begin")
res.setHeader("content-type", "audio/mp3");
fs.createReadStream(filename).pipe(res);
fs.unlink(filename);
console.log("exec end")
}
});
console.log("router end");
});
问题是请求开始"循环",我想这就是我对它的描述,并且请求在停止之前被调用了3次。
例如,以下是http://localhost:3000/resources/video/JCHTX_pgw6A
requested JCHTX_pgw6A
router end
[Long pause here]
exec begin
exec end
GET /resources/video/JCHTX_pgw6A 200 17396.280 ms - -
requested JCHTX_pgw6A
router end
[Long pause here]
exec begin
exec end
GET /resources/video/JCHTX_pgw6A 200 17550.309 ms - -
requested JCHTX_pgw6A
router end
[Long pause here]
exec begin
exec end
GET /resources/video/JCHTX_pgw6A 200 1645.932 ms - -
此时它停止。有人知道为什么会发生这种情况,或者如何获得更多信息吗?我完全被难住了。
您不应该在启动后立即调用fs.unlink()
来流式传输文件,否则文件将停止流式传输到客户端。相反,要么找到一种直接从youtube流式传输的方法(IMHO是一个更好的解决方案,因为你可以避免撞到磁盘),要么至少等到文件流式传输完成后再删除。对于后者,这可能看起来像:
console.log("exec begin")
res.setHeader("content-type", "audio/mp3");
fs.createReadStream(filename).pipe(res).on('finish', function() {
fs.unlink(filename);
});
console.log("exec end")
或者可能更好(等待文件描述符实际首先关闭):
console.log("exec begin")
res.setHeader("content-type", "audio/mp3");
fs.createReadStream(filename).on('close', function() {
fs.unlink(filename);
}).pipe(res);
console.log("exec end")
将请求方法更改为POST,它停止了不当行为。