Commit 04b234e2 authored by Neil Gershenfeld's avatar Neil Gershenfeld

initial screen commit

parent 8934aaa8
//
// 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 = "<html>"
resp += "<body>"
resp += "last: "+last+"<br>"
resp += "max: "+max+"<br>"
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)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment