Copy link to clipboard
Copied
THE ISSUE:
For a while now I've been seaching for an easy way to add subtitles to my After Effects files. I know there are a few different ways to use free and/or paid extendscripts 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 manually do the corrections, 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 just import/link the SRT file into your library like you would with other kinds of footage?
THE ANSWER:
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 a SRT file instead of JSON?". As it turns out, if you omit the file mask in the import file dialog (All files (*.*)), you can in fact import *.srt files. Using
footage("filename.srt").sourceText
as an expression on a textLayer's Source Text if 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 sub 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:
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.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
+ '\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;
}
You simply place the above expression in the Source Text property of a TextLayer and replace "sub.srt" with the name of your imported subtitle file.
Copy link to clipboard
Copied
I'm trying to replicate your solution above. Could you please elaborate on "if you omit the file mask in the import file dialog (All files (*.*)), you can in fact import *.srt files."? I'm stuck on that step.
Thanks in advanced!
Copy link to clipboard
Copied
Apologies for the late reply.
If you have the Import FIle window open, you see "All acceptable files" in the lower right corner. This masks the files in the folder to only files that AE is sure of that can be opened. If you click on that and scroll all the way down you can choose "All files (*.*)". When you do that AE shows you all the files in the folder, like for instance .srt files.
Hope that helps!
Copy link to clipboard
Copied
Yes, this works, but after that you have to point out in a dropdown menu what kind of file you are importing. What kind do you use?
Copy link to clipboard
Copied
Oh, I hadn't actually noticed that dropdown. Perhaps that was introduced in the latest update of AE?
Anyway, if you set the format as JavaScript AE imports the .srt file and my script will read the contents correctly.
Copy link to clipboard
Copied
Your code is incredibly helpful, thank you so much for posting this! I have been looking for a better way of embedding subtitles into the videos themselves and this greatly helps with the process.
Here are two issues I'm having:
1. The subtitles are showing up correctly in After Effects but when I go to export/render the video, it just shows the first line the entire time.
2. I'm getting an error message. Which in part reads: This project contains an expression error: error 1 of 1. Expression disabled, Error at line 18 in property 'Source Text' of layer 1('subs') in comp 'Embed Captions 1280x720', property or method named '1' in Class 'Array' is missing or does not exist. It may have been renamed...
I am no After Effects pro by any means, so I am uncertain as to what to do. Any thoughts would be helpful. Thanks.
Copy link to clipboard
Copied
I am having the same #1 issue... the same line of text is rendered for the entire duration of the clip (only on render) I have tried multiple render formats... all the same result.
BTW, I am working on a MacBook Pro... (I really hope it isn't an OS related issue...)
Copy link to clipboard
Copied
So when I add to "Render Que" instead of trying to render it with Adobe Media Encoder, it renders the subtitles onto the video. The issue I'm having is the speed is incredibly slow compared to AME.
Copy link to clipboard
Copied
Hey! That worked like a charm! I have a pre-rendered animation that I am adding the subs to, so my comp is only the audio v/o, the animation, and the sub-titles... it renders quickly for me.
Maybe render the video/animation out first using AME and then do the SRT stuff by re-importing the render? (if that is even an issue... just a stab in the dark)
Thanks for the idea to used Render Queue! I NEVER think to use it...
Copy link to clipboard
Copied
Ok, I've just been pointed to this thread by a colleague.
Basically what you need to do to be able to render compositions with this script in Media Encoder is add the subtitle file to your timeline. Just drag the .srt file from your project panel onto your timeline and you should be good to go to.
isotropy​ I haven't been able to figure out what goes wrong in your case. It could be that the line breaks in your .srt file are somehow differently formatted. When I open my example subtitle in Notepad++ and turn on all hidden characters my lines end with [CR][LF].
Taabaascoo​ The example srt I'm using perfectly show the characters you're mentioning ("ä, ö, ü,"). Perhaps it has something to do with file encoding like ANSI/UTF? My srt is saved as UTF-8.
Copy link to clipboard
Copied
So I just tried my original .SRT files in AE 2019 and it's working fine - I had to change the project to the legacy javascript engine, but it's reading the files correctly! ¯\_(ツ)_/¯
Copy link to clipboard
Copied
Hey there, i'm not sure what i'm doing wrong, but when I apply the script, it's displaying the entire contents of my SRT file minus the first two lines. Any ideas?
Copy link to clipboard
Copied
This looks great, but i am getting an unexpected expression error, any ideas on this would be helpful,
1 var subFile = “video-1.srt";
Copy link to clipboard
Copied
Hi jonothonrossi,
you might want to look at the text formatting of your code. When I paste it into N++ the first quote symbol looks to be wrong. Check my screenshot.
hope this helps!
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Hello,
your script is really helpful for me! But i got one Problem when i use German subtitles with characters like "ä, ö, ü,". If one of this characters appear, this character and all the following subtitles disappear. Do you have any idea how i can solve this problem?
Thank you very much!!!
Copy link to clipboard
Copied
Hey, thanks for developing this, I have just tested it with an srt file, however, between each new line of subs, the first line keeps popping up for a millisecond.
It seems like if there is a break between the timecodes it displays a previous subtitle, I've checked this against another srt file and its the same issue.
Copy link to clipboard
Copied
You're a genius, THANK YOU!
Copy link to clipboard
Copied
Is there a way to adapt this script to read VTT files instead of SRTs?
Copy link to clipboard
Copied
Hi all, and thanks a lot for this helpful thread!
I'm having an issue though, when trying to replicate...
I get a TypeError message on line 18 stating:
Cannot read property 'match' of undefined
Also (but it might be related) what appears on screen instead of the requested .srt file is the last bit of the actual axpression, from "function(str)…"
Do you know what could go wong there?
Thanks a lot in advance!
Copy link to clipboard
Copied
Sorry for the late reply, but I'm not that often checking this thread.
MarkDon​ If you can share an example VTT file I might be able to see what I can do.
simonf49103525​ Any chance you can share the subtitle file you're having issues with?
Copy link to clipboard
Copied
Thanks, here is a sample vtt file
Also while I'm here I have a translations vendor trying to use this expression:
"We've been working through the provided workflow to use SRT files in After Effects, and we found that while we had success doing it on a Windows 10 laptop, were keep getting an error message when doing the same thing on a Macbook. The error message can be seen here:
As you are more familiar with this workflows, is there any chance you've run into a similar issue? Are there any particular things we may be missing? We are using the exact same files and workflow on both systems. Please let us know, either way, so we can continue troubleshooting if need be!
For reference, line 1 looks like this:
Any input is appreciated."
Thanks
Mark
Copy link to clipboard
Copied
I realize I'm late in finding this, but this post was very helpful. I was not able to use it as written in AE v 16.1.1 CC 2019. I did some tweaking and have included the code below.
I also was not able to export it to media encoder and have the text work possibly because of a bug with my cureent version of either Media Encoder or After Effects. I was able to export directly from AE to proRes and then in ME convert from ProRes to h264
var subFile = "mySubs.srt";
function srt(lines, i) {
origin = lines[i].split('\n');
if(origin.length>2){
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};
}
else{
return {id:0, start:0, end:0, sub:"nope"};
}
//return {id:ID, start:startText, end: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;
}
//------------------------------------
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 = "";
}
}
Copy link to clipboard
Copied
I can't get this to work. I get an error that says "cannot read property '0' of null". I'm on Mac, AE 17.0.5, using an srt file generated from Premiere.
Copy link to clipboard
Copied
Thank you for the update script, I could get either to work and I get an error saying it can't find the SRT file. I have tried adding the full path and local path. Is there anything else you need to do. The Import file approach doesn't make any difference for me.