Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使用node.js将当前下载的视频流式传输到html5播放器?_Javascript_Node.js_Html_Express_Video Streaming - Fatal编程技术网

Javascript 如何使用node.js将当前下载的视频流式传输到html5播放器?

Javascript 如何使用node.js将当前下载的视频流式传输到html5播放器?,javascript,node.js,html,express,video-streaming,Javascript,Node.js,Html,Express,Video Streaming,我目前正在做一个项目,下载一个torrent,并在下载时将其流式传输到html5视频播放器。我的项目的限制不允许我使用peerflix或webtorrent。我目前正在使用torrent stream模块。我的代码在node.js和pug中。详情如下: server.js var uri = 'magnet:?xt=urn:btih:11a2ac68a11634e980f265cb1433c599d017a759'; var engine = torrentStream(uri);

我目前正在做一个项目,下载一个torrent,并在下载时将其流式传输到html5视频播放器。我的项目的限制不允许我使用peerflix或webtorrent。我目前正在使用torrent stream模块。我的代码在node.js和pug中。详情如下:

server.js

var uri = 'magnet:?xt=urn:btih:11a2ac68a11634e980f265cb1433c599d017a759';

var engine = torrentStream(uri);    

let engineGo = function () {
      return new Promise(function (resolve, reject) {
        var engine = torrentStream(uri);
        engine.on('ready', function() {
            engine.files.forEach(function(file) {
              if (file.name.substr(file.name.length - 3) == 'mkv' || file.name.substr(file.name.length - 3) == 'mp4') {
                console.log('filename:', file.name);
                var stream = file.createReadStream();
                var writable = fs.createWriteStream(file.name);
                stream.pipe(writable);
                engine.on('download', function () {
                  console.log(file.name);
                  console.log(engine.swarm.downloaded / file.length * 100 + "%");
                  resolve(file);
                });
              }
           });
       });
     });
}

app.get('*', function (req, res) {
    if (req.url != "/Guardians.of.the.Galaxy.2014.1080p.BluRay.x264.YIFY.mp4") {
      var rpath = __dirname + '/views/index.pug';
      fs.readFile(rpath, 'utf8', function (err, str) {
        var fn = pug.compile(str, { filename: rpath, pretty: true});
        res.writeHead(200, { "Content-Type": "text/html" });
        res.write(fn());
        res.end();
      });
    } else {
      engineGo().then(function (result) {
        var filer = path.resolve(__dirname,result.name);
        fs.stat(filer, 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;
          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",
            'Connection': 'keep-alive',
            "Content-Length": chunksize,
            "Content-Type": "video/mp4"
          });
          var stream = fs.createReadStream(filer, { start: start, end: end })
          .on("open", function() {
             stream.pipe(res);
          }).on("data", function (data) {
             console.log(data);
          }).on("error", function(err) {
             res.end(err);
          });
        });
      });
    }
});
哈巴狗

doctype
html
  title
    |Welcome
  body
      video(id='video' src="http://localhost:8888/Guardians.of.the.Galaxy.2014.1080p.BluRay.x264.YIFY.mp4" type="video/mp4" controls)
在这一刻,这开始起作用。一旦我加载页面,承诺将执行并开始下载torrent。一旦来自torrent的第一位数据通过.on('open')上的流发送,视频将开始播放。播放机显示,随着更多信息的下载,视频中会添加更多信息,但它不会播放超过发送的初始数据。有没有什么方法可以告诉玩家更多的数据即将到来,而不是在读取发送的初始数据块时立即删除?任何建议都是有帮助的,请提前感谢

您可以尝试以下方法:

const path = require('path');
const parseRange = require('range-parser');
const engine = torrentStream('magnet:?xt=urn:btih:11a2ac68a11634e980f265cb1433c599d017a759');
const getTorrentFile = new Promise(function (resolve, reject) {
  engine.on('ready', function() {
    engine.files.forEach(function (file, idx) {
      const ext = path.extname(file.name).slice(1);
      if (ext === 'mkv' || ext === 'mp4') {
        file.ext = ext;
        resolve(file);
      }
    });
  });
});

app.use('*', function (req, res) {
  if (req.url != '/Guardians.of.the.Galaxy.2014.1080p.BluRay.x264.YIFY.mp4') {
    res.setHeader('Content-Type', 'text/html');
    if (req.method !== 'GET') return res.end();
    var rpath = __dirname + '/views/index.pug';
    fs.readFile(rpath, 'utf8', function (err, str) {
      var fn = pug.compile(str, { filename: rpath, pretty: true});
      res.end(fn());
    });
  } else {
    res.setHeader('Accept-Ranges', 'bytes');
    getTorrentFile.then(function (file) {
      res.setHeader('Content-Length', file.length);
      res.setHeader('Content-Type', `video/${file.ext}`);
      const ranges = parseRange(file.length, req.headers.range, { combine: true });
      if (ranges === -1) {
        // 416 Requested Range Not Satisfiable
        res.statusCode = 416;
        return res.end();
      } else if (ranges === -2 || ranges.type !== 'bytes' || ranges.length > 1) {
        // 200 OK requested range malformed or multiple ranges requested, stream entire video
        if (req.method !== 'GET') return res.end();
        return file.createReadStream().pipe(res);
      } else {
        // 206 Partial Content valid range requested
        const range = ranges[0];
        res.statusCode = 206;
        res.setHeader('Content-Length', 1 + range.end - range.start);
        res.setHeader('Content-Range', `bytes ${range.start}-${range.end}/${file.length}`);
        if (req.method !== 'GET') return res.end();
        return file.createReadStream(range).pipe(res);
      }
    }).catch(function (e) {
      console.error(e);
      res.end(e);
    });
  }
});

我使用它来获取请求的字节范围,因为它经过全面测试并处理奇数边缘情况。我也会在服务器启动时立即启动torrent下载。这是因为浏览器通常会对同一个音频/视频文件发出多个请求,但请求的字节范围不同,因此在每次请求该文件时启动新的torrent流不是很有效。

@Aks-torrent-stream@Aks这就是我使用torrent stream的原因。下载的时候把激流整理好了是啊,我的错!我不知道这个。我删除了我以前的评论,因为它在这里没用。很抱歉,我现在帮不了你。投票表决你的问题,这很有趣,我会尝试一些hours@Aks非常感谢你的帮助!