/** * Speed of pan and tilt * @type {number} 0 - 3F (hex) / 63 (dec) */ let pan_speed = 20; let tilt_speed = 20; let video_quality = "LQ"; /** * @type {WebSocket} */ let ws; let camerastream; // socketio let socketio; let files = [null,null,null,null,null]; let getbase64handle; let getsysteminfohandle; let $zoom; let $mute; let $unmute; window.addEventListener("unload",function (){ clearInterval(getbase64handle); clearInterval(getsysteminfohandle); send_stop_audio(); // wait a while const start = Date.now(); while(Date.now()-start<200){} ws.close(); }) window.addEventListener("load", function (){ $zoom = $('#zoom'); $mute = $('#mute'); $unmute = $('#unmute'); camerastream = document.getElementById("camerastream"); // pilihan komunikasi, disable salah satu initialize_socketio(); //initialize_websocket(); // Update camera stream every 50ms / 20fps getbase64handle = setInterval(function (){ send_get_base64(); },1000/15); getsysteminfohandle = setInterval(function (){ send_get_system_info(); }, 5000); set_pan_speed(32); set_tilt_speed(32); }) function initialize_socketio(){ socketio = io(":3001/socketio"); if (socketio){ socketio.on("connect",()=>{ console.log("Socket.io Connected to the server"); send_get_max_zoom(); send_get_volume(); send_get_zoom(); send_get_resolution(); send_get_audiofiles(); }) socketio.on("disconnect",(reason)=>{ console.log("Socket.io Disconnected from server because "+reason); }) socketio.on("connect_error",(error)=>{ console.log("Socket.io Connection error "+error); }); socketio.on("message",(data)=>{ let dx = JSON.parse(data); process_command(dx); }); } } function initialize_websocket(){ ws = new WebSocket("/ws"); if (ws){ ws.onopen = function(){ console.log("Connected to the server"); // request basic parameters send_get_max_zoom(); send_get_volume(); send_get_zoom(); send_get_resolution(); send_get_audiofiles(); } ws.onmessage = function(event){ //console.log("Received data from server: " + event.data); /** * @type {{reply: string, data: string|number, additional: string}} dx */ let dx = JSON.parse(event.data); process_command(dx); } ws.onclose = function(){ console.log("Connection closed"); } ws.onerror = function(){ console.log("Error in connection"); } } } /** * Update camera stream * @param {String} value */ function update_camerastream(value){ if (camerastream){ if (value && value.length>0){ camerastream.src = value; } else { if (camerastream.src!== "public/images/not-available.png") camerastream.src = "public/images/not-available.png"; } } } /** * Disable play button * @param index 1 - 5 */ function play_off(index){ $('#div'+index).prop("className", "button-container div-disabled"); $('#btn_play'+index) .prop("className", "btn-play1 show text-light"); } /** * Enable play button * @param index 1 - 5 */ function play_on(index){ let content = $('#desc_content'+index).html(); $('#div'+index).prop("className", "button-container"); $('#btn_play'+index) .prop("className", "btn-play1 show") .prop("title","Play "+content); $('#btn_stop'+index) .prop("title","Stop "+content); } /** * Show play button and hide stop button * @param index 1 - 5 */ function show_play_and_hide_stop(index){ $('#btn_play'+index).prop("className", "btn-play1 show"); $('#btn_stop'+index).prop("className", "btn-play1 hide"); } /** * Show stop button and hide play button * @param index 1 - 5 */ function show_stop_and_hide_play(index){ $('#btn_play'+index).prop("className", "btn-play1 hide"); $('#btn_stop'+index).prop("className", "btn-play1 show"); } /** * Enable all play buttons */ function allplay(){ for (let i = 0; i < 5; i++) { if (files[i]) play_on(i+1); } } /** * When play button is clicked * @param index 1 - 5 */ function play_button(index){ show_stop_and_hide_play(index); $('#status_player').html("Play"); for (let i = 1; i <= 5; i++){ if (i!==index) play_off(i); } send_play_audio(index); } /** * When stop button is clicked * @param index 1 - 5 */ function stop_button(index){ show_play_and_hide_stop(index); $('#status_player').html("Stop"); allplay(); send_stop_audio(); } function send_get_audiofiles(){ let cmd = JSON.stringify({ command: "GET AUDIOFILES", data: 0 }); if (ws){ if (ws.readyState===WebSocket.OPEN){ ws.send(cmd) } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_get_resolution(){ let cmd = JSON.stringify({ command: "GET RESOLUTION", data: 0 }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_get_zoom(){ let cmd = JSON.stringify({ command: "GET ZOOM", data: 0 }); if (ws){ if (ws.readyState===WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_get_volume(){ let cmd = JSON.stringify({ command: "GET VOLUME", data: 0 }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_get_max_zoom(){ let cmd = JSON.stringify({ command: "GET MAX ZOOM", data: 0 }); if (ws){ if (ws && ws.readyState===WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_get_system_info(){ let cmd = JSON.stringify({ command: "GET SYSTEM INFO", data: 0 }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } /** * Send command to stop audio */ function send_stop_audio(){ let cmd = JSON.stringify({ command: "STOP AUDIO", data: 0 }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_get_base64(){ let cmd = JSON.stringify({ command: "GET BASE64", data: video_quality }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); return; } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); return; } else console.log("Socket.io is not connected"); } update_camerastream(null); } /** * Send command to play audio * @param {number} index 1 - 5 */ function send_play_audio(index){ let cmd = JSON.stringify({ command: "PLAY AUDIO", data: index }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_unmute(){ let cmd = JSON.stringify({ command: "UNMUTE", data: 0 }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_mute(){ let cmd = JSON.stringify({ command: "MUTE", data: 0 }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_tilt_up(){ let cmd = JSON.stringify({ command: "TILT UP", data: tilt_speed }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); btn_center_off() } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); btn_center_off() } else console.log("Socket.io is not connected"); } } function send_tilt_down(){ let cmd = JSON.stringify({ command: "TILT DOWN", data: tilt_speed }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); btn_center_off() } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); btn_center_off() } else console.log("Socket.io is not connected"); } } function send_pan_left(){ let cmd = JSON.stringify({ command: "PAN LEFT", data: pan_speed }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); btn_center_off(); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); btn_center_off(); } else console.log("Socket.io is not connected"); } } function send_pan_right(){ let cmd = JSON.stringify({ command: "PAN RIGHT", data: pan_speed }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); btn_center_off() } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); btn_center_off() } else console.log("Socket.io is not connected"); } } function send_stop_movement(){ let cmd = JSON.stringify({ command: "STOP MOVEMENT", data: 0 }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_set_zoom(value){ let cmd = JSON.stringify({ command: "SET ZOOM", data: value }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function send_set_volume(value){ let cmd = JSON.stringify({ command: "SET VOLUME", data: value }); if (ws){ if (ws.readyState === WebSocket.OPEN){ ws.send(cmd); } else console.log("WebSocket is not open"); } else if (socketio){ if (socketio.connected){ socketio.emit("message",cmd); } else console.log("Socket.io is not connected"); } } function btn_center_off(){ $('#btn_center').prop("className", "btn-center-unactive fa-solid fa-circle"); } function set_zoom(){ send_set_zoom($('#zoom').val()); } function set_volumeoutput(value){ $('#volumebarvalue').val(value); send_set_volume(value); } function set_pan_speed(value){ pan_speed = value; clearpan(); let classvalue = "btn btn-dark btn-sm"; switch(pan_speed){ case 16: $('#pan1').prop("className", classvalue ); break; case 32: $('#pan2').prop("className", classvalue); break; case 48: $('#pan3').prop("className", classvalue); break; case 63: $('#pan4').prop("className", classvalue); break; } } function set_tilt_speed(value){ tilt_speed = value; cleartilt(); let classvalue = "btn btn-dark btn-sm"; switch (tilt_speed){ case 16: $('#tilt1').prop("className", classvalue); break; case 32: $('#tilt2').prop("className", classvalue); break; case 48: $('#tilt3').prop("className", classvalue); break; case 63: $('#tilt4').prop("className", classvalue); break; } } // Pan Tilt Speed function clearpan(){ for(let i = 1; i <= 4; i++){ $('#pan'+i).prop("className", "btn btn-outline-dark btn-sm"); } } function cleartilt(){ for(let i = 1; i <= 4; i++){ $('#tilt'+i).prop("className", "btn btn-outline-dark btn-sm"); } } function change_video_quality(){ let btn = document.getElementById("quality_video") video_quality = btn.checked?"HQ":"LQ"; } /** * Process Command * @param {{reply: string, data: string, additional: string}}dx */ function process_command(dx){ switch (dx.reply){ case "GET BASE64": if (dx.data.startsWith("data:image/jpeg;base64,")){ update_camerastream(dx.data); } else update_camerastream(null); if (dx.additional && dx.additional.length>0){ let stat = JSON.parse(dx.additional); if (Array.isArray(stat) && stat.length === 3){ $('#streaming_status').html("Streaming at "+stat[0]+"x"+stat[1]+" "+stat[2]+"fps"); } } break; case "SET VOLUME": //console.log("Set Volume: "+dx.data); break; case "GET VOLUME": //console.log("Get Volume: "+dx.data); $('#customRange').val(dx.data); break; case "GET MAX ZOOM": $zoom .prop("min", 1) .prop("max", dx.data); break; case "GET ZOOM": $zoom.val(dx.data); break; case "GET RESOLUTION": //console.log("Get Resolution: "+dx.data); break; case "PAN LEFT": //console.log("Pan Left"); break; case "PAN RIGHT": //console.log("Pan Right"); break; case "TILT UP": //console.log("Tilt Up"); break; case "TILT DOWN": //console.log("Tilt Down"); break; case "STOP MOVEMENT": //console.log("Stop Movement"); break; case "SET ZOOM": //console.log("Set Zoom: "+dx.data); break; case "PLAY AUDIO": //console.log("Play Audio: "+dx.data); if (dx.data.startsWith("Failed")){ alert(dx.data); } else $('#status_player').html("Playing Audio "+dx.data); break; case "STOP AUDIO": //console.log("Stop Audio"); document.getElementById("status_player").innerHTML = "Stop Playback"; break; case 'SET VIDEO QUALITY': //console.log("Set Video Quality: "+dx.data); break; case "MUTE": //console.log("Mute"); $mute.prop("className", "btn-mute hide"); $unmute.prop("className", "btn-mute show"); break; case "UNMUTE": //console.log("Unmute"); $mute.prop("className", "btn-mute show"); $unmute.prop("className", "btn-mute hide"); break; case "GET SYSTEM INFO": //console.log("Get System Info: "+dx.data); /** * @type {{cpu_temperature: string, ram_usage: string, cpu: string, cpu0: string, cpu1: string, cpu2: string, cpu3: string}} systeminfo */ let systeminfo = JSON.parse(dx.data); if (systeminfo.cpu_temperature && systeminfo.cpu_temperature.length>0) $('#cpu_temperature').html(`${systeminfo.cpu_temperature} °C`); if (systeminfo.cpu && systeminfo.cpu.length>0) $('#cpu_usage').html(`${systeminfo.cpu} %`); if (systeminfo.ram_usage && systeminfo.ram_usage.length>0) $('#ram_usage').html(`${systeminfo.ram_usage} %`); if (systeminfo.end0_TX && systeminfo.end0_TX.length>0) $('#ethernet_TX').html(systeminfo.end0_TX); if (systeminfo.end0_RX && systeminfo.end0_RX.length>0) $('#ethernet_RX').html(systeminfo.end0_RX); break; case "GET AUDIOFILES": //console.log("Get Audio Files: "+dx.data); let audiofiles = JSON.parse(dx.data); if (audiofiles.preset1 && audiofiles.preset1.length>0 && audiofiles.preset1!== "null") { files[0] = audiofiles.preset1; $('#desc_content1').html(audiofiles.preset1); play_on(1); } else { files[0] = null; $('#desc_content1').html(""); play_off(1); } if (audiofiles.preset2 && audiofiles.preset2.length>0 && audiofiles.preset2!== "null") { files[1] = audiofiles.preset2; $('#desc_content2').html(audiofiles.preset2); play_on(2); } else { files[1] = null; $('#desc_content2').html(""); play_off(2); } if (audiofiles.preset3 && audiofiles.preset3.length>0 && audiofiles.preset3!== "null") { files[2] = audiofiles.preset3; $('#desc_content3').html(audiofiles.preset3); play_on(3); } else { files[2] = null; $('#desc_content3').html(""); play_off(3); } if (audiofiles.preset4 && audiofiles.preset4.length>0 && audiofiles.preset4!== "null") { files[3] = audiofiles.preset4; $('#desc_content4').html(audiofiles.preset4); play_on(4); } else { files[3] = null; $('#desc_content4').html(""); play_off(4); } if (audiofiles.preset5 && audiofiles.preset5.length>0 && audiofiles.preset5!== "null") { files[4] = audiofiles.preset5; $('#desc_content5').html(audiofiles.preset5); play_on(5); } else { files[4] = null; $('#desc_content5').html(""); play_off(5); } break; } }