4
"""This module is for adding subtitles to MPEG video files using spumux.
6
Defined here are two functions for adding subtitles to an MPEG file:
8
add_subpictures: Add image files (.png)
9
add_subtitles: Add subtitle files (.sub, .srt etc.)
11
Use these if you just want to add subpictures or subtitles, and don't want
12
to think much about the XML internals.
19
from libtovid import utils
20
from libtovid import xml
22
# spumux XML elements and valid attributes
31
'horizontal-alignment',
41
'x0', 'y0', # Upper-left corner, inclusively
42
'x1', 'y1', # Lower-right corner, exclusively
43
'up', 'down', 'left', 'right']
52
'transparent', # color code
53
'force', # 'yes' (force display, required for menus)
54
'autooutline', # 'infer'
56
'autoorder', # 'rows' or 'columns'
62
### Internal functions
65
def get_xml(textsub_or_spu):
66
subpictures = xml.Element('subpictures')
67
stream = subpictures.add('stream')
68
stream.add_child(textsub_or_spu)
69
return str(subpictures)
72
def get_xmlfile(textsub_or_spu):
73
"""Write spumux XML file for the given Textsub or Spu element, and
74
return the written filename.
76
xmldata = get_xml(textsub_or_spu)
77
xmlfile = utils.temp_file(suffix=".xml")
78
xmlfile.write(xmldata)
83
def mux_subs(subtitle, movie_filename, stream_id=0):
84
"""Run spumux to multiplex the given subtitle with an .mpg file.
86
subtitle: Textsub or Spu element
87
movie_filename: Name of an .mpg file to multiplex subtitle into
88
stream_id: Stream ID number to pass to spumux
90
# Create temporary .mpg file in the same directory
91
base_dir = os.path.dirname(movie_filename)
92
subbed_filename = temp_name(suffix=".mpg", dir=base_dir)
93
# spumux xmlfile < movie_filename > subbed_filename
94
spumux = Command('spumux',
97
spumux.run_redir(movie_filename, subbed_filename)
101
os.remove(movie_filename)
102
# Rename temporary file to new file
103
os.rename(subbed_filename, movie_filename)
104
# Remove the XML file
105
os.remove(xmlfile.name)
109
### Exported functions
112
def add_subpictures(movie_filename, select, image=None, highlight=None):
113
"""Adds PNG image subpictures to an .mpg video file to create a DVD menu.
115
select: Image shown as the navigational selector or "cursor"
116
image: Image shown for non-selected regions
117
highlight: Image shown when "enter" is pressed
119
All images must be indexed, 4-color, transparent, non-antialiased PNG.
120
Button regions are auto-inferred.
122
spu = xml.Element('spu')
128
# TODO Find a good default outlinewidth
129
spu.set(autooutline=infer, outlinewidth=10)
130
# TODO: Support explicit button regions
131
mux_subs(spu, movie_filename)
134
def add_subtitles(movie_filename, sub_filenames):
135
"""Adds one or more subtitle files to an .mpg video file.
137
movie_filename: Name of .mpg file to add subtitles to
138
sub_filenames: Filename or list of filenames of subtitle
139
files to include (.sub/.srt etc.)
142
infile = load_media(movie_filename)
143
width, height = infile.scale
145
# Convert sub_filenames to list if necessary
146
if type(sub_filenames) == str:
147
sub_filenames = [sub_filenames]
148
# spumux each subtitle file with its own stream ID
149
for stream_id, sub_filename in enumerate(sub_filenames):
150
# <textsub attribute="value" .../>
151
textsub = xml.Element('textsub')
152
textsub.set(movie_fps=infile.fps,
155
filename=sub_filename)
156
mux_subs(textsub, movie_filename, stream_id)
159
if __name__ == '__main__':
160
print "spumux XML examples"
162
print "Subpicture example:"
163
spu = xml.Element('spu')
164
spu.add('button', name='but1', down='but2')
165
spu.add('button', name='but2', up='but1')
168
print "Text subtitle example:"
169
textsub = xml.Element('textsub')
170
textsub.set(filename='foo.sub',
173
print get_xml(textsub)