Supported formats
Subtitle formats
Hard coded formats
- These formats are handled by SP code directly. They are loaded
relatively fast and they support all available options from the
documentation (if available).
- Unicode is supported for these
formats, subtitle files can be encoded in a lot of 8, 16 and 32 bit
encodings including UTF-8 and UTF-16 (simply called Unicode in some
programs).
- Encoding is selected upon loading using the load menu in Main window.
Format |
Load |
Save |
Type |
Styles |
MicroDVD |
Yes |
Yes |
Frame |
Yes |
SubRip |
Yes |
Yes |
Time |
Yes |
SimpleTime |
Yes |
Yes |
Time |
No |
SubStation |
Yes |
Yes |
Time |
Yes |
ASS (Advanced SSA) |
Yes |
Yes |
Time |
Yes |
Subtitle processor (*.sp) |
Yes |
Yes |
Time / Frame |
Yes |
Generic text |
Yes |
No |
No timestamps |
No |
The Subtitle Processor format is an internal format based on ini
files that can be used to store all subtitle options, because it is a
"lossless" format (all options are saved). Every other format supports
only a subset of all options.
XSP (eXtensible Subtitle Parser) formats
- These formats are supported via the XSP engine. The XSP loads XML
files that define the structure of the subtitle formats and then parse
the subtitles according to the specification. They are slower than
built-in formats, but very flexible. New format can be added to SP by
only creating a new XML file.
- The only examples of subtitles in these formats I have are the
files generated by SubRip. The parser code is however quite robust and
it can probably overcome some errors in subtitle files.
Format |
Type |
Extension |
End timestamp |
DKS |
Time |
*.dks |
no |
FAB Subtitler |
Time |
*.txt |
yes |
MAC DVD Studio PRO |
Time |
*.txt |
yes |
MacSUB |
Frame |
*.scr |
yes |
MPL |
Frame |
*.mpl |
yes |
MPL 2 |
Frame |
*.mpl |
yes |
Phoenix Japanimation |
Frame |
*.pjs |
yes |
PowerDivX |
Time |
*.psb |
yes |
SubViewer 1 |
Time |
*.sub |
no |
SubViewer 2 |
Time |
*.sub |
yes |
Movie description formats
Format |
Load |
Save |
MicroDVD - MVD |
Yes |
Yes |
MVD support is limited. SP can only read the movie title and file
and one subtitle file and language tag. If there are other sections in
MVD, these are discarded. If there are more than one subtitles, only
one of them are loaded and the language tag may be incorrect.
PlayList formats
Format |
Load |
Save |
WinAMp 2.x m3u, extended |
Yes |
Yes |
PLS (widely used variation in INI format), extended |
Yes |
Yes |
M3U
Supports Winamp's #EXTINF tags, the
format is extended with
- #LOOPINF tag (since lines starting with
# are treated as comments, winamp ignore these lines and can load the
playlist).
- #PLSMDATA tag - contains movie
information for the whole playlist
- #PLSSUBS tag - contains subtitle file
for the whole playlist
- #SUBINF tag - subtitle file for a
single item
- #DATAINF tag - movie data for a single
item
The ordering of the tags does not matter, but all tags belong to the
file that follows them. The last tag before the file should be the
WinAMP's #EXTINF. The global tags (#PLSMDATA, #PLSSUBS)
can be anywhere in the file
Format of the #LOOPINF tag:
#LOOPINF:B1|0:02:42,639|E1|0:04:33,626
- #LOOPINF: - Identification of the tag
- B1 or B0 -
The loop beginning is valid (B1) or it is not valid (B0)
- 0:02:42,639 - Start time of the loop,
in the format HH:MM:SS,TTT. It must comply with this regular
expression: "(-?\d*:?\d*:?\d*)([,\.]\d*)?"
- E1 or E0 -
The loop end is valid (E1) or it is not valid (E0)
- 0:04:33,626 - End time of the loop
The fields of the tag are delimited by | (pipe). All fields are
mandatory.
Format of the #PLSMDATA and #DATAINF tags:
#PLSMDATA:imdb url|national db url|name|original
name|genre|country|year|director|actors|abstract|rating|*|Subtitles
language|viewing history|movie audio language|note
The items are delimited by the'|' char. a special '|*|' separator is
required between rating and sub language. '*' char in any data is
illegal, as well as the '|' char
Format of the #SUBINF and #PLSSUBS tags:
#SUBINF:.\Pieces.Of.April.LIMITED.DVDRip.XViD-DcN.srt
The subtitle file path is after the colon.
PLS
A regular INI file with defined sections and keys:
- [playlist] - all items are in this
section
- NumberOfEntries - number of items in
the playlist
- File%d - media file, indexed from 1
- Title%d - item's title
- Length%d - item's duration
SP understands additional keys
- SP_MainSubFile - subtitle file for
whole playlist
- SP_MainMoviedata - movie data in the
same format as the #PLSMDATA tag (after the ':')
- SP_LoopInfo%d - loop information for
the item in the same format as #LOOPINF (after the ':')
- SP_SubFile%d - subtitle file for the
item
- SP_MovieData%d - movie data for the item
Multimedia formats
Theoretically all formats that are supported by DirectShow (for
which you have the filters installed). You can load AVI, OGG, MPEG, ASF
or others, but only the AVI format (frame based) is fully tested. The
other formats are experimental, so be aware. You can also load sound
only files (e.g. mp3) and subtitles (time based, since the sound files
are only time-based) to display the words of a song while it is
playing. The support of sound only files is also experimental.
Movie data parser
This is INI file with defined keys and sections:
[Movie_DB_Extractor]
Name=ÈSFD - Parser's name
LongName=Èesko-Slovenská filmová databáze (9.1.2005)
- Parser's description
There are 11 items in this format:
- Expression_%d=(<div
class="nazovfilmu">.*?flag_[012346789].*?<td>)(.*?)(</td>)
- Regular expression that captures the required data
- Index_%d=2 - Index of the subexpression
that represents the data
- ExpressionDeletex_%d=<.*?> -
Regular expression to delete from the extracted data
The items are numbered from 0 to 10 (more fields may be added in
future; the order of the items is mandatory). The data fields
represented by the expressions are:
- IMDB ID
- National DB ID
- Name
- Original name
- Genre
- Country
- Year
- Directed by
- Actors
- Abstract
- Rating
For the detailed syntax of regular expressions see http://RegExpStudio.com, where is
the TRegExpr library described. The expressions should have
subexpressions, that determine the boundaries. Example:
(<div
class="nazovfilmu">.*?flag_[012346789].*?<td>)(.*?)(</td>)
This has 3 subexpressions:
- (<div
class="nazovfilmu">.*?flag_[012346789].*?<td>) -
determines the starting marker (index 1)
- (.*?) - the subexpression that
represents the data (index 2)
- (</td>) - Ending delimiter (index
3)
By the Index_%d key the index of the
expression that represents the data is specified (index=0 means the
whole expression).
All expressions are executed with the 'i' modifier, they are
case-insensitive.
When the web page does not contain some of these data fields, the
appropriate expression should be empty.
XSP Definition file
Here is an example XSP definition file. It is XML file, SP checks
for required tags and displays errors when they are not present. All
XSP definitions are stored in data\SubtitleFormats.zip, other files are
not loaded by SP.
Commented example:
<?xml version='1.0' encoding='ISO-8859-1' ?>
<SubtitleParser>
<!-- everything is case-sensitive -->
<!-- IDs 0..9 are reserved for internal loaders, 10..127
reserved by SP author, 128+ available -->
<Information name="SubViever 2" extension="sub" type="time"
id="10" />
<!-- if the expression is found in the file, the file will be
considered as
being in this format. Most times
it is suitable to use the exp. for Subtitle -->
<AutoDetect
expression="(?i-s)((\d*:\d*:\d*.\d*),(\d*:\d*:\d*.\d*)).*[\n\r]{1,2}(.*)"
/>
<!-- remempty - remove empty sybtitles (def. yes), fillendts
- use sub start to fill previous sub end (def. no)
(usefull for formats with no ends. Values possible - yes or no
-->
<LoaderOptions remempty="yes" fillendts="no" />
<!-- All index values are optional, when they are absent, the
index is considered to be 0 -->
<Credits expression="(?is)(\[information])(.*)(\[end
information])" index="2" >
<!-- the names correspond to field names in SPs
Credits editor -->
<Title expression="(?i-s)\[title](.*)" index="1"
name="Title" />
<Author expression="(?i-s)\[author](.*)"
index="1" name="Author" />
<TranslatedBy expression="(?i-s)\[source](.*)"
index="1" name="Source" />
<EditedBy expression="(?i-s)\[date](.*)"
index="1" name="Date" />
<TimedBy expression="(?i-s)\[version](.*)"
index="1" name="Version" />
<CheckedBy expression="(?i-s)\[prg](.*)"
index="1" name="Program" />
<SynchPoint expression="(?i-s)\[comment](.*)"
index="1" name="Comment" />
<UpdateAuthor expression="(?i-s)\[filepath](.*)"
index="1" name="Filepath" />
<!-- UpdateDetails expression="" index="0"
/ -->
<TimerShift expression="(?i-s)\[delay](.*)"
index="1" name="Delay" />
</Credits>
<Styles expression="(?i-s)\[subtitle](.*?)[\n|\r]{1,2}(.*)"
index="2" default="SubRipStyle">
<Style expression="(?s).*" index="0" >
<!-- when the Default property is
present, it is used in the case where the Expression is not found -->
<Name expression="" index="0"
default="SubRipStyle" />
<FontName
expression="(?i)\[font](.*?)[\n|\r|,]" index="1" />
<!-- the regexp should match a Hex
string of the color -->
<FontColor
expression="(?i)\[colf]&H(.*?)[\n|\r|,]" index="1" />
<FontSize
expression="(?i)\[size](.*?)[\n|\r|,]" index="1" />
<!-- xe is expression, b - Bold, i -
Italic, u - Underline, s - Strikeout,
Font style is present if the RE is
foound -->
<FontStyle
be="(?i)\[style](.*?)bd[\n|\r|,]" ie="(?i)\[style](.*?)it[\n|\r|,]"
ue="(?i)\[style](.*?)ud[\n|\r|,]" se="(?i)\[style](.*?)st[\n|\r|,]"
/>
</Style>
</Styles>
<Subtitles expression="(?is)(\[subtitle])(.*)" index="2" >
<!-- Type (mandatory)- frame or time or none.
Expression is mandatory -->
<Subtitle
expression="(?i-s)((\d*:\d*:\d*.\d*),(\d*:\d*:\d*.\d*)).*[\n\r]{1,2}(.*)"
index="0" >
<StartTime
expression="((\d*):(\d*):(\d*).(\d*))" type="time">
<!-- items that are not
present are not considered. FrameVal required in frame mode, one of the
TimeX in time mode -->
<!-- FrameVal index="0"/
-->
<TimeH index="2"/>
<TimeM index="3"/>
<TimeS index="4"/>
<TimeFrac index="5"/>
<!-- TimeFrame index="0"/
-->
</StartTime>
<EndTime
expression="(\d*:\d*:\d*.\d*),((\d*):(\d*):(\d*).(\d*))" type="time">
<!-- FrameVal index="0"/
-->
<TimeH index="3"/>
<TimeM index="4"/>
<TimeS index="5"/>
<TimeFrac index="6"/>
<!-- TimeFrame index="0"/
-->
</EndTime>
<Lines
expression="(?i-s)((\d*:\d*:\d*.\d*),(\d*:\d*:\d*.\d*)).*[\n\r]{1,2}(.*)"
index="4" >
<Line
expression="(?i-s)((.*?)(\[br]|$))" index="2"
/>
</Lines>
<!-- if empty then the value
'default' from 'Styles' is used -->
<Style expression="" index="0" />
</Subtitle>
</Subtitles>
<!-- Saver commands: {#Command}
Timestamp commands - last number means number of digits
These commands are processed only in the timestamp templates!
{#tt_t_h_2} time Hour
{#tt_t_m_2} time Minute
{#tt_t_s_2} time Second
{#tt_t_frac_2} time Fraction
{#tt_t_frame_2} time Frame
{#tt_f} frame (no width
spec}
{#tt_f_spaces_7}frame (fill with leading spaces)
{#tt_f_zero_7} frame (fill with leading zeros)
Other subtitles commands
{#sub_begin} - start of the iteration
{#sub_end} - end of the iteration
all text between these commands will be
iterated, including all line breaks
following the start or preceding the end
following sub commands are processed only between
sub_begin and sub_end
{#sub_start_ts} - start timestamp
{#sub_end_ts} - end timestamp
will be replaced with the resolved
timestamp template
{#sub_style} - style name
{#sub_firstlinetext} - text of the first line (when
it needs special care)
{#sub_lines_begin} - line iteraton
{#sub_lines_end}
when {#sub_firstlinetext} present,
this will start from the second
line
{#sub_linentext} - text of n-th line, available only
between sub_lines_begin and sub_lines_end.
Credits comands
{#c_title}
{#c_author}
{#c_translatedby}
{#c_editedby}
{#c_timedby}
{#c_checkedby}
{#c_synchpoint}
{#c_updateauthor}
(#c_updatedetails}
{#c_timershift}
Styles commands
{#s_begin} - start of the styles iteration
{#s_end} - end of the iteration
following commands only available between style
iterators
{#s_name} style name
{#s_fontname}
{#s_fontcolor}
{#s_fontsize}
{#s_fontstyle}
styles color commands - only in the color template
{#col_hex_r}
{#col_hex_g}
{#col_hex_b}
General commands
{#newline} - use when you need to add new line. XML
removes sequences ov newline markers so
if more than one nl is needed, use #newline instead of the second
nl
{#space} - use when more spaces in a row
are needed
{#tab} -
tabelator
-->
<SubtitleSaver>
<Options>
<!-- Line breaks: set crlf for dos,
lf for unix, cr for mac.
All linebreaks in Template are replaced
with this value. Default is crlf
(when the value could not be read from
xml -->
<LineBreak value="crlf" />
<!-- Round time to a specific number
of decimal places. negative number means
digits
after the decimal separator, positive digits before the separator -->
<TimeRoundoff decimals="-2" />
<!--Empty sub ends - write empty
subtitles to limit the duration
(suitable when the format has no end TS)
public - will be configurable in the
Setting screen
value - yes or no, default no
tolerance - the empty subs will be
written only if the difference between the
sub end and the next sub start is greater than this value (in frames)
-->
<EmptySubEnds public="no" value="no"
tolerance="1" />
<!-- optional timestamp templates for
formats with multiple types -->
<TimestampTemplates public="no">
<!-- timeStamp template -
actual template, public name - the name in the combo in Configuration
-->
<TimeStamp
template="{#tt_t_h_2}:{#tt_t_m_2}:{#tt_t_s_2}.{#tt_t_frac_2}"
publicname="HH:MM:SS.FF" />
</TimestampTemplates>
<Styles>
<FontStyle be="bd,"
ie="it," ue="ud," se="st," />
<LimitStyle
value="SubRipStyle" />
<ColorTemplate
value="&H{#col_hex_b}{#col_hex_g}{#col_hex_r}" />
</Styles>
</Options>
<Template>
[INFORMATION]
[TITLE]{#c_title}
[AUTHOR]{#c_author}
[SOURCE]{#c_translatedby}
[DATE]{#c_editedby}
[VERSION]{#c_timedby}
[PRG]{#c_checkedby}
[FILEPATH]{#c_updateauthor}
[DELAY]{#c_timershift}
[CD TRACK]1
[COMMENT]{#c_synchpoint}
[END INFORMATION]
[SUBTITLE]
{#s_begin}[COLF]{#s_fontcolor},[STYLE]{#s_fontstyle}[SIZE]{#s_fontsize},[FONT]{#s_fontname}{#s_end}
{#sub_begin}{#sub_start_ts},{#sub_end_ts}
{#sub_firstlinetext}{#sub_lines_begin}[br]{#sub_linentext}{#sub_lines_end}{#newline}
{#sub_end}</Template>
</SubtitleSaver>
</SubtitleParser>