Skip to content

Instantly share code, notes, and snippets.

@kiraind
Last active January 19, 2021 13:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kiraind/23747330671fff8b4256e6f39931cf06 to your computer and use it in GitHub Desktop.
Save kiraind/23747330671fff8b4256e6f39931cf06 to your computer and use it in GitHub Desktop.
Nikon RAW files converted to JPEG using mogrify with 'multithreading'
const fs = require('fs')
const cp = require('child_process')
const vamuved = require('vamuved')
function exec (command) {
return new Promise((resolve, reject) => {
cp.exec(command, (error, stdout, stderr) => {
if (error) {
reject(error.message)
return
}
if (stderr) {
reject(stderr)
return
}
resolve(stdout)
})
})
}
const outDir = 'out'
if (!fs.existsSync(outDir)) {
fs.mkdirSync(outDir)
}
class Converter {
constructor (threads) {
this.threads = threads
this.tasks = []
this.left = 0
this.next = 1
this.notified = false
this.times = []
}
addTask (task) {
this.tasks.push(task)
}
startConverting () {
this.next = 0
this.left = this.tasks.length
for (let i = 0; i < this.threads; i += 1) {
this.convert(i)
}
}
async convert (threadId) {
while (this.left !== 0) {
// take task
const task = this.tasks[this.next]
this.next += 1
this.left -= 1
// handle task
const index = parseInt(
task.match(/(?<=DSC_)\d+(?=\.NEF)/)[0]
)
const outIndex = index.toString().padStart(4, '0')
const outPath = `${outDir}/${outIndex}.jpg`
const command = `mogrify -normalize -format JPG -write ${outPath} ${task}`
const start = new Date()
await exec(command)
const finish = new Date()
// report
this.times.push(finish.valueOf() - start.valueOf())
if (this.times.length > 10) {
this.times.shift()
}
const avgTimeMs = this.times.reduce((acc, curr) => acc + curr, 0) / this.times.length
const leftS = avgTimeMs * this.left / this.threads / 1000
const left = {
s: Math.floor(leftS % 60).toString().padStart(2, '0'),
m: Math.floor(leftS % 3600 / 60).toString().padStart(2, '0'),
h: Math.floor(leftS / 3600).toString().padStart(2, '0')
}
const pct = Math.round(100 * (1 - this.left / this.tasks.length)).toString().padStart(3, ' ')
console.log(`th#${threadId}: ${pct}% — ${this.left} left ~ ${left.h}:${left.m}:${left.s}`)
}
if (!this.notified) {
this.notified = true
await vamuved.send('5fc4f28dceedc00011653934')
}
}
}
const files = fs.readdirSync('.')
const photos = files.filter(fileName => /.*\.NEF/i.test(fileName))
const threads = 4
const converter = new Converter(threads)
converter.tasks = photos
converter.startConverting()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment