Skip to main content
Participating Frequently
April 26, 2018
Question

SRT files in AE - a working solution -

  • April 26, 2018
  • 11 replies
  • 37436 views

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.

11 replies

New Participant
September 30, 2021

Hi, thanks for the solution, but I had to do a bunch of debugging to get it to work for me. Firstly, I did select 'All files' which let me import the SRT, but I had to import it as a Javascript, not a JSON. The project I'm working on means each lines of subtitles is just one word, so this might not work for everybody. The formatting for my SRT looks like this:

 

1
00:00:00,000 --> 00:00:00,329
So

2
00:00:00,329 --> 00:00:00,599
I'm

3
00:00:00,853 --> 00:00:01,513
very

4
00:00:01,513 --> 00:00:02,203
much

5
00:00:02,263 --> 00:00:02,863
looking

 

 

And my expression is this:

 

function srt(i) {

origin = lines[i].split('\n');

ID = parseInt(origin[0]);

timeText = origin[1].split(' --> ');

subtitle = origin[2];
	
return {id:ID, start_time:parseTime(timeText[0]), end_time:parseTime(timeText[1]), sub:subtitle};

}

//------------------------------------


function parseTime(str) {

timeText2 = str.split(':');
	
hours = parseInt(timeText2[0]);

minutes = parseInt(timeText2[1]);
	
time_sec = timeText2[2].split(',');

seconds = parseInt(time_sec[0]);

millisesconds = parseInt(time_sec[1]);

t = (hours*60*60) + (minutes*60) + seconds + (millisesconds/1000);

return t;

}

//------------------------------------

var subFile = "audiogram.srt";

var lines = footage(subFile).sourceText.split('\n\n');


if ( time >= srt(lines.length-1).start_time) {
	sourceText = srt(lines.length-1).sub;
} else {
	for (let n = 0; n < lines.length-1; n++) {
		if (time >= srt(n).start_time && time < srt(n+1).start_time) {
			sourceText = srt(n).sub;
			break;
		} else {
			sourceText = "";
		}
	}
}

 

So I parsed the time slightly differently and there were a couple other bugs I had to clean up. If your subtitles have more than one line, you probably just have to work in the for loop in the 'subtitle' variable. Hope this helps someone.

New Participant
September 11, 2024

The method for adding an SRT file in After Effects appears to be unavailable in version 23.0.0.

When importing an SRT file using the 'All Files' option, After Effects demands a specific format.

If I select JSON, After Effects will display a warning message and the import will fail.

New Participant
September 11, 2024

update: If I select JavaScript, the import will succeed.

However, the expression shows an error message "Error: TypeError: lines.split is not a function" in the line "origin = lines.split('\n');".

 

September 26, 2019

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 = "";

}

}

 

Carter Reedy
New Participant
May 13, 2020

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.

Participating Frequently
February 5, 2019

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?

New Participant
February 6, 2019

Thanks, here is a sample vtt file

https://interactiveservices-my.sharepoint.com/:u:/p/mdonohoe/EZHmYzi50lVFpSXlesotcYQBHqy-WMzrbSX6VRKJ0qMptw?e=FZl82P

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

New Participant
January 27, 2019

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!

New Participant
January 18, 2019

Is there a way to adapt this script to read VTT files instead of SRTs?

January 18, 2019

You're a genius, THANK YOU!

New Participant
November 27, 2018

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.

New Participant
October 19, 2018

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!!!

Participating Frequently
August 14, 2018

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?

New Participant
October 2, 2018

This looks great, but i am getting an unexpected expression error, any ideas on this would be helpful,

1 var subFile = “video-1.srt"

Participating Frequently
October 3, 2018

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!

James Jennings
New Participant
June 27, 2018

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.

New Participant
June 27, 2018

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...)

James Jennings
New Participant
June 28, 2018

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.