的
Accept Ranges报头(在该位
writeHead())所需的HTML5视频控制来工作。
我认为,不仅要盲目发送完整文件,还应首先检查
AcceptRangesREQUEST中的标头,然后读入并发送该位。
fs.createReadStreamsupport
start和
end选项。
所以我尝试了一个例子,它可以工作。该代码不是很漂亮,但是很容易理解。首先,我们处理范围标头以获取开始/结束位置。然后,我们用于
fs.stat获取文件的大小,而无需将整个文件读入内存。最后,用于
fs.createReadStream将请求的部分发送给客户端。
var fs = require("fs"), http = require("http"), url = require("url"), path = require("path");http.createServer(function (req, res) { if (req.url != "/movie.mp4") { res.writeHead(200, { "Content-Type": "text/html" }); res.end('<video src="http://localhost:8888/movie.mp4" controls></video>'); } else { var file = path.resolve(__dirname,"movie.mp4"); fs.stat(file, function(err, stats) { if (err) { if (err.pre === 'ENOENT') { // 404 Error if file not found return res.sendStatus(404); } res.end(err); } var range = req.headers.range; if (!range) { // 416 Wrong 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); }); }); }}).listen(8888);


