Skip to content

Instantly share code, notes, and snippets.

@ManzDev
Created September 13, 2017 20:34
Show Gist options
  • Save ManzDev/4e41f87360763a013d15bc10cf873473 to your computer and use it in GitHub Desktop.
Save ManzDev/4e41f87360763a013d15bc10cf873473 to your computer and use it in GitHub Desktop.
Split, divides or cut a long video in mp4 parts (requires ffmpeg)
#!/usr/bin/env node
let fs = require('fs'); // FileSystem
let cmd = require('child_process'); // System calls
let path = require('path'); // Paths
let color = {
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m',
white: '\x1b[37m',
lightgray: '\x1b[90m',
lightred: '\x1b[91m',
lightgreen: '\x1b[92m',
lightyellow: '\x1b[93m',
lightblue: '\x1b[94m',
lightmagenta: '\x1b[95m',
lightcyan: '\x1b[96m',
lightwhite: '\x1b[97m',
reset: '\x1b[0m',
style: {
bold: '\x1b[1m',
underline: '\x1b[4m'
}
}
// Example data.txt
// 00:00 00:59 Part 1 - Introduction
// 01:00 03:33 Part 2 - Content
// 03:34 06:41 Part 3 - The end
// Command syntax
if (process.argv.length == 2) {
console.log(`Use: ${color.lightblue}${process.argv[1]}${color.reset} [--render] <original.mp4> <data.txt> [number-line-only-process]\n`);
console.log(`\t${color.lightyellow}--render${color.reset}\tRe-encode entire video. More slow, but more accurate (youtube-friendly)`);
console.log(`\t${color.lightyellow}<original.mp4>${color.reset}\tOriginal loooong video.`);
console.log(`\t${color.lightyellow}<data.txt>${color.reset}\tFragments text file. Format: BEGIN_TIME END_TIME FILENAME`);
console.log(`\t${color.lightyellow}[number]${color.reset}\tProcess only specified video/line. Optional.`);
console.log(`\nThis command require ffmpeg and libraries installed.\n`);
process.exit();
}
let render = '-vcodec copy -acodec copy';
if (process.argv[2] == '--render') {
render = '';
process.argv.splice(2,1);
}
let video = process.argv[2];
let data = process.argv[3];
let number = process.argv[4];
fs.readFile(data, 'utf8', (err,data) => {
if (err)
return console.error(err);
else {
// Process data
lines = data.split('\r\n');
lines.forEach((e,i) => {
let [begin, end, ...filename] = e.split(' ');
filename = filename.join(' ');
let fullfilename = process.cwd() + path.sep + filename + '.mp4';
if ((number == i+1) || (number == null)) {
process.stdout.write(`File ${filename}.mp4... `);
if (fs.existsSync(fullfilename))
console.log(`Exists. ${color.lightblue}Skipping${color.reset}`);
else {
try {
let time = process.hrtime();
cmd.execSync(`ffmpeg -i "${video}" ${render} -ss ${begin} -to ${end} "${filename}.mp4"`, {stdio: ['ignore', 'pipe', 'pipe']});
let [s,ns] = process.hrtime(time);
s = (s > 60 ? Math.round(s/60) + 'min' : s + 'sec');
console.log(`${color.green}Ok${color.reset} ${Math.round(fs.statSync(fullfilename).size / 1024 / 1024)}Mb ~${s}`);
} catch(e) {
console.log(`${color.red}Error ${e.status} ${e.stderr.toString().split('\r\n').slice(-3)[1]}${color.reset}`);
}
}
}
});
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment