Modifying the timestamps of bmp subtitle tracks? (dvdsub, pgs, vosub, etc)

I’m writing a bash script that will help convert mkv files ripped from PAL discs to NTSC standard (so that the characters don’t sound like they’ve inhaled helium). Since this means lengthening the video/audio tracks, I need to adjust the chapter and subtitle file timestamps to match.

That’s easy enough when dealing with a .srt file. However, I’m not sure how I can do the same for bitmap subtitles such as dvdsub, pgs, etc. Is this something mkvtoolnix can help me with? I could either do this by exporting the timestamps into some sort of plain text like xml, and then import them back in after editing the timestamps. Or, if this requires editing the bytes directly, I’m not adverse to a little c programing. Only issue is I don’t know where to start with that.

It’s important that I clarify that I don’t want to use an editing program for this process. I know they exist, but they’re not made to be incorporated in a shell script. Besides, I want to learn how those programs do what they do, so that I can do it myself.

There are two features of mkvmerge/mkvextract that may help you.

The first one is the --sync option that can directly modify the timestamps of a track by adding a value and/or by multiplying with a factor. That allows you to easily scale a track synced to a 29.976 FPS track to fit to a 24 FPS track by multiplying every timestamp with 29.976/24, or to put it differently: 29.976 is 30000/1001, meaning your factor would be 30000/240024.

The second option is mkvmerge’s --timestamp option. With it you can tell mkvmerge to read timestamps for a track from a text file. You can generate those timestamps yourself, or you can use mkvextract to extract timetstamps for a track to one such file. Note though that you can only specify timestamps, meaning the duration of each subtitle frame won’t be affected — they’ll be stuck at the original duration, making this feature not well suited for modifying subtitle tracks.

The last option you talked about, modifying the timestamps directly in the source files, depends on the subtitle format in question. Each one (PGS, VobSub, DVB subs) has its own binary format & corresponding specifications (e.g. the Blu-ray specs for PGS, the DVD specs for VobSubs, DVB broadcasting specs by ETSI if I’m not mistaken for DVB subs).

If your original problem is to correct the pitch of the audio track, you have ways to do that without changing the length of audio and video.
AviSynth has scripting abilities to allow for reencoding and applying filters to audio/video. Amongst the available fitlers, I recall there were filters to correct pitch without changing the duration.
You could write a template script that you could then duplicate and edit programmaticaly while changing your video/audio inputs.

You may want to look at these filters:

AviSynth is a pretty old thing, it had its forks such has AviSynth+ or VapourSynth.
I’m suggesting this because in my experience devices can ignore informations added within the mkv file such has delays and sync at playback. I also experienced lags and weird desynchronization at playback if I would skip chapters or just fast-forward during playback.

If you just want to learn how to apply these kind of filters from a signal processing perspective, then I suggest reading the source for these filters. The tools I mentioned are open-source.

[Edit] I forgot to mention that avisynth has no reencoding capabilities out of the box, however some enconding tools support avisynth scripts as inputs.