Creating primitive subtitle (SubRip/.srt) file from scratch

I had a video I wanted to add a few subtitles lines here and there, without much effort. I ran:

$ apt-cache search subtitle editor
aegisub - Advanced subtitle editor
aegisub-l10n - Aegisub language packages
gaupol - subtitle editor for text-based subtitle files
libsubtitleeditor-dev - subtitleeditor lib - development files
libsubtitleeditor0 - subtitleeditor lib - runtime files
subtitleeditor - Graphical subtitle editor with sound waves representation
python-aeidon - reading, writing and manipulating text-based subtitle files
gnome-subtitles - Subtitle editor for the GNOME Desktop environment

and installed a few of them.

I was quite a disappointing experience. These softwares are more or less working but none was easy and fast enough to use for me not to prefer just using mpv and emacs, viewing with mpv and typing relevant lines in a text file with  timestamps.

Some of these softwares looked almost ok but adding new lines that was generally inconvenient (not able to insert at the exact place the playthrough is paused, or supposed to be able to but simple not working).

So, yeah, I got the simple way and built a file like :

1:01:01 adjkajdalm kadmùlajpod jaaaaaaaa aaaaaaaa aaaaaaaaaaaaaaaaaaa aaaaaaaaaaaa
11:01:01 adjkajdalm kadmùlajp odjaaaaaaaaa aaaaaaaaaaaaaaaaaa
111:01:01 adjkajda

And wrote a fast primitive script as follows:

#!/usr/bin/perl
use strict;
my $file = "THIS";
open(IN, "< $file.txt"); # input
open(OUT, "> $file.srt");
my $count = 0;
while (<IN>) {
 next if /^\s$/; #skip empty
 $count++;
 print OUT "$count\n";
 if (/^(\d{1,3})\:(\d{2}):(\d{2})\s/) { # extract time HH:MM:SS
 my ($h, $m, $s) = ($1, $2, $3);
 s/^$h:$m:$s\s//g; # remove the time from the line
 my $duration = 3; # 3 sec average duration 
 $duration = 5 if length($_) > 34; # 5 for almost two lines
 $duration = 2 if length($_) < 15; # 2 when very short
 
 my ($hplus, $mplus) = ($h, $m);
 my $splus = ($s + $duration);
 if ($splus > 60) { $mplus = ($m + 1); $splus = ($splus - 60); }
 if ($mplus > 60) { $hplus = ($h + 1); $mplus = ($mplus - 60); }
 
 print OUT sprintf("%02d:%02d:%02d,000 --> %02d:%02d:%02d,000",
 $h, $m, $s,
 $hplus, $mplus, $splus)."\n";
 } else {
 print "$count TIME ?\n"; 
 }
 print OUT $_;
 print OUT "\n";
}
close(IN);
close(OUT);
#EOF

It requires $file to be set accordingly to the name given to the input text file, obviously.

When satisfied with the written .srt, it’s convenient to embed it in the end file:

ffmpeg -i infile.mp4 -f srt -i infile.srt -c:v copy -c:a copy -c:s mov_text outfile.mp4

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s