218 lines
9.5 KiB
JavaScript
218 lines
9.5 KiB
JavaScript
const fs = require('fs')
|
|
const { spawn } = require('child_process')
|
|
module.exports = (s,config,lang) => {
|
|
// orphanedVideoCheck : new function
|
|
const checkIfVideoIsOrphaned = (monitor,videosDirectory,filename) => {
|
|
const response = {ok: true}
|
|
return new Promise((resolve,reject) => {
|
|
fs.stat(videosDirectory + filename,(err,stats) => {
|
|
if(!err && stats.size > 10){
|
|
s.knexQuery({
|
|
action: "select",
|
|
columns: "*",
|
|
table: "Videos",
|
|
where: [
|
|
['ke','=',monitor.ke],
|
|
['mid','=',monitor.mid],
|
|
['time','=',s.nameToTime(filename)],
|
|
],
|
|
limit: 1
|
|
},(err,rows) => {
|
|
if(!err && (!rows || !rows[0])){
|
|
//row does not exist, create one for video
|
|
var video = rows[0]
|
|
s.insertCompletedVideo(monitor,{
|
|
file : filename
|
|
},() => {
|
|
response.status = 2
|
|
resolve(response)
|
|
})
|
|
}else{
|
|
//row exists, no errors
|
|
response.status = 1
|
|
resolve(response)
|
|
}
|
|
})
|
|
}else{
|
|
response.status = 0
|
|
resolve(response)
|
|
}
|
|
})
|
|
})
|
|
}
|
|
const scanForOrphanedVideos = (monitor,options) => {
|
|
// const options = {
|
|
// checkMax: 2
|
|
// }
|
|
options = options ? options : {}
|
|
return new Promise((resolve,reject) => {
|
|
const response = {ok: false}
|
|
if(options.forceCheck === true || config.insertOrphans === true){
|
|
if(!options.checkMax){
|
|
options.checkMax = config.orphanedVideoCheckMax || 2
|
|
}
|
|
let finished = false
|
|
let orphanedFilesCount = 0;
|
|
let videosFound = 0;
|
|
const videosDirectory = s.getVideoDirectory(monitor)
|
|
const tempDirectory = s.getStreamsDirectory(monitor)
|
|
// const findCmd = [videosDirectory].concat(options.flags || ['-maxdepth','1'])
|
|
fs.writeFileSync(
|
|
tempDirectory + 'orphanCheck.sh',
|
|
`find "${videosDirectory}" -maxdepth 1 -type f -exec stat -c "%n" {} + | sort -r | head -n ${options.checkMax}`
|
|
);
|
|
let listing = spawn('sh',[tempDirectory + 'orphanCheck.sh'])
|
|
// const onData = options.onData ? options.onData : () => {}
|
|
const onError = options.onError ? options.onError : s.systemLog
|
|
const onExit = () => {
|
|
try{
|
|
listing.kill('SIGTERM')
|
|
fs.unlink(tempDirectory + 'orphanCheck.sh',() => {})
|
|
}catch(err){
|
|
s.debugLog(err)
|
|
}
|
|
delete(listing)
|
|
}
|
|
const onFinish = () => {
|
|
if(!finished){
|
|
finished = true
|
|
response.ok = true
|
|
response.orphanedFilesCount = orphanedFilesCount
|
|
resolve(response)
|
|
onExit()
|
|
}
|
|
}
|
|
const processLine = async (filePath) => {
|
|
let filename = filePath.split('/')
|
|
filename = `${filename[filename.length - 1]}`.trim()
|
|
if(filename && filename.indexOf('-') > -1 && filename.indexOf('.') > -1){
|
|
const { status } = await checkIfVideoIsOrphaned(monitor,videosDirectory,filename)
|
|
if(status === 2){
|
|
++orphanedFilesCount
|
|
}
|
|
++videosFound
|
|
if(videosFound === options.checkMax){
|
|
onFinish()
|
|
}
|
|
}
|
|
}
|
|
listing.stdout.on('data', async (d) => {
|
|
const filePathLines = d.toString().split('\n')
|
|
var i;
|
|
for (i = 0; i < filePathLines.length; i++) {
|
|
await processLine(filePathLines[i])
|
|
}
|
|
})
|
|
listing.stderr.on('data', d=>onError(d.toString()))
|
|
listing.on('close', (code) => {
|
|
// s.debugLog(`findOrphanedVideos ${monitor.ke} : ${monitor.mid} process exited with code ${code}`);
|
|
setTimeout(() => {
|
|
onFinish()
|
|
},1000)
|
|
});
|
|
}else{
|
|
resolve(response)
|
|
}
|
|
})
|
|
}
|
|
// orphanedVideoCheck : old function
|
|
const orphanedVideoCheck = (monitor,checkMax,callback,forceCheck) => {
|
|
var finish = function(orphanedFilesCount){
|
|
if(callback)callback(orphanedFilesCount)
|
|
}
|
|
if(forceCheck === true || config.insertOrphans === true){
|
|
if(!checkMax){
|
|
checkMax = config.orphanedVideoCheckMax || 2
|
|
}
|
|
|
|
var videosDirectory = s.getVideoDirectory(monitor)// + s.formattedTime(video.time) + '.' + video.ext
|
|
fs.readdir(videosDirectory,function(err,files){
|
|
if(files && files.length > 0){
|
|
var fiveRecentFiles = files.slice(files.length - checkMax,files.length)
|
|
var completedFile = 0
|
|
var orphanedFilesCount = 0
|
|
var fileComplete = function(){
|
|
++completedFile
|
|
if(fiveRecentFiles.length === completedFile){
|
|
finish(orphanedFilesCount)
|
|
}
|
|
}
|
|
fiveRecentFiles.forEach(function(filename){
|
|
if(/T[0-9][0-9]-[0-9][0-9]-[0-9][0-9]./.test(filename)){
|
|
fs.stat(videosDirectory + filename,(err,stats) => {
|
|
if(!err && stats.size > 10){
|
|
s.knexQuery({
|
|
action: "select",
|
|
columns: "*",
|
|
table: "Videos",
|
|
where: [
|
|
['ke','=',monitor.ke],
|
|
['mid','=',monitor.mid],
|
|
['time','=',s.nameToTime(filename)],
|
|
],
|
|
limit: 1
|
|
},(err,rows) => {
|
|
if(!err && (!rows || !rows[0])){
|
|
++orphanedFilesCount
|
|
var video = rows[0]
|
|
s.insertCompletedVideo(monitor,{
|
|
file : filename
|
|
},() => {
|
|
fileComplete()
|
|
})
|
|
}else{
|
|
fileComplete()
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}else{
|
|
finish()
|
|
}
|
|
})
|
|
}else{
|
|
finish()
|
|
}
|
|
}
|
|
function cutVideoLength(options){
|
|
return new Promise((resolve,reject) => {
|
|
const response = {ok: false}
|
|
const inputFilePath = options.filePath
|
|
const monitorId = options.mid
|
|
const groupKey = options.ke
|
|
const cutLength = options.cutLength || 10
|
|
const tempDirectory = s.getStreamsDirectory(options)
|
|
let fileExt = inputFilePath.split('.')
|
|
fileExt = fileExt[fileExt.length -1]
|
|
const filename = `${s.gid(10)}.${fileExt}`
|
|
const videoOutPath = `${tempDirectory}`
|
|
const cuttingProcess = spawn(config.ffmpegDir,['-loglevel','warning','-i', inputFilePath, '-c','copy','-t',`${cutLength}`,videoOutPath])
|
|
cuttingProcess.stderr.on('data',(data) => {
|
|
const err = data.toString()
|
|
s.debugLog('cutVideoLength',options,err)
|
|
})
|
|
cuttingProcess.on('close',(data) => {
|
|
fs.stat(videoOutPath,(err) => {
|
|
if(!err){
|
|
response.filename = filename
|
|
response.filePath = videoOutPath
|
|
setTimeout(() => {
|
|
s.file('delete',videoOutPath)
|
|
},1000 * 60 * 3)
|
|
}else{
|
|
s.debugLog('cutVideoLength:readFile',options,err)
|
|
}
|
|
resolve(response)
|
|
})
|
|
})
|
|
})
|
|
}
|
|
return {
|
|
orphanedVideoCheck: orphanedVideoCheck,
|
|
scanForOrphanedVideos: scanForOrphanedVideos,
|
|
cutVideoLength: cutVideoLength,
|
|
}
|
|
}
|