node.js中的视频流

时间:2015-10-08 07:10:01

标签: javascript node.js video streaming video-streaming

我想使用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'

这可能是因为路径正在改变。我应该遵循什么方法?可能吗?

1 个答案:

答案 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请求的响应,这样每次请求字节范围时都不需要这样做。