{{{ ZX2C4 }}}

A certain company needed a way to easily get text-based subtitle files in a batch fashion. The DVDs were available for ripping such subtitles, but the necessary OCR work proved too time-consuming and cumbersome, even with solutions like SubRip. So, I figured that 1000s of individuals on the Internet already gladly spend their days OCRing DVD subtitles into text formats, and sure enough databases like Subscene exist. So, I built a program to wrap Subscene’s web interface, and what better way to do this is there than QtWebKit?

Subtitler's Subscene Interface

I capture the downloads by using QtWebKit’s unsupportedContent signal and parse the downloads by using QNetworkAccessManager’s finished signal. I then run the zip archive through QtIOCompressor‘s code for unzipping zips, then extract and parse the subtitles.

A significant issue is that a lot of the subtitles on Subscene are from torrents that have videos which are cut off at the beginning. The solution is to shift each subtitle in the file by a constant time interval if neccessary, so I built an interface to easily see and shift timing:

Subtitler's Preview Interface

As you can see, it’s possible to shift all the subtitles. Phonon made this page a breeze. One significant challenge was writing a search algorithm that would find the correct Subtitle based on a time falling in a certain range. It needed to be super speedy and designed for sequential searches. I came up with the following, which could use a bit of improvement:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
QString SubtitleParser::subtitleAtTime(quint64 time)
{
	QLinkedList<Subtitle>::const_iterator i;
	bool forward = true;
	for (i = m_searchPosition; i != m_subtitles.constEnd(); ) {
		if (i->isContainedIn(time)) {
			m_searchPosition = i;
			return i->text();
		}
		if (i->isAfter(time)) {
			if (i == m_subtitles.constBegin())
				break;
			--i;
			forward = false;
		} else {
			if (!forward)
				break;
			++i;
		}
	}
	return QString(' ');
}

Another challenge was dealing with QWizard and QWizardPage, particularly issues with fields and custom buttons. The field/property system is just too cumbersome to work with; there ought to be a better way of establishing centralized data with straight up pointers. The buttons on QWizard all want to be global, so adding a custom button to a single page proved a bit hackish. It’s a cool API, but just a little bit limiting. If anyone has some suggestions, let me know.

As always, the code is available on my gitweb, and I encourage you to try it out, read the code, and send me suggestions in the comments below.

Though this was designed to work on Linux, Qt, being delightfully cross-platform, also makes it possible to run the Subtitler on OSX. Check out the OSX screencast:

Direct YouTube Link

August 13, 2009 · [Print]

5 Comments to “Subtitler in Qt”

  1. Strash says:

    For me the easiest way to resync subtitles is to use a function that show the next (or the previous) line of text with a sortcut. For example, in SMplayer (a very good mplayer front-end in Qt4), if you press Y you get the next line and if you press G you get the previous. When playing a movie you just have to look for the good line, then press the good key as soon as the character starts to speak.

    Oh, by the way, SMplayer fetch automatically subtitles from OpenSubtitles.org. Maybe you can suggest to add your code to SMplayer to allow it to get subtitles from subscene too ?

  2. Cool.. Really nice app. Didn’t know there were solutions already to sync subtitles!
    Just last week itself I wrote a simple python script to sync subtitles by -20s for one of movie(Bourne Identity :D ).

    I feel such features should be added to existing players like dragon.

  3. pano says:

    If you’re interested in subtitling apps, you should take a look at subtitle composer
    http://www.kde-apps.org/content/show.php/Subtitle+Composer?content=69822
    http://sourceforge.net/projects/subcomposer/

    :-)

  4. abhi says:

    Hey tried accessing the code in ur GIT repo.. its not there.. plz add it there..

Leave a Reply