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; } |