Skip to content

Instantly share code, notes, and snippets.

@corpix
Created June 7, 2012 15:49
Show Gist options
  • Save corpix/2889591 to your computer and use it in GitHub Desktop.
Save corpix/2889591 to your computer and use it in GitHub Desktop.
Конвертирование видео по расширению параллельно
#!/bin/env coffee
require 'colors'
childProcess = require 'child_process'
spawn = childProcess.spawn
program = require 'commander'
os = require 'os'
fs = require 'fs'
async = require 'async'
# Cached variables
cwd = process.cwd()
cpus = os.cpus().length
program
.version('0.0.1')
.option('-i, --input <extension>', 'Input extension')
.option('-o, --output <extension>', 'Output extension')
.option('-R, --recursive', 'Recursive search')
.parse(process.argv)
if not program.input or not program.output
throw new Error 'Input and output required'
program.input = program.input.replace(/\s+/, '').split ','
inputFilterRegex = new RegExp "(#{program.input.join '|'})$", 'i'
tasks = []
getTasks = (dir = cwd) ->
fs.readdirSync(dir).forEach (name) ->
base = "#{dir}/#{name}"
stat = fs.statSync base
if program.recursive and stat.isDirectory()
getTasks base
else
return if not (inputFilterRegex.test(name) && stat.isFile())
tasks.push
input: base
output: "#{base}.#{program.output}"
getTasks()
tasksToProcess = tasks.length
tasksProcessed = 0
# parsers
extract = (prefix, data, stop = '\s') ->
result = data.match new RegExp("#{prefix}([^#{stop}]+)#{stop}", 'im')
if result
result[1]
else
false
extractTime = (data) ->
extract 'time=', data, ' '
extractDuration = (data) ->
extract 'Duration: ', data, ','
# probe
ffprobe = (file, callback) ->
out = ''
child = spawn 'ffprobe', [ file ]
child.stderr.on 'data', (data)->
out += data.toString()
child.on 'exit', (code) ->
if code is 0
callback null, out
else
callback "FFprobe exited with status #{code}"
# queue
task = (task, callback) ->
ffprobe task.input, (err, probe) ->
return callback err if err
duration = extractDuration probe
ffmpeg = spawn 'ffmpeg', [ '-i', task.input, '-sameq', '-y', '-ac', 1, '-r', 25, task.output ]
ffmpeg.stderr.on 'data', (data) ->
time = extractTime data.toString()
return if not time
console.log "(#{tasksToProcess}/#{tasksProcessed}) #{time.cyan}/#{duration.magenta} - #{task.input.green} -> #{task.output.yellow}".bold
ffmpeg.on 'exit', (code) ->
tasksProcessed++
name = task.input.replace cwd, ''
if code isnt 0
console.log "✗ #{name}".red
callback "FFmpeg exited with code #{code}"
else
console.log "✔ #{name}".green
callback()
que = async.queue task, cpus
que.push tasks, (err) ->
console.error err if err
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment