humanize timelapse mp4 builder

fix-non-showing-inputs
Moe Alam 2020-10-09 12:34:15 -07:00
parent 862bcb4d1d
commit aae352c998
5 changed files with 144 additions and 28 deletions

View File

@ -135,6 +135,8 @@
"Size (mb)": "Size (mb)",
"Watch": "Watch",
"Download": "Download",
"videoBuildingText1": "Video is currently building. Check again later.",
"Build Video": "Build Video",
"Delete": "Delete",
"Fix": "Fix",
"Use HTML5 Play Method": "Use HTML5 Play Method",
@ -834,9 +836,12 @@
"Monitor mode is already": "Monitor mode is already",
"Monitor or Key does not exist.": "Monitor or Key does not exist.",
"No Group with this key exists": "No Group with this key exists",
"Downloading...": "Downloading...",
"Downloading Videos": "Downloading Videos",
"Zipping Videos": "Zipping Videos",
"Automatic Checking Cancelled": "Automatic Checking Cancelled",
"Success": "Success",
"Please Wait or Click to Stop Checking": "Please Wait or Click to Stop Checking",
"Search Settings": "Search Settings",
"Trigger Successful": "Trigger Successful",
"Trigger Blocked": "Trigger Blocked",

View File

@ -203,7 +203,10 @@ module.exports = function(s,config,lang,app,io){
/**
* API : Get fileBin file
*/
app.get(config.webPaths.apiPrefix+':auth/fileBin/:ke/:id/:year/:month/:day/:file', async (req,res) => {
app.get([
config.webPaths.apiPrefix+':auth/fileBin/:ke/:id/:file',
config.webPaths.apiPrefix+':auth/fileBin/:ke/:id/:year/:month/:day/:file',
], async (req,res) => {
s.auth(req.params,function(user){
var failed = function(){
res.end(user.lang['File Not Found'])
@ -233,11 +236,11 @@ module.exports = function(s,config,lang,app,io){
if(r && r[0]){
r = r[0]
r.details = JSON.parse(r.details)
req.dir = s.dir.fileBin + req.params.ke + '/' + req.params.id + '/' + r.details.year + '/' + r.details.month + '/' + r.details.day + '/' + req.params.file;
fs.stat(req.dir,function(err,stats){
const filePath = s.dir.fileBin + req.params.ke + '/' + req.params.id + (r.details.year && r.details.month && r.details.day ? '/' + r.details.year + '/' + r.details.month + '/' + r.details.day : '') + '/' + req.params.file;
fs.stat(filePath,function(err,stats){
if(!err){
res.on('finish',function(){res.end()})
fs.createReadStream(req.dir).pipe(res)
fs.createReadStream(filePath).pipe(res)
}else{
failed()
}

View File

@ -203,6 +203,66 @@ module.exports = function(s,config,lang,app,io){
},res,req);
});
/**
* API : Build MP4 File
*/
app.post([
config.webPaths.apiPrefix+':auth/timelapseBuildVideo/:ke',
config.webPaths.apiPrefix+':auth/timelapseBuildVideo/:ke/:id',
], function (req,res){
res.setHeader('Content-Type', 'application/json');
s.auth(req.params,function(user){
var hasRestrictions = user.details.sub && user.details.allmonitors !== '1'
if(
user.permissions.watch_videos==="0" ||
hasRestrictions &&
(
!user.details.video_view ||
user.details.video_view.indexOf(req.params.id) === -1
)
){
s.closeJsonResponse(res,[])
return
}
const monitorRestrictions = s.getMonitorRestrictions(user.details,req.params.id)
if(monitorRestrictions.length === 0){
s.closeJsonResponse(res,{
ok: false
})
return
}
const framesPosted = s.getPostData(req, 'frames', true) || []
const frames = []
var n = 0
framesPosted.forEach((frame) => {
var firstParam = ['ke','=',req.params.ke]
if(n !== 0)firstParam = (['or']).concat(firstParam)
frames.push(firstParam,['mid','=',req.params.id],['filename','=',frame.filename])
++n
})
s.knexQuery({
action: "select",
columns: "*",
table: "Timelapse Frames",
where: frames
},(err,r) => {
if(r.length === 0){
s.closeJsonResponse(res,{
ok: false
})
return
}
s.createVideoFromTimelapse(r,s.getPostData(req, 'fps'),function(response){
s.closeJsonResponse(res,{
ok : response.ok,
filename : response.filename,
fileExists : response.fileExists,
msg : response.msg,
})
})
})
},res,req);
});
/**
* API : Get Timelapse images
*/
app.get([
@ -291,7 +351,6 @@ module.exports = function(s,config,lang,app,io){
['time','=<',dateNowMoment],
]
},function(err,frames) {
console.log(frames.length)
var groups = {}
frames.forEach(function(frame){
if(groups[frame.ke])groups[frame.ke] = {}
@ -305,7 +364,6 @@ module.exports = function(s,config,lang,app,io){
if(response.ok){
}
console.log(response.fileLocation)
})
})
})

View File

@ -543,7 +543,9 @@ module.exports = function(s,config,lang){
fs.unlink(commandTempLocation,function(){
})
delete(s.group[ke].activeMonitors[mid].buildingTimelapseVideo)
setTimeout(() => {
delete(s.group[ke].activeMonitors[mid].buildingTimelapseVideo)
},3000)
})
var readFile = function(){
var filePath = concatFiles[currentFile]
@ -573,6 +575,7 @@ module.exports = function(s,config,lang){
callback({
ok: false,
fileExists: true,
filename: finalFileName + '.mp4',
fileLocation: finalMp4OutputLocation,
msg: lang['Already exists']
})

View File

@ -12,6 +12,7 @@ $(document).ready(function(e){
var playBackViewImage = timelapseWindow.find('.playBackView img')
var liveStreamView = timelapseWindow.find('.liveStreamView')
var monitorsList = timelapseWindow.find('.monitors_list')
var downloadButton = timelapseWindow.find('.download_mp4')
var apiBaseUrl = $.ccio.init('location',$user) + $user.auth_token
var downloadRecheckTimers = {}
var currentPlaylist = {}
@ -20,6 +21,8 @@ $(document).ready(function(e){
var playInterval = 1000 / 30
var fieldHolderCssHeightModifier = 0
var canPlay = false;
var downloaderIsChecking = false
var allowKeepChecking = true
var openTimelapseWindow = function(monitorId,startDate,endDate){
timelapseWindow.modal('show')
@ -62,6 +65,7 @@ $(document).ready(function(e){
}
var drawTimelapseWindowElements = function(selectedMonitor,startDate,endDate){
setDownloadButtonLabel(lang['Build Video'], 'database')
var dateRange = getSelectedTime(true)
if(!startDate)startDate = dateRange.startDate
if(!endDate)endDate = dateRange.endDate
@ -153,6 +157,13 @@ $(document).ready(function(e){
playPauseText.text(lang.Pause)
}
}
var iconHtml = function(iconClasses,withSpace){
if(withSpace === undefined)withSpace = true
return `<i class="fa fa-${iconClasses}"></i>` + (withSpace ? ' ' : '')
}
var setDownloadButtonLabel = function(text,icon){
downloadButton.html(icon ? iconHtml(icon) + text : text)
}
timelapseWindow.on('click','.frame',function(){
pauseTimelapse()
var selectedFrame = $(this).attr('data-filename')
@ -169,33 +180,68 @@ $(document).ready(function(e){
togglePlayPause()
})
timelapseWindow.on('click','.download_mp4',function(){
var _this = $(this)
var runDownloader = function(){
if(downloaderIsChecking){
allowKeepChecking = false
setDownloadButtonLabel(lang['Build Video'], 'database')
}else{
allowKeepChecking = true
var _this = $(this)
var fps = fpsSelector.val()
var dateRange = getSelectedTime(true)
var startDate = dateRange.startDate
var endDate = dateRange.endDate
var selectedMonitor = monitorsList.val()
var queryString = ['fps=' + fpsSelector.val(),'start=' + startDate,'end=' + endDate,'mp4=1']
var timerId = queryString.join('&')
var generatorUrl = apiBaseUrl + '/timelapse/' + $user.ke + '/' + selectedMonitor
$.getJSON(generatorUrl + '?' + queryString.join('&'),function(response){
_this.text(lang['Download'])
if(response.fileExists){
var downloadName = startDate + '_' + endDate + '_' + selectedMonitor + '.mp4'
var a = document.createElement('a')
a.href = generatorUrl + '?' + queryString.concat(['download="1"']).join('&')
a.download = downloadName
a.click()
}else{
_this.html(lang['Please Wait...'])
clearTimeout(downloadRecheckTimers[timerId])
downloadRecheckTimers[timerId] = setTimeout(function(){
_this.html(lang['Download'])
},5000)
var parsedFrames = JSON.stringify(currentPlaylistArray.map(function(frame){
return {
mid: frame.mid,
ke: frame.ke,
filename: frame.filename,
}
})
}))
var postBody = {
fps: fps,
frames: parsedFrames,
}
var timerId = JSON.stringify(parsedFrames)
var generatorUrl = apiBaseUrl + '/timelapseBuildVideo/' + $user.ke + '/' + selectedMonitor
var runDownloader = function(){
if(!allowKeepChecking){
setDownloadButtonLabel(lang['Automatic Checking Cancelled'])
downloadRecheckTimers[timerId] = setTimeout(function(){
setDownloadButtonLabel(lang['Build Video'], 'database')
},5000)
downloaderIsChecking = false
allowKeepChecking = true
return
}
downloaderIsChecking = true
setDownloadButtonLabel(lang['Please Wait or Click to Stop Checking'], 'spinner fa-pulse')
$.post(generatorUrl,postBody,function(response){
if(response.fileExists){
setDownloadButtonLabel(lang['Downloading...'], 'spinner fa-pulse')
var downloadUrl = apiBaseUrl + '/fileBin/' + $user.ke + '/' + selectedMonitor + '/' + response.filename
var downloadName = startDate + '_' + endDate + '_' + selectedMonitor + '.mp4'
var a = document.createElement('a')
a.href = downloadUrl
a.download = downloadName
a.click()
setTimeout(function(){
setDownloadButtonLabel(lang['Download'], 'download')
},2000)
downloaderIsChecking = false
allowKeepChecking = true
}else{
setDownloadButtonLabel(lang['Please Wait or Click to Stop Checking'], 'spinner fa-pulse')
clearTimeout(downloadRecheckTimers[timerId])
downloadRecheckTimers[timerId] = setTimeout(function(){
setDownloadButtonLabel(lang['Please Wait or Click to Stop Checking'], 'spinner fa-pulse')
runDownloader()
},5000)
}
})
}
runDownloader()
}
runDownloader()
})
timelapseWindow.on('shown.bs.modal', function (e) {
resetFilmStripPositions()
@ -216,4 +262,5 @@ $(document).ready(function(e){
openWindow: openTimelapseWindow,
monitorsList: monitorsList
}
setDownloadButtonLabel(lang['Build Video'], 'database')
})