Created
November 10, 2015 20:31
-
-
Save vankasteelj/39723be4a99fc2d151b1 to your computer and use it in GitHub Desktop.
transcode .ass, .ssa, .txt to SRT
This file contains hidden or 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
//transcode .ass, .ssa, .txt to SRT | |
var convert2srt = function (file, ext, callback) { | |
var readline = require('readline'), | |
counter = null, | |
lastBeginTime, | |
//input | |
orig = /([^\\]+)$/.exec(file)[1], | |
origPath = file.substr(0, file.indexOf(orig)), | |
//output | |
srt = orig.replace(ext, '.srt'), | |
srtPath = Settings.tmpLocation, | |
//elements | |
dialog, begin_time, end_time; | |
fs.writeFileSync(path.join(srtPath, srt), ''); //create or delete content; | |
console.debug('SUB format can be converted:', orig); | |
var rl = readline.createInterface({ | |
input: fs.createReadStream(path.join(origPath, orig)), | |
output: process.stdout, | |
terminal: false | |
}); | |
rl.on('line', function (line) { | |
//detect encoding | |
var charset = charsetDetect.detect(line); | |
var encoding = charset.encoding; | |
var line_, parsedBeginTime, parsedEndTime, parsedDialog; | |
//parse SSA | |
if (ext === '.ssa' || ext === '.ass') { | |
encoding = 'utf-8'; | |
if (line.indexOf('Format:') !== -1) { | |
var ssaFormat = line.split(','); | |
for (var i = 0; i < ssaFormat.length; i++) { | |
switch (ssaFormat[i]) { | |
case 'Text': | |
case ' Text': | |
dialog = i; | |
break; | |
case 'Start': | |
case ' Start': | |
begin_time = i; | |
break; | |
case 'End': | |
case ' End': | |
end_time = i; | |
break; | |
default: | |
} | |
} | |
if (dialog && begin_time && end_time) { | |
console.debug('SUB formatted in \'ssa\''); | |
} | |
return; //we have the elms spots, move on to the next line | |
} | |
if (line.indexOf('Dialogue:') === -1) { //not a dialog line | |
return; | |
} | |
line_ = line.split(','); | |
parsedBeginTime = line_[begin_time]; | |
parsedEndTime = line_[end_time]; | |
parsedDialog = line_[dialog]; | |
parsedDialog = parsedDialog.replace('{\\i1}', '<i>').replace('{\\i0}', '</i>'); //italics | |
parsedDialog = parsedDialog.replace('{\\b1}', '<b>').replace('{\\b0}', '</b>'); //bold | |
parsedDialog = parsedDialog.replace('\\N', '\n'); //return to line | |
parsedDialog = parsedDialog.replace(/{.*?}/g, ''); //remove leftovers brackets | |
} | |
//parse TXT | |
if (ext === '.txt') { | |
line_ = line.split('}'); | |
var formatSeconds = function (seconds) { | |
var date = new Date(1970, 0, 1); | |
date.setSeconds(seconds); | |
return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1'); | |
}; | |
parsedBeginTime = formatSeconds(line_[0].replace('{', '') / 25); | |
parsedEndTime = formatSeconds(line_[1].replace('{', '') / 25); | |
parsedDialog = line_[2].replace('|', '\n'); | |
} | |
//SRT needs a number for each subtitle | |
counter += 1; | |
//keep only the last lang | |
if (parsedBeginTime < lastBeginTime) { | |
counter = 1; | |
fs.writeFileSync(path.join(srtPath, srt), ''); | |
console.debug('SUB contains multiple tracks, keeping only the last'); | |
} | |
//SRT formatting | |
var parsedLine = | |
counter + '\n' + | |
parsedBeginTime + ' --> ' + parsedEndTime + '\n' + | |
parsedDialog; | |
fs.appendFileSync(path.join(srtPath, srt), '\n\n' + parsedLine, encoding); | |
lastBeginTime = parsedBeginTime; | |
}); | |
setTimeout(function () { | |
fs.readFile(path.join(srtPath, srt), function (err, dataBuff) { | |
if (!err) { | |
console.debug('SUB transcoded to SRT:', srt); | |
callback(dataBuff); | |
} else { | |
console.warn('SUB transcoding failed', err); | |
} | |
}); | |
}, 2000); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It is crappy and needs serious rewrite, but I scavenged that from popcorntime and found it useful, although I have nor the time nor the will to rewrite it or deeply analyze it.