NodeJS, Tools

How to Delay ASS Subtitles

I was watching a series and had to shift my subtitles by 38 seconds every time I open a video. After a few times of pain, I ended up writing a script to cut the crap, have some fun, and get a bit into NodeJS file I/O! 😀

It only deals with subtitle files of *.ASS extension. `delay_ass.js` being the NodeJS script file, you can use it like:

$ node delay_ass.js example.ass -32

Grab it here:

// 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;
}
view raw delay_ass.js hosted with ❤ by GitHub
Standard

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.