HomeProjectsA movie Subtitle Editor

A movie Subtitle Editor

A few days ago I wanted to create Romanian subtitles for a movie that I want to watch with my friends.  After Googling around I found 4 projects that claim to do this in Linux.  These are:

  • gnome-subtitles
  • ksubtile
  • subtitleeditor
  • gaupol

All of them seemed very disappointing.

  • Gnome-subtitles uses gstreamer, which for some reason wasn't able to open my movie.
  • Ksubtile seems to be designed only to edit subtitles, but I needed to create them; all the interface is greyed out and basically couldn't do anything with it, except close it.
  • Subtitleeditor seemed more reasonable, but video playback is horrible (seek doesn't work properly) and I couldn't figure out how to make it insert current time; keyboard features are very poor (as in all GTK applications after all)—in order to work, focus must be in some bizzare position that I never quite understand.
  • Gaupol is just a miserable interface that allows you to edit subtitles (as if I couldn't do this in Emacs).

Wait!  EMACS!  Isn't there anything like this?

I found GNEVE, an Emacs-based video editor (!).  I played with it.  It promises to do a lot more than what I need, but for some reason subtitles won't be generated correctly anyway (totally wrong timing).  But nevertheless, it was cool, it has some interesting ideas that form the basis on my little project:

SESE: Simple Emacs-based Subtitle Editor

SESE is a major mode that I wrote for Emacs, based on ideas and even some code from GNEVE.  It Just Works.  It doesn't require a patched MPlayer (unlike GNEVE); I found that the default timings reported by MPlayer are more than enough for subtitles (resolution is 1/10 sec. which is pretty good).

SESE has the following simple features:

  • open MPlayer to play movie with a shortcut
  • press a shortcut at any time to start a new subtitle
  • press the same shortcut a few seconds later to end the subtitle
  • at this point, playback is paused and you can type the lines
  • you can easily seek to the subtitle prior to the caret position, with a shortcut
  • you can easily change the start/end time positions for a subtitle you already wrote (with a shortcut)
  • the file format is a “custom” one (see below); that's because it was easier to maintain; you can generate subtitles in SRT any time.

Installation

Download sese.el and put it into some directory in your Emacs's load-path.  For example, if you have the following in your ~/.emacs:

(setq load-path
      (cons (expand-file-name "~/emacs") load-path))

then you can save sese.el in ~/emacs.

Then put the following lines in your ~/.emacs:

(autoload 'sese-mode "sese" "Subtitle Editor major mode" t)
(setq auto-mode-alist
      (cons '("\\.sese\\'" . sese-mode) auto-mode-alist))

and restart Emacs.  You're now ready to start writing subtitles.

File format

I decided to implement my own simple format, rather than working directly with SRT, SUB or anything else; that's because it's easier to parse/maintain and in the future I will be able to easily generate other subtitle formats from a central file.

The .sese file format looks like this:

# MOVIE: ~/movies/foo-movie.avi

10.5 - 13.5 {
	subtitle line 1
	subtitle line 2
}

13.7 - 14.7 {
	OK.
}

So each subtitle starts with a line that contains the start time (i.e. 10.5), end time (13.5) and a bracket.  SESE is kind of picky about whitespace so—don't put a newline before the bracket.  But wait, you don't even need to write this; SESE writes it for you.

Inside the brackets, you write the text that should appear for the subtitle.  I recommend (though this is not enforced) that each line starts with a TAB character.  Of course, SESE does this for you automagically.

Good subtitles should not have more than 2 lines and no more than 60 characters per line; SESE sets the fill-column to 59.  I find longer subtitles hard to read, though sometimes they are necessary...

I recommend you to write this file in UTF8; later, when the subtitles are generated, you can easily convert that to whatever you want using M-x set-buffer-file-coding-system.

Usage

Let's say you want to write subtitles for a movie ~/movies/foo-movie.avi.  Start like this:

  1. Press C-x C-f (open file) and create a new file ~/movies/foo-movie.sese.  SESE mode will start automatically.

  2. Press C-? (usually it's control shift /) to open a movie.  Type the AVI file name with TAB completion.  Video playback will start automatically.  Note that this inserts a comment containing the video file; next time you'll press this keybinding, it'll just open the existing video without asking for a filename.

  3. Make sure the Emacs window is focused (i.e. press ALT-TAB).  MPlayer should stay on top.

  4. If it's a new file, you may need to press C-END (move the caret to end of file).

  5. Now, to start a subtitle press C-ENTER.  Start time will be inserted into your Emacs buffer.  Video playback continues; don't move the caret.

  6. To end the subtitle press C-ENTER again.  End time will be inserted as well as a set of brackets; the caret is positioned so that you only need to type the lines.  Video playback is paused.

  7. To resume playback and immediately start a new subtitle, press C-ENTER.  To resume playback without starting a new subtitle, press C-P (toggles between play/pause).

  8. To restart playback from the start time of the last subtitle, press C-] (that's right sqare bracket).

  9. While the caret is between the brackets, you can press M-[ to reset the start time of this subtitle to the current video position.  Similarly, M-] resets the end time.

  10. To render the subtitles in a format that MPlayer can use, do M-x sese-render-subtitles.  It will determine the file name based on the video file name, but it won't save the file by default—it'll just insert the generated subtitles in an Emacs buffer; you can save them with C-x C-s.

To control the video player, you can use C-, (control comma) and C-. (control dot) to seek back/forward 1 second, or M-, (meta comma) and M-. (meta dot) to seek back/forward 10 seconds.  These come in handy sometimes, but many times it will be even more convenient to just focus the MPlayer window and use it's controls.

That's all folks.  Happy subtitling!  If you can think of some improvement, please drop me a note.

Lessons I've learned

I'm not an (E)Lisp hacker so I spent a fair amount of time writing that code.

  • I noticed that string concatenation is waaaay slower than array join, pretty much like in IE's JavaScript.  But wait, there's no “join” function.  (And for some reason the ELisp info pages have gone from my Debian installation, and I can't figure out how to bring it back.)

    So I was using something like this to generate the final SRT:

    (let ((output ""))
        (while i-still-have-lines
            (generate-srt-line)
            (setq output (concat output srt-line))))
    

    That was awfully, awfully slow.  I later found mapconcat which is a lot faster.  Use it like this:

    (let ((output '()))
        (while i-still-have-lines
            (generate-srt-line)
            (setq output (append output `(,srt-line))))
        (setq output (mapconcat 'identity output "\n\n")))
    

    I would feel better to have a function named "join" that did that without me having to pass an "identity" function that basically does nothing.  I know it's easy to write, but it would be nice to just have it in the core Elisp.  Oh well.

  • Wait, what was that?  What's with the "`(," stuff?

    Again, I had to spend quite some time to dig this.  I had code like this for syntax highlighting:

    (defconst sese-fragment-regexp
      (concat sese-start-regexp sese-number-regexp))
    
    (defvar sese-font-lock-keywords
      (list
       `(sese-fragment-regexp
         (1 font-lock-keyword-face t)
         (4 font-lock-reference-face t))
    

    It didn't work because sese-fragment-regexp remains quoted; in fact, we should replace it with a string (the regexp).  So I needed to put a comma right before it.

    That's quite a horrible syntax... but as I went through the manual, it does make sense.

Comments

  • By: Frederick Noronha, Goa, IndiaMay 06 (00:10) 2008RE: A movie Subtitle Editor §

    Sounds very interesting and promising. Just what I was looking out for. Must say, I've not tried it yet, but I plan to! Thank you!

  • By: cronMay 13 (19:34) 2008RE: A movie Subtitle Editor §

    I'm looking forward to trying this out. Your introduction sounds exactly like what I was thinking as I tried to figure out how one might use subtitleeditor :-)

    "aptitude install emacs21-common-non-dfsg" will probably bring back the emacs documentation to your debian, by the way.

    • By: cronMay 13 (22:21) 2008RE[2]: A movie Subtitle Editor §

      I didn't have "filladapt", so I downloaded it from http://www.wonderworks.com/download/filladap…

      My emacs (21.4.1) doesn't have a "looking-back" function, so I copied the hack described at the end of http://moinmoin.wikiwikiweb.de/EmacsForMoinM… into sese.el to add one.

      After that, it's all working nicely, except that my mplayer doesn't support seeking to arbitrary positions for all file formats, so the C-] is off by a few seconds for some files :-/

      Anyway, very nice work, thanks for sharing!

    • By: mishooMay 13 (22:37) 2008RE[2]: A movie Subtitle Editor §

      Thanks! :-.  Damn, that *almost* worked.  I still can't find the "Elisp" item in the "info" table of contents, but that line did install some docs that I was missing (such as i.e. cc-mode documentation).

      I'm wondering why are they now in "non-free"...?

      • By: cronMay 22 (02:57) 2008RE[3]: A movie Subtitle Editor §

        Debian people believe that the GNU Free Documentation License is Evil (because of the "Invariant Sections" requirement, I think) and therefore the emacs documentation must be hidden away in a cryptically-named package in non-free. In the case of the elisp-manual, it looks like they didn't even move it to non-free, they just removed it from the distro. Bah.

        478 subtitles later, I still like your mode. Having a Real Editor to edit subtitles (and their timings!) is very pleasant, especially for long monologues. I had to remove the C-p binding, though... I needed the "real" C-p all the time to go back up and reedit the previous subtitles when I changed my mind about how to translate something.

        • By: mishooMay 25 (00:17) 2008RE[4]: A movie Subtitle Editor §

          “I needed the "real" C-p all the time to go back up[...]”

          Oh, sorry, I never thought of that...  My hands are trained to use the arrow keys for movement :-) (old habit since when I was a Windows freak).  I should think of a different default binding, in spirit of Emacs.

          BTW, I'm not exactly sure what I did, but I got all the documentation back.  I think this package did it: emacs22-common-non-dfsg.

        • By: mishooMay 25 (00:25) 2008RE[4]: A movie Subtitle Editor §

          Oh damn, I just noticed that you mentioned the "non-dfsg" package in your first post :).  For some reason I missed it.  Sorry..

  • By: Deniz DoganOct 09 (17:48) 2008RE: A movie Subtitle Editor §

    Haven't tried this, but it really sounds amazing! I actually thought to myself "hey, what if I made a subtitle editor for Emacs", but damn me if there weren't already a bunch of such things out there. :)

  • By: LacramioaraOct 16 (18:19) 2008RE: A movie Subtitle Editor §

    Sorry for my ignorance, when i do C-ENTER i get this message "Search failed: ^}" and well, nothing happens.
    Could you please help me with a piece of advice?

    • By: mishooOct 16 (19:55) 2008RE[2]: A movie Subtitle Editor §

      It's probably a problem with my code, but I could tell more and maybe fix it if I knew exactly what's the file you're editing and where is the cursor position when this happens.

      If you can, please email this information to mihai.bazon@gmail.com

  • By: Somebody interestedNov 13 (06:50) 2008RE: A movie Subtitle Editor §

    Wow this sound exact what I am looking for.
    Really too bad, that I havent managed to change from Win to linux yet.
    You can say what you want, but Windows is for dumb people and Linux for Smart ones.
    Yeah, too bad that I am too dumb for Linux

    • By: mishooNov 14 (23:24) 2008RE[2]: A movie Subtitle Editor §

      "Windows is for dumb people and Linux for Smart ones."

      This is true, but not strictly in the sense that you intended.  Windows is for you *because you are dumb*, and not because Windows is designed for dumb people.  Windows is a lot harder to use than Linux but brainwashed people like you can't even admit the possibility to try it.

      If that's the way you feel about yourself, let me tell you that you're not just too dumb to use Linux; you're simply too dumb, period. ;-.  Think again... try it... let us know about your experience...  and then we'll discuss.

Page info
Created:
2008/02/16 15:50
Modified:
2008/05/11 21:36
Author:
Mihai Bazon
Comments:
14
Tags:
emacs, programming
See also