Reputation: 135
I'm having some problems when trying to stream videos in nodejs. When I tried just pass the video path to the source/video html tag, it doenst worked. Then, I realized that problably I would have to stream the video.
The problem is: When I stream the video, I just get the video being played in the browser, as a direct link to some downloaded video, not the renderized page with some data(video title and path).
I wanna render the page and then run the video. When I render, I receive the error: "Can't set headers after they're sent".
My code:
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")
})
Upvotes: 0
Views: 514
Reputation: 611
You can't use both
res.writeHead();
and
res.render();
Read more: Error: Can't set headers after they are sent to the client
Upvotes: 1