-1){
row[m]=b;
}
})
return row
}
function downloadMonitorConfigurationsToDisk(monitorIds){
var selectedMonitors = []
$.each(monitorIds,function(n,monitorId){
var monitor = monitorId instanceof Object ? monitorId : loadedMonitors[monitorId]
if(monitor)selectedMonitors.push(monitor)
})
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(selectedMonitors));
$('#temp').html('')
.find('a')
.attr('href',dataStr)
.attr('download',`${applicationName}_Monitors_${$user.ke}_${new Date()}.json`)
[0].click()
}
function importShinobiMonitor(monitor){
}
function importM3u8Playlist(textData){
var m3u8List = textData.replace('#EXTM3U','').trim().split('\n')
var parsedList = {}
var currentName
m3u8List.forEach(function(line){
if(line.indexOf('#EXTINF:-1,') > -1){
currentName = line.replace('#EXTINF:-1,','').trim()
}else{
parsedList[currentName] = line.trim()
}
})
$.each(parsedList,function(name,url){
var link = getUrlPieces(url)
var newMon = $.aM.generateDefaultMonitorSettings()
newMon.details = JSON.parse(newMon.details)
newMon.mid = 'HLS' + name.toLowerCase()
newMon.name = name
newMon.port = link.port
newMon.host = link.hostname
newMon.path = link.pathname
newMon.details.tv_channel = '1'
newMon.details.tv_channel_id = name
newMon.details.auto_host_enable = '1'
newMon.details.auto_host = url
newMon.details.stream_quality = '1'
newMon.details.stream_fps = ''
newMon.details.stream_vcodec = 'libx264'
newMon.details.stream_acodec = 'aac'
newMon.details.stream_type = 'hls'
newMon.details.hls_time = '10'
newMon.type = 'mp4'
newMon.details = JSON.stringify(newMon.details)
postMonitor(newMon)
})
}
function importZoneMinderMonitor(Monitor){
var newMon = generateDefaultMonitorSettings()
newMon.details = JSON.parse(newMon.details)
newMon.details.stream_type = 'jpeg'
switch(Monitor.Type.toLowerCase()){
case'ffmpeg':case'libvlc':
newMon.details.auto_host_enable = '1'
newMon.details.auto_host = Monitor.Path
if(newMon.auto_host.indexOf('rtsp://') > -1 || newMon.auto_host.indexOf('rtmp://') > -1 || newMon.auto_host.indexOf('rtmps://') > -1){
newMon.type = 'h264'
}else{
$.ccio.init('note',{title:lang['Please Check Your Settings'],text:lang.migrateText1,type:'error'})
}
break;
case'local':
newMon.details.auto_host = Monitor.Device
break;
case'remote':
break;
}
newMon.details = JSON.stringify(newMon.details)
return newMon
}
function importMonitor(textData){
try{
var parsedData = textData instanceof Object ? textData : safeJsonParse(textData)
function postMonitor(v){
var monitorId = v.mid
$.post(`${getApiPrefix('configureMonitor')}/${monitorId}`,{
data: JSON.stringify(v,null,3)
},function(d){
debugLog(d)
})
}
//zoneminder one monitor
if(parsedData.monitor){
postMonitor(importZoneMinderMonitor(parsedData.monitor.Monitor))
}else
//zoneminder multiple monitors
if(parsedData.monitors){
$.each(parsedData.monitors,function(n,v){
postMonitor(importZoneMinderMonitor(v.Monitor))
})
}else
//shinobi one monitor
if(parsedData.mid){
postMonitor(parsedData)
}else
//shinobi multiple monitors
if(parsedData[0] && parsedData[0].mid){
$.each(parsedData,function(n,v){
postMonitor(v)
})
}
}catch(err){
//#EXTM3U
if(textData instanceof String && textData.indexOf('#EXTM3U') > -1 && textData.indexOf('{"') === -1){
importM3u8Playlist(textData)
}else{
debugLog(err)
new PNotify({
title: lang['Invalid JSON'],
text: lang.InvalidJSONText,
type: 'error'
})
}
}
}
function deleteMonitors(monitorsSelected,afterDelete){
$.confirm.create({
title: lang['Delete']+' '+lang['Monitors'],
body: ''+lang.DeleteMonitorsText+'
',
clickOptions: [
{
title:lang['Delete']+' '+lang['Monitors'],
class:'btn-danger',
callback:function(){
$.each(monitorsSelected,function(n,monitor){
$.get(`${getApiPrefix(`configureMonitor`)}/${monitor.mid}/delete`,function(data){
console.log(data)
if(monitorsSelected.length === n + 1){
//last
if(afterDelete)afterDelete(monitorsSelected)
}
})
})
}
},
{
title:lang['Delete Monitors and Files'],
class:'btn-danger',
callback:function(){
$.each(monitorsSelected,function(n,monitor){
$.get(`${getApiPrefix(`configureMonitor`)}/${monitor.mid}/delete?deleteFiles=true`,function(data){
console.log(data)
if(monitorsSelected.length === n + 1){
//last
if(afterDelete)afterDelete(monitorsSelected)
}
})
})
}
}
]
})
}
function launchImportMonitorWindow(callback){
var html = `${lang.ImportMultiMonitorConfigurationText}
`
$.confirm.create({
title: lang['Import Monitor Configuration'],
body: html,
clickOptions: [
{
title: lang['Import'],
class: 'btn-primary',
callback: function(){
var textData = safeJsonParse($.confirm.e.find('textarea').val())
if(callback){
callback(textData)
}else{
importMonitor(textData)
}
}
},
// {
// title: lang['Upload'],
// class: 'btn-primary',
// callback: function(e){
// var files = e.target.files; // FileList object
// f = files[0];
// var reader = new FileReader();
// reader.onload = function(ee) {
// $.confirm.e.find('textarea').val(ee.target.result);
// }
// reader.readAsText(f);
// }
// }
],
})
$.confirm.e.find('.upload').change(function(e){
var files = e.target.files; // FileList object
f = files[0];
var reader = new FileReader();
reader.onload = function(ee) {
$.confirm.e.find('textarea').val(ee.target.result);
}
reader.readAsText(f);
});
}
function drawMatrices(event,options){
var theContainer = options.theContainer
var height = options.height
var width = options.width
var widthRatio = width / event.details.imgWidth
var heightRatio = height / event.details.imgHeight
var objectTagGroup = event.details.reason === 'motion' ? 'motion' : event.details.name
theContainer.find(`.stream-detected-object[name="${objectTagGroup}"]`).remove()
var html = ''
$.each(event.details.matrices,function(n,matrix){
html += ``
if(matrix.tag)html += `${matrix.tag}`
html += '
'
})
theContainer.append(html)
}
function setMonitorCountOnUI(){
$('.cameraCount').text(Object.keys(loadedMonitors).length)
}
function muteMonitorAudio(monitorId,buttonEl){
var masterMute = dashboardOptions().switches.monitorMuteAudio
var monitorMutes = dashboardOptions().monitorMutes || {}
monitorMutes[monitorId] = monitorMutes[monitorId] === 1 ? 0 : 1
dashboardOptions('monitorMutes',monitorMutes)
var vidEl = $('.monitor_item[data-mid="' + monitorId + '"] video')[0]
try{
if(monitorMutes[monitorId] === 1){
vidEl.muted = true
}else{
if(masterMute !== 1){
if(windowFocus && hadFocus){
vidEl.muted = false
}else{
console.error('User must have window active to unmute.')
}
}
}
}catch(err){
console.log(err)
}
var volumeIcon = monitorMutes[monitorId] !== 1 ? 'volume-up' : 'volume-off'
if(buttonEl)buttonEl.find('i').removeClass('fa-volume-up fa-volume-off').addClass('fa-' + volumeIcon)
}
function getAvailableMonitorGroups(){
var theGroups = {}
$.each(loadedMonitors,function(n,monitor){
var monitorsGroups = safeJsonParse(monitor.details.groups)
$.each(monitorsGroups,function(m,groupId){
if(!theGroups[groupId])theGroups[groupId]={}
theGroups[groupId][monitor.mid] = monitor
})
})
availableMonitorGroups = theGroups
return theGroups;
}
function drawMonitorGroupList(){
var html = ''
getAvailableMonitorGroups()
$.each(availableMonitorGroups,function(groupId,v){
if($user.mon_groups[groupId]){
html += `${$user.mon_groups[groupId].name}`
}
})
monitorGroupSelections.html(html)
}
function loadMonitorGroup(groupId){
$.each(dashboardOptions().watch_on,function(groupKey,groupData){
$.each(groupData,function(monitorId,isOn){
if(isOn)mainSocket.f({
f: 'monitor',
ff: 'watch_off',
id: monitorId,
ke: $user.ke
})
})
})
$.each(availableMonitorGroups[groupId],function(n,monitor){
mainSocket.f({
f: 'monitor',
ff: 'watch_on',
id: monitor.mid,
ke: $user.ke
})
})
}
function buildDefaultMonitorMenuItems(){
return `
${lang['Live Grid']}
${lang['Pop']}
${lang['Toggle Substream']}
${lang['Videos List']}
${lang['Time-lapse']}
${lang['Monitor Settings']}
${lang['Export']}
${lang['Set Mode']}
${lang.Disable}
${lang['Watch-Only']}
${lang.Record}`
}
function magnifyStream(options){
if(!options.p && !options.parent){
var el = $(this),
parent = el.parents('[mid]')
}else{
parent = options.p || options.parent
}
if(!options.attribute){
options.attribute = ''
}
if(options.animate === true){
var zoomGlassAnimate = 'animate'
}else{
var zoomGlassAnimate = 'css'
}
if(!options.magnifyOffsetElement){
options.magnifyOffsetElement = '.stream-block'
}
if(!options.targetForZoom){
options.targetForZoom = '.stream-element'
}
if(options.auto === true){
var streamBlockOperator = 'position'
}else{
var streamBlockOperator = 'offset'
}
var magnifiedElement
if(!options.videoUrl){
if(options.useCanvas === true){
magnifiedElement = 'canvas'
}else{
magnifiedElement = 'iframe'
}
}else{
magnifiedElement = 'video'
}
if(!options.mon && !options.monitor){
var groupKey = parent.attr('ke')//group key
var monitorId = parent.attr('mid')//monitor id
var sessionKey = parent.attr('auth')//authkey
var monitor = $.ccio.mon[groupKey + monitorId + sessionKey]//monitor configuration
}else{
var monitor = options.mon || options.monitor
var groupKey = monitor.ke//group key
var monitorId = monitor.mid//monitor id
var sessionKey = monitor.auth//authkey
}
if(options.zoomAmount)zoomAmount = 3
if(!zoomAmount)zoomAmount = 3
var realHeight = parent.attr('realHeight')
var realWidth = parent.attr('realWidth')
var height = parseFloat(realHeight) * zoomAmount//height of stream
var width = parseFloat(realWidth) * zoomAmount//width of stream
var targetForZoom = parent.find(options.targetForZoom)
zoomGlass = parent.find(".zoomGlass")
var zoomFrame = function(){
var magnify_offset = parent.find(options.magnifyOffsetElement)[streamBlockOperator]()
var mx = options.pageX - magnify_offset.left
var my = options.pageY - magnify_offset.top
var rx = Math.round(mx/targetForZoom.width()*width - zoomGlass.width()/2)*-1
var ry = Math.round(my/targetForZoom.height()*height - zoomGlass.height()/2)*-1
var px = mx - zoomGlass.width()/2
var py = my - zoomGlass.height()/2
zoomGlass[zoomGlassAnimate]({left: px, top: py}).find(magnifiedElement)[zoomGlassAnimate]({left: rx, top: ry})
}
var commit = function(height,width){
zoomGlass.find(magnifiedElement).css({
height: height,
width: width
})
zoomFrame()
}
if(!height || !width || zoomGlass.length === 0){
zoomGlass = parent.find(".zoomGlass")
var zoomGlassShell = function(contents){return `${contents}
`}
if(!options.videoUrl){
$.ccio.snapshot(monitor,function(url,buffer,w,h){
parent.attr('realWidth',w)
parent.attr('realHeight',h)
if(zoomGlass.length === 0){
if(options.useCanvas === true){
parent.append(zoomGlassShell(''))
}else{
parent.append(zoomGlassShell(''))
}
zoomGlass = parent.find(".zoomGlass")
}
commit(h,w)
})
}else{
if(zoomGlass.length === 0){
parent.append(zoomGlassShell(``))
}
if(options.setTime){
var video = zoomGlass.find('video')[0]
video.currentTime = options.setTime
height = video.videoHeight
width = video.videoWidth
parent.attr('realWidth',width)
parent.attr('realHeight',height)
}
commit(height,width)
}
}else{
if(options.setTime){
var video = zoomGlass.find('video')
var src = video.attr('src')
video[0].currentTime = options.setTime
if(options.videoUrl !== src)zoomGlass.html(``)
}
commit(height,width)
}
}
$(document).ready(function(){
$('body')
.on('click','[system]',function(){
var e = {};
var el = $(this)
switch(el.attr('system')){
case'monitorMuteAudioSingle':
var monitorId = el.attr('mid')
muteMonitorAudio(monitorId,el)
break;
}
})
.on('click','[shinobi-switch]',function(){
var el = $(this)
var systemSwitch = el.attr('shinobi-switch');
dashboardSwitch(systemSwitch)
})
monitorGroupSelections
.on('click','[monitor-group]',function(){
var groupId = $(this).attr('monitor-group');
loadMonitorGroup(groupId)
openLiveGrid()
})
})