I'm trying to stream mediafiles (.mkv) in Node.js using fs.createReadStream(). This works fine for files smaller than 2MB, they load correctly as the src of their respective HTML5 video elements.
For mediafiles larger than 2MB, this doesnt work. They don't load. In the Console's Network tab, the GET request shows the status '(canceled)' after ~30KB of transfered data. The strange part is that the video element seems to show the correct duration of the mediafile.
Request Method:GET
Status Code:206 Partial Content
Request Headers
Accept:*/*
Accept-Encoding:identity;q=1, *;q=0
Accept-Language:nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4,de;q=0.2,el;q=0.2
Connection:keep-alive
Host:(...)
Range:bytes=0-
Referer:yaddayadda
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Response Headers
Accept-Ranges:bytes
Access-Control-Allow-Headers:origin, content-type
Access-Control-Allow-Methods:POST, GET, OPTIONS, DELETE
Access-Control-Allow-Origin:*
Connection:keep-alive
Content-Length:5716684
Content-Range:bytes 0-5716683/5716684
Content-Type:video/mp4
Date:Tue, 19 Nov 2013 16:29:51 GMT
X-Powered-By:Express
Serverside code
app.get('/getStream/:u/:f', function(req, res) {
"use strict";
var userId = req.params.u;
var file = req.params.f;
var path = "/tmp/" + userId + "/" + file;
var stat = fs.statSync(path);
var total = stat.size;
if (req.headers['range']) {
var range = req.headers.range;
var parts = range.replace(/bytes=/, "").split("-");
var partialstart = parts[0];
var partialend = parts[1];
var start = parseInt(partialstart, 10);
var end = partialend ? parseInt(partialend, 10) : total - 1;
var chunksize = (end - start) + 1;
console.log('RANGE: ' + start + ' - ' + end + ' = ' + chunksize);
var file = fs.createReadStream(path, {start: start, end: end});
res.writeHead(206, {'Content-Range': 'bytes ' + start + '-' + end + '/' + total, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/mp4'});
file.pipe(res);
} else {
console.log('ALL: ' + total);
res.writeHead(200, {'Content-Length': total, 'Content-Type': 'video/mp4'});
fs.createReadStream(path).pipe(res);
}
});
Serverside notes
I have tried with a simple stream.pipe(res) but the problem persists.
I hope I have included enough information.
Thanks in advance