Nodejs - 视频流问题

时间:2017-07-14 23:02:59

标签: node.js express video stream

尝试在nodejs中传输视频时遇到了一些问题。当我尝试将视频路径传递给源/视频html标记时,它确实有效。然后,我意识到我必须流式传输视频。

问题是:当我流式传输视频时,我只是在浏览器中播放视频,作为直接链接到某些下载的视频,而不是带有一些数据的视频标题和路径。(/ p) >

我想渲染页面然后运行视频。 渲染时,我收到错误:“发送后无法设置标题”。

我的代码:

 const express = require('express')
const multer = require('multer')
const moment = require('moment')
const uuidv4 = require('uuid/v4');
const bodyParser = require('body-parser')
const fs = require('fs')
const videoLib = require('node-video-lib')
const app = express()
const db = require('./db')
let Video = require('./models/videoModel')

//***** STAND LIBRARIES CONFIGURATION **********//
app.use(bodyParser.urlencoded({extended:true}))
app.use(bodyParser.json())
app.set('views', 'views')
app.set('view engine', 'ejs')
app.set(db)
//***** MULTER CONFIGURATION ***************//
let storage = multer.diskStorage({

  destination: function(req, file, cb){
    cb(null, './uploads')
  },
  filename: function(req, file, cb){
    let mime = file.mimetype.split('/')[1]
    let uuid = uuidv4()
    cb(null, uuid + "." + mime)
  }

})

function fileFilter(req, file, cb){
    const extension = file.mimetype.split('/')[0];
    if(extension !== 'video'){
        return cb(new Error('Something went wrong. Wrong file format'), false);
    }
    cb(null, true);
};
var upload = multer({storage:storage, fileFilter: fileFilter})

const uploadHandler = upload.single('video')

function uploadVideo(req, res, next){
  uploadHandler(req, res, next, function(err){
    if(req.fileValidationError){
      res.send('Error when upload')
    }
    console.log(req.file.filename)
    next()
  })
}
//******************************************//
function  newVideo(req, res){
  let videoParams = {title: req.body.title, path: req.file.filename}
  Video.create(videoParams, function(err, result){
    if(err){
      console.log(err)
    }
    else{
      console.log("Video salvo com sucesso")
      console.log(result)
      res.send(result )
    }
  })
}



app.get('/videos/:id', function(req, res){
  let path = req.params.id
  Video.find({path:path}, function(err, result){
    if(err){
      console.log(err);
    }
    else{
      if (true) {
        console.log("The url is:" + req.url);
        const path = req.url.split('/')[2]
        console.log("Path:" + path);
        var file = `./uploads/${path}`
        var range = req.headers.range;

        fs.stat(file, function(err, stats) {
          var total = stats.size;

          if(range){
            console.log('RANGE: ' + 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;

            console.log(req.url, start, end);

            res.writeHead(206, {
              "Content-Range": "bytes " + start + "-" + end + "/" + total,
              "Accept-Ranges": "bytes",
              "Content-Length": chunksize,
              "Content-Type": "video/mp4"
            });
            fs.createReadStream(file, { start: start, end: end }).pipe(res);
          } else {
            res.writeHead(200, { 'Content-Length': total, 'Content-Type': 'video/mp4' });
            fs.createReadStream(file).pipe(res);
            res.render('videos', {videoData:result})//Erro: can't set header after they're sent

          }
        });
      } else {
        console.log(req.url + ' (static)');
        next();
      }
    }
  })
})

app.get('/', function(req, res){
  Video.find({}, function(err, result){
    if(err){
      console.log(err);
    }
    else{
      console.log();
      res.render('home', {videoData:result})
    }
  })
})
app.post('/upload', uploadVideo, newVideo)

app.listen(3000, ()=>{
  console.log("Server running on port 3000")
})

1 个答案:

答案 0 :(得分:1)

你不能同时使用

res.writeHead();

res.render();

了解详情:Error: Can't set headers after they are sent to the client