Commit 198a5700 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

1. improved jp4 preview stability

2. multi cameras single control page
parent 8c90a903
# Runs 'make', 'make install', and 'make clean' in specified subdirectories # Runs 'make', 'make install', and 'make clean' in specified subdirectories
SUBDIRS := src/php_top src/python_tests src/debugfs-webgui src/jp4-canvas src/update src/eyesis4pi src/index src/pointers src/snapshot src/jp4-viewer src/photofinish # src1 SUBDIRS := src/php_top src/python_tests src/debugfs-webgui src/jp4-canvas src/update src/eyesis4pi src/index src/pointers src/snapshot src/jp4-viewer src/photofinish src/multicam # src1
INSTALLDIRS = $(SUBDIRS:%=install-%) INSTALLDIRS = $(SUBDIRS:%=install-%)
CLEANDIRS = $(SUBDIRS:%=clean-%) CLEANDIRS = $(SUBDIRS:%=clean-%)
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
<script src="js/jcanvas.js"></script> <script src="js/jcanvas.js"></script>
<script src="js/exif.js"></script> <script src="js/exif.js"></script>
<script src="js/jquery-jp4.js"></script> <script src="js/jquery-jp4.js"></script>
<link rel="stylesheet" href="js/bootstrap/css/bootstrap.css"> <link rel="stylesheet" href="js/bootstrap/css/bootstrap.css">
<style> <style>
.port_window{ .port_window{
...@@ -79,15 +79,15 @@ ...@@ -79,15 +79,15 @@
table td { table td {
padding-right:10px; padding-right:10px;
} }
.btn.active:focus, .btn:focus{ .btn.active:focus, .btn:focus{
outline:none; outline:none;
} }
.btn-toggle{ .btn-toggle{
padding: 1px 0px; padding: 1px 0px;
} }
</style> </style>
</head> </head>
<body> <body>
...@@ -99,9 +99,9 @@ ...@@ -99,9 +99,9 @@
$table_contents = ""; $table_contents = "";
$port_links = ""; $port_links = "";
$sample_port = -1; $sample_port = -1;
for($i=0;$i<4;$i++){ for($i=0;$i<4;$i++){
$sensor = $path."/sensor{$i}0"; $sensor = $path."/sensor{$i}0";
if (is_file($sensor)){ if (is_file($sensor)){
...@@ -109,7 +109,7 @@ ...@@ -109,7 +109,7 @@
if ($c!="none"){ if ($c!="none"){
$sample_port = $i; $sample_port = $i;
$sandp = "http://{$_SERVER["SERVER_ADDR"]}:".($port0+$i); $sandp = "http://{$_SERVER["SERVER_ADDR"]}:".($port0+$i);
$href1 = "$sandp/bimg"; $href1 = "$sandp/bimg";
$href2 = "$sandp/mimg"; $href2 = "$sandp/mimg";
...@@ -132,7 +132,7 @@ ...@@ -132,7 +132,7 @@
$master_port = elphel_get_P_value($sample_port,ELPHEL_TRIG_MASTER); $master_port = elphel_get_P_value($sample_port,ELPHEL_TRIG_MASTER);
$awb_on = elphel_get_P_value($master_port,ELPHEL_WB_EN); $awb_on = elphel_get_P_value($master_port,ELPHEL_WB_EN);
$aexp_on = elphel_get_P_value($master_port,ELPHEL_AUTOEXP_ON); $aexp_on = elphel_get_P_value($master_port,ELPHEL_AUTOEXP_ON);
echo "<table><tr>$table_contents</tr></table>\n"; echo "<table><tr>$table_contents</tr></table>\n";
echo "<br/>"; echo "<br/>";
...@@ -162,7 +162,7 @@ ...@@ -162,7 +162,7 @@
<button class="btn btn-xs <?php echo (!$aexp_on)?"btn-danger active":"btn-default";?>">OFF</button> <button class="btn btn-xs <?php echo (!$aexp_on)?"btn-danger active":"btn-default";?>">OFF</button>
</div> </div>
</td> </td>
</tr> </tr>
</table> </table>
<br /> <br />
<a href="autocampars.php" title="autocampars.php">Parameter Editor</a><br /> <a href="autocampars.php" title="autocampars.php">Parameter Editor</a><br />
...@@ -189,7 +189,7 @@ $(function(){ ...@@ -189,7 +189,7 @@ $(function(){
function init_jp4_previews(){ function init_jp4_previews(){
$('.port_preview').each(function(){ $('.port_preview').each(function(){
index = parseInt($(this).attr("index")); index = parseInt($(this).attr("index"));
$(this).jp4({ip:"127.0.0.1",port:2323+index,width:300,fast:true,lowres:4}); $(this).jp4({ip:location.host,port:2323+index,width:300,fast:true,lowres:4});
}); });
} }
...@@ -201,7 +201,7 @@ function init_awb_toggle(){ ...@@ -201,7 +201,7 @@ function init_awb_toggle(){
}else{ }else{
$(this).find('.btn.active').toggleClass('btn-danger'); $(this).find('.btn.active').toggleClass('btn-danger');
} }
// toggle active // toggle active
$(this).find('.btn').toggleClass('active'); $(this).find('.btn').toggleClass('active');
...@@ -214,7 +214,7 @@ function init_awb_toggle(){ ...@@ -214,7 +214,7 @@ function init_awb_toggle(){
} }
$(this).find('.btn').toggleClass('btn-default'); $(this).find('.btn').toggleClass('btn-default');
url = "parsedit.php?immediate&sensor_port=<?php echo $master_port;?>&WB_EN="+wb_en+"&*WB_EN=0xf"; url = "parsedit.php?immediate&sensor_port=<?php echo $master_port;?>&WB_EN="+wb_en+"&*WB_EN=0xf";
$.ajax({ $.ajax({
...@@ -235,7 +235,7 @@ function init_aexp_toggle(){ ...@@ -235,7 +235,7 @@ function init_aexp_toggle(){
}else{ }else{
$(this).find('.btn.active').toggleClass('btn-danger'); $(this).find('.btn.active').toggleClass('btn-danger');
} }
// toggle active // toggle active
$(this).find('.btn').toggleClass('active'); $(this).find('.btn').toggleClass('active');
...@@ -248,7 +248,7 @@ function init_aexp_toggle(){ ...@@ -248,7 +248,7 @@ function init_aexp_toggle(){
} }
$(this).find('.btn').toggleClass('btn-default'); $(this).find('.btn').toggleClass('btn-default');
url = "parsedit.php?immediate&sensor_port=<?php echo $master_port;?>&AUTOEXP_ON="+aexp_en+"&*AUTOEXP_ON=0xf"; url = "parsedit.php?immediate&sensor_port=<?php echo $master_port;?>&AUTOEXP_ON="+aexp_en+"&*AUTOEXP_ON=0xf";
$.ajax({ $.ajax({
...@@ -257,7 +257,7 @@ function init_aexp_toggle(){ ...@@ -257,7 +257,7 @@ function init_aexp_toggle(){
console.log("aexp "+(aexp_en?"on":"off")); console.log("aexp "+(aexp_en?"on":"off"));
} }
}); });
}); });
} }
......
...@@ -34,15 +34,22 @@ if (isset($_GET['ip'])) ...@@ -34,15 +34,22 @@ if (isset($_GET['ip']))
$ip = $_GET['ip']; $ip = $_GET['ip'];
else else
$ip = "localhost"; $ip = "localhost";
/* /*
header("Location: http://{$_SERVER['HTTP_HOST']}:$port/$rel"); header("Location: http://{$_SERVER['HTTP_HOST']}:$port/$rel");
die(); die();
*/ */
$port0 = 2323;
$pointers = elphel_get_circbuf_pointers(intval($port)-$port0,1);
$pointer = $pointers[count($pointers)-1]['circbuf_pointer'];
// allow CORS
header('Access-Control-Allow-Origin: *');
header('Content-type:image/jpeg'); header('Content-type:image/jpeg');
echo file_get_contents("http://$ip:$port/$rel"); echo file_get_contents("http://$ip:$port/$pointer/$rel");
//echo file_get_contents("http://$ip:$port/$rel");
die(); die();
?> ?>
...@@ -78,6 +78,8 @@ ...@@ -78,6 +78,8 @@
var cnv_working = $("<canvas>",{id:"working"}); var cnv_working = $("<canvas>",{id:"working"});
var cnv_display = $("<canvas>",{id:"display"}); var cnv_display = $("<canvas>",{id:"display"});
obj.busy = false;
// hide working canvas // hide working canvas
cnv_working.css({display:"none"}); cnv_working.css({display:"none"});
/* /*
...@@ -102,6 +104,7 @@ ...@@ -102,6 +104,7 @@
* make sure the image data starts with: "data:image/jpeg;base64," * make sure the image data starts with: "data:image/jpeg;base64,"
* EXIF.js does not like empty data type: "data:;base64," * EXIF.js does not like empty data type: "data:;base64,"
*/ */
obj.busy = true;
process_image(settings.image); process_image(settings.image);
}else{ }else{
send_request(); send_request();
...@@ -115,7 +118,8 @@ ...@@ -115,7 +118,8 @@
var http = new XMLHttpRequest(); var http = new XMLHttpRequest();
if (settings.port!=""&&settings.ip!=""){ if (settings.port!=""&&settings.ip!=""){
rq = "/get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=bimg&ts="+Date.now(); //rq = "/get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=bimg&ts="+Date.now();
rq = "http://"+settings.ip+"/get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=img&ts="+Date.now();
//rq = "get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=img&ts="+Date.now(); //rq = "get-image.php?ip="+settings.ip+"&port="+settings.port+"&rel=img&ts="+Date.now();
//settings.refresh = true; //settings.refresh = true;
}else{ }else{
...@@ -137,12 +141,16 @@ ...@@ -137,12 +141,16 @@
} }
}; };
obj.busy = true;
http.send(); http.send();
} }
this.refresh = function(){ this.refresh = function(){
send_request(); // skip if busy?
if (!obj.busy){
send_request();
}
} }
this.resize = function(w){ this.resize = function(w){
...@@ -244,6 +252,7 @@ ...@@ -244,6 +252,7 @@
} }
$(this).trigger("canvas_ready"); $(this).trigger("canvas_ready");
obj.busy = false;
if (settings.refresh) { if (settings.refresh) {
if (DEBUG){ if (DEBUG){
...@@ -360,6 +369,7 @@ ...@@ -360,6 +369,7 @@
} }
//trigger here //trigger here
cnv_working.trigger("canvas_ready"); cnv_working.trigger("canvas_ready");
obj.busy = false;
if (settings.refresh) { if (settings.refresh) {
if (DEBUG){ if (DEBUG){
...@@ -368,6 +378,8 @@ ...@@ -368,6 +378,8 @@
} }
send_request(); send_request();
} }
this.terminate();
} }
} }
...@@ -392,7 +404,7 @@ ...@@ -392,7 +404,7 @@
bayer_mode = 0; // r gr / gb b bayer_mode = 0; // r gr / gb b
if (typeof MakerNote !== 'undefined'){ if (typeof MakerNote !== 'undefined'){
bayer_mode = (MakerNote[10]>>2)&0x3; bayer_mode = (MakerNote[10]>>2)&0x3;
console.log("Bayer mode = "+bayer_mode); //console.log("Bayer mode = "+bayer_mode);
switch(bayer_mode){ switch(bayer_mode){
case 0: BAYER = [["Gr","R"],["B","Gb"]];break; case 0: BAYER = [["Gr","R"],["B","Gb"]];break;
case 1: BAYER = [["R","Gr"],["Gb","B"]];break; case 1: BAYER = [["R","Gr"],["Gb","B"]];break;
......
...@@ -7,11 +7,11 @@ self.onmessage = function(e) { ...@@ -7,11 +7,11 @@ self.onmessage = function(e) {
var H = e.data.height; var H = e.data.height;
var Mosaic = e.data.mosaic; var Mosaic = e.data.mosaic;
var Format = e.data.format; var Format = e.data.format;
var settings = e.data.settings; var settings = e.data.settings;
var Pixels = new Uint8Array(e.data.pixels); var Pixels = new Uint8Array(e.data.pixels);
if (settings.lowres==0){ if (settings.lowres==0){
var reorderedPixels = Elphel.Pixels.reorderBlocksJPx(Pixels,W,H,Format,Mosaic,settings.fast); var reorderedPixels = Elphel.Pixels.reorderBlocksJPx(Pixels,W,H,Format,Mosaic,settings.fast);
//reorder first then downscale //reorder first then downscale
...@@ -24,15 +24,16 @@ self.onmessage = function(e) { ...@@ -24,15 +24,16 @@ self.onmessage = function(e) {
W = W/2; W = W/2;
H = H/2; H = H/2;
} }
Elphel.Pixels.applySaturation(reorderedPixels,W,H,2); Elphel.Pixels.applySaturation(reorderedPixels,W,H,2);
postMessage({ postMessage({
width: W, width: W,
height: H, height: H,
pixels: reorderedPixels.buffer pixels: reorderedPixels.buffer
},[reorderedPixels.buffer]); },[reorderedPixels.buffer]);
//Elphel.test(); //Elphel.test();
this.close();
}; };
\ No newline at end of file
DOCUMENTROOT=$(DESTDIR)/www/pages/multicam
OWN = -o root -g root
INSTDOCS = 0644
INSTALL = install
DOCS= index.html \
multicam.js \
multicam.css \
multicam.php
all:
@echo "make all in src"
install:
@echo "make install in src"
$(INSTALL) $(OWN) -d $(DOCUMENTROOT)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(DOCS) $(DOCUMENTROOT)
clean:
@echo "make clean in src"
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Multi cameras control</title>
<script src="../js/jquery-3.1.1.js"></script>
<script src="../js/elphel.js"></script>
<script src="../js/jcanvas.js"></script>
<script src="../js/exif.js"></script>
<script src="../js/jquery-jp4.js"></script>
<link rel="stylesheet" href="../js/bootstrap/css/bootstrap.css">
<script type='text/javascript' src='multicam.js'></script>
<link rel='stylesheet' type='text/css' href='multicam.css'></link>
</head>
<body>
<div id='settings'>
<table>
<tr>
<td>
<div id='rec_button' class='rec_outer' title='start recording'>
<div class='rec_inner'></div>
</div>
</td>
</tr>
<tr id="toggle_awb" title='Auto White Balance'>
<td>Auto WB:</td>
<td>
<div id="toggle_awb" class="btn-group btn-toggle">
<button class="btn btn-xs btn-success active">ON</button>
<button class="btn btn-xs btn-default">OFF</button>
</div>
</td>
</tr>
<tr id="toggle_aexp" title='Auto Exposure'>
<td>Auto Exposure:</td>
<td>
<div id="toggle_aexp" class="btn-group btn-toggle">
<button class="btn btn-xs btn-success active">ON</button>
<button class="btn btn-xs btn-default">OFF</button>
</div>
</td>
</tr>
<tr>
<td hidden>
<br/>
<div id='edit_addrs_input' hidden>
<div id='eai_text_div'>
<textarea id='eai_text' rows='4' cols='30'></textarea>
</div>
<div id='eai_ok_div'>
<button id='eai_ok' class="btn btn-sm btn-success">ok</button>
</div>
</div>
<div id='edit_addrs' title='edit ip addresses'>
<button id='ea_btn' class="btn btn-sm btn-success">+</button>
</div>
<div id='addrs'>
</div>
</td>
</tr>
</table>
</div>
<div id='display'>
<div id='display_status'></div>
<hr/>
<div id='display_previews'></div>
</div>
</body>
</html>
\ No newline at end of file
#settings{
padding:5px;
}
table td {
padding-right:10px;
}
.btn.active:focus, .btn:focus{
outline:none;
}
.btn-toggle{
padding: 1px 0px;
}
#edit_addrs{
padding: 2px;
}
#ea_btn{
outline:none;
font-weight:bold;
}
#addrs{
padding: 0px 2px 2px 2px;
}
#eai_text{
resize:none;
margin:0px;
}
#edit_addrs_input{
position:absolute;
top:2px;
left:2px;
border:1px solid rgb(169,169,169);
padding:2px;
background: white;
z-index: 100;
}
#eai_text_div{
line-height:14px;
}
#rec_start{
outline:none;
border: 0px solid #00AA66;
}
.rec_outer{
position:relative;
width:50px;
height:50px;
border-radius:50%;
border: 1px solid rgba(100,100,100,1);
background: white;
}
.rec_inner{
position:relative;
top:25%;
left:25%;
width:50%;
height:50%;
border-radius:50%;
background: rgb(166,14,14);
}
.rec_outer:active{
border: 1px solid rgb(166,14,14);
}
.rec_outer_active{
border: 1px solid rgb(166,14,14);
}
.rec_inner_running{
top:5%;
left:5%;
width:90%;
height:90%;
}
.port_preview{
width:200px;
}
.hist_preview{
border:1px solid rgba(200,200,200,0.5);
width:200px;
}
#display{
padding:5px;
}
hr{
margin-top:2px;
margin-bottom:2px;
}
#display_status th, #s_device{
text-align:center;
}
#s_space{
text-align:right;
}
#display_status td, #display_status th{
border:1px solid rgba(100,100,100,0.8);
padding:2px 5px;
}
// port class
var Port = function(options){
var defaults = {
port: 0,
index: 0,
awb: NaN,
aexp: NaN,
preview: null
};
this._data = $.extend(defaults,options);
this.port = this._data.port;
this.index = this._data.index;
this.awb = this._data.awb;
this.aexp = this._data.aexp;
this.preview = this._data.preview;
}
// camera class
var Camera = function(options){
var defaults = {
ip: "",
init: false,
status: false,
camogm: false,
recording: false,
ports: []
};
this._data = $.extend(defaults,options);
this.ip = this._data.ip;
this.init = this._data.init;
this.status = this._data.status;
this.ports = this._data.ports;
};
// global
var recording = false;
var ips_from_url = false;
var cams = [];
var wb_en = 1;
var aexp_en = 1;
$(function(){
init();
});
function parseURL(){
var parameters=location.href.replace(/\?/ig,"&").split("&");
for (var i=0;i<parameters.length;i++) parameters[i]=parameters[i].split("=");
for (var i=1;i<parameters.length;i++) {
switch (parameters[i][0]) {
case "ip":
ips_from_url = true;
ips_str = parameters[i][1];
ips_str = ips_str.replace(/,|;/gm,'\n');
addrs_str2ips(ips_str);
break;
}
}
}
function init(){
parseURL();
if (!ips_from_url){
//get config
$.ajax({
url: "multicam.php?cmd=read",
success: function(data){
var addrs = $(data).find('camera');
for(var i=0;i<addrs.length;i++){
cams.push(new Camera({ip:$(addrs[i]).text()}));
}
init2();
}
});
}else{
init2();
}
init_rec_button();
//
$("#ea_btn").on('click',function(){
$("#edit_addrs_input").css({
top: $(this).offset().top,
left: $(this).offset().left
}).show();
$("#eai_text").focus();
});
$("#eai_ok").on('click',function(){
addrs_ta2ips();
$("#edit_addrs_input").hide();
});
$("#display").css({
position:'absolute',
top: '2px',
left: $("#settings").find("table").width()+10
});
}
function init2(){
addrs_ips2ta();
// create tables
addrs_create_tables();
// now get the ports
get_ports();
init_awb_toggle();
init_aexp_toggle();
}
function get_ports(){
for(var i=0;i<cams.length;i++){
$.ajax({
url: "http://"+cams[i].ip+"/multicam/multicam.php?cmd=ports",
ip:cams[i].ip,
index: i,
success: function(response){
var index = this.index;
var ports = $(response).find("port");
cams[this.index].status = true;
cams[this.index].init = true;
// ports are already ordered in response
ports.each(function(){
if ($(this).text()!=='none'){
var tmp_port = new Port({port: $(this).attr("port"), index: $(this).attr("index")});
cams[index].ports.push(tmp_port);
init_port(index,cams[index].ports.length-1);
}
});
// check camogm is alive
check_camogm(index);
init3(index);
}
}).fail(function(data,status){
console.log(this.ip+" request failed. Check errors");
// will be checked when sending requests
cams[this.index].status = false;
addrs_mark_bad_ip(this.ip);
});
}
}
function check_camogm(cam_i){
// run_status does not interact with camogm, quickest response
$.ajax({
url: "http://"+cams[cam_i].ip+"/camogm_interface.php?cmd=run_status",
cam_i: cam_i,
success: function(res){
var state = $(res).find('state').text();
// false(if not init) or 'on' or 'off'
cams[this.cam_i].camogm = state;
if (state=='off'){
console.log(cams[this.cam_i].ip+": camogm is off");
// launch it
camogm_launch(this.cam_i);
}
if (state=='on'){
console.log(cams[this.cam_i].ip+": camogm is on");
check_camogm_status(this.cam_i);
}
}
});
}
function camogm_launch(cam_i){
// raw recording is default on start
$.ajax({
url: "http://"+cams[cam_i].ip+"/camogm_interface.php?cmd=run_camogm",
cam_i: cam_i,
success: function(res){
console.log(cams[this.cam_i].ip+": "+res);
cams[this.cam_i].camogm = 'on';
check_camogm_status(this.cam_i);
}
});
}
function check_camogm_status(cam_i){
// run_status does not interact with camogm, quickest response
$.ajax({
url: "http://"+cams[cam_i].ip+"/camogm_interface.php?cmd=status",
cam_i: cam_i,
success: function(res){
var cam = cams[this.cam_i];
if ($(res).find('state').length!=0){
var state = $(res).find('state').text();
state = state.replace(/"/gm,'');
// false(if not init) or 'on' or 'off'
cams[this.cam_i].recording = state;
rec_button_update_state();
var se = $("#display_status").find("tr[ip='"+cam.ip+"']");
// device
var device = $(res).find('raw_device_path').text().replace(/"/gm,'');
se.find("#s_device").html(device);
// free space
var lba_end = parseInt($(res).find('lba_end').text());
var lba_current = parseInt($(res).find('lba_current').text());
var free_space = (lba_end - lba_current)/2/1024/1024;
free_space = Math.round(100*free_space)/100;
se.find("#s_space").html(free_space+" GB");
}
}
}).fail(function(data,status){
console.log("status request failed");
});
}
var all_ready_init_run = true;
function rec_button_update_state(){
var all_ready = true;
var any_running = false;
var any_stopped = false;
for(var i=0;i<cams.length;i++){
if (cams[i].init){
if ((cams[i].camogm=='on')&&(!cams[i].recording)){
all_ready = false;
break;
}
if(cams[i].recording=='running'){
any_running = true;
}else if(cams[i].recording=='stopped'){
any_stopped = true;
}
}
}
if (all_ready){
if (any_running && any_stopped){
console.log("WARNING: some camogms are running, some are stopped");
}
if (all_ready_init_run){
// display like it's running
if (any_running){
console.log("Turn on recording");
recording = true;
rec_button_switch(recording);
}
refresh_previews_intvl = setInterval(refresh_previews,1000);
refresh_status_intvl = setInterval(refresh_status,2000);
}
all_ready_init_run = false;
}
}
//var refresh_status_intvl;
//var refresh_previews_intvl;
// get initial wb_en and aexp_en from the lowest port
// assuming the lowest port has the same values
// wb_en
// parsedit.php?immediate&sensor_port=0&WB_EN
function init_port(cam_i,port_i){
var url = "http://"+cams[cam_i].ip+"/parsedit.php?immediate&sensor_port="+cams[cam_i].ports[port_i].index+"&WB_EN";
$.ajax({
url: url,
cam_i: cam_i,
port_i: port_i,
success: function(res){
wb_en = parseInt($(res).find("WB_EN").text());
cams[this.cam_i].ports[this.port_i].awb = wb_en;
button_update_state($("#toggle_awb"));
//button_switch($("#toggle_awb"),wb_en);
}
});
// aexp_en
// parsedit.php?immediate&sensor_port=0&WB_EN
var url = "http://"+cams[cam_i].ip+"/parsedit.php?immediate&sensor_port="+cams[cam_i].ports[port_i].index+"&AUTOEXP_ON";
$.ajax({
url: url,
cam_i: cam_i,
port_i: port_i,
success: function(res){
aexp_en = parseInt($(res).find("AUTOEXP_ON").text());
cams[this.cam_i].ports[this.port_i].aexp = aexp_en;
button_update_state($("#toggle_aexp"));
//button_switch($("#toggle_aexp"),aexp_en);
}
});
}
// * if any attribute is not initialized it will be NaN
// * if all do not match then take the last one
function button_update_state(btn){
// if all ports are filled out then update
var all_match = true;
var all_ready = true;
var start = false;
var old_port_attr;
for(var i=0;i<cams.length;i++){
if (cams[i].init){
for(var j=0;j<cams[i].ports.length;j++){
var port = cams[i].ports[j];
if (btn.attr("id")=="toggle_aexp"){
port_attr = port.aexp;
}
if (btn.attr("id")=="toggle_awb"){
port_attr = port.awb;
}
if (isNaN(port_attr)){
all_ready = false;
break;
}
if (start){
if (port_attr!=old_port_attr){
console.log(port_attr+" vs "+old_port_attr);
all_match = false;
}
}else{
start = true;
}
old_port_attr = port_attr;
}
if (!all_ready){
break;
}
}
}
// check results
if (!all_match){
console.log("WARNING: "+btn.attr("id")+": not all parameters match");
}else{
//console.log(btn.attr("id")+": all params across all cameras/ports match");
}
button_switch(btn,old_port_attr);
}
// can be used for refresh?
function init3(index){
// display
var cam = cams[index];
var ts = Date.now();
var img_str = "";
var hst_str = "";
for(var i=0;i<cam.ports.length;i++){
//img_src = 'http://'+cam.ip+':'+cam.ports[i].port+'/img?'+ts;
//hst_src = 'http://'+cam.ip+'/pnghist.cgi?sensor_port='+cam.ports[i].index+'&sqrt=1&scale=5&average=5&height=128&fillz=1&linterpz=0&draw=2&colors=41&_time='+ts;
img_str += [
' <td>',
' <div class=\'port_preview\' index=\''+i+'\'></div>',
' </td>'
].join('\n');
hst_str += [
' <td>',
' <img class=\'hist_preview\' index=\''+i+'\' />',
' </td>'
].join('\n');
}
var display_str = [
' <tr>',
' <td>'+cam.ip+':</td>',
' </tr>',
' <tr>',
img_str,
' </tr>',
' <tr>',
hst_str,
' </tr>'
].join('\n');
$("#display_previews").find("table[ip=\'"+cam.ip+"\']").html($(display_str));
// and status
var status_str = [
'<td id=\'s_ip\'>'+cam.ip+'</td>',
'<td id=\'s_device\'></td>',
'<td id=\'s_space\'></td>',
'<td id=\'s_errors\'></td>'
].join('\n');
$("#display_status").find("tr[ip=\'"+cam.ip+"\']").html($(status_str));
}
function refresh_previews(){
var ts = Date.now();
for(var i=0;i<cams.length;i++){
if (cams[i].init){
for(var j=0;j<cams[i].ports.length;j++){
var cam = cams[i];
//var img_src = 'http://'+cam.ip+':'+cam.ports[j].port+'/img?'+ts;
var hst_src = 'http://'+cam.ip+'/pnghist.cgi?sensor_port='+cam.ports[j].index+'&sqrt=1&scale=5&average=5&height=128&fillz=1&linterpz=0&draw=2&colors=41&_time='+ts;
var elem = $("#display_previews").find("table[ip=\'"+cam.ip+"\']");
//elem.find(".port_preview[index="+j+"]").attr('src',img_src);
if (!cam.ports[j].preview){
//console.log("preview does not exist");
var jp4prev = elem.find(".port_preview[index="+j+"]");
var preview = jp4prev.jp4({
ip: cam.ip,
port: cam.ports[j].port,
width: 200,
fast: true,
lowres:4,
webworker_path: "../js"
});
cam.ports[j].preview = preview;
}else{
cam.ports[j].preview.data.refresh();
}
//console.log(jp4prev.data.getAddr());
elem.find(".hist_preview[index="+j+"]").attr('src',hst_src);
}
}
}
}
function refresh_status(){
for(var i=0;i<cams.length;i++){
if (cams[i].init){
check_camogm_status(i);
}
}
}
function init_rec_button(){
$("#rec_button").on('click',function(){
recording = !recording;
rec_button_switch(recording);
if (recording){
url = "camogm_interface.php?cmd=start";
}else{
url = "camogm_interface.php?cmd=stop";
}
multi_ajax(url,function(res){
console.log(this.ip+": rec = "+recording);
});
//http://{$unique_cams[$i]['ip']}/camogm_interface.php?cmd=start
});
}
function rec_button_switch(state){
if (state){
$("#rec_button").addClass("rec_outer_active");
//$(".rec_inner").addClass("rec_inner_running");
rec_running(true);
}else{
$("#rec_button").removeClass("rec_outer_active");
//$(".rec_inner").removeClass("rec_inner_running");
rec_running(false);
}
}
var rec_running_intvl;
var refresh_status_intvl;
var refresh_previews_intvl;
function rec_running(state){
if (state){
rec_running_intvl = setInterval(rec_intvl,500);
$(".rec_inner").fadeOut(0);
}else{
clearInterval(rec_running_intvl);
$(".rec_inner").fadeIn(0);
}
}
function rec_intvl(){
$(".rec_inner").fadeToggle(100);
}
// create tables for previews
// but they are invisible until data comes in
function addrs_create_tables(){
$("#display_status").html([
'<table>',
'<tr>',
' <th>ip</th>',
' <th>device</th>',
' <th>free space</th>',
' <th>errors</th>',
'</tr>',
'</table>'
].join('\n'));
for(var i=0;i<cams.length;i++){
var tbl = [
'<div>',
' <table ip=\''+cams[i].ip+'\'>',
' </table>',
'</div>'
].join('\n');
$("#display_previews").append($(tbl));
var tbl_row = [
'<tr ip=\''+cams[i].ip+'\'>',
'</tr>'
].join('\n');
$("#display_status").find("table").append($(tbl_row));
}
}
function addrs_ips2addrs(){
$("#addrs").html("");
for(var i=0;i<cams.length;i++){
$("#addrs").append($('<div>').html(cams[i].ip));
}
}
function addrs_ips2ta(){
var arr = [];
var str = "";
for(var i=0;i<cams.length;i++){
arr.push(cams[i].ip);
}
str = arr.join("\n");
$("#eai_text").val(str);
addrs_ips2addrs();
}
function addrs_ta2ips(){
var str = $("#eai_text").val();
addrs_str2ips(str);
addrs_ips2addrs();
}
function addrs_str2ips(str){
cams = [];
var tmp_ips = str.split("\n");
for(var i=0;i<tmp_ips.length;i++){
str = tmp_ips[i].replace(/,|;|^\s+|\s+$/gm,'');
if (str!==""){
cams.push(new Camera({ip:str}));
}
}
}
function addrs_mark_bad_ip(ip){
$("#addrs").find("div").each(function(){
if ($(this).html()==ip){
$(this).css({color:"red"});
$(this).attr("title","N/A");
}
});
}
function init_awb_toggle(){
$('#toggle_awb').click(function() {
if ($(this).find('.btn.active').html()=="ON"){
wb_en = 0;
}else{
wb_en = 1;
}
button_switch($(this),wb_en);
// will it work without port 0?
url = "parsedit.php?immediate&sensor_port=0&WB_EN="+wb_en+"&*WB_EN=0xf";
multi_ajax(url,function(res){
console.log(this.ip+": awb "+wb_en);
});
});
}
// on or off
function button_switch(btn,state){
//btn = $('#toggle_awb');
if (state==1){
if (btn.find('.btn.active').html()=="OFF"){
btn.find('.btn.active').toggleClass('btn-danger');
// toggle active
btn.find('.btn').toggleClass('active');
btn.find('.btn.active').toggleClass('btn-success');
btn.find('.btn').toggleClass('btn-default');
}
}
if (state==0){
if (btn.find('.btn.active').html()=="ON"){
btn.find('.btn.active').toggleClass('btn-success');
// toggle active
btn.find('.btn').toggleClass('active');
btn.find('.btn.active').toggleClass('btn-danger');
btn.find('.btn').toggleClass('btn-default');
}
}
}
function init_aexp_toggle(){
$('#toggle_aexp').click(function() {
if ($(this).find('.btn.active').html()=="ON"){
aexp_en = 0;
}else{
aexp_en = 1;
}
button_switch($(this),aexp_en);
// will it work without port 0?
url = "parsedit.php?immediate&sensor_port=0&AUTOEXP_ON="+aexp_en+"&*AUTOEXP_ON=0xf";
multi_ajax(url,function(res){
console.log(this.ip+": aexp "+aexp_en);
});
});
}
function multi_ajax(url,callback){
for(var i=0;i<cams.length;i++){
if (cams[i].status){
$.ajax({
url: "http://"+cams[i].ip+"/"+url,
ip: cams[i].ip,
success: callback
});
}
}
}
<?php
$cmd = "donothing";
if (isset($_GET['cmd']))
$cmd = $_GET['cmd'];
else if (isset($argv[1]))
$cmd = $argv[1];
$config = "/var/volatile/html/multicam.xml";
// path to sysfs for port scanning
$portspath = "/sys/devices/soc0/elphel393-detect_sensors@0";
// total number of ports in 10393
$nports = 4;
$port0 = 2323;
// extract ip addresses
if ($_SERVER['REQUEST_METHOD']==="POST"){
$list = file_get_contents("php://input");
}else{
if (isset($_GET['ip'])){
$list = $_GET['ip'];
}else{
$list = $_SERVER['SERVER_ADDR'];
}
}
$ips = explode(',',$list);
// allow CORS
header('Access-Control-Allow-Origin: *');
switch($cmd){
case "ports":
print(getports());
break;
case "write":
// write
// use get and post requests
write_config($config,$ips);
print("ok");
break;
case "read":
default:
// will never need read - config is in http://camip/var/multicam.xml
// read
print(file_get_contents($config));
}
function write_config($config,$ips){
$list = "";
foreach($ips as $ip){
$list .= "\t<camera>$ip</camera>\n";
}
$xml = "<?xml version='1.0' standalone='yes'?>\n";
$xml .= "<Document>\n";
$xml .= $list;
$xml .= "</Document>\n";
file_put_contents($config,$xml);
return 0;
}
function getports(){
global $nports, $portspath, $port0;
$res = "\t<camera ip='".$_SERVER['SERVER_ADDR']."'>\n";
for($i=0;$i<$nports;$i++){
$sensor = $portspath."/sensor{$i}0";
// the file is always there actually
if(is_file($sensor)){
$c = trim(file_get_contents($sensor));
$p = $port0+$i;
$res .= "\t\t<port index='$i' port='$p'>$c</port>\n";
}
}
$res .= "\t</camera>\n";
$xml = "<?xml version='1.0' standalone='yes'?>\n";
$xml .= "<Document>\n";
$xml .= $res;
$xml .= "</Document>\n";
return $xml;
}
?>
\ No newline at end of file
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