public
Created

temp

  • Download Gist
app.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
// stream media
 
// urls to consider:
// http://html5doctor.com/video-canvas-magic/
// http://stackoverflow.com/questions/1106955/php-and-ffmpeg-performing-intelligent-video-conversion
// http://stackoverflow.com/questions/6954845/how-to-create-a-webm-video-file
// http://johndyer.name/ffmpeg-settings-for-html5-codecs-h264mp4-theoraogg-vp8webm/
// http://blog.pcode.nl/2010/10/17/encoding-webm-using-ffmpeg/
 
 
var fs = require('fs');
var util = require('util');
var express = require('express');
 
var port = 9001;
 
var app = express.createServer();
 
app.requireAuth = false;
 
//generic config
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({ secret: 'topsecret' }));
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
 
 
app.get('/media/*', function(req, res){
 
var file = 'media/' + req.params[0];
 
// TODO - get file info :: bitrate
var bitrate = 1048576; // 1M - rough guess at the bitrate of a 320x240 webm video
// TODO - implement application logic to determine secnodsToBuffer
var secondsToBuffer = 4;
 
// console.log(util.inspect(req, showHidden=false, depth=2));
// console.log(util.inspect(req.headers, showHidden=false, depth=0));
 
var stat = fs.statSync(file);
if (!stat.isFile()) return;
var size = stat.size;
 
var minChunkSize = secondsToBuffer * bitrate; // 512k (half a meg).
var numChunks = 10;
// can't get more than a 10th of the file at a time.
var chunkSize = parseInt(size/numChunks, 10);
if(chunkSize < minChunkSize){
chunkSize = minChunkSize;
}
 
var start = 0;
var end = 0;
var range = req.header('Range');
if (range != null) {
start = parseInt(range.slice(range.indexOf('bytes=')+6, range.indexOf('-')), 10);
end = parseInt(range.slice(range.indexOf('-')+1, range.length), 10);
}
if (isNaN(end) || end == 0){
end = size - 1;
}
if(end - start > chunkSize){
end = start + chunkSize;
}
if(end >= size){
end = size - 1;
}
if (start > end) return;
 
 
console.log('Browser requested bytes '+start+' to '+end+' of '+file);
 
var date = new Date();
 
res.writeHead(206, { // 206 is a partial http response
// 'Date':date.toUTCString(),
'Connection':'close',
// 'Cache-Control':'private',
// 'Content-Type':'video/webm',
// 'Content-Length':end - start,
'Content-Range':'bytes '+start+'-'+end+'/'+stat.size,
// 'Accept-Ranges':'bytes',
// 'Server':'CustomStreamer/0.0.1',
'Transfer-Encoding':'chunked'
});
 
var stream = fs.createReadStream(file, { flags:'r', start:start, end:end });
stream.pipe(res);
});
 
app.get(/^\/$/, function(req, res){
//res.send('<!doctype html><html><head><title>node stream video</title></head><body style="background:#000;"><video controls autoplay style="display:block;margin:30px auto;box-shadow:0 0 20px #444;border-radius:10px;"><source src="/media/video.webm" type="video/webm"></video></body></html>');
 
//render the index page
res.render('index.jade', {
locals: {
title: 'node stream video',
examples: []
}
});
});
 
 
 
app.listen(port);
 
process.on('uncaughtException', function(err) {
console.log(err);
});

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.