const ipc = require('node-ipc') const db = require('../db') const dbFile = db.models.file const path = require('path') const ffprobe = require('node-ffprobe') const execFile = require('child_process').execFile const mimeFromExtension = require('./mimeFromExtension') ffprobe.FFPROBE_PATH = process.env.FFPROBE_BINARY const Loader = require('../vendor/Loader') let processing = false module.exports = function processFiles() { if (processing) return processing = true dbFile.index({ processed: false, limit: 1 }).then( (files) => { console.log(files.length + ' files left to process') if (! files || files.length === 0) { processing = false return } let file = files.at ? files.at(0) : files[0] const mimeType = mimeFromExtension(file.name) file.mime = mimeType.mime file.type = mimeType.type switch (mimeType.type) { case 'audio': return processAudio(file) default: return processDone(file) } }).then( () => { console.log('done') if (processing) { processing = false setTimeout( processFiles ) } }) } function processAudio(file) { const filePath = path.join(__dirname, '../..', 'public/data', String(file.folder_id)) // console.log(filePath) const fullPath = path.join(filePath, file.name) console.log(fullPath) return new Promise ( (resolve, reject) => { cacheFfprobe(file, fullPath) .then(() => { return convertToAiff(fullPath) }) .then(() => { return processSpectrum(fullPath) }) .then(() => { return trimSpectrum(fullPath) }) .then(() => { return convertToMp3(fullPath) }) .then(() => { return processDone(file) }) .then(() => { return resolve() }) }) } function processSpectrum(fullPath) { return new Promise ( (resolve, reject) => { console.log('process spectrum') const aiffPath = fullPath + '.aiff' const pngPath = fullPath + '.png' execFile(process.env.PYTHON_BINARY, ['./python/spectrum.py', aiffPath, pngPath], (err, stdout, stderr) => { // console.log('spectrum done') resolve() }) }) } function trimSpectrum(fullPath) { return new Promise ( (resolve, reject) => { console.log('trim spectrum') const thumbPath = fullPath + '.png' execFile(process.env.CONVERT_BINARY, [thumbPath, '-trim', thumbPath], (err, stdout, stderr) => { // console.log('trim done') resolve() }) }) } function cacheFfprobe(file, fullPath) { return new Promise ( (resolve, reject) => { console.log('ffprobe') ffprobe(fullPath, function(err, probeData) { if (err) { console.error('\n------------------------- !!!\n\n') console.error(err) } if (probeData) { file.duration = probeData.format.duration } file.analysis = JSON.stringify(probeData) resolve() }) }) } function convertToAiff(fullPath) { return new Promise ( (resolve, reject) => { console.log('convert to aiff') const aiffPath = fullPath + '.aiff' execFile(process.env.FFMPEG_BINARY, ['-y', '-i', fullPath, '-acodec', 'pcm_s16le', '-ar', '44100', aiffPath], (err, stdout, stderr) => { // console.log(stdout, stderr) resolve() }) }) } function convertToMp3(fullPath) { return new Promise ( (resolve, reject) => { console.log('convert to mp3') if (fullPath.match(/\.mp3$/i)) { return resolve() } const mp3Path = fullPath + '.mp3' execFile(process.env.FFMPEG_BINARY, ['-y', '-i', fullPath, '-q:a', '6', mp3Path], (err, stdout, stderr) => { // console.log(stdout, stderr) resolve() }) }) } function thumbnailJpeg(fullPath, _w, _h) { const w = _w || 250 const h = _h || 250 return new Promise ( (resolve, reject) => { console.log('thumbnail jpeg') const jpegPath = jpegPath + '.jpg' execFile(process.env.CONVERT_BINARY, [fullPath, '-resize', w + 'x' + h, '-quality', 90, jpegPath], (err, stdout, stderr) => { // console.log(stdout, stderr) resolve() }) }) } function processImage(file) { return new Promise ( (resolve, reject) => { // process image? resolve() }) } function processDone(file) { file.processed = true ipc.of.cortex && ipc.of.cortex.emit("updateFile", { file: file }) return dbFile.update(file.id, file) }