So suppose you have a nice AE project, but for some reason you also want the dialogue captioned/subtitled. There are (at least) two easy ways to do this:

1. The obvious/boring one: Create a new text layer, style/position it, enter the text for the first bit, add opacity changes or trim the layer to display the text, repeat for every single piece of dialogue, die of old age before you get to render.

2. The script way:) (ie, the one this post is about)

Now, to do this, you’ll need to do the following:

a. Copy the script provided  at the end of this post, and save it under a sensible name (such as Subtitles.jsx)

b. Create a TXT file with all the subtitles. Each one should go on its own line; in case you want several lines to be visible at the same time, you can separate them with the pipe character ( | )

c. Create / style / position a new text layer in your composition. With the layer selected, add markers (NumPad * ) every time a line should be shown / hidden

d. Run the script

e. Select the text file

That’s all there is to it :)

Below, a super quick-n-dirty preview of the result:

Subtitle script demonstration from !Rocky on Vimeo.

Also, I know this isn’t exactly IT related, nor the most optimised script ever, but it might be useful to someone :)

{
	//	Subtitle generator by !Rocky
	//	modified by Colin Harman ( http://colinharman.com/ ) to work on a Mac
	//
	//	Save this code as
	//	"subtitles.jsx"
	//
	//	Create a text file with your subtitles.
	//	Each line of text is one on-screen line.
	//	To have several lines on-screen at the same time,
	//	simply separate them with a pipe ( | ) character.
	//	eg "Character 1 talks|Character 2 interrupts"
	//
	//	Create a new text layer in your comp, adjust its position,
	//	make sure the text's centered, so it looks nice
	//	Add markers (Numpad *) where each subtitle line must be shown/hidden.
	//	With the text layer selected, run the script, and select the subtitles file.
	//	Enjoy!

	function makeSubs() {
		var layer = app.project.activeItem.selectedLayers[0];

		if (layer.property("sourceText") != null) {
			var textFile = fileGetDialog("Select a text file to open.", "");
			if (textFile != null) {
				var textLines = new Array();
				textFile.open("r", "TEXT", "????");

				while (!textFile.eof)
					textLines[textLines.length] = textFile.readln();

				textFile.close();

				var sourceText = layer.property("sourceText");
				var markers = layer.property("marker");

				for (var i = sourceText.numKeys; i >= 1; i--)
					sourceText.removeKey(i);

				var line = 0;
				var subTime, subText;
				for (var i = 1; i <= markers.numKeys; i++) {
					subTime = markers.keyTime(i);
					sourceText.setValueAtTime(0, " ");

					if ((i % 2) == 0) {
						subText = " ";
					}
					else {
						subText = textLines[line].replace("|", "\x0d\x0a");
						line++;
					}
					sourceText.setValueAtTime(subTime, new TextDocument(subText));
				}
			}
		}
	}
	makeSubs();
}