我正在开发一个在线课程申请表。一旦用户注册了课程,那么该用户当然可以转到主页,然后单击任何视频讲座来查看它。 要流式传输.mp4格式的视频,我使用的是socket.io。 这就是我现在正在做的事情。
router.get('/learn/:courseName/lecture/:video', isAuthenticated, function (req, res) {
// var file = path.resolve(__dirname,"movie.mp4");
console.log('courseName is: ' + req.params.courseName);
console.log('video name is: ' + req.params.video);
var file = "/home/mobileedx/WebstormProjects/passportAuthentication/videoLecture/movie.mp4";
console.log('file is: ' + file);
fs.stat(file, function(err, stats) {
if (err) {
if (err.code === 'ENOENT') {
// 404 Error if file not found
return res.sendStatus(404);
}
res.end(err);
}
var range = req.headers.range;
console.log('value of range is: ' + range);
if(!range) {
return res.sendStatus(416);
}
var positions = range.replace(/bytes=/, "").split("-");
var start = parseInt(positions[0], 10);
var total = stats.size;
var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
var chunksize = (end - start) + 1;
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
var stream = fs.createReadStream(file, { start: start, end: end })
.on("open", function() {
stream.pipe(res);
}).on("error", function(err) {
res.end(err);
});
console.log('stream value is: ' + stream);
});
});
但是,当我尝试从浏览器访问它时,我在浏览器中收到错误,因为"范围不满意"。我正在使用谷歌浏览器和Mozilla Firefox进行测试。
我记录了req.headers.range,并将其值设为' undefined'。 这里是。
当我们通过浏览器访问它时,这是请求和响应标头。你可以注意到,没有'范围' GET请求中的标头。
请告诉我,这里出了什么问题。因为,如果我运行与独立应用程序相同的代码,那么它可以工作。
答案 0 :(得分:0)
正如您可能知道的那样,您正在从代码直接生成错误消息,因为未定义范围值 - 这些行将其发回:
var range = req.headers.range;
console.log('value of range is: ' + range);
if(!range) {
return res.sendStatus(416);
}
416错误将生成您显示的消息。
我认为问题在于您的代码假设在没有范围请求的情况下接收HTTP请求是错误的,但这实际上是一个可选参数:
使用条件或无条件GET方法的HTTP检索请求可以使用Range请求标头(http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35.2)
请求实体的一个或多个子范围,而不是整个实体
浏览器第一次请求没有任何范围值的正常情况。当服务器响应以指示它接受范围请求时,浏览器将发送另一个包含范围的请求。
此答案中有一个非常有用的流程示例:https://stackoverflow.com/a/8507991/334402
如果您想为此使用Express静态服务功能,因为它支持范围,那么这里有详细记录:https://github.com/expressjs/serve-static
以上链接中的示例代码:
var finalhandler = require('finalhandler')
var http = require('http')
var serveStatic = require('serve-static')
// Serve up public/ftp folder
var serve = serveStatic('public/ftp', {'index': ['index.html', 'index.htm']})
// Create server
var server = http.createServer(function onRequest (req, res) {
serve(req, res, finalhandler(req, res))
})
// Listen
server.listen(3000)
<强>更新强>
这是一个非常简单的node.js视频服务器。
您只需要在与app.js相同的文件夹中创建一个视频目录,然后将视频放在那里。
如果您的视频名为BigBuckBunny.mp4,则可以通过网址http://localhost:3000/BigBuckBunny.mp4
访问该视频var express = require('express')
var serveStatic = require('serve-static')
var app = express()
app.use(serveStatic(__dirname + '/videos'))
app.listen(3000)
答案 1 :(得分:0)
截至目前,我已经实施了一个非常天真的解决方案,我当然希望改进。所以这是我的代码,肯定需要优化。任何第三方npm模块也会帮助我。
NSTimeInterval
请让我知道,我如何优化此解决方案或我以前的代码才能工作。即使任何第三方npm模块也会帮助我。 感谢。