Mapping cultural references using subtitles and PAL to NTSC conversion.

I'm a visual junkie. Not only that, a significant percentage of the visual culture I grew up in is completely alien to my non-Russian friends. Which means, more often than not I find myself in the middle of a conversation making obscure references without much hope of getting through. Although Tarkovsky is a safe bet and so is Bekmambetov these days, the rest needs to be localized into Americana. This means two things: subtitles and PAL to NTSC conversion. And even though there are a couple of end-to-end applications for acomplishing that I always end up doing bits and pieces of this work in a variety of simple (even command-line!) tools: FFmpeg, mjpeg_tools, dvdauthor, mkisofs and, above all, awk and sed.

GTOC is your friend -- click and explore


Subtitles, are, of course, the most time consuming of the two things on the list. Make sure you schedule at least 4 times as much as the running time of the material (which for the typical movie means an entire working day) and feel free to follow these simple instructions:
  1. Prepare a transcript for the video in the native language using a SubRip format. I like it for simplicity it is just a text file with a very simple structure and it is also supported by 99% of the A/V tools. You can use any of the Free Software applications that are specifically designed for this purpose: GTK based Subtitleeditor and Java based Jubler come readily to mind. Or you can simply start MPlayer and record timestamps by hand. Whatever works for you.
  2. Now that you have your sub.srt file make sure that the timings in native language are reasonable. How much lag there has to be between something happening in the video/audio track and your subtitles is a matter of personal choice. Just make sure you are comfortable with it: $ mplayer -sub sub.srt -font ~/.fonts/Arial.ttf video.mpeg
  3. It turns out that MPlayer is pretty liberal as far as glitches and bugs in subtitle file go. It is a good idea to at least check the file for timestamps being monotonous: $ grep -- "-->" sub.srt | tr -d ':,' | sed -e 's#-->#\\n#' |\\ awk 'BEGIN { d=0; } { if ($0<d) { print $0 "<" d; } else { d=$0; } }'
  4. Translation into English is next. Make sure that you don't go overboard with it though. Each subtitle should not be longer than 50 characters (80 characters max) and the duration for each of them shouldn't be smaller than 25 characters per minute.
Ok, you're done with subtitling. Next step is to create an NTSC DVD from your PAL material. Now, in general video standard conversion is a pretty complicated thing. Especially if it is done right using motion estimated conversion algorithms. We, however, are going to cheat a little. We won't be doing any real conversion per se, we will just pretend that our PAL footage is progressive (if it is not it needs to be deinterlaced) and as such is a good approximation of a movie reel.

Movies run 24 frames per second, PAL runs at 25. All in all it is not that much of a strech really, although a dreaded
PAL speedup issue will crop up and it'll make us fiddle with the audio track. Actually, in our case it'll be more appropriate to call it a "PAL slowdown" issue and the only reason I'm trading audio fidelity for video fidelity here is because the audio track is in a foreign language to begin with. Now, assuming that your original material is coming from a PAL DVD here's what it takes to: deinterlace its VOBs, scale them to fit an NTSC resolution and encode all that into a 2:3 pulldown flagged MPEG2: $ ffmpeg -i <(cat \*.VOB) -f yuv4mpegpipe - |\\ yuvdeinterlace | yuvscaler -M BICUBIC -O SIZE_720x480 |\\ mpeg2enc -n n -f 8 -F 4 -a 2 -p -o /tmp/pal_slowdown.mpeg Once again -- the trick here is that we DO NOT change the framerate by interpolating missing fields. We are encoding the NTSC DVD using a Telecine Process as though the original was a movie reel.

