UNPKG

shinobi-video-synopsis

Version:

Create Video Synopsis from provided videos. Frames are extracted from each video provided and backgrounds are subtracted around moving elements and merged into a single video for quick review.

69 lines (68 loc) 2.77 kB
const { stripNamePng, createBaseFolder, } = require('./utils.js'); const fs = require('fs'); const gm = require('gm').subClass({imageMagick: true}) const flattenImage = (gmImageBuffer,filename) => { return new Promise((resolve,reject) => { gmImageBuffer.flatten().write(filename, (err) => { resolve(err) }); }) } exports.mergeFramePairs = (options) => { const engine = options.engine const videoNames = options.videoNames || [] const subtractedBackgrounds = options.subtractedBackgroundsDirectory const mergedFrames = options.mergedFramesDirectory const firstFrameDirectory = options.firstFrameDirectory const onFrameComplete = options.onFrameComplete || function(){} const response = { startedAt: new Date(), videoNames: videoNames, numberOfVideos: videoNames.length, numberOfFrames: 0, } return new Promise(async (resolve,reject) => { var backgroundPath = firstFrameDirectory + fs.readdirSync(firstFrameDirectory)[0] var videoImages = {} var videoImagePairs = [] videoNames.forEach((videoName) => { const videoFolder = subtractedBackgrounds + videoName + '/' videoImages[videoName] = fs.readdirSync(videoFolder) videoImages[videoName].forEach((filename) => { const n = stripNamePng(filename) if(!videoImagePairs[n])videoImagePairs[n] = [] videoImagePairs[n].push(videoFolder + filename) }) }) if(videoImagePairs.length > 0){ for (var i = 0; i < videoImagePairs.length; i++) { const pair = videoImagePairs[i] var newImage = gm() .in('-geometry', '+0+0') .in(backgroundPath) for (var ii = 0; ii < pair.length; ii++) { const imagePath = pair[ii] newImage.in('-geometry', '+0+0').in(imagePath) } engine.logStderr(`${mergedFrames}${i}.jpg`) const error = await flattenImage(newImage,`${mergedFrames}${i}.jpg`) if(error){ engine.logStderr(error) } ++response.numberOfFrames engine.logStderr(i === videoImagePairs.length - 1,i, videoImagePairs.length - 1) onFrameComplete(i,videoImagePairs.length) if(i === videoImagePairs.length - 1 || engine.cancelledProcess){ response.endedAt = new Date() response.timeSpent = response.endedAt - response.startedAt resolve(response) } } }else{ resolve(response) } }) }