我想使用node.js来传输视频。我跟着this article。它从当地工作得很好。但我需要从网络流式传输视频。
我的要求略有不同。我必须从源代码中隐藏原始URL。因此,我需要显示自己的网址<source src="http://localhost:8888" type="video/mp4"/>
,而不是显示原始网址。而不是显示<source src="http://goo.gl/KgGx0s" type="video/mp4"/>
。
使用以下代码
var indexPage, movie_webm, movie_mp4, movie_ogg;
fs.readFile(path.resolve(__dirname,"ANY_LOCAL_VIDEO.mp4"), function (err, data) {
if (err) {
throw err;
}
console.log(data.length);
movie_mp4 = data;
});
http.createServer(function (req, res) {
var reqResource = url.parse(req.url).pathname;
var total;
total = movie_mp4.length;
var range = req.headers.range;
var positions = range.replace(/bytes=/, "").split("-");
var start = parseInt(positions[0], 10);
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"});
res.end(movie_mp4.slice(start, end+1), "binary");
}).listen(8888);
它适用于本地视频。但是,如果我提供fs.readFile("http://goo.gl/KgGx0s", function (err, data) {
而不是上面的代码,它就无法正常工作。我尝试将fs.readFile
更改为fs.filepath
,但仍无效。我收到此错误
c:\git\personal\streaming-video-html5\server.js:13
throw err;
^
Error: ENOENT, open 'c:\git\personal\streaming-video-html5\http:\goo.gl\KgGx0s'
这可能是因为路径正在改变。我应该遵循什么方法?可能吗?
答案 0 :(得分:1)
您正在寻找的内容类似于request module。
您可以直接获取远程视频,然后将其直接发送到您的回复中。
我要做的是首先向远程视频发出HEAD
请求,以确认它是否接受字节范围并获取视频的内容长度。
获得该信息后,您可以设置响应标头,HTTP状态代码为206
,表示这是部分响应。
现在您已经编写了响应标头,您可以创建对远程视频的请求,沿原始请求中的字节范围发送并直接管道到您的响应(res
);
var fileUrl = 'https://ia800300.us.archive.org/1/items/night_of_the_living_dead/night_of_the_living_dead_512kb.mp4';
var range = req.headers.range;
var positions, start, end, total, chunksize;
// HEAD request for file metadata
request({
url: fileUrl,
method: 'HEAD'
}, function(error, response, body){
setResponseHeaders(response.headers);
pipeToResponse();
});
function setResponseHeaders(headers){
positions = range.replace(/bytes=/, "").split("-");
start = parseInt(positions[0], 10);
total = headers['content-length'];
end = positions[1] ? parseInt(positions[1], 10) : total - 1;
chunksize = (end-start)+1;
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type":"video/mp4"
});
}
function pipeToResponse() {
var options = {
url: fileUrl,
headers: {
range: "bytes=" + start + "-" + end,
connection: 'keep-alive'
}
};
request(options).pipe(res);
}
您可以缓存HEAD
请求的响应,这样每次请求字节范围时都不需要这样做。