Well, now that the movie got 25/24 (4.166%) longer we have to rescale the audio track as well. Fortunately, the jack of all trades in the audio kingdom -- Audacity has a special filter just for that. It is called Change tempo and it usually works pretty well: $ ffmpeg -i <(cat \*.VOB) /tmp/audio.wav $ audacity /tmp/audio.wav # apply "Change tempo" $ ffmpeg -i /tmp/audio.wav -ab 128000 /tmp/audio.mp2 $ rm /tmp/audio.wav Now all that left for you to do is to multiplex the new audio track from the freshly minted /tmp/audio.mp2 and the newly encoded MPEG2 from /tmp/pal_slowdown.mpeg into the, still subtitleless, MPEG2 stream /tmp/nosubs.mpeg: $ mplex -f8 -o /tmp/nosubs.mpeg /tmp/pal_slowdown.mpeg /tmp/audio.mp2 Ok, it seems like all we have left to do at this point is to multiplex subtitles into the MPEG2 stream and enjoy an NTSC DVD in its full glory. Well, there's a catch -- we have to stretch subtitles in the same way we stretched audio track: all timestamps have to be multiplied by 1.043: cat sub.srt | awk ' \\ function fwd(t) { split(t, ar, ":"); split(ar[3], arr, ","); ar[3]=arr[1]; ar[4]=arr[2]; return ar[1]\*60\*60\*1000+ ar[2]\*60\*1000+ ar[3]\*1000+ ar[4]; } function rev(ts) { ts=ts/1000; printf("%02d:%02d:%02d,%03d", (ts/(60\*60\*1000))%24, (ts/(60\*1000))%60, (ts/1000)%60, ts%1000); } /-->/ { rev(fwd($1)\*1043); printf " --> " ; rev(fwd($3)\*1043); print ""; next; } { print $0; }' > slowed_down.srt Done. Next step -- embedding subtitles into an MPEG2 stream. We are going to do this in style, though. We don't want to simply permanently burn the image of subtitles onto each frame. We want them to behave like they do on commercial DVDs: be switchable on/off from the remote control and also be "on" by default. Fortunately, the tool from a dvdauthor package called spumux is exactly the right tool for the job. Now in order for it to work we have to give it an XML configuration file and also store an appropriate TTF font in a ~/.spumux subdirectory (I like Bitstream's Vera -- it looks nice and it is free): $ cp ~/.fonts/Vera.ttf ~/.spumux/ $ cat spumux.xml <subpictures> <stream> <textsub filename="slowed_down.srt" characterset="ISO8859-1" fontsize="25.0" font="Vera.ttf" horizontal-alignment="center" vertical-alignment="bottom" left-margin="60" right-margin="60" top-margin="20" bottom-margin="30" subtitle-fps="30" movie-fps="30" movie-width="720" movie-height="480" /> </stream> </subpictures> $ spumux -P spumux.xml < /tmp/nosubs.mpeg > final.mpeg We're almost done. The very last step is to author a DVD content with a dvdauthor utility and create an ISO image. Just as spumux, dvdauthor needs an XML configuration file and since we wanted our subtitles to be on by default we have to instruct it to write into the register of the DVDs virtual machine (yep, DVDs are just like Java -- they have a virtual machine). That's what that weird looking subtitle=64; is there for: $ cat dvd.xml <dvdauthor> <vmgm /> <titleset> <titles> <pgc> <pre> subtitle=64; </pre> <vob file="final.mpeg" /> </pgc> </titles> </titleset> </dvdauthor> $ dvdauthor -o dvd -x dvd.xml $ mkisofs -dvd-video -udf -o dvd.iso -V RomanProductions ./dvd Done! Go ahead, burn a bunch of DVD-R and start introducing your American friends into the wonderful world of totally foreign things.



linux(1)> grep -- "-->" sub.srt | tr -d ':,' | sed -e 's#-->#\\#' |\\
awk   'BEGIN { d=0; } { if ($0linux(2)> ffmpeg -i <(cat \*.VOB) -f yuv4mpegpipe - |\\
yuvdeinterlace  | yuvscaler -M BICUBIC -O SIZE_720x480 |\\
mpeg2enc  -n n -f 8 -F 4  -a 2 -p -o /tmp/pal_slowdown.mpeg
linux(3)> ffmpeg -i <(cat \*.VOB) /tmp/audio.wav
linux(4)> audacity /tmp/audio.wav # apply "Change tempo"
linux(5)> ffmpeg -i /tmp/audio.wav -ab 128000 /tmp/audio.mp2
linux(6)> rm /tmp/audio.wav
linux(7)> mplex -f 8 -o /tmp/nosubs.mpeg /tmp/pal_slowdown.mpeg /tmp/audio.mp2
linux(8)> cat sub.srt | awk ' \\
function fwd(t) { split(t, ar, ":");
                  split(ar[3], arr, ",");
                  ar[3]=arr[1]; ar[4]=arr[2];
                  return ar[1]\*60\*60\*1000+ar[2]\*60\*1000+ar[3]\*1000+ar[4];
                }
function rev(ts) { ts=ts/1000;
                   printf("%02d:%02d:%02d,%03d", 
                           (ts/(60\*60\*1000))%24, 
                              (ts/(60\*1000))%60, 
                          (ts/1000)%60, ts%1000); 
                 } 
/-->/ { rev(fwd($1)\*1043); 
        printf " --> " ; 
        rev(fwd($3)\*1043); 
        print ""; 
        next;  
      } 
      { print $0; }' > slowed_down.srt
linux(9)> cp ~/.fonts/Vera.ttf ~/.spumux/
linux(10)> cat spumux.xml
<subpictures>
   <stream>
      <textsub filename="slowed_down.srt" characterset="ISO8859-1"
         fontsize="25.0" font="Vera.ttf" horizontal-alignment="center"
         vertical-alignment="bottom" left-margin="60" right-margin="60"
         top-margin="20" bottom-margin="30" subtitle-fps="30"
         movie-fps="30" movie-width="720" movie-height="480"
      />
   </stream>
</subpictures>
linux(11)> spumux -P  spumux.xml < /tmp/nosubs.mpeg > final.mpeg
linux(12)> cat dvd.xml
<dvdauthor>
    <vmgm />
    <titleset>
        <titles>
            <pgc>
                <pre> subtitle=64; </pre>
                <vob file="final.mpeg" />
            </pgc>
        </titles>
    </titleset>
</dvdauthor>
linux(13)> dvdauthor -o dvd -x dvd.xml
linux(14)> mkisofs -dvd-video -udf -o dvd.iso -V RomanProductions ./dvd
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

rvs

Search

Top Tags
Archives
« July 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today