From 1e5ea4b3e97d5e61a63e68e49b83d1edcd466aaf Mon Sep 17 00:00:00 2001 From: Moe Date: Wed, 2 Jun 2021 13:11:36 -0700 Subject: [PATCH] make event video notification use last recorded video made by event --- libs/events/utils.js | 26 +++++++ libs/monitor.js | 122 +++++++++++++++++-------------- libs/notifications/discordBot.js | 29 ++++++-- libs/notifications/email.js | 26 +++++-- libs/notifications/telegram.js | 28 +++++-- 5 files changed, 158 insertions(+), 73 deletions(-) diff --git a/libs/events/utils.js b/libs/events/utils.js index d6a7a6e1..2b34c18d 100644 --- a/libs/events/utils.js +++ b/libs/events/utils.js @@ -416,6 +416,30 @@ module.exports = (s,config,lang,app,io) => { await extender(d,filter) } } + const getEventBasedRecordingUponCompletion = function(options){ + const response = {ok: true} + return new Promise((resolve,reject) => { + const groupKey = options.ke + const monitorId = options.mid + const activeMonitor = s.group[groupKey].activeMonitors[monitorId] + const eventBasedRecording = activeMonitor.eventBasedRecording + if(eventBasedRecording.process){ + const monitorConfig = s.group[groupKey].rawMonitorConfigurations[monitorId] + const recordingDirectory = s.getVideoDirectory(monitorConfig) + const fileTime = eventBasedRecording.lastFileTime + const filename = `${fileTime}.mp4` + response.filename = `${filename}` + response.filePath = `${recordingDirectory}${filename}` + eventBasedRecording.process.on('close',function(){ + setTimeout(() => { + resolve(response) + },1000) + }) + }else{ + resolve(response) + } + }) + } const createEventBasedRecording = function(d,fileTime){ if(!fileTime)fileTime = s.formattedTime() const logTitleText = lang["Traditional Recording"] @@ -443,6 +467,7 @@ module.exports = (s,config,lang,app,io) => { } if(!activeMonitor.eventBasedRecording.process){ activeMonitor.eventBasedRecording.allowEnd = false; + activeMonitor.eventBasedRecording.lastFileTime = `${fileTime}`; const runRecord = function(){ var ffmpegError = '' var error @@ -652,5 +677,6 @@ module.exports = (s,config,lang,app,io) => { legacyFilterEvents: legacyFilterEvents, triggerEvent: triggerEvent, addEventDetailsToString: addEventDetailsToString, + getEventBasedRecordingUponCompletion: getEventBasedRecordingUponCompletion, } } diff --git a/libs/monitor.js b/libs/monitor.js index d7034553..8c5d249a 100644 --- a/libs/monitor.js +++ b/libs/monitor.js @@ -285,67 +285,77 @@ module.exports = function(s,config,lang){ }) } s.mergeDetectorBufferChunks = function(monitor,callback){ - var pathDir = s.dir.streams+monitor.ke+'/'+monitor.id+'/' - var mergedFile = s.formattedTime()+'.mp4' - var mergedFilepath = pathDir+mergedFile - fs.readdir(pathDir,function(err,streamDirItems){ - var items = [] - var copiedItems = [] - var videoLength = s.group[monitor.ke].rawMonitorConfigurations[monitor.id].details.detector_send_video_length - if(!videoLength || videoLength === '')videoLength = '10' - if(videoLength.length === 1)videoLength = '0' + videoLength - var createMerged = function(copiedItems){ - var allts = pathDir+items.join('_') - s.fileStats(allts,function(err,stats){ - if(err){ - //not exist - var cat = 'cat '+copiedItems.join(' ')+' > '+allts - exec(cat,function(){ - var merger = spawn(config.ffmpegDir,splitForFFPMEG(('-re -i '+allts+' -acodec copy -vcodec copy -t 00:00:' + videoLength + ' '+pathDir+mergedFile))) - merger.stderr.on('data',function(data){ - s.userLog(monitor,{type:"Buffer Merge",msg:data.toString()}) - }) - merger.on('close',function(){ - s.file('delete',allts) - copiedItems.forEach(function(copiedItem){ - s.file('delete',copiedItem) + return new Promise((resolve,reject) => { + var pathDir = s.dir.streams+monitor.ke+'/'+monitor.id+'/' + var mergedFile = s.formattedTime()+'.mp4' + var mergedFilepath = pathDir+mergedFile + fs.readdir(pathDir,function(err,streamDirItems){ + var items = [] + var copiedItems = [] + var videoLength = s.group[monitor.ke].rawMonitorConfigurations[monitor.id].details.detector_send_video_length + if(!videoLength || videoLength === '')videoLength = '10' + if(videoLength.length === 1)videoLength = '0' + videoLength + var createMerged = function(copiedItems){ + var allts = pathDir+items.join('_') + s.fileStats(allts,function(err,stats){ + if(err){ + //not exist + var cat = 'cat '+copiedItems.join(' ')+' > '+allts + exec(cat,function(){ + var merger = spawn(config.ffmpegDir,splitForFFPMEG(('-re -i '+allts+' -acodec copy -vcodec copy -t 00:00:' + videoLength + ' '+pathDir+mergedFile))) + merger.stderr.on('data',function(data){ + s.userLog(monitor,{type:"Buffer Merge",msg:data.toString()}) + }) + merger.on('close',function(){ + s.file('delete',allts) + copiedItems.forEach(function(copiedItem){ + s.file('delete',copiedItem) + }) + setTimeout(function(){ + s.file('delete',mergedFilepath) + },1000 * 60 * 3) + delete(merger) + if(callback)callback(mergedFilepath,mergedFile) + resolve({ + filePath: mergedFilepath, + filename: mergedFile, + }) }) - setTimeout(function(){ - s.file('delete',mergedFilepath) - },1000 * 60 * 3) - delete(merger) - callback(mergedFilepath,mergedFile) }) - }) - }else{ - //file exist - callback(mergedFilepath,mergedFile) - } - }) - } - streamDirItems.forEach(function(filename){ - if(filename.indexOf('detectorStream') > -1 && filename.indexOf('.m3u8') === -1){ - items.push(filename) - } - }) - items.sort() - // items = items.slice(items.length - 5,items.length) - items.forEach(function(filename){ - try{ - var tempFilename = filename.split('.') - tempFilename[0] = tempFilename[0] + 'm' - tempFilename = tempFilename.join('.') - var tempWriteStream = fs.createWriteStream(pathDir+tempFilename) - tempWriteStream.on('finish', function(){ - copiedItems.push(pathDir+tempFilename) - if(copiedItems.length === items.length){ - createMerged(copiedItems.sort()) + }else{ + //file exist + if(callback)callback(mergedFilepath,mergedFile) + resolve({ + filePath: mergedFilepath, + filename: mergedFile, + }) } }) - fs.createReadStream(pathDir+filename).pipe(tempWriteStream) - }catch(err){ - } + streamDirItems.forEach(function(filename){ + if(filename.indexOf('detectorStream') > -1 && filename.indexOf('.m3u8') === -1){ + items.push(filename) + } + }) + items.sort() + // items = items.slice(items.length - 5,items.length) + items.forEach(function(filename){ + try{ + var tempFilename = filename.split('.') + tempFilename[0] = tempFilename[0] + 'm' + tempFilename = tempFilename.join('.') + var tempWriteStream = fs.createWriteStream(pathDir+tempFilename) + tempWriteStream.on('finish', function(){ + copiedItems.push(pathDir+tempFilename) + if(copiedItems.length === items.length){ + createMerged(copiedItems.sort()) + } + }) + fs.createReadStream(pathDir+filename).pipe(tempWriteStream) + }catch(err){ + + } + }) }) }) } diff --git a/libs/notifications/discordBot.js b/libs/notifications/discordBot.js index be45231a..0da09fc0 100644 --- a/libs/notifications/discordBot.js +++ b/libs/notifications/discordBot.js @@ -1,6 +1,9 @@ var fs = require("fs") var Discord = require("discord.js") module.exports = function(s,config,lang){ + const { + getEventBasedRecordingUponCompletion, + } = require('../events/utils.js')(s,config,lang) //discord bot if(config.discordBot === true){ try{ @@ -64,14 +67,28 @@ module.exports = function(s,config,lang){ s.group[d.ke].activeMonitors[d.id].detector_discordbot = null },detector_discordbot_timeout) if(monitorConfig.details.detector_discordbot_send_video === '1'){ - // change to function that captures on going video capture, waits, grabs new video file, slices portion (max for transmission) and prepares for delivery - s.mergeDetectorBufferChunks(d,function(mergedFilepath,filename){ + let videoPath = null + let videoName = null + const eventBasedRecording = await getEventBasedRecordingUponCompletion({ + ke: d.ke, + mid: d.mid + }) + if(eventBasedRecording.filePath){ + videoPath = eventBasedRecording.filePath + videoName = eventBasedRecording.filename + }else{ + const siftedVideoFileFromRam = await s.mergeDetectorBufferChunks(d) + videoPath = siftedVideoFileFromRam.filePath + videoName = siftedVideoFileFromRam.filename + } + console.log(videoPath,videoName) + if(videoPath){ sendMessage({ author: { name: s.group[d.ke].rawMonitorConfigurations[d.id].name, icon_url: config.iconURL }, - title: filename, + title: videoName, fields: [], timestamp: d.currentTime, footer: { @@ -80,11 +97,11 @@ module.exports = function(s,config,lang){ } },[ { - attachment: mergedFilepath, - name: filename + attachment: videoPath, + name: videoName } ],d.ke) - }) + } } d.screenshotBuffer = d.screenshotBuffer || d.frame if(!d.screenshotBuffer){ diff --git a/libs/notifications/email.js b/libs/notifications/email.js index e6e51ef5..6e9a32eb 100644 --- a/libs/notifications/email.js +++ b/libs/notifications/email.js @@ -4,6 +4,9 @@ const { checkEmail, } = require("./emailUtils.js") module.exports = function(s,config,lang){ + const { + getEventBasedRecordingUponCompletion, + } = require('../events/utils.js')(s,config,lang) // mailing with nodemailer try{ if(config.mail){ @@ -152,18 +155,31 @@ module.exports = function(s,config,lang){ }) } if(monitorConfig.details.detector_mail_send_video === '1'){ - // change to function that captures on going video capture, waits, grabs new video file, slices portion (max for transmission) and prepares for delivery - s.mergeDetectorBufferChunks(d,function(mergedFilepath,filename){ + let videoPath = null + let videoName = null + const eventBasedRecording = await getEventBasedRecordingUponCompletion({ + ke: d.ke, + mid: d.mid + }) + if(eventBasedRecording.filePath){ + videoPath = eventBasedRecording.filePath + videoName = eventBasedRecording.filename + }else{ + const siftedVideoFileFromRam = await s.mergeDetectorBufferChunks(d) + videoPath = siftedVideoFileFromRam.filePath + videoName = siftedVideoFileFromRam.filename + } + if(videoPath){ fs.readFile(mergedFilepath,function(err,buffer){ if(buffer){ sendMessage({ from: config.mail.from, to: checkEmail(r.mail), - subject: filename, + subject: videoName, html: '', attachments: [ { - filename: filename, + filename: videoName, content: buffer } ] @@ -175,7 +191,7 @@ module.exports = function(s,config,lang){ }) } }) - }) + } } d.screenshotBuffer = d.screenshotBuffer || d.frame if(!d.screenshotBuffer){ diff --git a/libs/notifications/telegram.js b/libs/notifications/telegram.js index 35af8f69..9dee149c 100644 --- a/libs/notifications/telegram.js +++ b/libs/notifications/telegram.js @@ -1,5 +1,8 @@ var fs = require("fs") module.exports = function(s,config,lang){ + const { + getEventBasedRecordingUponCompletion, + } = require('../events/utils.js')(s,config,lang) //telegram bot if(config.telegramBot === true){ const TelegramBot = require('node-telegram-bot-api'); @@ -58,18 +61,31 @@ module.exports = function(s,config,lang){ s.group[d.ke].activeMonitors[d.id].detector_telegrambot = null },detector_telegrambot_timeout) if(monitorConfig.details.detector_telegrambot_send_video === '1'){ - // change to function that captures on going video capture, waits, grabs new video file, slices portion (max for transmission) and prepares for delivery - s.mergeDetectorBufferChunks(d,function(mergedFilepath,filename){ + let videoPath = null + let videoName = null + const eventBasedRecording = await getEventBasedRecordingUponCompletion({ + ke: d.ke, + mid: d.mid + }) + if(eventBasedRecording.filePath){ + videoPath = eventBasedRecording.filePath + videoName = eventBasedRecording.filename + }else{ + const siftedVideoFileFromRam = await s.mergeDetectorBufferChunks(d) + videoPath = siftedVideoFileFromRam.filePath + videoName = siftedVideoFileFromRam.filename + } + if(videoPath){ sendMessage({ - title: filename, + title: videoName, },[ { type: 'video', - attachment: mergedFilepath, - name: filename + attachment: videoPath, + name: videoName } ],d.ke) - }) + } } d.screenshotBuffer = d.screenshotBuffer || d.frame if(!d.screenshotBuffer){