SRT Subtitles in After Effects

The issue:

For a while I had been searching for an easy way to add subtitles to my After Effects files. I knew there were a few different ways to use free and paid extend scripts but the ones I’ve found all ended up with having hard-coded keyframes. When you’ve made some manual changes to your subs in AE, and there were some last-minute changes to your subs you either had to do the corrections manually or re-run the script with the new sub and re-do all you manual (formatting) changes.

Wouldn’t it be ideal if you could import/link the SRT file into your library like you would with other kinds of footage?

 

Well, as it turns out: you can!

Since the CC2018 version of AE, you can import JSON files to create data-driven animations. Well, isn’t a JSON file basically just text? So this got me thinking; “what if I tried importing an SRT file instead of JSON?”. In the import AE import window you need to set the file filter to view all files (*.*) so you see the .srt file and then set the formating to Javascript. When you then use the expression

1
footage(“filename.srt).sourceText

on a textLayer’s Source Text property it showed the (complete) contents of the SRT file. All I had to do now is parse the contents, get the in-time, out-time and the actual subtitle text and have it all displayed at the right time. Mind you, I’m not a programmer so there might be a better, more efficient, prettier looking solution than this, but here’s my working solution:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
var subFile = “sub.srt;

var lines = footage(subFile).sourceText.split(‘\n\r\n’);

for (n = 0; n < lines.length; n++) { if (time >= srt(lines, n).start && time < srt(lines, n).end) {
sourceText = srt(lines, n).sub;
break;
} else {
sourceText = “”;
}
}
//————————————

function srt(lines, i) {
origin = lines[i].split(‘\n’);
ID = parseInt(origin[0]);
startText = origin[1].match(/^[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]/)[0].replace(,,:);
endText = origin[1].match(/\s[0-9][0-9]:[0-9][0-9]:[0-9][0-9],[0-9][0-9][0-9]/)[0].replace(‘ ‘,).replace(,,:);
var subtitle = “”;
for (var j = 2; j < origin.length; j++) {
subtitle = subtitle + origin[j] + ‘\n’;
}
return {id:ID, start:parseTime(startText), end:parseTime(endText), sub:subtitle};
}
//————————————

function parseTime(str) {
hours = parseInt(str.split(:)[0]);
minutes = parseInt(str.split(:)[1]);
seconds = parseInt(str.split(:)[2]);
millisesconds = parseInt(str.split(:)[3]);
t = (hours*60*60) + (minutes*60) + seconds + (millisesconds/1000);
t = Math.round(t*100)/100;
return t;
}