Add GamePad support for Live Grid
parent
081c106b42
commit
7cd0d10066
|
@ -125,6 +125,13 @@ module.exports = function(s,config,lang){
|
|||
"fieldType": "select",
|
||||
"possible": s.listOfStorage
|
||||
},
|
||||
{
|
||||
"name": "detail=ptz_id",
|
||||
"field": lang["PTZ Control ID"],
|
||||
"example": "1",
|
||||
"form-group-class": "h_c_input h_c_1",
|
||||
"description": lang["ptzControlIdFieldText"],
|
||||
},
|
||||
{
|
||||
"name": "detail=auto_compress_videos",
|
||||
"field": lang['Compress Completed Videos'],
|
||||
|
|
|
@ -136,6 +136,8 @@
|
|||
"Google Drive": "Google Drive",
|
||||
"Invert Y-Axis": "Invert Y-Axis",
|
||||
"Get Code": "Get Code",
|
||||
"PTZ Control ID": "PTZ Control ID",
|
||||
"ptzControlIdFieldText": "When using a Control Stick or GamePad you can choose an available number to use.",
|
||||
"PTZ Tracking": "PTZ Tracking",
|
||||
"PTZ Tracking Target": "PTZ Tracking Target",
|
||||
"Event Counts": "Event Counts",
|
||||
|
|
|
@ -0,0 +1,369 @@
|
|||
$(document).ready(function() {
|
||||
var selectedController = 0;
|
||||
var keyLegend = {
|
||||
"0": "b",
|
||||
"1": "a",
|
||||
"2": "y",
|
||||
"3": "x",
|
||||
"4": "l",
|
||||
"5": "r",
|
||||
"6": "zl",
|
||||
"7": "zr",
|
||||
"8": "minus",
|
||||
"9": "plus",
|
||||
"10": "l_stick",
|
||||
"11": "r_stick",
|
||||
"12": "up",
|
||||
"13": "down",
|
||||
"14": "left",
|
||||
"15": "right",
|
||||
}
|
||||
var lastState = {
|
||||
sticks: {
|
||||
left: {},
|
||||
right: {},
|
||||
}
|
||||
}
|
||||
var lastPtzDirection = {}
|
||||
var buttonsPressed = {}
|
||||
var hasGP = false;
|
||||
var repGP;
|
||||
var stickBase = 2048
|
||||
var stickMax = 4096
|
||||
var deadZoneThreshold = 0.35
|
||||
var outerDeadZone = 1.01
|
||||
var selectedMonitor = dashboardOptions().gamepadMonitorSelection;
|
||||
var monitorKeys = {};
|
||||
var gp = null;
|
||||
var onMonitorOpenForGamepad = () => {}
|
||||
window.setGamepadMonitorSelection = (monitorId) => {
|
||||
dashboardOptions('gamepadMonitorSelection', monitorId);
|
||||
selectedMonitor = `${monitorId}`;
|
||||
}
|
||||
|
||||
function canGame() {
|
||||
return "getGamepads" in navigator;
|
||||
}
|
||||
|
||||
function convertStickAxisTo2048(value){
|
||||
var newVal = parseInt((stickMax - stickBase) * value + stickBase)
|
||||
return newVal
|
||||
}
|
||||
|
||||
function getAnalogStickValues(gp, i, callback){
|
||||
var label = i === 0 ? 'left' : 'right'
|
||||
var horizontal = gp.axes[i] * outerDeadZone
|
||||
var vertical = gp.axes[i + 1] * outerDeadZone
|
||||
var newH = convertStickAxisTo2048(horizontal > deadZoneThreshold || horizontal < -deadZoneThreshold ? horizontal : 0)
|
||||
var newV = convertStickAxisTo2048((vertical > deadZoneThreshold || vertical < -deadZoneThreshold ? vertical : 0) * -1)
|
||||
if(
|
||||
newH !== lastState.sticks[label].h ||
|
||||
newV !== lastState.sticks[label].v
|
||||
){
|
||||
callback(label, newH, newV)
|
||||
}
|
||||
lastState.sticks[label].h = newH
|
||||
lastState.sticks[label].v = newV
|
||||
}
|
||||
|
||||
function getStickValue(gp, i, callback){
|
||||
var label = `axis${axis}`;
|
||||
var axis = gp.axes[i] * outerDeadZone
|
||||
var newH = convertStickAxisTo2048(axis > deadZoneThreshold || axis < -deadZoneThreshold ? axis : 0)
|
||||
if(newH !== lastState[label]){
|
||||
callback(newH)
|
||||
}
|
||||
lastState[label] = newH
|
||||
}
|
||||
|
||||
function getButtonsPressed(gp, callback, offCallback = () => {}){
|
||||
$.each(keyLegend,function(code,key){
|
||||
if(gp.buttons[code] && gp.buttons[code].pressed){
|
||||
if(!lastState[key]){
|
||||
buttonsPressed[code] = true;
|
||||
callback(code)
|
||||
}
|
||||
lastState[key] = true
|
||||
}else{
|
||||
if(lastState[key]){
|
||||
buttonsPressed[code] = false;
|
||||
offCallback(code)
|
||||
}
|
||||
lastState[key] = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function setCameraFromButtonCode(buttonCode){
|
||||
try{
|
||||
const addedOneToButtonCode = parseInt(buttonCode) + 1
|
||||
const monitor = loadedMonitors[monitorKeys[addedOneToButtonCode]];
|
||||
const isFullscreened = !!document.fullscreenElement;
|
||||
if(isFullscreened) {
|
||||
document.exitFullscreen()
|
||||
closeAllLiveGridPlayers(true)
|
||||
}
|
||||
openMonitorInLiveGrid(monitor.mid, function(){
|
||||
if(isFullscreened) {
|
||||
fullScreenLiveGridStreamById(monitor.mid)
|
||||
}
|
||||
})
|
||||
|
||||
}catch(err){
|
||||
console.log('No Monitor Associated :', buttonCode)
|
||||
}
|
||||
}
|
||||
|
||||
// function setCameraFromButtonNumbers(){
|
||||
// const buttons = Object.keys(buttonsPressed).filter(code => buttonsPressed[code]);
|
||||
// console.log('pressed', buttons)
|
||||
// if(buttons.length > 1){
|
||||
//
|
||||
// }else if(buttons.length > 0){
|
||||
// const monitor = loadedMonitors[monitorKeys[buttons[0]]];
|
||||
// console.log(monitorKeys[buttons[0]])
|
||||
// openMonitorInLiveGrid(monitor.mid)
|
||||
// }
|
||||
// }
|
||||
|
||||
function openMonitorInLiveGrid(monitorId, callback){
|
||||
lastPtzDirection = {};
|
||||
setGamepadMonitorSelection(monitorId)
|
||||
mainSocket.f({
|
||||
f: 'monitor',
|
||||
ff: 'watch_on',
|
||||
id: monitorId
|
||||
})
|
||||
onMonitorOpenForGamepad = (monitorId) => {
|
||||
setTimeout(() => {
|
||||
if(monitorId === selectedMonitor){
|
||||
onMonitorOpenForGamepad = () => {}
|
||||
if(callback)callback()
|
||||
}
|
||||
}, 200)
|
||||
}
|
||||
}
|
||||
|
||||
function sendPtzCommand(direction, doMove){
|
||||
runPtzMove(selectedMonitor, direction, doMove)
|
||||
}
|
||||
|
||||
function sentPtzToHome(){
|
||||
runPtzCommand(selectedMonitor, 'center')
|
||||
}
|
||||
|
||||
function translatePointTiltStick(x, y){
|
||||
if(x > stickBase && !lastPtzDirection['right']){
|
||||
lastPtzDirection['right'] = true
|
||||
lastPtzDirection['left'] = false
|
||||
// sendPtzCommand('left', false)
|
||||
sendPtzCommand('right', true)
|
||||
}else if(x < stickBase && !lastPtzDirection['left']){
|
||||
lastPtzDirection['left'] = true
|
||||
lastPtzDirection['right'] = false
|
||||
// sendPtzCommand('right', false)
|
||||
sendPtzCommand('left', true)
|
||||
}else if(x === stickBase){
|
||||
if(lastPtzDirection['right'])sendPtzCommand('right', false)
|
||||
if(lastPtzDirection['left'])sendPtzCommand('left', false)
|
||||
lastPtzDirection['right'] = false
|
||||
lastPtzDirection['left'] = false
|
||||
}
|
||||
if(y > stickBase && !lastPtzDirection['up']){
|
||||
lastPtzDirection['up'] = true
|
||||
lastPtzDirection['down'] = false
|
||||
// sendPtzCommand('down', false)
|
||||
sendPtzCommand('up', true)
|
||||
}else if(y < stickBase && !lastPtzDirection['down']){
|
||||
lastPtzDirection['down'] = true
|
||||
lastPtzDirection['up'] = false
|
||||
// sendPtzCommand('up', false)
|
||||
sendPtzCommand('down', true)
|
||||
}else if(y === stickBase){
|
||||
if(lastPtzDirection['up'])sendPtzCommand('up', false)
|
||||
if(lastPtzDirection['down'])sendPtzCommand('down', false)
|
||||
lastPtzDirection['down'] = false
|
||||
lastPtzDirection['up'] = false
|
||||
}
|
||||
console.log(lastPtzDirection)
|
||||
}
|
||||
|
||||
function translateZoomAxis(value){
|
||||
if(value > stickBase && !lastPtzDirection['zoom_in']){
|
||||
lastPtzDirection['zoom_in'] = true
|
||||
lastPtzDirection['zoom_out'] = false
|
||||
// sendPtzCommand('zoom_out', false)
|
||||
sendPtzCommand('zoom_in', true)
|
||||
}else if(value < stickBase && !lastPtzDirection['zoom_out']){
|
||||
lastPtzDirection['zoom_out'] = true
|
||||
lastPtzDirection['zoom_in'] = false
|
||||
// sendPtzCommand('zoom_in', false)
|
||||
sendPtzCommand('zoom_out', true)
|
||||
}else if(value === stickBase){
|
||||
if(lastPtzDirection['zoom_in'])sendPtzCommand('zoom_in', false)
|
||||
if(lastPtzDirection['zoom_out'])sendPtzCommand('zoom_out', false)
|
||||
lastPtzDirection['zoom_in'] = false
|
||||
lastPtzDirection['zoom_out'] = false
|
||||
}
|
||||
}
|
||||
|
||||
function reportOnXboxGamepad() {
|
||||
try{
|
||||
var gp = navigator.getGamepads()[0];
|
||||
getButtonsPressed(gp, function(buttonCode){
|
||||
if(buttonCode == 6){
|
||||
sendPtzCommand('zoom_out', true)
|
||||
}else if(buttonCode == 7){
|
||||
sendPtzCommand('zoom_in', true)
|
||||
}else if(buttonCode == 8){
|
||||
closeSnapshot()
|
||||
openSnapshot()
|
||||
}else if(buttonCode == 9){
|
||||
sentPtzToHome()
|
||||
}else if(buttonCode == 11){
|
||||
if (!document.fullscreenElement) {
|
||||
fullScreenLiveGridStreamById(selectedMonitor)
|
||||
}else{
|
||||
document.exitFullscreen()
|
||||
}
|
||||
}else{
|
||||
setCameraFromButtonCode(buttonCode)
|
||||
}
|
||||
}, function(buttonCode){
|
||||
if(buttonCode == 6){
|
||||
sendPtzCommand('zoom_out', false)
|
||||
}else if(buttonCode == 7){
|
||||
sendPtzCommand('zoom_in', false)
|
||||
}
|
||||
})
|
||||
getAnalogStickValues(gp, 0, function(stick, x, y){
|
||||
translatePointTiltStick(x, y)
|
||||
})
|
||||
getAnalogStickValues(gp, 2, function(stick, x, y){
|
||||
translateZoomAxis(y)
|
||||
})
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
// stopReporting()
|
||||
}
|
||||
}
|
||||
|
||||
function reportOnGenericGamepad() {
|
||||
try{
|
||||
const gp = navigator.getGamepads()[0];
|
||||
getButtonsPressed(gp, function(buttonCode){
|
||||
if(buttonCode == 10){
|
||||
closeSnapshot()
|
||||
}else if(buttonCode == 11){
|
||||
closeSnapshot()
|
||||
openSnapshot()
|
||||
}else{
|
||||
setCameraFromButtonCode(buttonCode)
|
||||
}
|
||||
},function(buttonCode){
|
||||
|
||||
})
|
||||
getStickValue(gp, 2,function(value){
|
||||
translateZoomAxis(value)
|
||||
})
|
||||
}catch(err){
|
||||
console.log(err)
|
||||
// stopReporting()
|
||||
}
|
||||
}
|
||||
|
||||
function openSnapshot(){
|
||||
if(!$.confirm.e.is(':visible')){
|
||||
getSnapshot(loadedMonitors[selectedMonitor],function(url){
|
||||
$.confirm.create({
|
||||
title: lang.Snapshot,
|
||||
body: `<img src="${url}">`,
|
||||
clickOptions: {
|
||||
class: 'btn-primary',
|
||||
title: lang.Close,
|
||||
},
|
||||
clickCallback: async function(){}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
function closeSnapshot(){
|
||||
$.confirm.e.modal('hide')
|
||||
}
|
||||
|
||||
var reportOnGamepad = reportOnXboxGamepad;
|
||||
|
||||
function startReporting(){
|
||||
if(hasGP){
|
||||
console.log('Reading Gamepad')
|
||||
var gp = navigator.getGamepads()[0];
|
||||
repGP = window.setInterval(reportOnGamepad,200);
|
||||
}
|
||||
}
|
||||
|
||||
function stopReporting(){
|
||||
console.log('Stopping Gamepad')
|
||||
window.clearInterval(repGP)
|
||||
}
|
||||
|
||||
function generateMonitorKeysFromPtzIds(){
|
||||
monitorKeys = []
|
||||
Object.values(loadedMonitors)
|
||||
.filter(item => !!parseInt(item.details.ptz_id))
|
||||
.sort((a, b) => parseInt(b.details.ptz_id) - parseInt(a.details.ptz_id))
|
||||
.forEach((item) => {
|
||||
console.log(item.details.ptz_id)
|
||||
monitorKeys[item.details.ptz_id] = item.mid;
|
||||
});
|
||||
console.log(monitorKeys)
|
||||
}
|
||||
|
||||
function setControllerType(gamepadId){
|
||||
switch(true){
|
||||
case gamepadId.includes('Xbox'):
|
||||
reportOnGamepad = reportOnXboxGamepad
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(canGame()) {
|
||||
$(window).on("gamepadconnected", function(e) {
|
||||
hasGP = true;
|
||||
if(tabTree.name === 'liveGrid'){
|
||||
startReporting()
|
||||
}
|
||||
const gamepadName = e.originalEvent.gamepad.id;
|
||||
setControllerType(gamepadName)
|
||||
console.log('Gamepad Connected!', gamepadName)
|
||||
})
|
||||
.on("gamepaddisconnected", function() {
|
||||
if(!navigator.getGamepads()[0]){
|
||||
hasGP = false;
|
||||
console.log('Gamepad Disconnected!')
|
||||
}
|
||||
})
|
||||
}
|
||||
onDashboardReady(function(d){
|
||||
generateMonitorKeysFromPtzIds();
|
||||
})
|
||||
onWebSocketEvent(function(d){
|
||||
switch(d.f){
|
||||
case'monitor_edit':
|
||||
generateMonitorKeysFromPtzIds();
|
||||
break;
|
||||
case'monitor_watch_on':
|
||||
var monitorId = d.mid || d.id;
|
||||
onMonitorOpenForGamepad(monitorId)
|
||||
break;
|
||||
}
|
||||
})
|
||||
addOnTabOpen('liveGrid', function () {
|
||||
startReporting()
|
||||
})
|
||||
addOnTabReopen('liveGrid', function () {
|
||||
startReporting()
|
||||
})
|
||||
addOnTabAway('liveGrid', function () {
|
||||
stopReporting()
|
||||
})
|
||||
});
|
|
@ -771,6 +771,10 @@ function fullScreenLiveGridStream(monitorItem){
|
|||
}
|
||||
fullScreenInit(videoElement[0])
|
||||
}
|
||||
function fullScreenLiveGridStreamById(monitorId){
|
||||
const monitorItem = liveGrid.find(`[data-mid="${monitorId}"]`)
|
||||
fullScreenLiveGridStream(monitorItem)
|
||||
}
|
||||
function toggleJpegMode(){
|
||||
var sendData = {
|
||||
f: 'monitor',
|
||||
|
@ -1099,6 +1103,7 @@ $(document).ready(function(e){
|
|||
.on('click','.toggle-live-grid-monitor-ptz-controls',function(){
|
||||
var monitorItem = $(this).parents('[data-mid]').attr('data-mid')
|
||||
drawPtzControlsOnLiveGridBlock(monitorItem)
|
||||
setGamepadMonitorSelection()
|
||||
})
|
||||
.on('click','.toggle-live-grid-monitor-menu,.mdl-overlay-menu-backdrop',function(){
|
||||
var monitorItem = $(this).parents('[data-mid]')
|
||||
|
@ -1112,6 +1117,7 @@ $(document).ready(function(e){
|
|||
.on('click','.toggle-live-grid-monitor-fullscreen',function(){
|
||||
var monitorItem = $(this).parents('[data-mid]')
|
||||
fullScreenLiveGridStream(monitorItem)
|
||||
setGamepadMonitorSelection()
|
||||
})
|
||||
.on('click','.run-live-grid-monitor-pop',function(){
|
||||
var monitorId = $(this).parents('[data-mid]').attr('data-mid')
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
<script src="<%-window.libURL%>assets/js/bs5.schedules.js"></script>
|
||||
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.js"></script>
|
||||
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.cycle.js"></script>
|
||||
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.gamepad.js"></script>
|
||||
<script src="<%-window.libURL%>assets/js/bs5.liveGrid.keyboard.js"></script>
|
||||
<script src="<%-window.libURL%>assets/js/bs5.regionEditor.js"></script>
|
||||
<script src="<%-window.libURL%>assets/js/bs5.timelapseViewer.js"></script>
|
||||
|
|
Loading…
Reference in New Issue