Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Delay ASS subtitles by certain seconds.
// USAGE:
// node delay_ass.js subtitle.ass -32
const fs = require('fs');
const fileName = process.argv[2];
const delaySeconds = process.argv[3];
const encoding = process.argv[4] || 'utf16le';
if (typeof delaySeconds === 'undefined') {
console.log(
'Error: Please provide a number after file name for seconds to delay, e.g.:'
);
console.log('$ node delay_ass.js S02E01.ass -12.5');
return;
}
const isDelay = !delaySeconds.startsWith('-');
const adjective = isDelay ? 'later' : 'earlier';
fs.readFile(fileName, encoding, (err, data) => {
if (err) return console.log(err);
const dataLines = data.split(/\n/);
const newLines = dataLines.map(line => {
if (line.startsWith('Dialogue:')) {
return processLine(line);
} else {
return line;
}
});
const newData = newLines.join('\n');
fs.writeFile(fileName, newData, encoding, err => {
if (err) return console.log(err);
console.log(
'Successfully made subtitle appear ',
adjective,
'by',
delaySeconds,
'seconds.'
);
});
});
function processLine(line) {
const blocks = line.split(/,/);
const newBlocks = blocks.map((block, i) => {
if (i === 1 || i === 2) {
return delayTimestamp(block);
} else {
return block;
}
});
return newBlocks.join(',');
}
function delayTimestamp(time, delayStr = delaySeconds) {
// E.G. 0:14:12.04
const timeArr = time.split(/:/).map(e => parseFloat(e, 10));
const [h, m, s] = timeArr;
const totalS = s + 60 * m + 3600 * h;
const delay = parseFloat(delayStr, 10);
const newTotalS = totalS + delay;
const newH = Math.max(0, Math.floor(newTotalS / 3600));
const newM = Math.max(0, Math.floor((newTotalS % 3600) / 60));
const newS = Math.max(0, newTotalS % 60);
const newTime = [newH, newM, newS.toFixed(2)].join(':');
return newTime;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.