我想使用 node.js 流式传输视频。我已关注this article 。而且在本地运行良好。但我需要从网络流式传输视频。
我的要求略有不同。我必须从源代码中隐藏原始 URL。因此,我需要显示我自己的 URL,如 <source src="http://localhost:8888" type="video/mp4"/>
,而不是显示原始 URL。 。而不是显示<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'
这可能是因为路径正在改变。我应该遵循什么方法?是否可以?
最佳答案
您正在寻找类似 request module 的内容.
您可以简单地获取远程视频,然后将其直接传送到您的响应。
我要做的是首先向远程视频发出 HEAD
请求,以确认它接受字节范围并获取视频的内容长度。
获得该信息后,您可以设置响应 header ,HTTP 状态代码为 206
,表明这是部分响应。
现在您已经编写了响应 header ,您可以创建一个对远程视频的请求,沿着原始请求中的字节范围发送并将其直接通过管道传输到您的响应 (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
请求的响应,这样您就不需要在每次请求字节范围时都执行此操作。
关于javascript - Node.js 中的视频流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33008951/