Created
June 7, 2012 15:49
-
-
Save corpix/2889591 to your computer and use it in GitHub Desktop.
Конвертирование видео по расширению параллельно
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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