diff --git a/screen.js b/screen.js new file mode 100644 index 0000000000000000000000000000000000000000..41e23ff41a3c7e9bbf15319fc3b0435daf024513 --- /dev/null +++ b/screen.js @@ -0,0 +1,135 @@ +// +// screen.js +// mjpeg content server +// Neil Gershenfeld +// 2/9/17 +// todo +// standalone client content push +// browser client content push +// https +// parse command line +// add authentication +// interframe compression +// include audio +// uses maim for screen capture: +// https://github.com/naelstrof/maim +// https://github.com/naelstrof/maim/archive/master.zip +// install libimlib2-dev libxrandr-dev libxfixes-dev cmake +// +// command line +// +if (process.argv.length != 5) { + console.log("node screen.js server_port server_update_rate_ms client_update_rate_ms") + process.exit() + } +var port = parseInt(process.argv[2]) +var server_delay = parseFloat(process.argv[3]) +var client_delay = parseFloat(process.argv[4]) +// +// requires +// +var http = require('http') +const spawn = require('child_process').spawn; +const spawnSync = require('child_process').spawnSync +const fork = require('child_process').fork +const fs = require('fs') +const events = require('events') +// +// globals +// +var img,newimg +var max=0 +var last +// +// initialization +// +spawnSync('maim',['--showcursor','out.jpg']) +img = fs.readFileSync('out.jpg','binary') +var requests = [null] +// +// start http server +// +http.createServer(function(request,response) { + var headers = request.headers + var method = request.method + var url = request.url + if (url == '/') { + fs.readFile('viewer.html',function(err,data){ + response.writeHead(200,{'Content-Type':'text/html'}); + response.end(data) + }) + } + else if (url == '/img') { + requests.push(response) + } + else if (url == '/initvars') { + var vars = {'client_delay':client_delay} + response.writeHead(200,{'Content-Type':'text/plain'}); + response.end(JSON.stringify(vars)) + } + else if (url == '/initimg') { + response.writeHead(200,{'Content-Type':'application/octet-stream'}) + response.end(img,'binary') + } + else if (url == '/screen.js') { + fs.readFile('screen.js',function(err,data){ + response.writeHead(200,{'Content-Type':'text/plain'}); + response.end(data) + }) + } + else if (url == '/viewer.html') { + fs.readFile('viewer.html',function(err,data){ + response.writeHead(200,{'Content-Type':'text/plain'}); + response.end(data) + }) + } + else if (url == '/stats') { + var resp = "" + resp += "" + resp += "last: "+last+"
" + resp += "max: "+max+"
" + response.writeHead(200,{'Content-Type':'text/html'}); + response.end(resp) + } + }).listen(port) +// +// start event loop +// +update() +// +// event loop +// +function update() { + if (requests[0] == null) { + const ps = spawn('maim',['--showcursor','out.jpg']) + ps.on('close',function(code){ + fs.readFile('out.jpg','binary',function(err,data){ + var changed = false + for (var i = 0; i < img.length; ++i) { + if (img[i] != data[i]) { + changed = true + break + } + } + if (changed == true) { + if (requests.length > max) + max = requests.length + last = requests.length + img = data + requests.splice(0,1) + requests.push(null) + //console.log('changed: '+requests.length) + } + //else + //console.log('not changed: '+requests.length) + }) + setTimeout(update,server_delay) + }) + } + else { + requests[0].writeHead(200,{'Content-Type':'application/octet-stream'}) + requests[0].end(img,'binary') + requests.splice(0,1) + setTimeout(update,server_delay) + } + }