Created
September 1, 2017 01:50
-
-
Save Meandmybadself/2641024faa25a63540242e8aac56961f to your computer and use it in GitHub Desktop.
Joins movies in a directory using ffmpeg.
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
const fs = require('fs') | |
const dir = process.argv[2] | |
const txtFilename = 'files.txt' | |
const outputFilename = 'output.mp4' | |
const { exec } = require('child_process') | |
let output = '' | |
const files = fs.readdirSync(dir).filter(f => ( | |
f !== '.DS_Store' && | |
f !== outputFilename && | |
ext(f) !== 'js' && | |
ext(f) !== 'txt') | |
).sort(naturalSort) | |
files.forEach(el => { | |
output += `file '${el}'\n` | |
}) | |
fs.writeFileSync(txtFilename, output, 'utf8') | |
exec(`ffmpeg -f concat -i ${txtFilename} -c copy ${outputFilename}`) | |
fs.unlinkSync(txtFilename) | |
function ext (p) { | |
const e = p.split('.').pop().toLowerCase() | |
return e | |
} | |
function naturalSort (a, b) { | |
var re = /(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g, | |
sre = /^\s+|\s+$/g, // trim pre-post whitespace | |
snre = /\s+/g, // normalize all whitespace to single ' ' character | |
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/, | |
hre = /^0x[0-9a-f]+$/i, | |
ore = /^0/, | |
i = function (s) { | |
return (naturalSort.insensitive && ('' + s).toLowerCase() || '' + s).replace(sre, '') | |
}, | |
// convert all to strings strip whitespace | |
x = i(a), | |
y = i(b), | |
// chunk/tokenize | |
xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'), | |
yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/, '').split('\0'), | |
// numeric, hex or date detection | |
xD = parseInt(x.match(hre), 16) || (xN.length !== 1 && Date.parse(x)), | |
yD = parseInt(y.match(hre), 16) || xD && y.match(dre) && Date.parse(y) || null, | |
normChunk = function (s, l) { | |
// normalize spaces; find floats not starting with '0', string or 0 if not defined (Clint Priest) | |
return (!s.match(ore) || l == 1) && parseFloat(s) || s.replace(snre, ' ').replace(sre, '') || 0 | |
}, | |
oFxNcL, oFyNcL | |
// first try and sort Hex codes or Dates | |
if (yD) { | |
if (xD < yD) { return -1 } else if (xD > yD) { return 1 } | |
} | |
// natural sorting through split numeric strings and default strings | |
for (var cLoc = 0, xNl = xN.length, yNl = yN.length, numS = Math.max(xNl, yNl); cLoc < numS; cLoc++) { | |
oFxNcL = normChunk(xN[cLoc] || '', xNl) | |
oFyNcL = normChunk(yN[cLoc] || '', yNl) | |
// handle numeric vs string comparison - number < string - (Kyle Adams) | |
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) { | |
return isNaN(oFxNcL) ? 1 : -1 | |
} | |
// if unicode use locale comparison | |
if (/[^\x00-\x80]/.test(oFxNcL + oFyNcL) && oFxNcL.localeCompare) { | |
var comp = oFxNcL.localeCompare(oFyNcL) | |
return comp / Math.abs(comp) | |
} | |
if (oFxNcL < oFyNcL) { return -1 } else if (oFxNcL > oFyNcL) { return 1 } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment