Changes of Revision 6

tovid.changes Changed
x
 
1
@@ -1,4 +1,11 @@
2
 -------------------------------------------------------------------
3
+Sat Mar 14 15:34:58 UTC 2015 - aloisio@gmx.com
4
+
5
+- Update to 0.35
6
+  * full changelog at http://tovid.wikia.com/wiki/Tovid_changelog 
7
+- Fixed build for 13.2 and newer
8
+
9
+-------------------------------------------------------------------
10
 Fri Dec 26 15:40:08 UTC 2014 - obs@botter.cc
11
 
12
 - Require /usr/bin/mkisofs instead of just mkisofs [PM-118] 
13
tovid.spec Changed
44
 
1
@@ -10,13 +10,13 @@
2
 
3
 Summary:        Video conversion and DVD authoring tools
4
 Name:           tovid
5
-Version:        0.34
6
+Version:        0.35
7
 Release:        0.pm.1
8
 Group:          Productivity/Multimedia/Video/Editors and Convertors
9
-License:        GNU General Public License version 2 or later (GPLv2 or later)
10
+License:        GPL-2.0+
11
 Url:            http://tovid.sourceforge.net/
12
 # http://tovid.googlecode.com/files/tovid-%{version}.tar.gz
13
-Source:         tovid-%{version}.tar.bz2
14
+Source:         tovid-%{version}.tar.gz
15
 Source90:       %{name}-rpmlintrc
16
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root
17
 %if %suse_version > 1110
18
@@ -46,7 +46,11 @@
19
 %endif
20
 Requires:       python-cairo
21
 Requires:       python-imaging
22
-Requires:       python-wxGTK
23
+%if 0%{?suse_version} >= 1320
24
+Requires:       python-wxGTK >= 3.0
25
+%else
26
+Requires:       python-wxGTK < 3.0
27
+%endif
28
 Requires:       sox
29
 Requires:       transcode
30
 Requires:       vcdimager
31
@@ -66,7 +70,11 @@
32
 BuildRequires:  normalize
33
 BuildRequires:  python-cairo
34
 BuildRequires:  python-imaging
35
-BuildRequires:  python-wxGTK
36
+%if 0%{?suse_version} >= 1320
37
+BuildRequires:  python-wxGTK >= 3.0
38
+%else
39
+BuildRequires:  python-wxGTK < 3.0
40
+%endif
41
 BuildRequires:  sox
42
 BuildRequires:  transcode
43
 BuildRequires:  vcdimager
44
tovid-0.34.tar.bz2/libtovid/author.py Deleted
265
 
1
@@ -1,263 +0,0 @@
2
-"""This module is for authoring a DVD or (S)VCD using dvdauthor or vcdimager.
3
-"""
4
-
5
-__all__ = [
6
-    'Disc',
7
-    'Menu',
8
-    'Video',
9
-    'Group',
10
-    'Titleset',
11
-    'vcdimager_xml',
12
-    'dvdauthor_xml',
13
-]
14
-
15
-from libtovid import xml
16
-
17
-
18
-###
19
-### Supporting classes
20
-###
21
-
22
-class Video:
23
-    """A video title for inclusion on a video disc.
24
-    """
25
-    def __init__(self, filename, title=''):
26
-        self.filename = filename
27
-        self.title = title
28
-        self.chapters = []
29
-
30
-
31
-class Group:
32
-    """A group title for inclusion on a video disc.
33
-    """
34
-    def __init__(self, filenames, title):
35
-        self.filenames = filenames
36
-        self.title = title
37
-
38
-
39
-class Menu:
40
-    """A menu for navigating the titles on a video disc.
41
-    """
42
-    def __init__(self, filename='', videos=None):
43
-        """Create a menu linking to the given `Video`\s."""
44
-        self.filename = filename
45
-        self.videos = videos or []
46
-
47
-    def add(self, video):
48
-        """Add a `Video` to the Menu."""
49
-        self.videos.append(video)
50
-
51
-
52
-class Titleset:
53
-    """A group of `Video`\s, with an optional `Menu`.
54
-    """
55
-    def __init__(self, menu=None, videos=None):
56
-        """Create a Titleset containing the given `Video`\s.
57
-        """
58
-        self.menu = menu
59
-        self.videos = videos or []
60
-
61
-    def add(self, video):
62
-        """Add a `Video` to the Titleset."""
63
-        self.videos.append(video)
64
-
65
-
66
-class Disc:
67
-    """A video disc containing one or more `Titleset`\s, and an optional
68
-    top `Menu` for navigating to each Titleset.
69
-
70
-    """
71
-    def __init__(self, name='Untitled', format='dvd', tvsys='ntsc',
72
-                 titlesets=None):
73
-        """Create a Disc with the given properties.
74
-
75
-            format
76
-                'vcd', 'svcd', or 'dvd'
77
-            tvsys
78
-                'pal' or 'ntsc'
79
-            title
80
-                String containing the title of the disc
81
-            titlesets
82
-                List of `Titleset` objects
83
-        """
84
-        self.name = name
85
-        self.format = format
86
-        self.tvsys = tvsys
87
-        self.topmenu = None
88
-        self.titlesets = titlesets or []
89
-
90
-
91
-
92
-###
93
-### Internal functions
94
-###
95
-
96
-def _add_titleset(titleset, ts_id, segment_items, sequence_items, pbc):
97
-    """Add titleset content to a vcdimager XML structure. This function is
98
-    used internally, mainly to keep `vcdimager_xml` from being too long.
99
-    """
100
-    menu = titleset.menu
101
-    videos = titleset.videos
102
-    # Add menu
103
-    if menu:
104
-        segment_items.add('segment-item', src=menu.filename,
105
-                          id='seg-menu-%d' % ts_id)
106
-        # Add menu to pbc
107
-        selection = pbc.add('selection', id='select-menu-%d' % ts_id)
108
-        selection.add('bsn', '1')
109
-        # Link back to topmenu (not sure what'll happen if there isn't one...)
110
-        selection.add('return', ref='select-topmenu')
111
-        selection.add('loop', '0', jump_timing='immediate')
112
-        selection.add('play-item', ref='seg-menu-%d' % ts_id)
113
-        # Navigational links to titleset videos
114
-        for video_id in range(len(videos)):
115
-            selection.add('select',
116
-                          ref='play-title-%d-%d' % (ts_id, video_id))
117
-    # Add videos
118
-    for video_id, video in enumerate(videos):
119
-        # Add sequence items
120
-        sequence_item = sequence_items.add('sequence-item')
121
-        sequence_item.set(id='seq-title-%d-%d' % (ts_id, video_id),
122
-                          src=video.filename)
123
-        # Add chapter entries
124
-        for chapterid, chapter in enumerate(video.chapters):
125
-            sequence_item.add('entry', chapter, id='chapter-%d' % chapterid)
126
-        # Add playlists to pbc
127
-        playlist = pbc.add('playlist')
128
-        playlist.set(id='play-title-%d-%d' % (ts_id, video_id))
129
-        # Add prev/next links if appropriate
130
-        if 0 <= video_id < len(videos):
131
-            if 0 < video_id:
132
-                playlist.add('prev',
133
-                             ref='play-title-%d-%d' % (ts_id, video_id-1))
134
-            if video_id < len(videos) - 1:
135
-                playlist.add('next',
136
-                             ref='play-title-%d-%d' % (ts_id, video_id+1))
137
-        # Add a return link to the menu, if there is one
138
-        if menu:
139
-            playlist.add('return', ref='select-menu-%d' % ts_id)
140
-        playlist.add('wait', '0')
141
-        playlist.add('play-item', ref='seq-title-%d-%d' % (ts_id, video_id))
142
-
143
-
144
-###
145
-### Exported functions
146
-###
147
-
148
-def vcdimager_xml(disc):
149
-    """Return the vcdimager XML string for the given `Disc`.
150
-    """
151
-    assert isinstance(disc, Disc)
152
-    # XML header (will be added later)
153
-    header = '<?xml version="1.0"?>\n'
154
-    header += '<!DOCTYPE videocd PUBLIC "-//GNU/DTD VideoCD//EN"\n'
155
-    header += '  "http://www.gnu.org/software/vcdimager/videocd.dtd">\n'
156
-    # Root videocd element
157
-    attributes = {
158
-        'xmlns': 'http://www.gnu.org/software/vcdimager/1.0/',
159
-        'class': disc.format}
160
-    if disc.format == 'vcd':
161
-        attributes['version'] = '2.0'
162
-    else: # SVCD
163
-        attributes['version'] = '1.0'
164
-    root = xml.Element('videocd')
165
-    root.set(**attributes)
166
-    # Add info block
167
-    info = root.add('info')
168
-    info.add('album-id', 'VIDEO_DISC')
169
-    info.add('volume-count', '1')
170
-    info.add('volume-number', '1')
171
-    info.add('restriction', '0')
172
-    # Add pvd block
173
-    pvd = root.add('pvd')
174
-    pvd.add('volume-id', 'VIDEO_DISC')
175
-    pvd.add('system-id', 'CD-RTOS CD-BRIDGE')
176
-
177
-    # Add segment, sequence, and pbc
178
-    segment_items = root.add('segment-items')
179
-    sequence_items = root.add('sequence-items')
180
-    pbc = root.add('pbc')
181
-    # Add topmenu
182
-    if disc.topmenu:
183
-        segment_items.add('segment-item', src=disc.topmenu.filename,
184
-                          id='seg-topmenu')
185
-        selection = pbc.add('selection', id='select-topmenu')
186
-        selection.add('bsn', '1')
187
-        selection.add('loop', '0', jump_timing='immediate')
188
-        selection.add('play-item', ref='seg-topmenu')
189
-    # Add titlesets
190
-    for ts_id, titleset in enumerate(disc.titlesets):
191
-        _add_titleset(titleset, ts_id, segment_items, sequence_items, pbc)
192
-        # If we're doing a topmenu, add a link to the titleset menu
193
-        if disc.topmenu:
194
-            selection.add('select', ref='select-menu-%d' % ts_id)
195
-
196
-    # Return XML with header prepended
197
-    return header + str(root) + '\n'
198
-
199
-
200
-def dvdauthor_xml(disc):
201
-    """Return the dvdauthor XML string for the given `Disc`.
202
-    """
203
-    assert isinstance(disc, Disc)
204
-    # Root dvdauthor element
205
-    root = xml.Element('dvdauthor', dest=disc.name.replace(' ', '_'))
206
-    vmgm = root.add('vmgm')
207
-    # Add topmenu if present
208
-    if disc.topmenu:
209
-        menus = vmgm.add('menus')
210
-        menus.add('video')
211
-        pgc = menus.add('pgc', entry='title')
212
-        vob = pgc.add('vob', file=disc.topmenu.filename)
213
-        for index, titleset in enumerate(disc.titlesets):
214
-            if titleset.menu:
215
-                pgc.add('button', 'jump titleset %d menu;' % (index + 1))
216
-            else:
217
-                pgc.add('button', 'jump titleset %d;' % (index + 1))
218
-    # Add each titleset
219
-    for titleset in disc.titlesets:
220
-        menu = titleset.menu
221
-        ts = root.add('titleset')
222
-        # Add menu if present
223
-        if menu:
224
-            menus = ts.add('menus')
225
-            menus.add('video')
226
-            pgc = menus.add('pgc', entry='root')
227
-            vob = pgc.add('vob', file=menu.filename)
228
-            for index, video in enumerate(titleset.videos):
229
-                pgc.add('button', 'jump title %d;' % (index + 1))
230
-            if disc.topmenu:
231
-                pgc.add('button', 'jump vmgm menu;')
232
-        titles = ts.add('titles')
233
-        # Add a pgc for each video
234
-        for video in titleset.videos:
235
-            pgc = titles.add('pgc')
236
-            vob = pgc.add('vob', file=video.filename)
237
-            if video.chapters:
238
-                vob.set(chapters=','.join(video.chapters))
239
-            pgc.add('post', 'call menu;')
240
-    # Return XML string
241
-    return str(root) + '\n'
242
-
243
-
244
-if __name__ == '__main__':
245
-    menu1 = Menu('menu1.mpg')
246
-    videos1 = [
247
-        Video('video1.mpg'),
248
-        Video('video2.mpg'),
249
-        Video('video3.mpg')]
250
-    menu2 = Menu('menu2.mpg')
251
-    videos2 = [
252
-        Video('video4.mpg'),
253
-        Video('video5.mpg'),
254
-        Video('video6.mpg')]
255
-    titlesets = [
256
-        Titleset(menu1, videos1),
257
-        Titleset(menu2, videos2)]
258
-    disc = Disc('dvd_test', 'dvd', 'ntsc', titlesets)
259
-
260
-    print("dvdauthor XML example:")
261
-    print(dvdauthor_xml(disc))
262
-
263
-    print("vcdimager XML example:")
264
-    print(vcdimager_xml(disc))
265
tovid-0.34.tar.bz2/libtovid/backend Deleted
2
 
1
-(directory)
2
tovid-0.34.tar.bz2/libtovid/backend/__init__.py Deleted
9
 
1
@@ -1,7 +0,0 @@
2
-"""Backends, which do some task using a command-line program.
3
-
4
-This module is split into submodules, each named after the command-line
5
-program they predominantly rely on. Backends which use several of these
6
-submodules may be defined here in ``__init__.py``.
7
-"""
8
-
9
tovid-0.34.tar.bz2/libtovid/backend/ffmpeg.py Deleted
181
 
1
@@ -1,179 +0,0 @@
2
-"""Video encoding and identification using ``ffmpeg``.
3
-"""
4
-
5
-__all__ = [
6
-    'encode',
7
-    'encode_audio',
8
-    'identify',
9
-]
10
-
11
-import re
12
-from libtovid import log
13
-from libtovid import cli
14
-
15
-def encode(source, target, **kw):
16
-    """Encode a multimedia video using ffmpeg.
17
-
18
-        source
19
-            Input `~libtovid.media.MediaFile`
20
-        target
21
-            Output `~libtovid.media.MediaFile`
22
-        kw
23
-            Keyword arguments to customize encoding behavior
24
-
25
-    Supported keywords:
26
-
27
-        quant
28
-            Minimum quantization, from 1-31 (1 being fewest artifacts)
29
-        vbitrate
30
-            Maximum video bitrate, in kilobits per second.
31
-        abitrate
32
-            Audio bitrate, in kilobits per second
33
-        interlace
34
-            'top' or 'bottom', to do interlaced encoding with
35
-            top or bottom field first
36
-
37
-    For example::
38
-
39
-        ffmpeg_encode(source, target, quant=4, vbitrate=7000)
40
-    """
41
-    cmd = cli.Command('ffmpeg', '-y', '-i', source.filename)
42
-
43
-    # Use format/tvsys that ffmpeg knows about
44
-    if target.format in ['vcd', 'svcd', 'dvd']:
45
-        cmd.add('-tvstd', target.tvsys,
46
-                '-target', '%s-%s' % (target.tvsys, target.format))
47
-
48
-    # Interpret keyword arguments
49
-    if 'quant' in kw:
50
-        cmd.add('-qmin', kw['quant'], '-qmax', 31)
51
-    if 'vbitrate' in kw:
52
-        cmd.add('-b', '%dk' % kw['vbitrate'])
53
-    if 'abitrate' in kw:
54
-        cmd.add('-ab', '%dk' % kw['abitrate'])
55
-    if 'interlace' in kw:
56
-        if kw['interlace'] == 'bottom':
57
-            cmd.add('-top', 0, '-flags', '+alt+ildct+ilme')
58
-        elif kw['interlace'] == 'top':
59
-            cmd.add('-top', 1, '-flags', '+alt+ildct+ilme')
60
-
61
-    # Frame rate and audio sampling rate
62
-    cmd.add('-r', target.fps,
63
-            '-ar', target.samprate)
64
-
65
-    # Convert scale/expand to ffmpeg's padding system
66
-    if target.scale:
67
-        cmd.add('-s', '%sx%s' % target.scale)
68
-        # Letterbox if necessary
69
-        if target.expand != target.scale:
70
-            e_width, e_height = target.expand
71
-            s_width, s_height = target.scale
72
-            h_pad = (e_width - s_width) / 2
73
-            v_pad = (e_height - s_height) / 2
74
-            if h_pad > 0:
75
-                cmd.add('-padleft', h_pad, '-padright', h_pad)
76
-            if v_pad > 0:
77
-                cmd.add('-padtop', v_pad, '-padbottom', v_pad)
78
-
79
-    # Aspect
80
-    if target.widescreen:
81
-        cmd.add('-aspect', '16:9')
82
-    else:
83
-        cmd.add('-aspect', '4:3')
84
-
85
-    cmd.add(target.filename)
86
-    cmd.run()
87
-
88
-
89
-def encode_audio(source, audiofile, target):
90
-    """Encode the audio stream in a source file to a target format, saving
91
-    to the given filename.
92
-
93
-        source
94
-            Input `~libtovid.media.MediaFile`
95
-        audiofile
96
-            Filename for encoded audio
97
-        target
98
-            Output `~libtovid.media.MediaFile`
99
-
100
-    If no audio is present in the source file, encode silence.
101
-    """
102
-    cmd = cli.Command('ffmpeg')
103
-
104
-    # If source has audio, encode it
105
-    if source.has_audio:
106
-        cmd.add('-i', source.filename)
107
-    # Otherwise, encode silence (minimum 4 seconds)
108
-    else:
109
-        cmd.add('-f', 's16le', '-i', '/dev/zero')
110
-        if source.length < 4:
111
-            cmd.add('-t', '4.0')
112
-        else:
113
-            cmd.add('-t', '%f' % source.length)
114
-
115
-    cmd.add('-vn', '-ac', '2', '-ab', '224k')
116
-    cmd.add('-ar', target.samprate)
117
-    cmd.add('-acodec', target.acodec)
118
-    cmd.add('-y', audiofile)
119
-
120
-    cmd.run()
121
-
122
-
123
-from libtovid.media import MediaFile
124
-
125
-def identify(filename):
126
-    """Identify a video file using ffmpeg, and return a
127
-    `~libtovid.media.MediaFile` with the video's specifications.
128
-    """
129
-    result = MediaFile(filename)
130
-
131
-    cmd = cli.Command('ffmpeg', '-i', filename)
132
-    cmd.run(capture=True)
133
-
134
-    # ffmpeg puts its output on stderr
135
-    output = cmd.get_errors()
136
-
137
-    video_line = re.compile(''
138
-        'Stream (?P<tracknum>[^:]+): Video: ' # Track number (ex. #0.0)
139
-        '(?P<vcodec>[^,]+), '                 # Video codec (ex. mpeg4)
140
-        '(?P<colorspace>[^,]+), '             # Color space (ex. yuv420p)
141
-        '(?P<width>\d+)x(?P<height>\d+), '    # Resolution (ex. 720x480)
142
-        '((?P<vbitrate>\d+) kb/s, )?'         # Video bitrate (ex. 8000 kb/s)
143
-        '(?P<fps>[\d.]+)')                    # FPS (ex. 29.97 fps(r))
144
-
145
-    audio_line = re.compile(''
146
-        'Stream (?P<tracknum>[^:]+): Audio: ' # Track number (ex. #0.1)
147
-        '(?P<acodec>[^,]+), '                 # Audio codec (ex. mp3)
148
-        '(?P<samprate>\d+) Hz, '              # Sampling rate (ex. 44100 Hz)
149
-        '(?P<channels>[^,]+), '               # Channels (ex. stereo)
150
-        '(?P<abitrate>\d+) kb/s')             # Audio bitrate (ex. 128 kb/s)
151
-
152
-    # Parse ffmpeg output and set MediaFile attributes
153
-    for line in output.split('\n'):
154
-        video_match = video_line.search(line)
155
-        audio_match = audio_line.search(line)
156
-
157
-        if video_match:
158
-            m = video_match
159
-            result.vcodec = m.group('vcodec')
160
-            result.scale = (int(m.group('width')),
161
-                            int(m.group('height')))
162
-            result.expand = result.scale
163
-            result.fps = float(m.group('fps'))
164
-            if m.group('vbitrate'):
165
-                result.vbitrate = int(m.group('vbitrate'))
166
-
167
-        elif audio_match:
168
-            m = audio_match
169
-            result.acodec = m.group('acodec')
170
-            result.samprate = int(m.group('samprate'))
171
-            result.abitrate = int(m.group('abitrate'))
172
-            if m.group('channels') == '5.1':
173
-                result.channels = 6
174
-            elif m.group('channels') == 'stereo':
175
-                result.channels = 2
176
-            else:
177
-                result.channels = 1
178
-
179
-    return result
180
-
181
tovid-0.34.tar.bz2/libtovid/backend/mpeg2enc.py Deleted
222
 
1
@@ -1,220 +0,0 @@
2
-"""Video and frame encoding using ``mpeg2enc``.
3
-"""
4
-
5
-__all__ = [
6
-    'encode',
7
-    'encode_video',
8
-    'encode_frames',
9
-]
10
-
11
-# TODO: Filter out some of the inter-backend dependencies
12
-
13
-import os, glob
14
-from libtovid import log
15
-from libtovid import util
16
-from libtovid import cli
17
-from libtovid.backend import mplex, mplayer, ffmpeg
18
-
19
-def encode(source, target, **kw):
20
-    """Encode a multimedia video using mplayer|yuvfps|mpeg2enc.
21
-
22
-        source
23
-            Input `~libtovid.media.MediaFile`
24
-        target
25
-            Output `~libtovid.media.MediaFile`
26
-        kw
27
-            Keyword arguments to customize encoding behavior
28
-
29
-    Supported keywords:
30
-
31
-        None yet
32
-
33
-    """
34
-    log.warning("This encoder is very experimental, and may not work.")
35
-
36
-    outname = target.filename
37
-    # YUV raw video FIFO, for piping video from mplayer to mpeg2enc
38
-    yuvfile = '%s.yuv' % outname
39
-    if os.path.exists(yuvfile):
40
-        os.remove(yuvfile)
41
-
42
-    # Filenames for intermediate streams (ac3/m2v etc.)
43
-    # Appropriate suffix for audio stream
44
-    if target.format in ['vcd', 'svcd']:
45
-        audiofile = '%s.mp2' % outname
46
-    else:
47
-        audiofile = '%s.ac3' % outname
48
-    # Appropriate suffix for video stream
49
-    if target.format == 'vcd':
50
-        videofile = '%s.m1v' % outname
51
-    else:
52
-        videofile = '%s.m2v' % outname
53
-    # Do audio
54
-    ffmpeg.encode_audio(source, audiofile, target)
55
-    # Do video
56
-    mplayer.rip_video(source, yuvfile, target)
57
-    encode_video(source, yuvfile, videofile, target)
58
-    # Combine audio and video
59
-    mplex.mux(videofile, audiofile, target)
60
-
61
-
62
-
63
-def encode_video(source, yuvfile, videofile, target):
64
-    """Encode a yuv4mpeg stream to an MPEG video stream.
65
-
66
-        source
67
-            Input `~libtovid.media.MediaFile`
68
-        yuvfile
69
-            Filename of .yuv stream coming from mplayer
70
-        videofile
71
-            Filename of .m[1|2]v to write encoded video stream to
72
-        target
73
-            Output `~libtovid.media.MediaFile`
74
-
75
-    """
76
-    # TODO: Control over quality (bitrate/quantization) and disc split size,
77
-    # corresp. to $VID_BITRATE, $MPEG2_QUALITY, $DISC_SIZE, etc.
78
-    # Missing options (compared to tovid)
79
-    # -S 700 -B 247 -b 2080 -v 0 -4 2 -2 1 -q 5 -H -o FILE
80
-    pipe = cli.Pipe()
81
-
82
-    # Feed the .yuv file into the pipeline
83
-    cat = cli.Command('cat', yuvfile)
84
-    pipe.add(cat)
85
-
86
-    # Adjust framerate if necessary by piping through yuvfps
87
-    if source.fps != target.fps:
88
-        log.info("Adjusting framerate")
89
-        yuvfps = cli.Command('yuvfps')
90
-        yuvfps.add('-r', util.float_to_ratio(target.fps))
91
-        pipe.add(yuvfps)
92
-
93
-    # Encode the resulting .yuv stream by piping into mpeg2enc
94
-    mpeg2enc = cli.Command('mpeg2enc')
95
-    # TV system
96
-    if target.tvsys == 'pal':
97
-        mpeg2enc.add('-F', '3', '-n', 'p')
98
-    elif target.tvsys == 'ntsc':
99
-        mpeg2enc.add('-F', '4', '-n', 'n')
100
-    # Format
101
-    format = target.format
102
-    if format == 'vcd':
103
-        mpeg2enc.add('-f', '1')
104
-    elif format == 'svcd':
105
-        mpeg2enc.add('-f', '4')
106
-    elif 'dvd' in format:
107
-        mpeg2enc.add('-f', '8')
108
-    # Aspect ratio
109
-    if target.widescreen:
110
-        mpeg2enc.add('-a', '3')
111
-    else:
112
-        mpeg2enc.add('-a', '2')
113
-    mpeg2enc.add('-o', videofile)
114
-    pipe.add(mpeg2enc)
115
-
116
-    # Run the pipeline to encode the video stream
117
-    pipe.run()
118
-
119
-
120
-# --------------------------------------------------------------------------
121
-#
122
-# Frame encoder
123
-#
124
-# --------------------------------------------------------------------------
125
-from libtovid import standard
126
-
127
-def encode_frames(imagedir, outfile, format, tvsys, aspect, interlaced=False):
128
-    """Convert an image sequence in the given directory to match a target
129
-    `~libtovid.media.MediaFile`, putting the output stream in outfile.
130
-
131
-        imagedir
132
-            Directory containing images (and only images)
133
-        outfile
134
-            Filename for output.
135
-        tvsys
136
-            TVsys desired for output (to deal with FPS)
137
-        aspect
138
-            Aspect ratio ('4:3', '16:9')
139
-        interlaced
140
-            Frames are interlaced material
141
-
142
-    Currently supports JPG and PNG images; input images must already be
143
-    at the desired target resolution.
144
-    """
145
-
146
-    # Use absolute path name
147
-    imagedir = os.path.abspath(imagedir)
148
-    print("Creating video stream from image sequence in %s" % imagedir)
149
-    # Determine image type
150
-    images = glob.glob("%s/*" % imagedir)
151
-    extension = images[0][-3:]
152
-    if extension not in ['jpg', 'png']:
153
-        raise ValueError("Image format '%s' isn't currently supported to "
154
-              "render video from still frames" % extension)
155
-    # Make sure remaining image files have the same extension
156
-    for img in images:
157
-        if not img.endswith(extension):
158
-            raise ValueError("%s does not have a .%s extension" %
159
-                  (img, extension))
160
-
161
-    pipe = cli.Pipe()
162
-
163
-    # Use jpeg2yuv/png2yuv to stream images
164
-    if extension == 'jpg':
165
-        jpeg2yuv = cli.Command('jpeg2yuv')
166
-
167
-        jpeg2yuv.add('-Ip') # Progressive
168
-
169
-        jpeg2yuv.add('-f', '%.3f' % standard.fps(tvsys),
170
-                     '-j', '%s/%%08d.%s' % (imagedir, extension))
171
-        pipe.add(jpeg2yuv)
172
-    elif extension == 'png':
173
-        #ls = cli.Command('sh', '-c', 'ls %s/*.png' % imagedir)
174
-        #xargs = cli.Command('xargs', '-n1', 'pngtopnm')
175
-        png2yuv = cli.Command('png2yuv')
176
-
177
-        png2yuv.add('-Ip') # Progressive
178
-
179
-
180
-        png2yuv.add('-f', '%.3f' % standard.fps(tvsys),
181
-                    '-j', '%s/%%08d.png' % (imagedir))
182
-
183
-        pipe.add(png2yuv)
184
-
185
-        #pipe.add(ls, xargs, png2yuv)
186
-        #cmd += 'pnmtoy4m -Ip -F %s %s/*.png' % standard.fps_ratio(tvsys)
187
-
188
-    # TODO: Scale to correct target size using yuvscaler or similar
189
-
190
-    # Pipe image stream into mpeg2enc to encode
191
-    mpeg2enc = cli.Command('mpeg2enc')
192
-
193
-    # Anyways.
194
-    mpeg2enc.add('-I 0') # Progressive
195
-
196
-    # Bottom-first, determined in render/drawing.py::interlace_drawings()
197
-    if (interlaced):
198
-        mpeg2enc.add('--playback-field-order', 'b')  # Bottom-first field order
199
-        # conforming to drawing.py::interlace_drawings()
200
-
201
-    mpeg2enc.add('-v', '0',
202
-                 '-q' '3',
203
-                 '-o' '%s' % outfile)
204
-    # Format
205
-    if format == 'vcd':
206
-        mpeg2enc.add('--format', '1')
207
-    elif format == 'svcd':
208
-        mpeg2enc.add('--format', '4')
209
-    else:
210
-        mpeg2enc.add('--format', '8')
211
-    # Aspect ratio
212
-    if aspect == '16:9':
213
-        mpeg2enc.add('-a', '3')
214
-    elif aspect == '4:3':
215
-        mpeg2enc.add('-a', '2')
216
-
217
-    pipe.add(mpeg2enc)
218
-
219
-    pipe.run(capture=True)
220
-    pipe.get_output() # and wait :)
221
-
222
tovid-0.34.tar.bz2/libtovid/backend/mplayer.py Deleted
213
 
1
@@ -1,211 +0,0 @@
2
-"""Video encoding, ripping, and identification using ``mplayer``.
3
-"""
4
-
5
-__all__ = [
6
-    'encode',
7
-    'identify',
8
-    'rip_video',
9
-]
10
-
11
-from libtovid import log
12
-from libtovid import cli
13
-from libtovid.media import MediaFile
14
-from libtovid.backend import ffmpeg
15
-
16
-def encode(source, target, **kw):
17
-    """Encode a multimedia video using mencoder.
18
-
19
-        source
20
-            Input `~libtovid.media.MediaFile`
21
-        target
22
-            Output `~libtovid.media.MediaFile`
23
-        kw
24
-            Keyword arguments to customize encoding behavior
25
-
26
-    Supported keywords:
27
-
28
-        None yet
29
-
30
-    """
31
-    cmd = cli.Command('mencoder')
32
-    cmd.add(source.filename,
33
-            '-o', target.filename,
34
-            '-oac', 'lavc',
35
-            '-ovc', 'lavc',
36
-            '-of', 'mpeg')
37
-    # Format
38
-    cmd.add('-mpegopts')
39
-    if target.format in ['vcd', 'svcd']:
40
-        cmd.add('format=x%s' % target.format)
41
-    else:
42
-        cmd.add('format=dvd')
43
-
44
-    # FIXME: This assumes we only have ONE audio track.
45
-    if source.has_audio:
46
-        # Adjust audio sampling rate if necessary
47
-        if source.samprate != target.samprate:
48
-            log.info("Resampling needed to achieve %d Hz" % target.samprate)
49
-            cmd.add('-srate', target.samprate)
50
-            cmd.add('-af', 'lavcresample=%s' % target.samprate)
51
-        else:
52
-            log.info("No resampling needed, already at %d Hz" % target.samprate)
53
-
54
-    else:
55
-        log.info("No audio file, generating silence of %f seconds." % \
56
-                 source.length)
57
-        # Generate silence.
58
-        if target.format in ['vcd', 'svcd']:
59
-            audiofile = '%s.mpa' % target.filename
60
-        else:
61
-            audiofile = '%s.ac3' % target.filename
62
-        ffmpeg.encode_audio(source, audiofile, target)
63
-        # TODO: make this work, it's still not adding the ac3 file correctly.
64
-        cmd.add('-audiofile', audiofile)
65
-
66
-    # Video codec
67
-    if target.format == 'vcd':
68
-        lavcopts = 'vcodec=mpeg1video'
69
-    else:
70
-        lavcopts = 'vcodec=mpeg2video'
71
-    # Audio codec
72
-    lavcopts += ':acodec=%s' % target.acodec
73
-    lavcopts += ':abitrate=%s:vbitrate=%s' % \
74
-            (target.abitrate, target.vbitrate)
75
-    # Maximum video bitrate
76
-    lavcopts += ':vrc_maxrate=%s' % target.vbitrate
77
-    if target.format == 'vcd':
78
-        lavcopts += ':vrc_buf_size=327'
79
-    elif target.format == 'svcd':
80
-        lavcopts += ':vrc_buf_size=917'
81
-    else:
82
-        lavcopts += ':vrc_buf_size=1835'
83
-    # Set appropriate target aspect
84
-    if target.widescreen:
85
-        lavcopts += ':aspect=16/9'
86
-    else:
87
-        lavcopts += ':aspect=4/3'
88
-    # Pass all lavcopts together
89
-    cmd.add('-lavcopts', lavcopts)
90
-
91
-    # FPS
92
-    if target.tvsys == 'pal':
93
-        cmd.add('-ofps', '25/1')
94
-    elif target.tvsys == 'ntsc':
95
-        cmd.add('-ofps', '30000/1001') # ~= 29.97
96
-
97
-    # Scale/expand to fit target frame
98
-    if target.scale:
99
-        vfilter = 'scale=%s:%s' % target.scale
100
-        # Expand is not done unless also scaling
101
-        if target.expand != target.scale:
102
-            vfilter += ',expand=%s:%s' % target.expand
103
-        cmd.add('-vf', vfilter)
104
-
105
-    cmd.run()
106
-
107
-
108
-def identify(filename):
109
-    """Identify a video file using mplayer, and return a
110
-    `~libtovid.media.MediaFile` with the video's specifications.
111
-    """
112
-    # TODO: Raise an exception if the file couldn't be identified
113
-    # TODO: Infer aspect ratio
114
-
115
-    media = MediaFile(filename)
116
-
117
-    mp_dict = {}
118
-    # Use mplayer
119
-    cmd = cli.Command('mplayer',
120
-                  '-identify',
121
-                  '%s' % filename,
122
-                  '-vo', 'null',
123
-                  '-ao', 'null',
124
-                  '-frames', '1',
125
-                  '-channels', '6')
126
-    cmd.run(capture=True)
127
-
128
-    # Look for mplayer's "ID_..." lines and include each assignment in mp_dict
129
-    for line in cmd.get_output().splitlines():
130
-        log.debug(line)
131
-        if line.startswith("ID_"):
132
-            left, right = line.split('=')
133
-            mp_dict[left] = right.strip()
134
-
135
-    # Check for existence of streams
136
-    if 'ID_VIDEO_ID' in mp_dict:
137
-        media.has_video = True
138
-    else:
139
-        media.has_video = False
140
-    if 'ID_AUDIO_ID' in mp_dict:
141
-        media.has_audio = True
142
-    else:
143
-        media.has_audio = False
144
-
145
-    # Parse the dictionary and set appropriate values
146
-    for left, right in mp_dict.iteritems():
147
-        if left == "ID_VIDEO_WIDTH":
148
-            media.scale = (int(right), media.scale[1])
149
-        elif left == "ID_VIDEO_HEIGHT":
150
-            media.scale = (media.scale[0], int(right))
151
-        elif left == "ID_VIDEO_FPS":
152
-            media.fps = float(right)
153
-        elif left == "ID_VIDEO_FORMAT":
154
-            media.vcodec = right
155
-        elif left == "ID_VIDEO_BITRATE":
156
-            media.vbitrate = int(right) / 1000
157
-        elif left == "ID_AUDIO_CODEC":
158
-            media.acodec = right
159
-        elif left == "ID_AUDIO_FORMAT":
160
-            pass
161
-        elif left == "ID_AUDIO_BITRATE":
162
-            media.abitrate = int(right) / 1000
163
-        elif left == "ID_AUDIO_RATE":
164
-            media.samprate = int(right)
165
-        elif left == "ID_AUDIO_NCH":
166
-            media.channels = right
167
-        elif left == 'ID_LENGTH':
168
-            media.length = float(right)
169
-    media.expand = media.scale
170
-
171
-    # Fix mplayer's audio codec naming for ac3 and mp2
172
-    if media.acodec == "8192":
173
-        media.acodec = "ac3"
174
-    elif media.acodec == "80":
175
-        media.acodec = "mp2"
176
-    # Fix mplayer's video codec naming for mpeg1 and mpeg2
177
-    if media.vcodec == "0x10000001":
178
-        media.vcodec = "mpeg1"
179
-    elif media.vcodec == "0x10000002":
180
-        media.vcodec = "mpeg2"
181
-    return media
182
-
183
-
184
-
185
-
186
-def rip_video(source, yuvfile, target):
187
-    """Rip video to the given yuv4mpeg file.
188
-
189
-        source
190
-            Input `~libtovid.media.MediaFile`
191
-        yuvfile
192
-            File to put ripped video in
193
-        target
194
-            Output `~libtovid.media.MediaFile`
195
-
196
-    """
197
-    # TODO: Custom mplayer options, subtitles, interlacing,
198
-    # corresp.  to $MPLAYER_OPT, $SUBTITLES, $VF_PRE/POST, $YUV4MPEG_ILACE,
199
-    # etc.
200
-    cmd = cli.Command('mplayer')
201
-    cmd.add(source.filename)
202
-    cmd.add('-vo', 'yuv4mpeg:file=%s' % yuvfile)
203
-    cmd.add('-nosound', '-benchmark', '-noframedrop')
204
-    # TODO: Support subtitles. For now, use default tovid behavior.
205
-    cmd.add('-noautosub')
206
-    if target.scale:
207
-        cmd.add('-vf', 'scale=%s:%s' % target.scale)
208
-    if target.expand > target.scale:
209
-        cmd.add('-vf-add', 'expand=%s:%s' % target.expand)
210
-    # Run the command to rip the video
211
-    cmd.run(background=True)
212
-
213
tovid-0.34.tar.bz2/libtovid/backend/mplex.py Deleted
40
 
1
@@ -1,38 +0,0 @@
2
-"""Multiplexing using ``mplex``.
3
-"""
4
-
5
-__all__ = [
6
-    'mux',
7
-]
8
-
9
-from libtovid import cli
10
-
11
-def mux(vstream, astream, target):
12
-    """Multiplex audio and video stream files to the given target.
13
-
14
-        vstream
15
-            Filename of MPEG video stream
16
-        astream
17
-            Filename of MP2/AC3 audio stream
18
-        target
19
-            Profile of output file
20
-
21
-    """
22
-    cmd = cli.Command('mplex')
23
-    format = target.format
24
-    if format == 'vcd':
25
-        cmd.add('-f', '1')
26
-    elif format == 'dvd-vcd':
27
-        cmd.add('-V', '-f', '8')
28
-    elif format == 'svcd':
29
-        cmd.add('-V', '-f', '4', '-b', '230')
30
-    elif format == 'half-dvd':
31
-        cmd.add('-V', '-f', '8', '-b', '300')
32
-    elif format == 'dvd':
33
-        cmd.add('-V', '-f', '8', '-b', '400')
34
-    # elif format == 'kvcd':
35
-    #   cmd += ' -V -f 5 -b 350 -r 10800 '
36
-    cmd.add(vstream, astream, '-o', target.filename)
37
-    # Run the command to multiplex the streams
38
-    cmd.run()
39
-
40
tovid-0.34.tar.bz2/libtovid/backend/spumux.py Deleted
182
 
1
@@ -1,180 +0,0 @@
2
-"""This module is for adding subtitles to MPEG video files using spumux.
3
-
4
-Defined here are two functions for adding subtitles to an MPEG file:
5
-
6
-    `add_subpictures`
7
-        Add image files (``.png``)
8
-    `add_subtitles`
9
-        Add subtitle files (``.sub``, ``.srt`` etc.)
10
-
11
-Use these if you just want to add subpictures or subtitles, and don't want
12
-to think much about the XML internals.
13
-"""
14
-
15
-__all__ = [
16
-    'add_subpictures',
17
-    'add_subtitles',
18
-]
19
-
20
-import os
21
-from libtovid import util
22
-from libtovid import xml
23
-from libtovid import cli
24
-from libtovid.backend import mplayer
25
-
26
-# spumux XML elements and valid attributes
27
-#
28
-# subpictures
29
-# stream
30
-# textsub
31
-#     ['filename',
32
-#     'characterset',
33
-#     'fontsize',
34
-#     'font',
35
-#     'horizontal-alignment',
36
-#     'vertical-alignment',
37
-#     'left-margin',
38
-#     'right-margin',
39
-#     'subtitle-fps',
40
-#     'movie-fps',
41
-#     'movie-width',
42
-#     'movie-height']
43
-# button
44
-#     ['name',
45
-#     'x0', 'y0', # Upper-left corner, inclusively
46
-#     'x1', 'y1', # Lower-right corner, exclusively
47
-#     'up', 'down', 'left', 'right']
48
-# action
49
-#     ['name']
50
-# spu
51
-#     ['start',
52
-#     'end',
53
-#     'image',
54
-#     'highlight',
55
-#     'select',
56
-#     'transparent',   # color code
57
-#     'force',         # 'yes' (force display, required for menus)
58
-#     'autooutline',   # 'infer'
59
-#     'outlinewidth',
60
-#     'autoorder',     # 'rows' or 'columns'
61
-#     'xoffset',
62
-#     'yoffset']
63
-
64
-def _get_xml(textsub_or_spu):
65
-    """Return an XML string for the given Textsub or Spu element.
66
-    """
67
-    subpictures = xml.Element('subpictures')
68
-    stream = subpictures.add('stream')
69
-    stream.add_child(textsub_or_spu)
70
-    return str(subpictures)
71
-
72
-
73
-def _get_xmlfile(textsub_or_spu):
74
-    """Write spumux XML file for the given Textsub or Spu element, and
75
-    return the written filename.
76
-    """
77
-    xmldata = _get_xml(textsub_or_spu)
78
-    xmlfile = open(util.temp_file(suffix=".xml"), 'w')
79
-    xmlfile.write(xmldata)
80
-    xmlfile.close()
81
-    return xmlfile.name
82
-
83
-
84
-def _mux_subs(subtitle, movie_filename, stream_id=0):
85
-    """Run spumux to multiplex the given subtitle with an ``.mpg`` file.
86
-
87
-        subtitle
88
-            Textsub or Spu element
89
-        movie_filename
90
-            Name of an ``.mpg`` file to multiplex subtitle into
91
-        stream_id
92
-            Stream ID number to pass to spumux
93
-    """
94
-    # Create XML file for subtitle element
95
-    xmlfile = _get_xmlfile(subtitle)
96
-    # Create a temporary .mpg for the subtitled output
97
-    #base_dir = os.path.dirname(movie_filename)
98
-    subbed_filename = util.temp_file(suffix=".mpg")
99
-    # spumux xmlfile < movie_filename > subbed_filename
100
-    spumux = cli.Command('spumux', '-s%s' % stream_id,  xmlfile.name)
101
-    spumux.run_redir(movie_filename, subbed_filename)
102
-    spumux.wait()
103
-
104
-    # Remove old file
105
-    os.remove(movie_filename)
106
-    # Rename temporary file to new file
107
-    os.rename(subbed_filename, movie_filename)
108
-    # Remove the XML file
109
-    os.remove(xmlfile.name)
110
-
111
-
112
-def add_subpictures(movie_filename, select, image=None, highlight=None):
113
-    """Adds ``.png`` subpictures to an ``.mpg`` video file to create a DVD menu.
114
-
115
-        select
116
-            ``.png`` filename shown for the navigational selector or "cursor"
117
-        image
118
-            ``.png`` filename shown for non-selected regions
119
-        highlight
120
-            ``.png`` filename shown when "enter" is pressed
121
-
122
-    All images must be indexed, 4-color, transparent, non-antialiased PNG.
123
-    Button regions are auto-inferred.
124
-    """
125
-    spu = xml.Element('spu')
126
-    spu.set(start='0',
127
-            force='yes',
128
-            select=select,
129
-            image=image,
130
-            highlight=highlight)
131
-    # TODO Find a good default outlinewidth
132
-    spu.set(autooutline='infer', outlinewidth='10')
133
-    # TODO: Support explicit button regions
134
-    _mux_subs(spu, movie_filename)
135
-
136
-
137
-def add_subtitles(movie_filename, sub_filenames):
138
-    """Adds one or more subtitle files to an ``.mpg`` video file.
139
-
140
-        movie_filename
141
-            Name of ``.mpg`` file to add subtitles to
142
-        sub_filenames
143
-            Filename or list of filenames of subtitle
144
-            files to include (``.sub``, ``.srt`` etc.)
145
-
146
-    """
147
-    infile = mplayer.identify(movie_filename)
148
-    width, height = infile.scale
149
-
150
-    # Convert sub_filenames to list if necessary
151
-    if type(sub_filenames) == str:
152
-        sub_filenames = [sub_filenames]
153
-    # spumux each subtitle file with its own stream ID
154
-    for stream_id, sub_filename in enumerate(sub_filenames):
155
-        # <textsub attribute="value" .../>
156
-        textsub = xml.Element('textsub')
157
-        textsub.set(movie_fps=infile.fps,
158
-                    movie_width=width,
159
-                    movie_height=height,
160
-                    filename=sub_filename)
161
-        _mux_subs(textsub, movie_filename, stream_id)
162
-
163
-
164
-
165
-if __name__ == '__main__':
166
-    print("spumux XML examples")
167
-
168
-    print("Subpicture example:")
169
-    spu = xml.Element('spu')
170
-    spu.add('button', name='but1', down='but2')
171
-    spu.add('button', name='but2', up='but1')
172
-    print(_get_xml(spu))
173
-
174
-    print("Text subtitle example:")
175
-    textsub = xml.Element('textsub')
176
-    textsub.set(filename='foo.sub',
177
-                fontsize=14.0,
178
-                font="Luxi Mono")
179
-    print(_get_xml(textsub))
180
-
181
-
182
tovid-0.34.tar.bz2/libtovid/backend/transcode.py Deleted
121
 
1
@@ -1,119 +0,0 @@
2
-"""Video frame ripping and video identification using ``transcode``.
3
-"""
4
-
5
-# Sample output from tcprobe:
6
-#
7
-# [tcprobe] RIFF data, AVI video
8
-# [avilib] V: 24.000 fps, codec=DIVX, frames=15691, width=1024, height=576
9
-# [avilib] A: 48000 Hz, format=0x2000, bits=0, channels=5, bitrate=448 kbps,
10
-# [avilib]    10216 chunks, 36614144 bytes, CBR
11
-# [tcprobe] summary for Elephants_1024.avi, (*) = not default, 0 = not
12
-# detected
13
-# import frame size: -g 1024x576 [720x576] (*)
14
-#        frame rate: -f 24.000 [25.000] frc=0 (*)
15
-#       audio track: -a 0 [0] -e 48000,0,5 [48000,16,2] -n 0x2000 [0x2000] (*)
16
-#                    bitrate=448 kbps
17
-#            length: 15691 frames, frame_time=41 msec, duration=0:10:53.790
18
-
19
-__all__ = [
20
-    'identify',
21
-    'rip_frames',
22
-]
23
-
24
-import os, re, glob
25
-from libtovid import log
26
-from libtovid import cli
27
-from libtovid.media import MediaFile
28
-
29
-def identify(filename):
30
-    """Identify a video file using transcode (tcprobe), and return a
31
-    `~libtovid.media.MediaFile` with the video's specifications.
32
-    """
33
-    result = MediaFile(filename)
34
-
35
-    cmd = cli.Command('tcprobe', '-i', filename)
36
-    cmd.run(capture=True)
37
-    output = cmd.get_output()
38
-
39
-    video_line = re.compile('V: '
40
-        '(?P<fps>[\d.]+) fps, '
41
-        'codec=(?P<vcodec>[^,]+), '
42
-        'frames=\d+, '
43
-        'width=(?P<width>\d+), '
44
-        'height=(?P<height>\d+)')
45
-
46
-    audio_line = re.compile('A: '
47
-        '(?P<samprate>\d+) Hz, '
48
-        'format=(?P<acodec>[^,]+), '
49
-        'bits=\d+, '
50
-        'channels=(?P<channels>[^,]+), '
51
-        'bitrate=(?P<abitrate>\d+) kbps')
52
-
53
-    for line in output.split('\n'):
54
-        if 'V: ' in line:
55
-            match = video_line.search(line)
56
-            result.fps = float(match.group('fps'))
57
-            result.vcodec = match.group('vcodec')
58
-            result.scale = (int(match.group('width')),
59
-                            int(match.group('height')))
60
-            result.expand = result.scale
61
-
62
-        elif 'A: ' in line:
63
-            match = audio_line.search(line)
64
-            result.acodec = match.group('acodec')
65
-            result.samprate = int(match.group('samprate'))
66
-            result.abitrate = int(match.group('abitrate'))
67
-            result.channels = int(match.group('channels'))
68
-
69
-    return result
70
-
71
-
72
-def rip_frames(media, out_dir, frames='all', size=(0, 0)):
73
-    """Extract frame images from a `~libtovid.media.MediaFile` and return a
74
-    list of frame image files.
75
-
76
-        media
77
-            `~libtovid.media.MediaFile` to extract images from
78
-        out_dir
79
-            Directory where output images should be stored; images are saved
80
-            in a subdirectory of ``out_dir`` named after the input filename
81
-        frames
82
-            Which frames to rip: ``'all'`` for all frames, ``15`` to rip frame
83
-            15; ``[30, 90]`` to rip frames 30 through 90, etc.
84
-        size
85
-            Resolution of frame images (default: original size), used
86
-            for prescaling
87
-
88
-    """
89
-    out_dir = os.path.abspath(out_dir)
90
-    if os.path.exists(out_dir):
91
-        log.warning("Temp directory: %s already exists. Overwriting." % out_dir)
92
-        os.system('rm -rf "%s"' % out_dir)
93
-    os.mkdir(out_dir)
94
-
95
-    # TODO: use tcdemux to generate a nav index, like:
96
-    # tcdemux -f 29.970 -W -i "$FILE" > "$NAVFILE"
97
-
98
-    # Use transcode to rip frames
99
-    cmd = cli.Command('transcode',
100
-                  '-i', '%s' % media.filename)
101
-    # Resize
102
-    if size != (0, 0):
103
-        cmd.add('-Z', '%sx%s' % size)
104
-    # Encode selected frames
105
-    if frames == 'all':
106
-        # transcode does all by default
107
-        pass
108
-    elif isinstance(frames, int):
109
-        # rip a single frame
110
-        cmd.add('-c', '%s-%s' % (frames, frames))
111
-    elif isinstance(frames, list):
112
-        # rip a range of frames
113
-        cmd.add('-c', '%s-%s' % (frames[0], frames[-1]))
114
-    cmd.add('-y', 'jpg,null')
115
-    cmd.add('-o', '%s/frame_' % out_dir)
116
-    log.info("Creating image sequence from %s" % media.filename)
117
-    cmd.run()
118
-
119
-    # Return a list of ripped files
120
-    return glob.glob('%s/frame_*.jpg' % out_dir)
121
tovid-0.34.tar.bz2/libtovid/deps.py Deleted
212
 
1
@@ -1,210 +0,0 @@
2
-"""This module is for verifying libtovid's run-time dependencies.
3
-For example::
4
-
5
-    deps.require(deps.core)
6
-
7
-will look for all of tovid's core dependencies. If any cannot be found, the
8
-missing ones are printed and an exception is raised. Run ``deps.py`` from a prompt
9
-for further examples.
10
-
11
-In practice::
12
-
13
-    try:
14
-        deps.require(deps.core)
15
-    except deps.MissingDep:
16
-        print("Exiting...")
17
-        sys.exit(1)
18
-
19
-`deps.core` is an internal dictionary of tovid's core dependencies, where the
20
-keys are the names, and the values are brief descriptions with URLs.
21
-
22
-Provided dependency dictionaries:
23
-
24
-    core
25
-        grep/sed/md5sum, mplayer, mencoder, mpjpegtools, ffmpeg
26
-    magick
27
-        composite, convert
28
-    dvd
29
-        spumux, dvdauthor, growisofs
30
-    vcd
31
-        vcdxbuild, cdrdao
32
-    transcode
33
-        tcprobe, tcrequant
34
-    plugin
35
-        sox, normalize
36
-    all
37
-        ALL dependencies above
38
-
39
-If you don't want to use a provided dictionary, you can specify individual
40
-program names to look for::
41
-
42
-    deps.require("more less cat")
43
-
44
-`require` also provides ways to print custom URLs and help when it cannot find
45
-dependencies. See ``help(deps.require)`` or keep reading.
46
-"""
47
-
48
-__all__ = [
49
-    'which',
50
-    'require',
51
-    'MissingDep',
52
-]
53
-
54
-import subprocess
55
-import textwrap
56
-
57
-from libtovid.util.output import red
58
-
59
-class MissingDep (Exception):
60
-    """Missing dependency exception."""
61
-    pass
62
-
63
-###
64
-### Module data
65
-###
66
-
67
-# Dictionary format: {"name": "description (url)"}
68
-all = {}
69
-
70
-core = { 
71
-    "grep":         "a GNU utility (www.gnu.org/software/grep)",
72
-    "sed":          "a GNU utility (directory.fsf.org/GNU/software/sed.html)",
73
-    "md5sum":       "a GNU utility (www.gnu.org/software/coreutils)",
74
-    "mplayer":      "part of mplayer (www.mplayerhq.hu)",
75
-    "mencoder":     "part of mplayer (www.mplayerhq.hu)",
76
-    "mplex":        "part of mjpegtools (mjpeg.sf.net)",
77
-    "mpeg2enc":     "part of mjpegtools (mjpeg.sf.net)",
78
-    "yuvfps":       "part of mjpegtools (mjpeg.sf.net)",
79
-    "yuvdenoise":   "part of mjpegtools (mjpeg.sf.net)",
80
-    "ppmtoy4m":     "part of mjpegtools (mjpeg.sf.net)",
81
-    "mp2enc":       "part of mjpegtools (mjpeg.sf.net)",
82
-    "jpeg2yuv":     "part of mjpegtools (mjpeg.sf.net)",
83
-    "ffmpeg":       "a video encoding utility (ffmpeg.mplayerhq.hu)"      }
84
-all.update(core)
85
-
86
-magick = {
87
-    "composite":    "part of ImageMagick (www.imagemagick.org)",
88
-    "convert":      "part of ImageMagick (www.imagemagick.org)"     }
89
-all.update(magick)
90
-
91
-dvd = {
92
-    "spumux":       "part of dvdauthor (dvdauthor.sf.net)",
93
-    "dvdauthor":    "part of dvdauthor (dvdauthor.sf.net)",
94
-    "growisofs":    "part of dvd+rw-tools (fy.chalmers.se/~appro/linux/DVD+RW)"}
95
-all.update(dvd)
96
-
97
-vcd = {
98
-    "vcdxbuild":    "part of vcdimager (www.vcdimager.org)",
99
-    "cdrdao":       "a cd burning application (cdrdao.sf.net)"   }
100
-all.update(vcd)
101
-
102
-transcode = {
103
-    "tcprobe":      "part of transcode (www.transcoding.org)",
104
-    "tcrequant":    "part of transcode (www.transcoding.org)"   }
105
-all.update(transcode)
106
-
107
-plugin = {
108
-    "sox":          "swiss army knife for sound (sox.sf.net)",
109
-    "normalize":    "wave gain and normalization (normalize.nongnu.org)" }
110
-all.update(plugin)
111
-
112
-__missing_dependency_message = \
113
-"""Please install the above MISSING dependencies and try again. See
114
-http://tovid.wikia.com/wiki/Tovid_dependencies for more help.
115
-"""
116
-
117
-###
118
-### Exported functions
119
-###
120
-
121
-def which(executable):
122
-    """Locate the given executable program name on the current path.
123
-    If found, return the full pathname; otherwise, return the empty string.
124
-    """
125
-    proc = subprocess.Popen(['which', executable],
126
-        stdout=subprocess.PIPE, stderr=subprocess.PIPE)
127
-    return proc.stdout.read().rstrip('\n')
128
-
129
-def require(deps, 
130
-            help="You need these to finish what you were doing.",
131
-            description="oops"):
132
-
133
-    """Assert that one or more dependencies exist on the system. If any
134
-    are missing, raise a `MissingDep` exception.
135
-
136
-        deps
137
-            Names of dependencies to assert. May be a single name,
138
-            a python list or space-separated string list of names,
139
-            or a dictionary of the form {depname: description}.
140
-        help
141
-            A help message about why the dependencies are needed
142
-        description
143
-            A short description of the dep, and its homepage URL
144
-            (ignored if deps is a dictionary).
145
-
146
-    If a given dependency name is found in one of the internal dictionaries,
147
-    (core, magick, etc.), its description is taken from there.
148
-
149
-    Examples:
150
-
151
-        require(all)
152
-            Look for ALL dependencies that are defined internally.
153
-
154
-        require(core, "You are missing CORE dependencies!")
155
-            Use the core dictionary to determine which dependencies to 
156
-            look for. Print the help message if any dependency is missing.
157
-
158
-        require("xine", "You can't preview!", "a video player (xinehq.de)")
159
-            Check for xine and print the custom help and URL messages
160
-            if missing.
161
-
162
-        require("mplayer mencoder", url="a video player (mplayerhq.hu)")
163
-            Look for mplayer and mencoder. Use the default help message,
164
-            but print a custom URL.
165
-
166
-    """
167
-    # Get the deps to check for: dictionary.keys(), or a list
168
-    if type(deps) == dict:
169
-        deps = deps.keys()
170
-    elif type(deps) == str:
171
-        deps = deps.split(' ')
172
-    elif type(deps) != list:
173
-        raise ValueError("%s is not dictionary, list, or string!" % str(deps))
174
-
175
-    # Find the missing dependencies
176
-    have_deps = True
177
-    for dep in deps:
178
-        if which(dep) == '':
179
-            if type(deps) == dict:
180
-                description = deps[dep]
181
-            elif dep in all:
182
-                description = all[dep]
183
-            # Tell the user which dependencies they're missing
184
-            print(red("MISSING:") + " %s, %s" % (dep, description))
185
-            have_deps = False
186
-
187
-    # Having reported the missing dependencies, print the help message and quit
188
-    if not have_deps:
189
-        print("\n", textwrap.fill(help + ' ' + __missing_dependency_message, 79))
190
-        raise MissingDep("Cannot find required dependencies!")
191
-
192
-
193
-
194
-if __name__ == "__main__":
195
-    trials = [  
196
-        (core,        "You are missing CORE dependencies!", "custom url 1"),
197
-        (core,        "You are missing CORE dependencies!", "custom url 2"),
198
-        ("grp md5sm", "You're missing some vowels!",        "custom url 4"),
199
-        ("foo",       "heh, you don't have foo?!",          "see foo.org")   ]
200
-
201
-    for dep, help, url in trials:
202
-        try:
203
-            print("================================================")
204
-            print("Starting test...")
205
-            require(dep, help, url)
206
-        except MissingDep:
207
-            print("(Would exit here.)\n")
208
-        else:
209
-            print("Test passed!\n")
210
-
211
-
212
tovid-0.34.tar.bz2/libtovid/encode.py Deleted
207
 
1
@@ -1,205 +0,0 @@
2
-"""Encode video to standard formats, using one of several supported backends.
3
-
4
-One high-level function is provided::
5
-
6
-    encode(infile, outfile, format, tvsys, method, **kwargs)
7
-
8
-For example::
9
-
10
-    encode('/video/foo.avi', '/video/bar.mpg', 'dvd', 'ntsc', 'ffmpeg')
11
-
12
-This will encode ``/video/foo.avi`` to NTSC DVD format using ffmpeg, saving
13
-the result as ``/video/bar.mpg``. The ``format``, ``tvsys``, and ``method``
14
-arguments are optional; if you do::
15
-
16
-    encode('/video/foo.avi', '/video/bar.mpg')
17
-
18
-then encoding will be DVD NTSC, using ffmpeg.
19
-
20
-Keyword arguments may be used to further refine encoding behavior, for example::
21
-
22
-    encode('foo.avi', 'foo.mpg', 'dvd', 'pal',
23
-           quality=7, interlace='bottom', ...)
24
-
25
-The supported keywords may vary by backend, but some keywords are supported
26
-by all backends. The available backends are:
27
-
28
-    - `~libtovid.backend.ffmpeg`
29
-    - `~libtovid.backend.mplayer`
30
-    - `~libtovid.backend.mpeg2enc`
31
-
32
-"""
33
-
34
-__all__ = [
35
-    'encode',
36
-    'eval_keywords',
37
-    'fit',
38
-]
39
-
40
-from libtovid.backend import ffmpeg, mplayer, mpeg2enc
41
-from libtovid.media import MediaFile, standard_media, correct_aspect
42
-
43
-
44
-_bitrate_limits = {
45
-    'vcd': (1150, 1150),
46
-    'kvcd': (400, 4000),
47
-    'dvd-vcd': (400, 4000),
48
-    'svcd': (900, 2400),
49
-    'half-dvd': (600, 6000),
50
-    'dvd': (900, 9000)
51
-    }
52
-
53
-# --------------------------------------------------------------------------
54
-#
55
-# Primary interface
56
-#
57
-# --------------------------------------------------------------------------
58
-
59
-def encode(infile, outfile, format='dvd', tvsys='ntsc', method='ffmpeg',
60
-           **kwargs):
61
-    """Encode a multimedia file ``infile`` according to a target profile,
62
-    saving the encoded file to ``outfile``.
63
-
64
-        infile
65
-            Input filename
66
-        outfile
67
-            Desired output filename (``.mpg`` implied)
68
-        format
69
-            One of 'vcd', 'svcd', 'dvd' (case-insensitive)
70
-        tvsys
71
-            One of 'ntsc', 'pal' (case-insensitive)
72
-        method
73
-            Encoding backend: `~libtovid.backend.ffmpeg`,
74
-            `~libtovid.backend.mplayer`, or `~libtovid.backend.mpeg2enc`
75
-        kwargs
76
-            Additional keyword arguments (name=value)
77
-
78
-    For example::
79
-
80
-        encode('/video/foo.avi', '/video/bar.mpg', 'dvd', 'ntsc', 'ffmpeg')
81
-
82
-    This will encode ``/video/foo.avi`` to NTSC DVD format using ffmpeg, saving
83
-    the result as '/video/bar.mpg'. The ``format``, ``tvsys``, and ``method``
84
-    arguments are optional; if you do::
85
-
86
-        encode('/video/foo.avi', '/video/bar.mpg')
87
-
88
-    then encoding will be DVD NTSC, using ffmpeg.
89
-
90
-    Keyword arguments may be used to further refine encoding behavior, for example::
91
-
92
-        encode('foo.avi', 'foo.mpg', 'dvd', 'pal',
93
-               quality=7, interlace='bottom', ...)
94
-
95
-    The supported keywords may vary by backend, but some keywords are supported
96
-    by all backends.
97
-
98
-
99
-    """
100
-    source = mplayer.identify(infile)
101
-    # Add .mpg to outfile if not already present
102
-    if not outfile.endswith('.mpg'):
103
-        outfile += '.mpg'
104
-    # Get an appropriate encoding target
105
-    target = standard_media(format, tvsys)
106
-    target.filename = outfile
107
-    # Set desired aspect ratio, or auto
108
-    if 'aspect' in kwargs:
109
-        target = correct_aspect(source, target, kwargs['aspect'])
110
-    else:
111
-        target = correct_aspect(source, target, 'auto')
112
-
113
-    # Some friendly output
114
-    print("Source media:")
115
-    print(source)
116
-    print(' ')
117
-    print("Target media:")
118
-    print(target)
119
-
120
-    # Get the appropriate encoding backend
121
-    encode_method = get_encoder(method)
122
-    # Evaluate high-level keywords
123
-    kwargs = eval_keywords(source, target, **kwargs)
124
-    # Encode!
125
-    encode_method(source, target, **kwargs)
126
-
127
-
128
-# --------------------------------------------------------------------------
129
-#
130
-# Helper functions
131
-#
132
-# --------------------------------------------------------------------------
133
-
134
-def _get_encoder(backend):
135
-    """Get an encoding function."""
136
-    if backend == 'ffmpeg':
137
-        return ffmpeg.encode
138
-    elif backend in ['mplayer', 'mencoder']:
139
-        return mplayer.encode
140
-    elif backend == 'mpeg2enc':
141
-        return mpeg2enc.encode
142
-
143
-
144
-def eval_keywords(source, target, **kwargs):
145
-    """Interpret keywords that affect other keywords, and return the result.
146
-    These are keywords that can be shared between multiple encoding backends.
147
-
148
-    Supported keywords:
149
-
150
-        quality
151
-            From 1 (lowest) to 10 (highest) video quality.
152
-            Overrides 'quant' and 'vbitrate' keywords.
153
-        fit
154
-            Size in MiB to fit output video to (overrides 'quality')
155
-            Overrides 'quant' and 'vbitrate' keywords.
156
-
157
-    """
158
-    # Set quant and vbitrate to match desired quality
159
-    if 'quality' in kwargs:
160
-        kwargs['quant'] = 13-kwargs['quality']
161
-        max_bitrate = _bitrate_limits[target.format][1]
162
-        kwargs['vbitrate'] = kwargs['quality'] * max_bitrate / 10
163
-    # Set quant and vbitrate to fit desired size
164
-    if 'fit' in kwargs:
165
-        kwargs['quant'], kwargs['vbitrate'] = \
166
-            fit(source, target, kwargs['fit'])
167
-    return kwargs
168
-
169
-
170
-def fit(source, target, fit_size):
171
-    """Return video (quantization, bitrate) to fit a video into a given size.
172
-
173
-        source
174
-            `~libtovid.media.MediaFile` input (the video being encoded)
175
-        target
176
-            `~libtovid.media.MediaFile` output (desired target profile)
177
-        fit_size
178
-            Desired encoded file size, in MiB
179
-
180
-    """
181
-    assert isinstance(source, MediaFile)
182
-    assert isinstance(target, MediaFile)
183
-    fit_size = float(fit_size)
184
-    mpeg_overhead = fit_size / 100
185
-    aud_vid_size = fit_size - mpeg_overhead
186
-    audio_size = float(source.length * target.abitrate) / (8*1024)
187
-    video_size = aud_vid_size - audio_size
188
-    vid_bitrate = int(video_size*8*1024 / source.length)
189
-
190
-    print("Length: %s seconds" % source.length)
191
-    print("Overhead: %s MiB" % mpeg_overhead)
192
-    print("Audio: %s MiB" % audio_size)
193
-    print("Video: %s MiB" % video_size)
194
-    print("VBitrate: %s kbps" % vid_bitrate)
195
-
196
-    # Keep bitrates sane for each disc format
197
-    lower, upper = _bitrate_limits[target.format]
198
-    quant = 3
199
-    if vid_bitrate < lower:
200
-        return (quant, lower)
201
-    elif vid_bitrate > upper:
202
-        return (quant, upper)
203
-    else:
204
-        return (quant, vid_bitrate)
205
-
206
-
207
tovid-0.34.tar.bz2/libtovid/media.py Deleted
197
 
1
@@ -1,195 +0,0 @@
2
-"""This module provides a multimedia file class for storing a profile of
3
-attributes including resolution, audio and video codecs and bitrates.
4
-
5
-These can be used for getting a target `MediaFile` for encoding via
6
-one of the backends in :mod:`libtovid.backend`. For example::
7
-
8
-    >>> dvd = standard_media('dvd', 'ntsc')
9
-    >>> print(dvd)
10
-    Filename:
11
-    Format: DVD
12
-    TVsys: NTSC
13
-    Length: 0 seconds
14
-    Video: 720x480 29.97fps 4:3 mpeg2 6000kbps
15
-    Audio: ac3 224kbps 48000hz 2-channel
16
-
17
-"""
18
-
19
-__all__ = [
20
-    'MediaFile',
21
-    'standard_media',
22
-    'correct_aspect',
23
-]
24
-
25
-import copy
26
-from libtovid import log
27
-from libtovid import standard
28
-from libtovid.util import ratio_to_float
29
-
30
-# Analysis of MediaFile attributes
31
-#
32
-# acodec: ID, target
33
-# abitrate: ID, target
34
-# channels: ID
35
-# samprate: ID, source, target
36
-# vcodec: ID
37
-# vbitrate: ID, target
38
-# length: ID, source
39
-# scale: (ID), (source), target
40
-# expand: target
41
-# fps: ID, source, target
42
-# aspect: source
43
-# widescreen: target
44
-#
45
-#
46
-# Redundancies(?):
47
-# widescreen/aspect
48
-# scale/expand if aspect is known
49
-
50
-class MediaFile:
51
-    """A multimedia video file, and its vital statistics.
52
-    """
53
-    def __init__(self, filename='', format='none', tvsys='none'):
54
-        log.debug("MediaFile(%s, %s, %s)" % (filename, format, tvsys))
55
-        # TODO: Set attributes to match given format and tvsys
56
-        self.filename = filename
57
-        self.format = format
58
-        self.tvsys = tvsys
59
-        self.length = 0
60
-        # TODO: Support multiple audio and video tracks
61
-        self.has_audio = False
62
-        self.has_video = False
63
-        # Audio attributes
64
-        self.acodec = 'none'
65
-        self.abitrate = 0
66
-        self.channels = 0
67
-        self.samprate = 0
68
-        # Video attributes
69
-        self.vcodec = 'none'
70
-        # TODO: Better names for scale & expand, but not so long as
71
-        # 'inner_resolution' and 'outer_resolution', or
72
-        # 'picture_res' and 'frame_res'. Suggestions?
73
-        self.scale = (0, 0)
74
-        self.expand = (0, 0)
75
-        self.vbitrate = 0
76
-        self.fps = 0.0
77
-        self.aspect = '0:0'
78
-        self.widescreen = False
79
-
80
-
81
-    def __str__(self):
82
-        """Return a string representation of the MediaFile.
83
-        """
84
-        width, height = self.expand or self.scale
85
-        # List of lines of output
86
-        lines = [
87
-            'Filename: %s' % self.filename,
88
-            'Format: %s' % self.format,
89
-            'TVsys: %s' % self.tvsys,
90
-            'Length: %s seconds' % self.length,
91
-            'Video: %sx%s %sfps %s %s %skbps' % \
92
-            (width, height, self.fps, self.aspect, self.vcodec, self.vbitrate),
93
-            'Audio: %s %skbps %shz %s-channel' % \
94
-            (self.acodec, self.abitrate, self.samprate, self.channels)
95
-            ]
96
-        # Add newlines and return
97
-        return '\n'.join(lines)
98
-
99
-
100
-def standard_media(format, tvsys):
101
-    """Return a `MediaFile` compliant with a standard format and TV system.
102
-
103
-        format
104
-            Standard format ('vcd', 'svcd', or 'dvd')
105
-        tvsys
106
-            TV system ('pal' or 'ntsc')
107
-
108
-    """
109
-    log.debug("standard_media(%s, %s)" % (format, tvsys))
110
-    media = MediaFile('', format, tvsys)
111
-    # Set valid video attributes
112
-    media.vcodec = standard.vcodec(format)
113
-    media.scale = standard.resolution(format, tvsys)
114
-    media.expand = media.scale
115
-    media.fps = standard.fps(tvsys)
116
-    # Set valid audio attributes
117
-    media.acodec = standard.acodec(format)
118
-    media.samprate = standard.samprate(format)
119
-    # TODO: How to handle default bitrates? These functions return a range.
120
-    #media.vbitrate = standard.vbitrate(format)[1]
121
-    #media.abitrate = standard.abitrate(format)[1]
122
-    media.abitrate = 224
123
-    if format == 'vcd':
124
-        media.vbitrate = 1150
125
-    elif format == 'svcd':
126
-        media.vbitrate = 2600
127
-    else:
128
-        media.vbitrate = 6000
129
-    return media
130
-
131
-
132
-def correct_aspect(source, target, aspect='auto'):
133
-    """Calculate the necessary scaling to fit source into target at a given
134
-    aspect ratio, without distorting the picture.
135
-
136
-        source
137
-            Input `MediaFile`
138
-        target
139
-            Output `MediaFile`
140
-        aspect
141
-            Aspect ratio to assume for input file (e.g., '4:3', '16:9')
142
-            or 'auto' to use autodetection based on source aspect
143
-
144
-    Return a new target `MediaFile` with correct scaling, using letterboxing
145
-    if appropriate, and anamorphic widescreen if available (DVD only).
146
-    """
147
-    assert isinstance(source, MediaFile)
148
-    assert isinstance(target, MediaFile)
149
-
150
-    # Base new target on existing one
151
-    target = copy.copy(target)
152
-
153
-    # Convert aspect (ratio) to a floating-point value
154
-    if aspect == 'auto':
155
-        src_aspect = ratio_to_float(source.aspect)
156
-    else:
157
-        src_aspect = ratio_to_float(aspect)
158
-
159
-    # Use anamorphic widescreen for any video ~16:9 or wider
160
-    # (Only DVD supports this)
161
-    if src_aspect >= 1.7 and target.format == 'dvd':
162
-        target_aspect = 16.0/9.0
163
-        widescreen = True
164
-    else:
165
-        target_aspect = 4.0/3.0
166
-        widescreen = False
167
-
168
-    # Start by assuming direct scaling to target resolution
169
-    width, height = target.scale
170
-
171
-    # If aspect matches target, no letterboxing is necessary
172
-    tolerance = 0.05
173
-    if abs(src_aspect - target_aspect) < tolerance:
174
-        scale = (width, height)
175
-    # If aspect is wider than target, letterbox vertically
176
-    elif src_aspect > target_aspect:
177
-        scale = (width, int(height * target_aspect / src_aspect))
178
-    # Otherwise (rare), letterbox horizontally
179
-    else:
180
-        scale = (int(width * src_aspect / target_aspect), height)
181
-
182
-    # Always expand to the target resolution
183
-    expand = (width, height)
184
-
185
-    # If input file is already the correct size, don't scale
186
-    if scale == source.scale:
187
-        scale = False
188
-
189
-    # Final scaling/expansion for correct aspect ratio display
190
-    target.scale = scale
191
-    target.expand = expand
192
-    target.widescreen = widescreen
193
-    return target
194
-
195
-
196
-
197
tovid-0.34.tar.bz2/libtovid/opts.py Deleted
256
 
1
@@ -1,254 +0,0 @@
2
-# opts.py
3
-
4
-# WARNING: This module is a hack in progress
5
-
6
-__all__ = [
7
-    'Option',
8
-    'Usage',
9
-    'parse',
10
-    'validate',
11
-]
12
-
13
-import sys
14
-import textwrap
15
-from libtovid.odict import Odict
16
-from libtovid.util import trim
17
-
18
-class Option (object):
19
-    """A command-line-style option, expected argument formatting, default value,
20
-    and notes on usage and purpose.
21
-
22
-    For example::
23
-
24
-        debug_opt = Option(
25
-            'debug',
26
-            'none|some|all',
27
-            'some',
28
-            "Amount of debugging information to display"
29
-           )
30
-
31
-    This defines a 'debug' option, along with a human-readable string showing
32
-    expected argument formatting, a default value, and a string documenting the
33
-    option's purpose and/or usage information.
34
-    """
35
-    def __init__(self, name, argformat='', default=None,
36
-                 doc='Undocumented option', alias=None,
37
-                 required=False):
38
-        """Create a new option definition with the given attributes.
39
-
40
-            name
41
-                Option name
42
-            argformat
43
-                String describing format of expected arguments
44
-            default
45
-                Default value, if any
46
-            doc
47
-                Manual-page-style documentation of the option
48
-            alias
49
-                An ('option', 'value') equivalent for this option
50
-
51
-        """
52
-        self.name = name
53
-        self.argformat = argformat
54
-        self.default = default
55
-        self.doc = trim(doc)
56
-        self.alias = alias
57
-        self.required = required
58
-        # If an alias was provided, generate documentation.
59
-        # i.e., alias=('tvsys', 'ntsc') means this option is the same as
60
-        # giving the 'tvsys' option with 'ntsc' as the argument.
61
-        if self.alias:
62
-            self.doc = 'Same as -%s %s.' % alias
63
-
64
-
65
-    def num_args(self):
66
-        """Return the number of arguments expected by this option,
67
-        or -1 if unlimited.
68
-        """
69
-        # Flag alias for another option
70
-        if self.alias:
71
-            return 0
72
-        # Boolean: no argument
73
-        elif isinstance(self.default, bool):
74
-            return 0
75
-        # List: unlimited arguments
76
-        elif isinstance(self.default, list):
77
-            return -1
78
-        # Unary: one argument
79
-        else:
80
-            return 1
81
-
82
-
83
-    def __str__(self):
84
-        """Return a string containing "usage notes" for this option.
85
-        """
86
-        if self.alias:
87
-            usage = "-%s: Same as '-%s %s'\n" % \
88
-                  (self.name, self.alias[0], self.alias[1])
89
-        else:
90
-            usage = "-%s %s " % (self.name, self.argformat)
91
-            if self.required:
92
-                usage += "(REQUIRED)\n"
93
-            else:
94
-                usage += "(default: %s)\n" % self.default
95
-            for line in textwrap.wrap(self.doc, 60):
96
-                usage += '    ' + line + '\n'
97
-        return usage
98
-
99
-class Usage (object):
100
-    """Command-line usage definition."""
101
-    def __init__(self, usage_string='program [options]', *options):
102
-        """Define usage of a command-line program.
103
-
104
-            usage_string
105
-                Command-line syntax and required options
106
-            options
107
-                List of allowed Options
108
-
109
-        Examples::
110
-
111
-            usage = Usage('pytovid [options] -in FILENAME -out NAME',
112
-                Option('in', 'FILENAME', None,
113
-                    "Input video file, in any format."),
114
-                Option('out', 'NAME', None,
115
-                    "Output prefix or name."),
116
-                Option('format', 'vcd|svcd|dvd|half-dvd|dvd-vcd', 'dvd',
117
-                    "Make video compliant with the specified format")
118
-            )
119
-            print(usage)
120
-            print(usage.options['format'])
121
-
122
-        """
123
-        self.usage_string = usage_string
124
-        # Odict of options indexed by name
125
-        names = [opt.name for opt in options]
126
-        self.options = Odict(names, options)
127
-
128
-
129
-    def __str__(self):
130
-        """Return string-formatted usage notes.
131
-        """
132
-        result = "Usage: %s\n" % self.usage_string
133
-        result += "Allowed options:\n"
134
-        option_list = ['-' + opt.name for opt in self.options.values()]
135
-        result += ', '.join(option_list)
136
-        return result
137
-
138
-
139
-
140
-from copy import copy
141
-
142
-def parse(args):
143
-    """Parse a list of arguments and return a dictionary of found options.
144
-
145
-        args:    List of command-line arguments (such as from sys.argv)
146
-
147
-    The argument list is interpreted in this way:
148
-
149
-        * If it begins with '-', it's an option
150
-        * Arguments that precede the first option are ignored
151
-        * Anything following an option is an argument to that option
152
-        * If there is no argument to an option, it's a flag (True if present)
153
-        * If there's one argument to an option, it's a single string value
154
-        * If there are multiple arguments to an option, it's a list of strings
155
-
156
-    """
157
-    args = copy(args)
158
-    options = {}
159
-    current = None
160
-    while len(args) > 0:
161
-        arg = args.pop(0)
162
-        # New option
163
-        if arg.startswith('-'):
164
-            current = arg.lstrip('-')
165
-            # Treat it as a flag unless we see arguments later
166
-            options[current] = True
167
-
168
-        # Argument to current option
169
-        elif current:
170
-            # Was a flag, now has a single value
171
-            if options[current] is True:
172
-                options[current] = arg
173
-            # Was a single value, now a list
174
-            elif type(options[current]) != list:
175
-                options[current] = [options[current], arg]
176
-            # Was a list, so append new value
177
-            else:
178
-                options[current].append(arg)
179
-    return options
180
-
181
-
182
-import re
183
-
184
-def validate(option, arg):
185
-    """Check whether an argument is valid for a given option.
186
-
187
-        option: An Option to validate
188
-        arg:    Candidate argument
189
-
190
-    Expected/allowed values are inferred from the argformat string.
191
-
192
-    argformat patterns to consider:
193
-        opta|optb|optc      # Either opta, optb, or optc
194
-        [100-999]           # Any integer between 100 and 999
195
-        NUM:NUM             # Any two integers separated by a colon
196
-        VAR                 # A single string (VAR can be any all-caps word)
197
-        VAR [, VAR]         # List of strings
198
-        (empty)             # Boolean; no argument required
199
-
200
-    All very experimental...
201
-    """
202
-    # TODO: Eliminate hackery; find a more robust way of doing this.
203
-    # Also, pretty inefficient, since regexp matching is done every
204
-    # time this function is called.
205
-
206
-    # Empty argformat means boolean/no argument expected
207
-    if option.argformat == '':
208
-        if arg in [True, False, '']:
209
-            return True
210
-        else:
211
-            return False
212
-
213
-    # Any alphanumeric word (any string)
214
-    if re.compile('^\w+$').match(option.argformat):
215
-        if arg.__class__ == str:
216
-            return True
217
-        else:
218
-            return False
219
-
220
-    # Square-bracketed values are ranges, i.e. [1-99]
221
-    match = re.compile('^\[\d+-\d+\]$').match(option.argformat)
222
-    if match:
223
-        # Get min/max by stripping and splitting argformat
224
-        limits = re.split('-', match.group().strip('[]'))
225
-        option.min = int(limits[0])
226
-        option.max = int(limits[1])
227
-        if int(arg) >= option.min and int(arg) <= option.max:
228
-            return True
229
-        else:
230
-            return False
231
-
232
-    # Values separated by | are mutually-exclusive
233
-    if re.compile('[-\w]+\|[-\w]+').match(option.argformat):
234
-        if arg in option.argformat.split('|'):
235
-            return True
236
-        else:
237
-            return False
238
-
239
-    # For now, accept any unknown cases
240
-    return True
241
-
242
-
243
-
244
-if __name__ == '__main__':
245
-    print("Option-parsing demo")
246
-
247
-    print("You passed the following arguments:")
248
-    print(sys.argv[1:])
249
-
250
-    print("Parsing...")
251
-    options = parse(sys.argv[1:])
252
-
253
-    print("Found the following options:")
254
-    print(options)
255
-
256
tovid-0.34.tar.bz2/libtovid/render Deleted
2
 
1
-(directory)
2
tovid-0.34.tar.bz2/libtovid/render/__init__.py Deleted
9
 
1
@@ -1,7 +0,0 @@
2
-__all__ = [
3
-    'animation',
4
-    'drawing',
5
-    'effect',
6
-    'flipbook', 
7
-    'layer',
8
-]
9
tovid-0.34.tar.bz2/libtovid/render/animation.py Deleted
318
 
1
@@ -1,316 +0,0 @@
2
-"""This module provides classes and functions for working with animation.
3
-Two classes are provided:
4
-
5
-    `Keyframe`
6
-        A frame with a specific data value
7
-    `Tween`
8
-        A data sequence interpolated from Keyframes
9
-
10
-The data being interpolated may represent color, opacity, location, or anything
11
-else that can be described numerically. Keyframe data may be scalar (single
12
-integers or decimal values) or vector (tuples such as ``(x, y)`` coordinates or
13
-``(r, g, b)`` color values).
14
-
15
-For example, let's define three keyframes::
16
-
17
-    >>> keys = [Keyframe(1, 0),
18
-    ...         Keyframe(6, 50),
19
-    ...         Keyframe(12, 10)]
20
-
21
-The value increases from 0 to 50 over frames 1-6, then back down to 10
22
-over frames 6-12. The values at intermediate frames (2-5 and 7-11) can be
23
-interpolated or "tweened" automatically, using the Tween class::
24
-
25
-    >>> tween = Tween(keys)
26
-    >>> tween.data
27
-    [0, 10, 20, 30, 40, 50, 43, 36, 30, 23, 16, 10]
28
-
29
-Another example using tweening of ``(x, y)`` coordinates::
30
-
31
-    >>> keys = [Keyframe(1, (20, 20)),
32
-    ...         Keyframe(6, (80, 20)),
33
-    ...         Keyframe(12, (100, 100))]
34
-
35
-Here, a point on a two-dimensional plane starts at (20, 20), moving first
36
-to the right, to (80, 20), then diagonally to (100, 100)::
37
-
38
-    >>> tween = Tween(keys)
39
-    >>> for (x, y) in tween.data:
40
-    ...     print((x, y))
41
-    ...
42
-    (20, 20)
43
-    (32, 20)
44
-    (44, 20)
45
-    (56, 20)
46
-    (68, 20)
47
-    (80, 20)
48
-    (83, 33)
49
-    (86, 46)
50
-    (90, 60)
51
-    (93, 73)
52
-    (96, 86)
53
-    (100, 100)
54
-
55
-"""
56
-
57
-__all__ = [
58
-    'Keyframe',
59
-    'Tween',
60
-    'lerp',
61
-    'cos_interp',
62
-    'interpolate',
63
-]
64
-
65
-import copy
66
-import doctest
67
-import math
68
-
69
-class Keyframe:
70
-    """Associates a specific frame in an animation with a numeric value.
71
-    A Keyframe is a ``(frame, data)`` pair defining a "control point" on a graph::
72
-
73
-            100 |
74
-                |       Keyframe(10, 50)
75
-           data |      *
76
-                |
77
-              0 |__________________________
78
-                1     10     20     30
79
-                        frame
80
-
81
-    The data can represent anything you like. For instance, opacity::
82
-
83
-            100 |* Keyframe(1, 100)
84
-                |
85
-     opacity(%) |
86
-                |
87
-              0 |____________________* Keyframe(30, 0)
88
-                1     10     20     30
89
-                        frame
90
-
91
-    See the `Tween` class below for what you can do with these Keyframes,
92
-    once you have them.
93
-    """
94
-    def __init__(self, frame, data):
95
-        """Create a keyframe, associating a given frame with some data.
96
-        The data may be an integer, floating-point value, or a tuple like
97
-        (x, y) or (r, g, b).
98
-        """
99
-        self.frame = frame
100
-        self.data = data
101
-
102
-
103
-### --------------------------------------------------------------------------
104
-### Interpolation algorithms
105
-### --------------------------------------------------------------------------
106
-
107
-def lerp(x, (x0, y0), (x1, y1)):
108
-    """Do linear interpolation between points ``(x0, y0)``, ``(x1, y1)``, and
109
-    return the ``y`` for the given ``x``.
110
-
111
-    This form of interpolation simply connects two points with a straight
112
-    line. Blunt, but effective.
113
-    """
114
-    return y0 + (x - x0) * (y1 - y0) / (x1 - x0)
115
-
116
-
117
-def cos_interp(x, (x0, y0), (x1, y1)):
118
-    """Do cosine-based interpolation between ``(x0, y0)``, ``(x1, y1)`` and
119
-    return the ``y`` for the given ``x``.
120
-
121
-    Essentially, a crude alternative to polynomial spline interpolation; this
122
-    method transitions between two values by matching a segment of the cosine
123
-    curve [0, pi] (for decreasing value) or [pi, 2*pi] (for increasing value)
124
-    to the interval between the given points.
125
-
126
-    It gives smoother results at inflection points than linear interpolation,
127
-    but will result in "ripple" effects if keyframes are too dense or many.
128
-    """
129
-    # Map the interpolation area (domain of x) to [0, pi]
130
-    x_norm = math.pi * (x - x0) / (x1 - x0)
131
-    # For y0 < y1, use upward-sloping part of the cosine curve [pi, 2*pi]
132
-    if y0 < y1:
133
-        x_norm += math.pi
134
-    # Calculate and return resulting y-value
135
-    y_min = min(y1, y0)
136
-    y_diff = abs(y1 - y0)
137
-    return y_min + y_diff * (math.cos(x_norm) + 1) / 2.0
138
-
139
-
140
-def interpolate(frame, left, right, method='linear'):
141
-    """Return the interpolated value at ``frame``, between two `Keyframe`
142
-    endpoints, using the given interpolation method ('linear' or 'cosine').
143
-
144
-    The left and right Keyframes mark the endpoints of the curve to be
145
-    interpolated. For example, if a value changes from 50 to 80 over the
146
-    course of frames 1 to 30::
147
-
148
-        >>> left = Keyframe(1, 50)
149
-        >>> right = Keyframe(30, 80)
150
-
151
-    Then, the value at frame 10 can be interpolated as follows::
152
-
153
-        >>> interpolate(10, left, right, 'linear')
154
-        59
155
-        >>> interpolate(10, left, right, 'cosine')
156
-        56.582194019564263
157
-
158
-    For frames outside the keyframe interval, the corresponding endpoint value
159
-    is returned::
160
-
161
-        >>> interpolate(0, left, right, 'linear')
162
-        50
163
-        >>> interpolate(40, left, right, 'linear')
164
-        80
165
-
166
-    """
167
-    assert isinstance(left, Keyframe) and isinstance(right, Keyframe)
168
-    # At or beyond endpoints, return endpoint value
169
-    if frame <= left.frame:
170
-        return left.data
171
-    elif frame >= right.frame:
172
-        return right.data
173
-
174
-    # Use the appropriate interpolation function
175
-    if method == 'cosine':
176
-        interp_func = cos_interp
177
-    else: # method == 'linear'
178
-        interp_func = lerp
179
-
180
-    # Interpolate integers or floats
181
-    if isinstance(left.data, int) or isinstance(left.data, float):
182
-        p0 = (left.frame, left.data)
183
-        p1 = (right.frame, right.data)
184
-        return interp_func(frame, p0, p1)
185
-    # Interpolate a tuple (x, y, ...)
186
-    elif isinstance(left.data, tuple):
187
-        # Interpolate each dimension separately
188
-        dim = 0
189
-        result = []
190
-        while dim < len(left.data):
191
-            interp_val = interp_func(frame,
192
-                                     (left.frame, left.data[dim]),
193
-                                     (right.frame, right.data[dim]))
194
-            result.append(interp_val)
195
-            dim += 1
196
-        return tuple(result)
197
-
198
-
199
-class Tween:
200
-    """An "in-between" sequence, calculated by interpolating the data in a
201
-    list of keyframes according to a given interpolation method.
202
-
203
-    First, define some keyframes::
204
-
205
-        >>> keyframes = [Keyframe(1, 1), Keyframe(10, 25)]
206
-
207
-    At frame 1, the value is 1; at frame 10, the value is 25. To get an
208
-    interpolation of the data between these two keyframes, use::
209
-
210
-        >>> tween = Tween(keyframes)
211
-
212
-    Now, retrieve the interpolated data all at once::
213
-
214
-        >>> tween.data
215
-        [1, 3, 6, 9, 11, 14, 17, 19, 22, 25]
216
-
217
-    Or by using array notation, indexed by frame number::
218
-
219
-        >>> tween[3]
220
-        6
221
-        >>> tween[8]
222
-        19
223
-
224
-    """
225
-    def __init__(self, keyframes, method='linear'):
226
-        """Create an in-between sequence from a list of keyframes. The
227
-        interpolation method can be 'linear' or 'cosine'.
228
-
229
-        See `libtovid.render.effect` for implementation examples.
230
-        """
231
-        for keyframe in keyframes:
232
-            assert isinstance(keyframe, Keyframe)
233
-        self.keyframes = keyframes
234
-        self.start = self.keyframes[0].frame
235
-        self.end = self.keyframes[-1].frame
236
-        self.method = method
237
-        # Do the tweening
238
-        self.data = self._calculate()
239
-
240
-
241
-    def _calculate(self):
242
-        """Perform in-betweening calculation on the current keyframes and
243
-        return a list of tweened values, indexed by frame number.
244
-        """
245
-        data = []
246
-        # TODO: Sort keyframes in increasing order by frame number (to ensure
247
-        # keyframes[0] is the first frame, and keyframes[-1] is the last frame)
248
-        # Make a copy of keyframes
249
-        keys = copy.copy(self.keyframes)
250
-        first = self.start
251
-        last = self.end
252
-
253
-        # If keyframe interval is empty, use constant data from first keyframe
254
-        if first == last:
255
-            return keys[0].data
256
-
257
-        # Pop off keyframes as each interval is calculated
258
-        left = keys.pop(0)
259
-        right = keys.pop(0)
260
-        frame = first
261
-        # Interpolate until the last frame is reached
262
-        while frame <= last:
263
-            value = interpolate(frame, left, right, self.method)
264
-            data.append(value)
265
-            # Get the next interval, if it exists
266
-            if frame == right.frame and len(keys) > 0:
267
-                left = right
268
-                right = keys.pop(0)
269
-            frame += 1
270
-
271
-        return data
272
-
273
-
274
-    def __getitem__(self, frame):
275
-        """Return the interpolated data at the given frame. This allows
276
-        accessing a tweened value with subscripting by frame number::
277
-
278
-            >>> keys = [Keyframe(1, 1), Keyframe(30, 50)]
279
-            >>> tween = Tween(keys)
280
-            >>> tween[1]
281
-            1
282
-            >>> tween[30]
283
-            50
284
-            >>> tween[21]
285
-            34
286
-
287
-        Frame numbers outside the keyframed region have the same values as
288
-        those at the corresponding endpoints::
289
-
290
-            >>> tween[0]
291
-            1
292
-            >>> tween[100]
293
-            50
294
-        """
295
-        # If data is a single value, frame is irrelevant
296
-        if not isinstance(self.data, list):
297
-            return self.data
298
-        # Otherwise, return the value for the given frame, extending endpoints
299
-        elif frame < self.start:
300
-            return self.data[0]
301
-        elif frame > self.end:
302
-            return self.data[-1]
303
-        else:
304
-            return self.data[frame - self.start]
305
-
306
-
307
-if __name__ == '__main__':
308
-    doctest.testmod(verbose=True)
309
-
310
-    p0 = (1, 1)
311
-    p1 = (20, 20)
312
-
313
-    print("Interpolation methods")
314
-    print("x      lerp     cos_interp")
315
-    for x in range(1, 21):
316
-        print("%s      %s       %s" % \
317
-              (x, lerp(x, p0, p1), cos_interp(x, p0, p1)))
318
tovid-0.34.tar.bz2/libtovid/render/drawing.py Deleted
1458
 
1
@@ -1,1456 +0,0 @@
2
-# -=- encoding: latin-1 -=-
3
-
4
-# Run this script standalone for a demonstration:
5
-#    $ python libtovid/render/drawing.py
6
-
7
-# To use this module from your Python interpreter, run:
8
-#    $ python
9
-#    >>> from libtovid.render.drawing import *
10
-
11
-"""Interactive vector drawing and rendering interface.
12
-
13
-This module provides a class called Drawing, which provides a blank canvas
14
-that can be painted with vector drawing functions, and later rendered to
15
-a raster image file (.png, .jpg etc.) at any desired resolution.
16
-
17
-To create a new, blank Drawing::
18
-
19
-    >>> d = Drawing(800, 600)          # width, height
20
-
21
-Here, (800, 600) defines two things:
22
-
23
-    - On-screen display size, in pixels (800px x 600px)
24
-    - Intended viewing aspect ratio (800:600 or 4:3)
25
-
26
-Note that you are still doing vector drawing, so whatever size you pick here
27
-has no bearing on your final target resolution--it's mostly intended for a
28
-convenient "preview" size while doing interactive drawing.
29
-
30
-Back on topic: you can now add shapes to the drawing, fill and stroke them::
31
-
32
-    >>> d.circle(500, 300, 150)        # (x, y, radius)
33
-    >>> d.fill('blue', 0.8)            # color name with optional alpha
34
-    >>> d.stroke('rgb(0, 128, 255)')   # rgb values 0-255
35
-
36
-Then add more shapes::
37
-
38
-    >>> d.rectangle(25, 25, 320, 240)  # x, y, width, height
39
-    >>> d.fill('rgb(40%, 80%, 10%)')   # rgb percentages
40
-    >>> d.stroke('#FF0080', 0.5)       # rgb hex notation with an alpha
41
-
42
-To see what the drawing looks like so far, do::
43
-
44
-    >>> display(d)                     # display at existing size
45
-    >>> display(d, 720, 480)           # display at different size
46
-    >>> display(d, fix_aspect=True)    # display in correct aspect ratio
47
-
48
-You may then decide to add more to the drawing::
49
-
50
-    >>> d.set_source('white')
51
-    >>> d.text("Dennis", 50, 100)      # text, x, y
52
-
53
-And preview again::
54
-
55
-    >>> display(d)
56
-
57
-Once you finish your beautiful painting, save it as a nice high-res PNG::
58
-
59
-    >>> save_png(d, "my.png", 1600, 1200)
60
-
61
-Cairo references:
62
-
63
-    [1] http://www.cairographics.org
64
-    [2] http://tortall.net/mu/wiki/CairoTutorial
65
-
66
-"""
67
-
68
-__all__ = [
69
-    'Drawing',
70
-    'render',
71
-    'display',
72
-    'save_image',
73
-    'save_jpg',
74
-    'save_pdf',
75
-    'save_png',
76
-    'save_ps',
77
-    'save_svg',
78
-    'write_ppm',
79
-]
80
-
81
-import os
82
-import sys
83
-import time
84
-import commands
85
-from copy import copy
86
-from math import pi, sqrt
87
-import cairo
88
-import Image      # for JPG export
89
-import ImageColor # for getrgb, getcolor
90
-import ImageFile  # for write_png()
91
-from libtovid import log
92
-from libtovid.util import to_unicode
93
-
94
-def get_surface(width, height, surface_type='image', filename=''):
95
-    """Get a cairo surface at the given dimensions.
96
-    """
97
-    if type(width) != int or type(height) != int:
98
-        log.warning("Surface width and height should be integers."\
99
-                    " Converting to int.")
100
-
101
-    if surface_type == 'image':
102
-        return cairo.ImageSurface(cairo.FORMAT_ARGB32,
103
-                                  int(width), int(height))
104
-    elif surface_type == 'svg':
105
-        return cairo.SVGSurface(filename, width, height)
106
-    elif surface_type == 'pdf':
107
-        return cairo.PDFSurface(filename, width, height)
108
-    elif surface_type == 'ps':
109
-        return cairo.PSSurface(filename, width, height)
110
-
111
-
112
-
113
-### --------------------------------------------------------------------
114
-### Classes
115
-### --------------------------------------------------------------------
116
-class Step:
117
-    """An atomic drawing procedure, consisting of a closed function that
118
-    draws on a given cairo surface, and human-readable information about
119
-    what parameters were given to it.
120
-    """
121
-    def __init__(self, function, *args):
122
-        self.function = function
123
-        self.name = function.__name__.lstrip('_')
124
-        self.args = args
125
-    def __str__(self):
126
-        return "%s%s" % (self.name, self.args)
127
-
128
-
129
-# Drawing class notes
130
-#
131
-# The Drawing class has a number of methods (circle, rectangle, fill, stroke
132
-# and many others) that need to operate on a Cairo surface. But we'd like to
133
-# delay execution of actually drawing on that surface--otherwise, we can't
134
-# easily render a given Drawing to a custom resolution.
135
-#
136
-# Closures save the day here--that is, functions without "free variables".
137
-# Anytime you "paint" on the Drawing, what's actually happening is a new
138
-# function is getting created, whose sole purpose in life is to carry out that
139
-# specific paint operation. These tiny, single-purpose functions are then
140
-# added to a list of steps (self.steps) that will actually be executed at
141
-# rendering-time (i.e., when you do display() or save_png).
142
-#
143
-# This not only lets us render a Drawing to different resolutions, but allows
144
-# the possibility of rendering to different Cairo surfaces.
145
-
146
-class Drawing:
147
-
148
-    tk = None # tkinter widget to send redraws to
149
-
150
-    def __init__(self, width=800, height=600, autodraw=False):
151
-        """Create a blank drawing at the given size.
152
-
153
-            width, height
154
-                Dimensions of the drawable region, in arbitrary units
155
-            autodraw
156
-                Redraw a preview image after each drawing operation
157
-        """
158
-        self.size = (width, height)
159
-        self.w = width
160
-        self.h = height
161
-        self.aspect = float(width) / height
162
-        self.autodraw = autodraw
163
-        #self.commands = []
164
-        self.steps = []
165
-        # "Dummy" surface/context at the original resolution;
166
-        # should not be drawn on
167
-        self.surface = get_surface(width, height, 'image')
168
-        self.cr = cairo.Context(self.surface)
169
-
170
-
171
-    def addStep(self, func, *args):
172
-        """Add a Step to self.steps using the given function and args."""
173
-        step = Step(func, *args)
174
-        self.steps.append(step)
175
-        if self.autodraw and step.name in ['fill', 'stroke']:
176
-            display(self, 640, 480, True)
177
-
178
-
179
-    def doStep(self, func, *args):
180
-        """Add the given Step, and execute it."""
181
-        self.addStep(func, *args)
182
-        func(self.cr)
183
-
184
-
185
-    def history(self):
186
-        """Return a formatted string of all steps in this Drawing."""
187
-        result = ''
188
-        for number, step in enumerate(self.steps):
189
-            result += '%d. %s\n' % (number, step)
190
-        return result
191
-
192
-
193
-    def affine(self, rot_x, rot_y, scale_x, scale_y, translate_x, translate_y):
194
-        """Define a 3x3 transformation matrix::
195
-
196
-            [ scale_x  rot_y    translate_x ]
197
-            [ rot_x    scale_y  translate_y ]
198
-            [ 0        0        1           ]
199
-
200
-        This is scaling, rotation, and translation in a single matrix,
201
-        so it's a compact way to represent any transformation.
202
-
203
-        See [http://www.w3.org/TR/SVG11/coords.html] for more on
204
-        these matrices and how to use them.
205
-        """
206
-        mtx = cairo.Matrix(scale_x, rot_x, rot_y, scale_y,
207
-                           translate_x, translate_y)
208
-        def _affine(cr):
209
-            cr.set_matrix(mtx)
210
-        self.doStep(_affine, rot_x, rot_y, scale_x, scale_y,
211
-                     translate_x, translate_y)
212
-
213
-
214
-    def arc(self, x, y, radius, start_deg, end_deg):
215
-        """Draw an arc from (x, y), with the specified radius, starting at
216
-        degree start_deg and ending at end_deg.
217
-        """
218
-        def _arc(cr):
219
-            cr.arc(x, y, radius, start_deg * pi/180., end_deg * pi/180.)
220
-        self.doStep(_arc, x, y, radius, start_deg, end_deg)
221
-
222
-
223
-    def arc_rad(self, x, y, radius, start_rad, end_rad):
224
-        """Draw an arc from (x, y), with the specified radius, starting at
225
-        radian start_rad and ending at end_rad.
226
-        """
227
-        def _arc_rad(cr):
228
-            cr.arc(x, y, radius, start_rad, end_rad)
229
-        self.doStep(_arc_rad, x, y, radius, start_rad, end_rad)
230
-
231
-
232
-    # TODO: Rewrite/cleanup bezier function
233
-    def bezier(self, points, rel=False, close_path=False):
234
-        """Create a Bezier curve.
235
-
236
-        Points should look like::
237
-
238
-            points = [[(x0, y0), (x_ctl1, y_ctl1), (x_ctl2, y_ctl2)],
239
-                      [(x0, y0), (x_ctl1, y_ctl1), (x_ctl2, y_ctl2)],
240
-                      [(x0, y0), (x_ctl1, y_ctl1), (x_ctl2, y_ctl2)],
241
-                      [(x0, y0)],
242
-                      ]
243
-
244
-        where (x0, y0) are the point coordinates, and x_ctl* are the control
245
-        points coordinates.
246
-
247
-            - ctl1 - control from last point
248
-            - ctl2 - control to next point
249
-
250
-        The last line would specify that control points
251
-        are at the same place (x0, y0), drawing straight lines.
252
-
253
-            rel
254
-                when this is True, the x_ctl and y_ctl become relatives
255
-                to the (x0, y0) points
256
-            close_path
257
-                set this to True to call cr.close_path() before stroking.
258
-
259
-        """
260
-        assert len(points) > 1, "You need at least two points"
261
-        for pt in points:
262
-            # If only one point is specified, copy it for control points
263
-            if len(pt) == 1:
264
-                pt.append(pt[0])       # add the two identical
265
-                pt.append(pt[0])       # control points
266
-            assert len(pt) == 3, "You need to specify three tuples for each point, or one single"
267
-            for y in pt:
268
-                assert isinstance(y, tuple) and len(y) == 2, "You need "\
269
-                       "to specify two-values tuples"
270
-        # Map relative stuff to absolute, when rel=True
271
-        if rel:
272
-            for x in range(0, len(points)):
273
-                pt = points[x]
274
-                assert len(pt) == 3, "In relative mode, you must "\
275
-                       "specify control points"
276
-                # Render relative values to absolute values.
277
-                npt = []
278
-                #             #  x      #  y
279
-                npt.append([pt[0][0], pt[0][1]]) # x0, y0
280
-                npt.append([pt[0][0] + pt[1][0], pt[0][1] + pt[1][1]])
281
-                npt.append([pt[0][0] + pt[2][0], pt[0][1] + pt[2][1]])
282
-                points[x] = npt
283
-
284
-        # Define the actual drawing function
285
-        def _bezier(cr):
286
-            # Move to the first x,y in the first point
287
-            cr.new_path()
288
-            cr.move_to(points[0][0][0], points[0][0][1])
289
-            for pt in points:
290
-                cr.curve_to(pt[2][0], pt[2][1],
291
-                            pt[0][0], pt[0][1],
292
-                            pt[1][0], pt[1][1])
293
-            if close_path:
294
-                cr.close_path()
295
-        self.doStep(_bezier, points, rel, close_path)
296
-
297
-
298
-    def circle(self, center_x, center_y, radius):
299
-        """Draw a circle defined by center point and radius."""
300
-        def _circle(cr):
301
-            cr.new_path()
302
-            cr.arc(center_x, center_y, radius, 0, 2*pi)
303
-        self.doStep(_circle, center_x, center_y, radius)
304
-
305
-
306
-    def fill(self, source=None, opacity=None):
307
-        """Fill the current (closed) path with an optionally given color.
308
-
309
-        If arguments are present, they are passed to set_source()
310
-        before filling. Note that this source will be applied to further
311
-        fill()ings or stroke()ings or text() calls.
312
-        """
313
-        # Optionally set fill color, and save it.
314
-        if source is not None:
315
-            self.set_source(source, opacity)
316
-
317
-        def _fill(cr):
318
-            cr.fill_preserve()
319
-        self.doStep(_fill, source, opacity)
320
-
321
-
322
-    def fill_rule(self, rule):
323
-        """Set the fill rule to one of:
324
-
325
-            evenodd, winding (nonzero)
326
-
327
-        This determines which parts of an overlapping path polygon will
328
-        be filled with the fill() command.
329
-
330
-        http://www.w3.org/TR/SVG/painting.html#FillRuleProperty
331
-        """
332
-        tr = {'evenodd': cairo.FILL_RULE_EVEN_ODD,
333
-              'winding': cairo.FILL_RULE_WINDING}
334
-
335
-        # Test value
336
-        tr[rule]
337
-
338
-        def _fill_rule(cr):
339
-            cr.set_fill_rule(tr[rule])
340
-        self.doStep(_fill_rule, rule)
341
-
342
-
343
-    def font(self, name, slant='normal', weight='normal'):
344
-        """Set the current font.
345
-
346
-            name
347
-                name of the Font, or family (sans-serif, serif)
348
-            slant
349
-                one of: italic, normal, oblique
350
-            weight
351
-                one of: normal, bold
352
-        """
353
-        sl = {'italic': cairo.FONT_SLANT_ITALIC,
354
-              'normal': cairo.FONT_SLANT_NORMAL,
355
-              'oblique': cairo.FONT_SLANT_OBLIQUE}
356
-        wg = {'normal': cairo.FONT_WEIGHT_NORMAL,
357
-              'bold': cairo.FONT_WEIGHT_BOLD}
358
-        def _font(cr):
359
-            cr.select_font_face(name, sl[slant], wg[weight])
360
-        self.doStep(_font, name, slant, weight)
361
-
362
-
363
-    def font_size(self, pointsize):
364
-        """Set the current font size in points.
365
-        """
366
-        def _font_size(cr):
367
-            cr.set_font_size(pointsize)
368
-        self.doStep(_font_size, pointsize)
369
-
370
-
371
-    def font_stretch(self, x=1.0, y=1.0):
372
-        """Set the font stretch type in both directions to one of:
373
-
374
-        = 1.0 -- normal
375
-        > 1.0 -- strench
376
-        < 1.0 -- shrink
377
-
378
-        """
379
-        def _font_stretch(cr):
380
-            m = cr.get_font_matrix()
381
-            m.scale(x, y)
382
-            cr.set_font_matrix(m)
383
-        self.doStep(_font_stretch, x, y)
384
-
385
-
386
-    def font_rotate(self, degrees):
387
-        """Set the font rotation, in degrees.
388
-        """
389
-        def _font_rotate(cr):
390
-            m = cr.get_font_matrix()
391
-            m.rotate(degrees * pi/180.)
392
-            cr.set_font_matrix(m)
393
-        self.doStep(_font_rotate, degrees)
394
-
395
-
396
-    def image_surface(self, x, y, width, height, surface, mask=None):
397
-        """Draw a given cairo.ImageSurface centered at (x, y), at the given
398
-        width and height.
399
-
400
-        If you specify mask, it must be a cairo ImageSurface.
401
-        """
402
-        # Calculate centering and scaling
403
-        add_x, add_y = (0, 0)
404
-        dw = float(width) / float(surface.get_width())
405
-        dh = float(height) / float(surface.get_height())
406
-        if (dw > dh):
407
-            scale = dh
408
-            add_x = (width - dh * float(surface.get_width())) / 2
409
-        else:
410
-            scale = dw
411
-            add_y = (height - dw * float(surface.get_height())) / 2
412
-
413
-        # Save context and get the surface to right dimensions
414
-        self.save()
415
-        self.translate(x + add_x, y + add_y)
416
-        self.scale(scale, scale)
417
-
418
-        # Create and append the drawing function
419
-        if (mask):
420
-            def _image_surface(cr):
421
-                cr.set_source_surface(surface)
422
-                cr.mask_surface(mask)
423
-            self.doStep(_image_surface, x, y, width, height, surface, mask)
424
-        else:
425
-            def _image_surface(cr):
426
-                cr.set_source_surface(surface)
427
-                cr.paint()
428
-            self.doStep(_image_surface, x, y, width, height, surface, mask)
429
-
430
-        self.restore()
431
-
432
-
433
-    def image(self, x, y, width, height, source):
434
-        """Draw an image centered at (x, y), scaled to the given width and
435
-        height. Return the corresponding cairo.ImageSurface object.
436
-
437
-            source
438
-                - a .png filename (quicker and alpha present),
439
-                - a cairo.ImageSurface object, which is even better,
440
-                - a file object
441
-                - a filename - any file supported by python-imaging,
442
-                  a.k.a PIL [1]
443
-
444
-        Ref:
445
-          [1] http://www.pythonware.com/library/pil/handbook/formats.htm
446
-
447
-        You can apply some operator() to manipulation how the image is going
448
-        to show up. See operator()
449
-        """
450
-        # Determine what type of source was given, and make it into
451
-        # a cairo.ImageSurface
452
-        if isinstance(source, cairo.ImageSurface):
453
-            surface = source
454
-        # PNG files can be added directly
455
-        elif isinstance(source, str) and source.endswith('.png'):
456
-            surface = cairo.ImageSurface.create_from_png(source)
457
-        # Other formats must be converted to PNG
458
-        else:
459
-            infile = Image.open(source)
460
-            outfile = open('/tmp/export.png', 'wb+')
461
-            infile.save(outfile, 'PNG')
462
-            outfile.seek(0)
463
-            surface = cairo.ImageSurface.create_from_png(outfile)
464
-            outfile.close()
465
-        # Let someone else do the dirty work
466
-        self.image_surface(x, y, width, height, surface)
467
-
468
-        return surface
469
-
470
-
471
-    def line(self, x0, y0, x1, y1):
472
-        """Set new path as a line from (x0, y0) to (x1, y1).
473
-
474
-        Don't forget to stroke()
475
-        """
476
-        def _line(cr):
477
-            cr.new_path()
478
-            cr.move_to(x0, y0)
479
-            cr.line_to(x1, y1)
480
-        self.doStep(_line, x0, y0, x1, y1)
481
-
482
-
483
-    def operator(self, operator='clear'):
484
-        """Set the operator mode.
485
-
486
-            operator
487
-                One of: clear, source, over, in, out, atop, dest,
488
-                dest_over, dest_in, dest_out, dest_atop, xor, add, saturate
489
-
490
-        """
491
-        ops = {'clear': cairo.OPERATOR_CLEAR,
492
-               'source': cairo.OPERATOR_SOURCE,
493
-               'over': cairo.OPERATOR_OVER,
494
-               'in': cairo.OPERATOR_IN,
495
-               'out': cairo.OPERATOR_OUT,
496
-               'atop': cairo.OPERATOR_ATOP,
497
-               'dest': cairo.OPERATOR_DEST,
498
-               'dest_over': cairo.OPERATOR_DEST_OVER,
499
-               'dest_in': cairo.OPERATOR_DEST_IN,
500
-               'dest_out': cairo.OPERATOR_DEST_OUT,
501
-               'dest_atop': cairo.OPERATOR_DEST_ATOP,
502
-               'xor': cairo.OPERATOR_XOR,
503
-               'add': cairo.OPERATOR_ADD,
504
-               'saturate': cairo.OPERATOR_SATURATE,
505
-               }
506
-
507
-        # Test bad value
508
-        ops[operator]
509
-
510
-        def _operator(cr):
511
-            cr.set_operator(ops[operator])
512
-        self.doStep(_operator, operator)
513
-
514
-
515
-    def paint(self):
516
-        """Paint the current source everywhere within the current clip
517
-        region.
518
-        """
519
-        def _paint(cr):
520
-            cr.paint()
521
-        self.doStep(_paint)
522
-
523
-
524
-    def paint_with_alpha(self, alpha):
525
-        """Paints the current source everywhere within the current clip
526
-        region using a mask of constant alpha value alpha.
527
-
528
-        The effect is similar to paint(), but the drawing is faded out
529
-        using the alpha value.
530
-        """
531
-        def _paint_with_alpha(cr):
532
-            cr.paint_with_alpha(alpha)
533
-        self.doStep(_paint_with_alpha, alpha)
534
-
535
-
536
-    def point(self, x, y):
537
-        """Draw a point at (x, y).
538
-        """
539
-        # Circle radius 1/1000 the drawing width
540
-        radius = float(self.size[0]) / 1000
541
-        def _point(cr):
542
-            cr.new_path()
543
-            cr.arc(x, y, radius, 0, 2*pi)
544
-        self.doStep(_point, x, y)
545
-
546
-
547
-    def polygon(self, points, close_path=True):
548
-        """Define a polygonal path defined by (x, y) points in the given
549
-        list.
550
-
551
-            points = [(x0, y0),
552
-                       (x1, y1),
553
-                       (x2, y2)]
554
-
555
-        Draw strokes and filling yourself, with fill() and stroke().
556
-        """
557
-        nlist = []
558
-        for tup in points:
559
-            nlist.append([tup])
560
-        self.bezier(nlist, False, close_path)
561
-
562
-
563
-    def polyline(self, points, close_path=True):
564
-        """Draw a polygon defined by (x, y) points in the given list.
565
-
566
-        This is a short- (or long-) hand for polygon. In Cairo, you draw
567
-        your filling (fill()), or strokes (stroke()) yourself, so
568
-        having polyline and polygon is basiclly useless.
569
-        """
570
-        self.polygon(points, close_path)
571
-
572
-
573
-    def rectangle_corners(self, x0, y0, x1, y1):
574
-        """Draw a rectangle defined by opposite corners (x0, y0) and (x1, y1).
575
-        """
576
-        def _rectangle_corners(cr):
577
-            cr.new_path()
578
-            cr.rectangle(x0, y0, x1-x0, y1-y0)
579
-        self.doStep(_rectangle_corners, x0, y0, x1, y1)
580
-
581
-
582
-    def rectangle(self, x, y, width, height):
583
-        """Draw a rectangle with top-left corner at (x, y), and (width x height)
584
-        in size.
585
-        """
586
-        def _rectangle(cr):
587
-            cr.new_path()
588
-            cr.rectangle(x, y, width, height)
589
-        self.doStep(_rectangle, x, y, width, height)
590
-
591
-
592
-    def rotate_deg(self, degrees):
593
-        """Rotate by the given number of degrees.
594
-        """
595
-        def _rotate_deg(cr):
596
-            m = cr.get_matrix()
597
-            m.rotate(degrees * pi/180.)
598
-            cr.set_matrix(m)
599
-        self.doStep(_rotate_deg, degrees)
600
-
601
-    rotate = rotate_deg
602
-    def rotate_rad(self, rad):
603
-        """Rotate by the given number of radians.
604
-        """
605
-        def _rotate_rad(cr):
606
-            m = cr.get_matrix()
607
-            m.rotate(rad)
608
-            cr.set_matrix(m)
609
-        self.doStep(_rotate_rad, rad)
610
-
611
-
612
-    def roundrectangle(self, x0, y0, x1, y1, bevel_width, bevel_height):
613
-        """Draw a rounded rectangle from (x0, y0) to (x1, y1), with
614
-        a bevel size of (bevel_width, bevel_height).
615
-        """
616
-        bw = bevel_width
617
-        bh = bevel_height
618
-        # Add bezier points
619
-        tl1 = [(x0, y0 + bh), (0, 0), (0, 0)]
620
-        tl2 = [(x0 + bw, y0), (0, 0), (-bw, 0)]
621
-        tr1 = [(x1 - bw, y0), (0, 0), (-bw, 0)]
622
-        tr2 = [(x1, y0 + bh), (0, 0), (0, -bw)]
623
-        br1 = [(x1, y1 - bh), (0, 0), (0, -bh)]
624
-        br2 = [(x1 - bw, y1), (0, 0), (+bw, 0)]
625
-        bl1 = [(x0 + bw, y1), (0, 0), (+bw, 0)]
626
-        bl2 = [(x0, y1 - bh), (0, 0), (0, +bh)]
627
-        end = [(x0, y0 + bh), (0, 0), (0, 0)]
628
-        # Call in relative mode bezier control points.
629
-        mylst = [tl1, tl2, tr1, tr2, br1, br2, bl1, bl2, end]
630
-        # Let bezier do the work
631
-        self.bezier(mylst, True)
632
-
633
-
634
-    def set_source(self, source, opacity=None):
635
-        """Set the source.
636
-
637
-            source
638
-                One of the following color formats as a string or a tuple
639
-                (see below), another Surface or Surface-derivative object,
640
-                or a Pattern object (and its derivatives).
641
-            opacity
642
-                Opacity ranging from 0.0 to 1.0. Defaults to None. If
643
-                you specify a 'string' or 'tuple' RGB-like code as
644
-                source, opacity defaults to 1.0
645
-
646
-        You can use the following *tuple* format to specify color:
647
-
648
-        - (red, green, blue) with colors ranging from 0.0 to 1.0,
649
-          like Cairo wants them
650
-
651
-        You can use the following *string* formats to specify color:
652
-
653
-        - Hexadecimal color specifiers, given as '#rgb' or '#rrggbb'.
654
-          For example, '#ff0000' specifies pure red.
655
-        - RGB functions, given as 'rgb(red, green, blue)' where the colour
656
-          values are integers in the range 0 to 255. Alternatively, the color
657
-          values can be given as three percentages (0% to 100%). For example,
658
-          'rgb(255,0,0)' and 'rgb(100%,0%,0%)' both specify pure red.
659
-        - Hue-Saturation-Lightness (HSL) functions, given as:
660
-          'hsl(hue, saturation%, lightness%)' where hue is the colour given as
661
-          an angle between 0 and 360 (red=0, green=120, blue=240), saturation
662
-          is a value between 0% and 100% (gray=0%, full color=100%), and
663
-          lightness is a value between 0% and 100% (black=0%, normal=50%,
664
-          white=100%). For example, 'hsl(0,100%,50%)' is pure red.
665
-        - Common HTML colour names. The ImageColor module provides some 140
666
-          standard colour names, based on the colors supported by the X
667
-          Window system and most web browsers. Colour names are case
668
-          insensitive. For example, 'red' and 'Red' both specify pure red.
669
-
670
-        """
671
-        mysource = self.create_source(source, opacity)
672
-        def _set_source(cr):
673
-            cr.set_source(mysource)
674
-        # Only do the step if the source could be created
675
-        if mysource:
676
-            self.doStep(_set_source, source, opacity)
677
-
678
-
679
-    def create_source(self, source, opacity=None):
680
-        """Return a source pattern (solid, gradient, image surface)
681
-        with anything fed into it. Returns None if the source could not
682
-        be created successfully.
683
-
684
-        See the set_source() documentation for more details on inputs.
685
-
686
-        You can feed anything returned by this function into set_source()
687
-        """
688
-        if isinstance(source, cairo.Pattern):
689
-            return source
690
-        # A string--color name, rgb(), hsv(), or hexadecimal
691
-        elif isinstance(source, str):
692
-            try:
693
-                (r, g, b) = ImageColor.getrgb(source)
694
-            except ValueError, err:
695
-                log.error(err)
696
-                return None
697
-            alpha = 1.0
698
-            if opacity is not None:
699
-                alpha = opacity
700
-            return cairo.SolidPattern(r / 255.0, g / 255.0,
701
-                                      b / 255.0, alpha)
702
-        # An (r, g, b) tuple
703
-        elif isinstance(source, tuple):
704
-            assert len(source) == 3
705
-            (r, g, b) = source
706
-            alpha = 1.0
707
-            if opacity is not None:
708
-                alpha = opacity
709
-            return cairo.SolidPattern(r, g, b, alpha)
710
-        # A cairo Gradient
711
-        elif isinstance(source, cairo.Gradient):
712
-            return source
713
-        # A cairo Surface
714
-        elif isinstance(source, cairo.Surface):
715
-            return cairo.SurfacePattern(source)
716
-        else:
717
-            raise TypeError, "source must be one of: str, tuple, "\
718
-                  "cairo.Pattern, cairo.Gradient or cairo.Surface"
719
-
720
-
721
-    def get_source(self):
722
-        """Return the actually used source pattern
723
-
724
-        This returns either of these:
725
-
726
-            cairo.SolidPattern (RGB or RGBA color)
727
-            cairo.SurfacePattern (some other image)
728
-            cairo.LinearGradient (linear gradient :)
729
-            cairo.RadialGradient (radial gradient :)
730
-
731
-        You can then use this source in set_source(), to use the same
732
-        pattern for fill()ing or stroke()ing.
733
-        """
734
-        # TODO: Fix or remove this function
735
-        return self.cr.get_source()
736
-
737
-
738
-    def scale(self, factor_x, factor_y):
739
-        """Set scaling to (factor_x, factor_y), where 1.0 means no scaling.
740
-
741
-        Note that the center point for scaling is (0,0); to scale from a
742
-        different center point, use scale_centered()
743
-        """
744
-        def _scale(cr):
745
-            m = cr.get_matrix()
746
-            m.scale(factor_x, factor_y)
747
-            cr.set_matrix(m)
748
-        self.doStep(_scale, factor_x, factor_y)
749
-
750
-
751
-    def scale_centered(self, center_x, center_y, factor_x, factor_y):
752
-        """Set scaling to (dx, dy), where dx and dy are horizontal and
753
-        vertical ratios (floats).
754
-
755
-        scale_centered() will keep the (center_x, center_y) in the middle
756
-        of the scaling, operating a translation in addition to scaling.
757
-        """
758
-        def _scale_centered(cr):
759
-            m = cr.get_matrix()
760
-            # Ouch, we want to keep the center x,y at the same place?!
761
-            m.translate(-(center_x * factor_x - center_x),
762
-                        -(center_y * factor_y - center_y))
763
-            m.scale(factor_x, factor_y)
764
-            cr.set_matrix(m)
765
-        self.doStep(_scale_centered, center_x, center_y, factor_x, factor_y)
766
-
767
-
768
-    def stroke(self, source=None, opacity=None):
769
-        """Stroke the current shape.
770
-
771
-        See fill() documentation for parameter explanation. They are the
772
-        same.
773
-        """
774
-        # Optionally set stroke color, and save it.
775
-        if source is not None:
776
-            self.set_source(source, opacity)
777
-
778
-        def _stroke(cr):
779
-            # Optionally set fill color, and save it.
780
-            cr.stroke_preserve()
781
-        self.doStep(_stroke, source, opacity)
782
-
783
-
784
-    def stroke_antialias(self, do_antialias=True):
785
-        """Enable/disable antialiasing for strokes.
786
-
787
-            do_antialias: True, False, 'none', 'default', or 'gray'
788
-
789
-        This does not affect text. See text_antialias() for more info
790
-        on text antialiasing.
791
-        """
792
-        if do_antialias:
793
-            aa_type = cairo.ANTIALIAS_GRAY
794
-        else:
795
-            aa_type = cairo.ANTIALIAS_NONE
796
-
797
-        def _stroke_antialias(cr):
798
-            cr.set_antialias(aa_type)
799
-        self.doStep(_stroke_antialias, do_antialias)
800
-
801
-
802
-    def stroke_dash(self, array, offset=0.0):
803
-        """Set the dash style.
804
-
805
-            array
806
-                A list of floats, alternating between ON and OFF for
807
-                each value
808
-            offset
809
-                An offset into the dash pattern at which the stroke
810
-                should start
811
-
812
-        For example::
813
-
814
-            >>> stroke_dash([5.0, 3.0])
815
-
816
-        alternates between 5 pixels on, and 3 pixels off.
817
-        """
818
-        def _stroke_dash(cr):
819
-            cr.set_dash(array, offset)
820
-        self.doStep(_stroke_dash, array, offset)
821
-
822
-
823
-    def stroke_linecap(self, cap_type):
824
-        """Set the type of line cap to use for stroking.
825
-
826
-            cap_type
827
-                'butt', 'round', or 'square'
828
-        """
829
-        dic = {'butt': cairo.LINE_CAP_BUTT,
830
-               'round': cairo.LINE_CAP_ROUND,
831
-               'square': cairo.LINE_CAP_SQUARE}
832
-
833
-        # Test value
834
-        dic[cap_type]
835
-
836
-        def _stroke_linecap(cr):
837
-            cr.set_line_cap(dic[cap_type])
838
-        self.doStep(_stroke_linecap, cap_type)
839
-
840
-
841
-    def stroke_linejoin(self, join_type):
842
-        """Set the type of line-joining to do for stroking.
843
-
844
-            join_type
845
-                'bevel', 'miter', or 'round'
846
-        """
847
-        dic = {'bevel': cairo.LINE_JOIN_BEVEL,
848
-               'miter': cairo.LINE_JOIN_MITER,
849
-               'round': cairo.LINE_JOIN_ROUND}
850
-
851
-        # Test value
852
-        dic[join_type]
853
-
854
-        def _stroke_linejoin(cr):
855
-            cr.set_line_join(dic[join_type])
856
-        self.doStep(_stroke_linejoin, join_type)
857
-
858
-
859
-    def stroke_width(self, width):
860
-        """Set the current stroke width in pixels."""
861
-        # (Pixels or points?)
862
-        def _stroke_width(cr):
863
-            cr.set_line_width(width)
864
-        self.doStep(_stroke_width, width)
865
-
866
-
867
-    def text(self, text_string, x, y, align='left'):
868
-        """Draw the given text string.
869
-
870
-            text_string
871
-                utf8 encoded text string
872
-            x, y
873
-                lower-left corner position
874
-
875
-        Set the text's color with set_source() before calling text().
876
-        """
877
-        text_string = to_unicode(text_string)
878
-
879
-        def _text(cr):
880
-            (dx, dy, w, h, ax, ay) = cr.text_extents(text_string)
881
-            if align == 'right':
882
-                nx = x - w
883
-            elif align == 'center':
884
-                nx = x - w / 2
885
-            else:
886
-                nx = x
887
-            cr.move_to(nx, y)
888
-            cr.show_text(text_string)
889
-        self.doStep(_text, text_string, x, y, align)
890
-
891
-
892
-    def text_path(self, text_string, x, y):
893
-        """Same as text(), but sets a path and doesn't draw anything.
894
-        Call stroke() or fill() yourself.
895
-
896
-        Has the parameters and returns the same values as text().
897
-
898
-        Beware that text() calls the Cairo function show_text() which
899
-        caches glyphs, so is more efficient when dealing with large
900
-        texts.
901
-        """
902
-        if not isinstance(text_string, unicode):
903
-            text_string = unicode(text_string.decode('latin-1'))
904
-        def _text_path(cr):
905
-            cr.move_to(x, y)
906
-            cr.text_path(text_string)
907
-        self.doStep(_text_path, text_string, x, y)
908
-
909
-
910
-    def text_extents(self, text):
911
-        """Returns the dimensions of the to-be-drawn text.
912
-
913
-        Call this before calling text() if you want to place it well,
914
-        according to the dimensions of the text rectangle to be drawn.
915
-
916
-        See text()'s return value for details.
917
-
918
-        Returns:
919
-            (x_bearing, y_bearing, width, height, x_advance, y_advance)
920
-        """
921
-        text = to_unicode(text)
922
-        return self.cr.text_extents(text)
923
-
924
-
925
-    def translate(self, dx, dy):
926
-        """Do a translation by (dx, dy) pixels."""
927
-        def _translate(cr):
928
-            m = cr.get_matrix()
929
-            m.translate(dx, dy)
930
-            cr.set_matrix(m)
931
-        self.doStep(_translate, dx, dy)
932
-
933
-
934
-    def push_group(self):
935
-        """Temporarily redirects drawing to an intermediate surface
936
-        known as a group.
937
-
938
-        The redirection lasts until the group is completed by a call
939
-        to pop_group() or pop_group_to_source(). These calls provide
940
-        the result of any drawing to the group as a pattern, (either
941
-        as an explicit object, or set as the source pattern).
942
-        """
943
-        def _push_group(cr):
944
-            cr.push_group()
945
-        self.doStep(_push_group)
946
-
947
-
948
-    def pop_group_to_source(self):
949
-        """Terminates the redirection begun by a call to push_group() and
950
-        installs the resulting pattern as the source pattern in the current
951
-        cairo context.
952
-        """
953
-        def _pop_group_to_source(cr):
954
-            cr.pop_group_to_source()
955
-        self.doStep(_pop_group_to_source)
956
-
957
-
958
-    def save(self):
959
-        """Save state for Cairo and local contexts.
960
-
961
-        You can save in a nested manner, and calls to restore() will pop
962
-        the latest saved context.
963
-        """
964
-        def _save(cr):
965
-            cr.save()
966
-        self.doStep(_save)
967
-
968
-    BEGIN = save
969
-    def restore(self):
970
-        """Restore the previously saved context.
971
-        """
972
-        def _restore(cr):
973
-            cr.restore()
974
-        self.doStep(_restore)
975
-
976
-    END = restore
977
-    def font_family(self, family):
978
-        """Set the current font, by family name."""
979
-        def _font_family(cr):
980
-            cr.select_font_face(family)
981
-        self.doStep(_font_family, family)
982
-
983
-    font_face = font_family
984
-    def text_align(self, text_string, x, y, align='left'):
985
-        """Draw the given text string.
986
-
987
-            text_string
988
-                UTF-8 encoded text string
989
-            x, y
990
-                Lower-left corner position
991
-            align
992
-                'left', 'center', 'right'. This only changes the
993
-                alignment in 'x', and 'y' stays the baseline.
994
-
995
-        Set the text's color with set_source() before calling text().
996
-        """
997
-        (dx, dy, w, h, ax, ay) = self.cr.text_extents(text_string)
998
-        w = 0
999
-        if align == 'right':
1000
-            x = x - w
1001
-        elif align == 'center':
1002
-            x = x - w / 2
1003
-        else: # 'left'
1004
-            x = x
1005
-        # Let text() do the drawing
1006
-        self.text(text_string, x, y)
1007
-
1008
-
1009
-    def text_path_align(self, x, y, text_string, centered=False):
1010
-        """Same as text_align(), but sets a path and doesn't draw anything.
1011
-        Call stroke() or fill() yourself.
1012
-        """
1013
-        (dx, dy, w, h, ax, ay) = self.cr.text_extents(text_string)
1014
-        if centered:
1015
-            x = x - w / 2
1016
-            y = y + h / 2
1017
-        # Let text_path() do the drawing
1018
-        self.text_path(text_string, x, y)
1019
-
1020
-
1021
-### --------------------------------------------------------------------
1022
-### Exported functions
1023
-### --------------------------------------------------------------------
1024
-# Cached masks, rendered only once.
1025
-interlace_fields = None
1026
-
1027
-
1028
-def interlace_drawings(draw1, draw2):
1029
-    """Merge two drawings into one, using interlacing fields.
1030
-
1031
-    This method interlaces with the BOTTOM-FIRST field order.
1032
-    """
1033
-    global interlace_fields
1034
-
1035
-    dr = Drawing(draw1.w, draw1.h)
1036
-
1037
-    # create masks (only once)
1038
-    if (not interlace_fields):
1039
-        fields = [0, 1]
1040
-        for f in range(0, 2):
1041
-            img = cairo.ImageSurface(cairo.FORMAT_ARGB32, draw1.w, draw1.h)
1042
-            cr = cairo.Context(img)
1043
-            cr.set_antialias(cairo.ANTIALIAS_NONE)
1044
-            cr.set_source_rgba(0.5, 0.5, 0.5, 1)
1045
-            cr.set_line_width(1)
1046
-
1047
-            for x in range(0, draw1.h / 2):
1048
-                # x*2 + f = top field first.., each two lines..
1049
-                # -1 à draw1.w +1 -> pour être sur de couvrir aussi les bouts.
1050
-                cr.move_to(-1, x*2 + f)
1051
-                cr.line_to(draw1.w + 1, x*2 + f)
1052
-                cr.stroke()
1053
-
1054
-            fields[f] = img
1055
-        interlace_fields = fields
1056
-    else:
1057
-        fields = interlace_fields
1058
-
1059
-    # For bottom first, use fields[0] first, and fields[1] after.
1060
-    # For top-first, use draw1 with fields[1] and draw2 with fields[0]
1061
-    # paint first image
1062
-    dr.image_surface(0, 0, dr.w, dr.h, draw1.surface, fields[0])
1063
-    # paint second image
1064
-    dr.image_surface(0, 0, dr.w, dr.h, draw2.surface, fields[1])
1065
-
1066
-    return dr
1067
-
1068
-
1069
-
1070
-def render(drawing, context, width, height):
1071
-    """Render a Drawing to the given cairo context at the given size.
1072
-    """
1073
-    # Scale from the original size
1074
-    scale_x = float(width) / drawing.size[0]
1075
-    scale_y = float(height) / drawing.size[1]
1076
-    drawing.scale(scale_x, scale_y)
1077
-    # Sneaky bit--scaling needs to happen before everything else
1078
-    drawing.steps.insert(0, drawing.steps.pop(-1))
1079
-
1080
-    # Execute all draw commands
1081
-    for step in drawing.steps:
1082
-        log.debug("Drawing step: %s" % step)
1083
-        step.function(context)
1084
-
1085
-    # Remove scaling function
1086
-    drawing.steps.pop(0)
1087
-
1088
-
1089
-def display(drawing, width=None, height=None, fix_aspect=False):
1090
-    """Render and display the given Drawing at the given size.
1091
-
1092
-        drawing
1093
-            A Drawing object to display
1094
-        width
1095
-            Pixel width of displayed image,
1096
-            or 0 to use the given Drawing's size
1097
-        height
1098
-            Pixel height of displayed image,
1099
-            or 0 to use the given Drawing's size
1100
-        fix_aspect
1101
-            True to adjust height to make the image
1102
-            appear in the correct aspect ratio
1103
-    """
1104
-    if not width:
1105
-        width = drawing.size[0]
1106
-    if not height:
1107
-        height = drawing.size[1]
1108
-
1109
-    # Adjust height to fix aspect ratio if desired
1110
-    if fix_aspect:
1111
-        height = width / drawing.aspect
1112
-    # Render and display a .png
1113
-    png_file = '/tmp/drawing.png'
1114
-    save_png(drawing, png_file, width, height)
1115
-    print("Displaying %s at %sx%s" % (png_file, width, height))
1116
-    print("(press 'q' in image window to continue)")
1117
-    print(commands.getoutput('display %s' % png_file))
1118
-
1119
-
1120
-def write_ppm(drawing, pipe, width, height, workdir=None):
1121
-    """Write image as a PPM file to a file-object
1122
-
1123
-      workdir
1124
-        Unused in this context, just to have parallel parameters
1125
-        with write_png().
1126
-
1127
-    Useful to pipe directly in ppmtoy4m and to pipe directly to mpeg2enc.
1128
-    """
1129
-    # Timing
1130
-    start = time.time()
1131
-    if (width, height) == drawing.size:
1132
-        #print("Not re-rendering")
1133
-        surface = drawing.surface
1134
-    else:
1135
-        surface = get_surface(width, height, 'image')
1136
-        context = cairo.Context(surface)
1137
-        render(drawing, context, width, height)
1138
-
1139
-    buf = surface.get_data()
1140
-    # Assumes surface is cairo.FORMAT_ARGB32
1141
-    im = Image.frombuffer('RGBA', (surface.get_width(),  surface.get_height()),
1142
-                          buf)
1143
-    im = im.transpose(Image.FLIP_TOP_BOTTOM)
1144
-    im.save(pipe, 'ppm')
1145
-
1146
-    #print("write_ppm took %s seconds" % (time.time() - start))
1147
-
1148
-
1149
-def write_png(drawing, pipe, width, height, workdir):
1150
-    """Write image as a PPM file to a file-object
1151
-
1152
-    Useful to pipe directly in::
1153
-
1154
-        pngtopnm -mix -background=rgb:00/00/00 | ppmtoy4m | mpeg2enc.
1155
-    """
1156
-    # Timing
1157
-    start = time.time()
1158
-    if (width, height) == drawing.size:
1159
-        #print("Not re-rendering")
1160
-        surface = drawing.surface
1161
-    else:
1162
-        surface = get_surface(width, height, 'image')
1163
-        context = cairo.Context(surface)
1164
-        render(drawing, context, width, height)
1165
-
1166
-    surface.write_to_png('%s/tmp.png' % workdir)
1167
-    im = Image.open('%s/tmp.png' % workdir)
1168
-    im.load()
1169
-    im.save(pipe, 'ppm')
1170
-
1171
-    #print("write_png took %s seconds" % (time.time() - start))
1172
-
1173
-
1174
-def save_png(drawing, filename, width, height):
1175
-    """Saves a drawing to PNG, keeping alpha channel intact.
1176
-
1177
-    This is the quickest, since Cairo itself exports directly to .png
1178
-    """
1179
-    # Timing
1180
-    start = time.time()
1181
-    if (width, height) == drawing.size:
1182
-        #print("Not re-rendering")
1183
-        surface = drawing.surface
1184
-    else:
1185
-        surface = get_surface(width, height, 'image')
1186
-        context = cairo.Context(surface)
1187
-        render(drawing, context, width, height)
1188
-    surface.write_to_png(filename)
1189
-    #print("save_png took %s seconds" % (time.time() - start))
1190
-
1191
-
1192
-def save_jpg(drawing, filename, width, height):
1193
-    """Saves a drawing to JPG, losing alpha channel information.
1194
-    """
1195
-    f = open('/tmp/export.png', 'wb+')
1196
-    save_png(drawing, f, width, height)
1197
-    f.seek(0)
1198
-    im = Image.open(f)
1199
-    im.save(filename)
1200
-    del(im)
1201
-    f.close()
1202
-
1203
-
1204
-def save_image(drawing, img_filename, width, height):
1205
-    """Render drawing to a .jpg, .png or other image.
1206
-    """
1207
-    log.info("Saving Drawing to %s" % img_filename)
1208
-    if img_filename.endswith('.png'):
1209
-        save_png(drawing, img_filename, width, height)
1210
-    elif img_filename.endswith('.jpg'):
1211
-        save_jpg(drawing, img_filename, width, height)
1212
-    else:
1213
-        log.debug("Creating temporary .png")
1214
-        temp_png = '/tmp/%s.png' % img_filename
1215
-        save_png(drawing, temp_png, width, height)
1216
-        log.debug("Converting temporary png to %s" % img_filename)
1217
-        cmd = "convert -size %sx%s " % drawing.size
1218
-        cmd += "%s %s" % (temp_png, img_filename)
1219
-        print(commands.getoutput(cmd))
1220
-
1221
-
1222
-def save_svg(drawing, filename, width, height):
1223
-    """Render drawing to an SVG file.
1224
-    """
1225
-    surface = get_surface(width, height, 'svg', filename)
1226
-    context = cairo.Context(surface)
1227
-    render(drawing, context, width, height)
1228
-    context.show_page()
1229
-    surface.finish()
1230
-    print("Saved SVG to %s" % filename)
1231
-
1232
-
1233
-def save_pdf(drawing, filename, width, height):
1234
-    """Render drawing to a PDF file.
1235
-    """
1236
-    surface = get_surface(width, height, 'pdf', filename)
1237
-    context = cairo.Context(surface)
1238
-    render(drawing, context, width, height)
1239
-    context.show_page()
1240
-    surface.finish()
1241
-    print("Saved PDF to %s" % filename)
1242
-
1243
-
1244
-def save_ps(drawing, filename, width, height):
1245
-    """Render drawing to a PostScript file.
1246
-    """
1247
-    surface = get_surface(width, height, 'ps', filename)
1248
-    context = cairo.Context(surface)
1249
-    render(drawing, context, width, height)
1250
-    context.show_page()
1251
-    surface.finish()
1252
-    print("Saved PostScript to %s" % filename)
1253
-
1254
-
1255
-### --------------------------------------------------------------------
1256
-### Demo functions
1257
-### --------------------------------------------------------------------
1258
-def draw_fontsize_demo(drawing):
1259
-    """Draw font size samples on the given drawing.
1260
-    """
1261
-    assert isinstance(drawing, Drawing)
1262
-
1263
-    # Save context
1264
-    drawing.save()
1265
-    # TODO: Remove this scaling hack
1266
-    drawing.scale(800.0/720, 600.0/480)
1267
-
1268
-    # Draw white text in a range of sizes
1269
-    drawing.set_source('white')
1270
-
1271
-    for size in [12, 16, 20, 24, 28, 32]:
1272
-        ypos = size * size / 5
1273
-        drawing.font('Nimbus Sans')
1274
-        drawing.font_size(size)
1275
-        drawing.text("%s pt: The quick brown fox" % size, 700, ypos, 'right')
1276
-
1277
-    # Restore context
1278
-    drawing.restore()
1279
-
1280
-
1281
-def draw_font_demo(drawing):
1282
-    """Draw samples of different fonts on the given drawing.
1283
-    """
1284
-    assert isinstance(drawing, Drawing)
1285
-
1286
-    # Save context
1287
-    drawing.save()
1288
-    # TODO: Remove this scaling hack
1289
-    drawing.scale(800.0/720, 600.0/480)
1290
-
1291
-    fontsize = 24
1292
-    drawing.font_size(fontsize)
1293
-    fonts = [
1294
-        'Arial',
1295
-        'Baskerville',
1296
-        'Dragonwick',
1297
-        'Georgia',
1298
-        'Helvetica',
1299
-        'Linotext',
1300
-        'Luxi Mono',
1301
-        'Nimbus Sans',
1302
-        'Old-Town',
1303
-        'Sharktooth',
1304
-        'Tahoma',
1305
-        'Times']
1306
-    ypos = 0
1307
-    for font in fonts:
1308
-        drawing.font(font)
1309
-        # Transparent shadow
1310
-        drawing.set_source('darkblue', 0.4)
1311
-        drawing.text(font, 3, ypos+3)
1312
-        # White text
1313
-        drawing.set_source('white', 1.0)
1314
-        drawing.text(font, 0, ypos)
1315
-        ypos += fontsize
1316
-
1317
-    # Restore context
1318
-    drawing.restore()
1319
-
1320
-
1321
-def draw_shape_demo(drawing):
1322
-    """Draw shape samples on the given drawing.
1323
-    """
1324
-    assert isinstance(drawing, Drawing)
1325
-
1326
-    # Save context
1327
-    drawing.save()
1328
-    # TODO: Remove this scaling hack
1329
-    drawing.scale(800.0/720, 600.0/480)
1330
-
1331
-    # Large orange circle with black stroke
1332
-    drawing.save()
1333
-    drawing.stroke_width(12)
1334
-    # Circle at (500, 200), with radius 200
1335
-    drawing.circle(500, 200, 200)
1336
-    drawing.stroke('black')
1337
-    drawing.fill('orange')
1338
-    drawing.restore()
1339
-
1340
-    # Grey-stroked blue circles
1341
-    drawing.save()
1342
-    # TODO:
1343
-    # All circles have the same stroke width and color (and, in other cases,
1344
-    # might all have the same fill style as well). A simpler interface is
1345
-    # called for, e.g.:
1346
-    # drawing.set_style(fill='#8080FF', stroke='#777', stroke_width=2)
1347
-    # drawing.circle((65, 50), 15)
1348
-    # drawing.circle((65, 100), 10)
1349
-    # drawing.circle((65, 150), 5)
1350
-    # drawing.set_style(fill='black') # stroke stays the same as before
1351
-    # drawing.rectangle((40, 30), (50, 150))
1352
-
1353
-    drawing.stroke_width(2)
1354
-    drawing.circle(65, 50, 15)
1355
-    drawing.fill('#8080FF')
1356
-    drawing.stroke('#777')
1357
-
1358
-    drawing.circle(60, 100, 10)
1359
-    drawing.fill('#2020F0')
1360
-    drawing.stroke('#777')
1361
-
1362
-    drawing.circle(55, 150, 5)
1363
-    drawing.fill('#0000A0')
1364
-    drawing.stroke('#777')
1365
-    drawing.restore()
1366
-
1367
-    # Semitransparent green rectangles
1368
-    drawing.save()
1369
-    drawing.translate(50, 400)
1370
-    for scale in [0.2, 0.4, 0.7, 1.1, 1.6, 2.2, 2.9, 3.7]:
1371
-        drawing.save()
1372
-        drawing.translate(scale * 70, scale * -50)
1373
-        drawing.scale(scale, scale)
1374
-        drawing.stroke_width(scale)
1375
-        # roundrectangle broken?
1376
-        drawing.roundrectangle(-30, -30, 30, 30, 8, 8)
1377
-        #drawing.rectangle(-30, -30, 30, 30)
1378
-        drawing.fill('lightgreen', scale / 5.0)
1379
-        drawing.stroke('black')
1380
-        drawing.restore()
1381
-    drawing.restore()
1382
-
1383
-    # Restore context
1384
-    drawing.restore()
1385
-
1386
-
1387
-def draw_stroke_demo(drawing):
1388
-    """Draw a stroke/strokewidth demo on the given drawing.
1389
-    """
1390
-    assert isinstance(drawing, Drawing)
1391
-
1392
-    # Save context
1393
-    drawing.save()
1394
-    # TODO: Remove this scaling hack
1395
-    drawing.scale(800.0/720, 600.0/480)
1396
-
1397
-    for width in [1, 2, 4, 6, 8, 10, 12, 14, 16]:
1398
-        drawing.stroke_width(width)
1399
-        rgb = ((255 - width * 8), (120 - width * 5), 0)
1400
-        offset = width * 10
1401
-        drawing.line(0, offset, -offset, offset)
1402
-        drawing.stroke('rgb(%s,%s,%s)' % rgb)
1403
-
1404
-    # Restore context
1405
-    drawing.restore()
1406
-
1407
-
1408
-if __name__ == '__main__':
1409
-    mytime = time.time() # Benchmark
1410
-
1411
-    drawing = Drawing(800, 600)
1412
-
1413
-    # Start a new
1414
-    drawing.save()
1415
-
1416
-    # Add a background fill
1417
-    #->Background
1418
-    drawing.set_source('darkgray')
1419
-    drawing.rectangle(0, 0, 800, 600)
1420
-    drawing.fill()
1421
-
1422
-    # Shape demo
1423
-    drawing.save()
1424
-    draw_shape_demo(drawing)
1425
-    drawing.restore()
1426
-
1427
-    # Font size demo
1428
-    drawing.save()
1429
-    draw_fontsize_demo(drawing)
1430
-    drawing.restore()
1431
-
1432
-    # Stroke demo
1433
-    drawing.save()
1434
-    drawing.translate(680, 240)
1435
-    draw_stroke_demo(drawing)
1436
-    drawing.restore()
1437
-
1438
-    # Font face demo
1439
-    drawing.save()
1440
-    drawing.translate(60, 160)
1441
-    draw_font_demo(drawing)
1442
-    drawing.restore()
1443
-
1444
-    # Close out the Cairo rendering...
1445
-    drawing.restore()
1446
-
1447
-    print("Took %f seconds" % (time.time() - mytime))
1448
-
1449
-    # Render and display the Drawing at several different sizes
1450
-    resolutions = [(352, 240), (352, 480), (720, 480), (800, 600)]
1451
-    #resolutions = [(720, 480)]
1452
-    for w, h in resolutions:
1453
-        display(drawing, w, h)
1454
-
1455
-    #save_svg(drawing, "/tmp/drawing.svg", 400, 300)
1456
-    #save_pdf(drawing, "/tmp/drawing.pdf", 400, 300)
1457
-    #save_ps(drawing, "/tmp/drawing.ps", 400, 300)
1458
tovid-0.34.tar.bz2/libtovid/render/effect.py Deleted
459
 
1
@@ -1,457 +0,0 @@
2
-"""This module defines classes for creating and drawing effects on a series
3
-of drawings (as in a Flipbook).
4
-
5
-Effect classes are arranged in a (currently) simple hierarchy::
6
-
7
-    Effect (base class)
8
-        Movement
9
-            Translate
10
-        Fade
11
-            FadeInOut
12
-        Colorfade
13
-        Spectrum
14
-        Scale
15
-        Whirl
16
-        PhotoZoom
17
-        KeyFunction
18
-
19
-"""
20
-
21
-__all__ = [
22
-    'Effect',
23
-    'Movement',
24
-    'Translate',
25
-    'Fade',
26
-    'FadeInOut',
27
-    'Colorfade',
28
-    'Spectrum',
29
-    'Scale',
30
-    'Whirl',
31
-    'PhotoZoom',
32
-    'KeyFunction',
33
-]
34
-
35
-from libtovid.render.drawing import Drawing
36
-from libtovid.render.animation import Keyframe, Tween
37
-from random import randint
38
-
39
-class Effect:
40
-    """A "special effect" created by keyframing a Cairo drawing command
41
-    along the given frame interval.
42
-    """
43
-    def __init__(self, start, end):
44
-        """Create an effect lasting from start frame to end frame.
45
-        """
46
-        self.start = start
47
-        self.end = end
48
-        # List of Keyframes
49
-        self.keyframes = [Keyframe(self.start, 0), Keyframe(self.end, 0)]
50
-        self.tween = Tween(self.keyframes)
51
-
52
-        # Parents
53
-        self._parent_flipbook = None
54
-        self._parent_layer = None
55
-
56
-
57
-    def init_parent_flipbook(self, fb):
58
-        self._parent_flipbook = fb
59
-
60
-
61
-    def init_parent_layer(self, layer):
62
-        self._parent_layer = layer
63
-
64
-
65
-    def pre_draw(self, drawing, frame):
66
-        """Set up effect elements that must be applied before drawing a Layer.
67
-
68
-            drawing
69
-                The Drawing to apply effects to
70
-            frame
71
-                The frame for which to render the effect
72
-
73
-        Extend this function in derived classes.
74
-        """
75
-        drawing.save()
76
-
77
-
78
-    def post_draw(self, drawing, frame):
79
-        """Finalize effect elements after a Layer is drawn.
80
-
81
-            drawing
82
-                The Drawing to apply effects to
83
-            frame
84
-                The frame for which to render the effect
85
-
86
-        Extend this function in derived classes.
87
-        """
88
-        drawing.restore()
89
-
90
-
91
-# New Effect template
92
-#
93
-# Copy and paste this code to create your own Effect
94
-#
95
-# The first line defines your effect's name. (Effect) means it inherits from
96
-# the base Effect class, and shares some properties with it.
97
-
98
-class MyEffect (Effect):
99
-    """Modify this documentation string to describe what your effect does.
100
-    """
101
-    # The __init__ function is called whenever a MyEffect is created. Make
102
-    # sure your __init__ takes start and end arguments; additional arguments
103
-    # (such as start_val and end_val below) allow someone using your effect
104
-    # class to customize its behavior in some way. See the other effects below
105
-    # for examples.
106
-    def __init__(self, start, end, start_val, end_val):
107
-        """Create a MyEffect lasting from start to end frame.
108
-        """
109
-        # Be sure to call this first-thing:
110
-        Effect.__init__(self, start, end)
111
-        # It initializes the base Effect class with start and end frames.
112
-
113
-        # Next, define any keyframes your effect needs to use. This
114
-        # effect just varies something from start_val to end_val:
115
-        self.keyframes = [
116
-            Keyframe(start, start_val),
117
-            Keyframe(end, end_val)
118
-            ]
119
-
120
-        # Call this afterwards, to calculate the values at all frames
121
-        self.tween = Tween(self.keyframes)
122
-
123
-    def draw(self, drawing, frame):
124
-        """Undocumented"""
125
-        # Example function that can be called when drawing a layer.
126
-        # The Layer must know that his particular effect requires the
127
-        # calling of this function, or to add special parameters, or to
128
-        # draw between items in the layer.
129
-
130
-        # First, it's good to make sure we really have a Drawing class
131
-        assert isinstance(drawing, Drawing)
132
-
133
-        # This effect varies the stroke width across a sequence of frames.
134
-        # Replace 'stroke_width' with your own drawing function(s)
135
-        drawing.stroke_width(self.tween[frame])
136
-
137
-    # Effect rendering occurs in two phases: pre_draw and post_draw.
138
-    # These functions are already defined in the Effect base class; extend
139
-    # them to do your effect rendering.
140
-    def pre_draw(self, drawing, frame):
141
-        """Do preliminary effect rendering."""
142
-        # Always call the base class pre_draw first:
143
-        Effect.pre_draw(self, drawing, frame)
144
-
145
-        # This effect varies the stroke width across a sequence of frames.
146
-        # Replace 'stroke_width' with your own drawing function(s)
147
-        drawing.stroke_width(self.tween[frame])
148
-
149
-    # Extend post_draw to do any post-rendering cleanup you need to do. Most
150
-    # of the time, you won't need to extend this, but if you do, be sure to
151
-    # call the base class post_draw at the end:
152
-    def post_draw(self, drawing, frame):
153
-        """Do post-drawing cleanup."""
154
-        # Post-drawing cleanup here
155
-        Effect.post_draw(self, drawing, frame)
156
-
157
-
158
-class Movement (Effect):
159
-    """A movement effect, from one point to another."""
160
-    def __init__(self, start, end, (x0, y0), (x1, y1)):
161
-        """Move from start (x0, y0) to end (x1, y1).
162
-        """
163
-        Effect.__init__(self, start, end)
164
-        self.keyframes = [
165
-            Keyframe(start, (x0, y0)),
166
-            Keyframe(end, (x1, y1))
167
-            ]
168
-        self.tween = Tween(self.keyframes)
169
-
170
-    def pre_draw(self, drawing, frame):
171
-        drawing.save()
172
-        drawing.translate(*self.tween[frame])
173
-
174
-    def post_draw(self, drawing, frame):
175
-        drawing.restore()
176
-
177
-class Translate (Movement):
178
-    """Translates the layer to some relative (x,y) coordinates
179
-    """
180
-    def __init__(self, start, end, (dx, dy)):
181
-        Movement.__init__(self, start, end, (0, 0), (dx, dy))
182
-
183
-
184
-class Fade (Effect):
185
-    """A generic fade effect, varying the opacity of a layer.
186
-    """
187
-    def __init__(self, keyframes, method='linear'):
188
-        """Fade in from start, for fade_length frames; hold at full
189
-        opacity, then fade out for fade_length frames before end.
190
-
191
-            fade_length
192
-                Number of frames to fade-in from start, and number of
193
-                frames to fade-out before end. Everything in-between
194
-                is at full opacity.
195
-            keyframes
196
-                A set of Keyframe() objects, determining the fading
197
-                curve. Values of the Keyframe() must be floats ranging
198
-                from 0.0 to 1.0 (setting opacity).
199
-            method
200
-                'linear' or 'cosine' interpolation
201
-
202
-        """
203
-        # A fill-opacity curve, something like:
204
-        #         ______        100%
205
-        #        /      \
206
-        # start./        \.end  0%
207
-        #
208
-        if isinstance(keyframes, list):
209
-            if not isinstance(keyframes[0], Keyframe):
210
-                raise ValueError, "Must be a list of Keyframe objects"
211
-            self.keyframes = keyframes
212
-        else:
213
-            raise ValueError, "List of Keyframe objects required"
214
-
215
-        self.tween = Tween(self.keyframes, method)
216
-
217
-
218
-    def pre_draw(self, drawing, frame):
219
-        """Called before drawing on a layer.
220
-        """
221
-        drawing.push_group()
222
-
223
-
224
-    def post_draw(self, drawing, frame):
225
-        """Called after drawing on a layer.
226
-        """
227
-        assert isinstance(drawing, Drawing)
228
-        drawing.pop_group_to_source()
229
-        drawing.paint_with_alpha(self.tween[frame])
230
-
231
-class FadeInOut (Fade):
232
-    def __init__(self, start, end, fade_length=30):
233
-        """Fade in from start, for fade_length frames; hold at full
234
-        opacity, then fade out for fade_length frames before end.
235
-
236
-            fade_length
237
-                Number of frames to fade-in from start, and number of
238
-                frames to fade-out before end. Everything in-between
239
-                is at full opacity.
240
-        """
241
-        # A fill-opacity curve, something like:
242
-        #         ______        100%
243
-        #        /      \
244
-        # start./        \.end  0%
245
-        #
246
-        self.keyframes = [
247
-                Keyframe(start, 0.0),                  # Start fading in
248
-                Keyframe(start + fade_length, 1.0),    # Fade-in done
249
-                Keyframe(end - fade_length, 1.0),      # Start fading out
250
-                Keyframe(end, 0.0)                     # Fade-out done
251
-                ]
252
-
253
-        self.tween = Tween(self.keyframes)
254
-
255
-class Colorfade (Effect):
256
-    """A color-slide effect between an arbitrary number of RGB colors.
257
-    """
258
-    def __init__(self, start, end, (r0, g0, b0), (r1, g1, b1)):
259
-        """Fade between the given RGB colors."""
260
-        Effect.__init__(self, start, end)
261
-        self.keyframes = [
262
-            Keyframe(start, (r0, g0, b0)),
263
-            Keyframe(end, (r1, g1, b1))
264
-            ]
265
-        self.tween = Tween(self.keyframes)
266
-
267
-
268
-    def pre_draw(self, drawing, frame):
269
-        """Set source color"""
270
-        drawing.set_source(self.tween[frame])
271
-
272
-
273
-    def post_draw(self, drawing, frame):
274
-        pass
275
-
276
-
277
-class Spectrum (Effect):
278
-    """A full-spectrum color-fade effect between start and end frames.
279
-    """
280
-    def __init__(self, start, end):
281
-        Effect.__init__(self, start, end)
282
-        step = (end - start) / 6
283
-        self.keyframes = [
284
-            Keyframe(start, (1.0, 0, 0)),
285
-            Keyframe(start + step, (1.0, 0, 1.0)),
286
-            Keyframe(start + step*2, (0, 0, 1.0)),
287
-            Keyframe(start + step*3, (0, 1.0, 1.0)),
288
-            Keyframe(start + step*4, (0, 1.0, 0)),
289
-            Keyframe(start + step*5, (1.0, 1.0, 0)),
290
-            Keyframe(end, (1.0, 0, 0))
291
-            ]
292
-        self.tween = Tween(self.keyframes)
293
-
294
-
295
-    def pre_draw(self, drawing, frame):
296
-        drawing.set_source(self.tween[frame])
297
-
298
-
299
-    def post_draw(self, drawing, frame):
300
-        pass
301
-
302
-class Scale (Effect):
303
-    """A Scaling effect, from one size to another.
304
-    """
305
-    def __init__(self, start, end, (w0, h0), (w1, h1)):
306
-        Effect.__init__(self, start, end)
307
-        self.keyframes = [
308
-            Keyframe(start, (w0, h0)),
309
-            Keyframe(end, (w1, h1))
310
-            ]
311
-        self.tween = Tween(self.keyframes)
312
-
313
-
314
-    def pre_draw(self, drawing, frame):
315
-        drawing.save()
316
-        drawing.scale(self.tween[frame])
317
-
318
-
319
-    def post_draw(self, drawing, frame):
320
-        drawing.restore()
321
-
322
-class Whirl (Effect):
323
-    """Rotates an object a number of times.
324
-    """
325
-    def __init__(self, keyframes, center=(0, 0), method='linear', units='deg'):
326
-        """Create a Whirl effect
327
-
328
-            method
329
-                'linear' or 'cosine', for passing from one angle to another
330
-            units
331
-                'deg' or 'rad', the unit used in the Keyframes
332
-        """
333
-        if units != 'deg' and units != 'rad':
334
-            raise ValueError, "units must be 'rad' (radians) or 'deg' (degrees)"
335
-        self.units = units
336
-
337
-        if not isinstance(center, tuple):
338
-            raise ValueError, "center must be a two-value tuple"
339
-        self.center = center
340
-
341
-        self.keyframes = keyframes
342
-        self.tween = Tween(self.keyframes, method)
343
-
344
-
345
-    def pre_draw(self, drawing, frame):
346
-        drawing.save()
347
-        # how to center the thing ? so you give a rotation point ?
348
-        drawing.translate(*self.center)
349
-        if self.units is 'deg':
350
-            drawing.rotate_deg(self.tween[frame])
351
-        elif self.units is 'rad':
352
-            drawing.rotate_rad(self.tween[frame])
353
-
354
-
355
-    def post_draw(self, drawing, frame):
356
-        drawing.translate(- self.center[0], - self.center[1])
357
-        drawing.restore()
358
-
359
-class PhotoZoom (Effect):
360
-    """Zoom in and create dynamism by moving a picture.
361
-
362
-    Normally applies to an Image layer, but can be used with others.
363
-    """
364
-    def __init__(self, keyframes, subject=(0, 0), direction=None,
365
-                 movement=50, method='linear'):
366
-        """Create a PhotoZoom effect
367
-
368
-            keyframes
369
-                0.0 for beginning of effect, and 1.0 to reach the end,
370
-                intermediate values show the intermediate state of the effect.
371
-            subject
372
-                Position of the subject of interest. That is the point where
373
-                the zoom in/out will focus it's attention.
374
-                If (0, 0), the focus will be chosen randomly in the 2/3 of
375
-                the center of the screen.
376
-            direction
377
-                'in', 'out', None (random)
378
-            movement
379
-                0 to 100, percentage of movement to create.
380
-            method
381
-                'linear' or 'cosine'
382
-        """
383
-        if direction not in ['in', 'out', None]:
384
-            raise ValueError, "'direction' must be 'in', 'out' or None"
385
-        if (direction == None):
386
-            self.direction = randint(0, 1) and 'in' or 'out'
387
-        else:
388
-            self.direction = direction
389
-
390
-        print("Zoom in direction: %s" % self.direction)
391
-
392
-        self.subject = subject
393
-
394
-        self.movement = movement
395
-
396
-        self.keyframes = keyframes
397
-        self.tween = Tween(self.keyframes, method)
398
-
399
-
400
-    def pre_draw(self, drawing, frame):
401
-        drawing.save()
402
-
403
-        fb = self._parent_flipbook
404
-        # Use subject, or randomize in the center 1/3 of the image.
405
-        if (self.subject == (0, 0)):
406
-            self.subject = (randint(int(0.33 * fb.w),
407
-                                    int(0.66 * fb.w)),
408
-                            randint(int(0.33 * fb.h),
409
-                                    int(0.66 * fb.h)))
410
-
411
-        # Max moving = 25% * pixels estimation * movement factor
412
-        zoomfactor = 0.25 * (self.movement / 100.)
413
-
414
-        inter = self.tween[frame]
415
-
416
-        if (self.direction == 'in'):
417
-            gozoom = 1.0 + (1.0 - inter) * zoomfactor
418
-        else:
419
-            gozoom = 1.0 + inter * zoomfactor
420
-
421
-        drawing.scale_centered(self.subject[0], self.subject[1],
422
-                               gozoom, gozoom)
423
-
424
-
425
-    def post_draw(self, drawing, frame):
426
-        drawing.restore()
427
-
428
-class KeyFunction (Effect):
429
-    """A keyframed effect on an arbitrary Drawing function.
430
-    """
431
-    def __init__(self, draw_function, keyframes, method='linear'):
432
-        """Create an effect using the given Drawing function, with values
433
-        determined by the given list of Keyframes. For example::
434
-
435
-            KeyFunction(Drawing.stroke_width,
436
-                        [Keyframe(1, 1), Keyframe(30, 12)])
437
-
438
-        This says to vary the stroke width from 1 (at frame 1) to 12 (at
439
-        frame 30).
440
-
441
-        The 'method' argument defines an interpolation method to use between
442
-        keyframes, and may be either 'linear' or 'cosine'.
443
-        """
444
-        # Call base constructor with start and end frames
445
-        Effect.__init__(self, keyframes[0].frame, keyframes[-1].frame)
446
-        # TODO: Make sure a valid function name is given
447
-        self.draw_function = draw_function
448
-        self.keyframes = keyframes
449
-        # Tween keyframes using the given interpolation method
450
-        self.tween = Tween(self.keyframes, method)
451
-
452
-    def pre_draw(self, drawing, frame):
453
-        drawing.save()
454
-        self.draw_function(drawing, self.tween[frame])
455
-
456
-    def post_draw(self, drawing, frame):
457
-        drawing.restore()
458
-
459
tovid-0.34.tar.bz2/libtovid/render/flipbook.py Deleted
430
 
1
@@ -1,428 +0,0 @@
2
-"""This module provides the Flipbook class, a collection of drawings that, when
3
-displayed in sequence, make up an animation or video.
4
-
5
-Run this module standalone for a demonstration:
6
-
7
-    $ python flipbook.py
8
-
9
-To use this module interactively, run 'python' from the command-line, and do:
10
-
11
-    >>> from libtovid.render.flipbook import Flipbook
12
-
13
-To create a Flipbook 10 seconds long with 'dvd' and 'ntsc' standards, do:
14
-
15
-    >>> flipbook = Flipbook(10, 'dvd', 'ntsc', '4:3')
16
-
17
-You can retrieve the canvas width and height with:
18
-
19
-    >>> flipbook.canvas
20
-    (640, 480)
21
-    >>> flipbook.w
22
-    640
23
-    >>> flipbook.h
24
-    480
25
-
26
-All drawing upon a Flipbook is achieved through the use of layers (layer.py).
27
-To use them, import the layer module:
28
-
29
-    >>> from libtovid.render import layer
30
-
31
-You can add layers to a Flipbook on-the-fly:
32
-
33
-    >>> flipbook.add(layer.Background('black'))
34
-    >>> flipbook.add(layer.Text("Hello, world"))
35
-
36
-Or, create layers separately before adding them to the Flipbook:
37
-
38
-    >>> text = Text("Elephant talk")
39
-    >>> flipbook.add(text)
40
-
41
-This latter approach is useful if you plan to apply animation effects to the
42
-Layer. For this, effects classes (effect.py) may be applied. First, import:
43
-
44
-    >>> from libtovid.render import effect
45
-
46
-Now, say we want the text "Elephant talk" to move across the screen, say from
47
-(100, 100) to (500, 100) over the course of the first 90 frames. The
48
-effect.Movement class does the trick:
49
-
50
-    >>> text.add_effect(effect.Movement(1, 90, (100, 100), (500, 100)))
51
-
52
-You can preview a specific frame of the Flipbook by calling render():
53
-
54
-    >>> flipbook.render(50)
55
-
56
-Or, you can generate all frames and create an .m2v video stream file by calling
57
-render_video():
58
-
59
-    >>> filename = flipbook.render_video()
60
-
61
-See the demo below for more on what's possible with Flipbooks.
62
-"""
63
-
64
-__all__ = ['Flipbook']
65
-
66
-import os
67
-import sys
68
-import time
69
-import math
70
-import cairo
71
-import shutil
72
-import random
73
-from libtovid.render.animation import Keyframe
74
-from libtovid.render.drawing import Drawing, interlace_drawings
75
-from libtovid.render.drawing import write_ppm, write_png, save_png
76
-from libtovid.render import layer, effect
77
-from libtovid import standard
78
-from libtovid.media import MediaFile
79
-from libtovid.backend import mplex, mplayer, ffmpeg
80
-
81
-
82
-class Flipbook:
83
-    """A collection of Drawings that together comprise an animation.
84
-    """
85
-    def __init__(self, seconds, format, tvsys, aspect='4:3', interlaced=False):
86
-        """Create a flipbook of the given length in seconds, at the given
87
-        resolution.
88
-
89
-            seconds
90
-                Length of flipbook playback in seconds
91
-            format
92
-                'dvd', 'vcd', 'svcd', 'dvd-vcd', or 'half-dvd'
93
-            tvsys
94
-                'ntsc' or 'pal'
95
-            aspect
96
-                '4:3' or '16:9' (the latter only for format='dvd')
97
-            interlaced
98
-                True/False. When enabled, the framerate will be doubled,
99
-                but only half the frames (twice the fields) will be rendered.
100
-
101
-        Once you've created the Flipbook, you can grab the dimensions
102
-        in with the property:
103
-
104
-            flipbook.canvas as (width, height)
105
-
106
-        and with the two properties:
107
-
108
-            flipbook.w (width)
109
-            flipbook.h (height)
110
-        """
111
-        self.tmpdir = '/tmp'
112
-        if 'TMPDIR' in os.environ:
113
-            self.tmpdir = os.environ['TMPDIR']
114
-        self.seconds = float(seconds)
115
-        self.fps = standard.fps(tvsys)
116
-        self.fps_ratio = standard.fps_ratio(tvsys)
117
-        if (interlaced):
118
-            self.fps *= 2
119
-        self.interlaced = interlaced
120
-        self.frames = int(seconds * self.fps)
121
-        self.output_size = standard.resolution(format, tvsys)
122
-        # TODO: We'll need aspect ratio here.. 4:3 or 16:9 anamorphic ?
123
-        self.format = format
124
-        self.tvsys = tvsys
125
-        if (aspect not in ['4:3', '16:9']):
126
-            raise ValueError, "aspect must be: '4:3' or '16:9'"
127
-        self.aspect = aspect
128
-        self.widescreen = False
129
-        if (aspect == '16:9'):
130
-            self.widescreen = True
131
-
132
-        self.canvas = self.get_canvas_size()
133
-        self.w = self.canvas[0]
134
-        self.h = self.canvas[1]
135
-
136
-        # Empty layers, and currently no drawings.
137
-        self.layers = []
138
-        self.drawings = []
139
-
140
-        self.called_init_childs = False
141
-
142
-
143
-    def init_childs(self):
144
-        """Give access to all descendant layers and effects to their parents.
145
-
146
-        In layers, you can access your parent layer (if sublayed) with:
147
-            layer._parent_layer
148
-        and to the top Flipbook object with:
149
-            layer._parent_flipbook
150
-
151
-        This function gets called just before rendering a video with
152
-            render_video()
153
-
154
-        It's also called in emergency if you call directly get_drawing().
155
-        """
156
-        for x in range(0, len(self.layers)):
157
-            self.layers[x][0].init_parent_flipbook(self)
158
-            self.layers[x][0].init_childs()
159
-
160
-        self.called_init_childs = True
161
-
162
-
163
-    def stof(self, seconds):
164
-        """Return the number of frames to the specified time (in seconds).
165
-        """
166
-        return int(self.fps * float(seconds))
167
-
168
-
169
-    def get_canvas_size(self):
170
-        """Return the dimensions of the canvas.
171
-        """
172
-        #ow = self.output_size[0]
173
-        oh = self.output_size[1]
174
-        a = self.aspect.split(':')
175
-
176
-        # Calculate the square pixels canvas size based on aspect ratio
177
-        # and intended output size.
178
-        x = float(a[0]) * float(oh) / float(a[1])
179
-        # Make sure they are factor of '2'
180
-        nw = int(math.ceil(x / 2.0) * 2)
181
-
182
-        # We'll always change only the width, like it seems the standard,
183
-        # since on TVs, the number of *lines* can't change (when interlacing
184
-        # is into business)
185
-        return (nw, oh)
186
-
187
-
188
-    def add(self, layer, position=(0, 0)):
189
-        """Add a Layer to the flipbook.
190
-        """
191
-        self.layers.append((layer, position))
192
-
193
-
194
-    def render(self, frame=1):
195
-        """Render the given frame.
196
-        """
197
-        print("DEPRECATED FUNCTION.")
198
-        exit()
199
-
200
-        filename = "/tmp/flipbook_%s.png" % frame
201
-        print("Rendering Flipbook frame %s to %s" % (frame, filename))
202
-        drawing = self.get_drawing(frame)
203
-
204
-        save_png(drawing, filename, self.output_size[0], self.output_size[1])
205
-
206
-
207
-    def get_drawing(self, frame):
208
-        """Get a Drawing of the given frame
209
-
210
-        TODO: 0-based or 1-based ?
211
-        """
212
-
213
-        # Make sure all layers and effects has been initialized with parents.
214
-        if (not self.called_init_childs):
215
-            self.init_childs()
216
-
217
-        drawing = Drawing(self.canvas[0], self.canvas[1])
218
-        # Draw each layer
219
-        for layer, position in self.layers:
220
-            drawing.save()
221
-            drawing.translate(position[0], position[1])
222
-            # Apply effects and draw
223
-            layer.draw_with_effects(drawing, frame)
224
-            drawing.restore()
225
-        return drawing
226
-
227
-
228
-    def render_video(self, out_filename=None):
229
-        """Render the flipbook to an .m2v video stream file.
230
-
231
-            out_filename
232
-                Filename for output. If not specified, a temporary filename
233
-                will be given, and returned from the function.
234
-
235
-        Return the filename of the output, in both cases.
236
-        """
237
-        # Make sure layers and effects have been initialized with parents.
238
-        self.init_childs()
239
-
240
-        #
241
-        # if self.tmpdir = /tmp, we get:
242
-        # /tmp
243
-        # /tmp/flipbook-120391232-work/
244
-        # /tmp/flipbook-120391232-work/bunch-of-files..m2v, .ac3, etc.
245
-        # /tmp/flipbook-120391232.mpg -> final output..
246
-        #
247
-
248
-        tmp_prefix = ''
249
-        tmp_workdir = ''
250
-        while 1:
251
-            rnd = random.randint(1000000, 9999999)
252
-            tmp_prefix = "%s/flipbook-%s" % (self.tmpdir, rnd)
253
-            tmp_workdir = "%s-work" % (tmp_prefix)
254
-
255
-            if not os.path.exists(tmp_workdir):
256
-                break
257
-
258
-        # In case no filename has been specified.
259
-        if not out_filename:
260
-            out_filename = "%s.mpg" % tmp_workdir
261
-
262
-        os.mkdir(tmp_workdir)
263
-
264
-        # Encode the frames to an .m2v file
265
-        m2v_file = "%s/video.m2v" % tmp_workdir
266
-        ac3_file = "%s/audio.ac3" % tmp_workdir
267
-
268
-
269
-        try:
270
-            #cairo.ImageSurface.get_data
271
-            pngorpnm = 'ppmtoy4m -F %s -A %s -Ip -B -S 420mpeg2' % \
272
-                     (self.fps_ratio, self.aspect)
273
-            _write_img = write_ppm  # set write function just below
274
-        except:
275
-            pngorpnm = 'ppmtoy4m -F %s -A %s -Ip -S 420mpeg2' % \
276
-                     (self.fps_ratio, self.aspect)
277
-            _write_img = write_png
278
-
279
-        # Cinelerra params: -b 0 -q 5 -a 2 -F 4 -I 0 -M 2 -f 8 -R 0
280
-        # TODO: move this to encode.py
281
-        # -M (multi-threading, num CPUs)
282
-        #
283
-        # -b 0 -q 5
284
-        #    or
285
-        # -b 7500
286
-        pipe = os.popen("%s | mpeg2enc -q 5 -g 45 -G 45 -f 8 -a 2 -I 0 "
287
-                        "-o '%s'" % (pngorpnm,  m2v_file), 'w')
288
-
289
-        frame = 1
290
-        while frame <= self.frames:
291
-            print("Drawing frame %s of %s" % (frame, self.frames))
292
-
293
-            if (self.interlaced):
294
-                draw1 = self.get_drawing(frame)
295
-                frame += 1
296
-                draw2 = self.get_drawing(frame)
297
-
298
-                drawing = interlace_drawings(draw1, draw2)
299
-            else:
300
-                drawing = self.get_drawing(frame)
301
-
302
-            # jpeg2yuv likes frames to start at 0
303
-                _write_img(drawing, pipe,
304
-                           self.output_size[0], self.output_size[1],
305
-                           tmp_workdir)
306
-
307
-            frame += 1
308
-
309
-        print("Closing encoder. Output to %s" % out_filename)
310
-        pipe.close()
311
-
312
-        print("Waiting for encoder to finish...")
313
-        time.sleep(0.5)
314
-
315
-        os.system("ls -al %s" % m2v_file)
316
-        os.system("cp %s /tmp/go.m2v" % m2v_file)
317
-        vidonly = mplayer.identify(m2v_file)
318
-
319
-        # Fix length
320
-        vidonly.length = float(self.seconds)
321
-
322
-        outvid = MediaFile(out_filename, self.format, self.tvsys)
323
-        outvid.aspect = self.aspect
324
-        # Important to render 16:9 video correctly.
325
-        outvid.widescreen = self.widescreen
326
-
327
-        print("Running audio encoder...")
328
-        ffmpeg.encode_audio(vidonly, ac3_file, outvid)
329
-
330
-        print("Mplex...")
331
-        mplex.mux(m2v_file, ac3_file, outvid)
332
-
333
-        # Clean up
334
-        print("Cleaning up %s ..." % tmp_workdir)
335
-        shutil.rmtree(tmp_workdir)
336
-
337
-        print("Output: %s" % out_filename)
338
-        return out_filename
339
-
340
-
341
-def draw_text_demo(flipbook):
342
-    """Draw a demonstration of Text layers with various effects.
343
-    """
344
-    assert isinstance(flipbook, Flipbook)
345
-
346
-    last_frame = flipbook.frames
347
-
348
-    # Background image
349
-    bgd = layer.Background('black')
350
-    flipbook.add(bgd)
351
-
352
-    text1 = layer.Text(u"Spectrum effect demo", color=None)
353
-    text1.add_effect(effect.Spectrum(1, last_frame))
354
-    flipbook.add(text1, (20, 30))
355
-
356
-    #text2 = layer.Text(u"FadeInOut effect demo")
357
-    #text2.add_effect(effect.FadeInOut(1, last_frame, last_frame / 4))
358
-    #flipbook.add(text2, (20, 60))
359
-
360
-    text3 = layer.Text(u"Movement effect demo")
361
-    text3.add_effect(effect.Movement(1, last_frame, (0, 0), (300, 50)))
362
-    flipbook.add(text3, (20, 90))
363
-
364
-    text4 = layer.Text(u"Whirl effect demo", color=None, align='center')
365
-    k = [Keyframe(0, 0),
366
-         Keyframe(30, 0),
367
-         Keyframe(40, 15),
368
-         Keyframe(45, -10),
369
-         Keyframe(50, 10),
370
-         Keyframe(55, -2),
371
-         Keyframe(60, 0)]
372
-    text4.add_effect(effect.Whirl(k, center=(25, 10), units='deg'))
373
-    text4.add_effect(effect.Colorfade(1, last_frame, (1.0, 0, 0), (0, 1.0, 0)))
374
-    flipbook.add(text4, (340, 350))
375
-
376
-    text5 = layer.Text(u'Whirl effect demo2 ', color='white', align="center")
377
-    k2 = [Keyframe(0, 0),
378
-          Keyframe(last_frame, 720)]
379
-    text5.add_effect(effect.Whirl(k2, center=(25, 10), units='deg'))
380
-    flipbook.add(text5, (450, 400))
381
-
382
-    # Keyframed opacity demos, using both linear and cosine interpolation
383
-    pulse = [Keyframe(1, 0.2),
384
-             Keyframe(last_frame * 2/10, 1.0),
385
-             Keyframe(last_frame * 4/10, 0.2),
386
-             Keyframe(last_frame * 6/10, 1.0),
387
-             Keyframe(last_frame * 8/10, 0.5),
388
-             Keyframe(last_frame, 1.0)]
389
-    # Text Layers
390
-    text_linear = layer.Text("Keyframed opacity (linear)", color='lightgreen')
391
-    text_cosine = layer.Text("Keyframed opacity (cosine)", color='lightgreen')
392
-    # Effects
393
-    eff_linear = effect.Fade(pulse, 'linear')
394
-    eff_cosine = effect.Fade(pulse, 'cosine')
395
-    # Graph of the keyframe effects
396
-    graph_linear = layer.InterpolationGraph(pulse, method='linear')
397
-    graph_cosine = layer.InterpolationGraph(pulse, method='cosine')
398
-    # Add effects to the text layers
399
-    text_linear.add_effect(eff_linear)
400
-    text_cosine.add_effect(eff_cosine)
401
-    # Add layers to the flipbook
402
-    flipbook.add(text_linear, (20, 150))
403
-    flipbook.add(graph_linear, (20, 180))
404
-    flipbook.add(text_cosine, (340, 150))
405
-    flipbook.add(graph_cosine, (340, 180))
406
-
407
-
408
-if __name__ == '__main__':
409
-    start_time = time.time() # Benchmark
410
-
411
-    if len(sys.argv) > 1:
412
-        seconds = int(sys.argv[1])
413
-    else:
414
-        seconds = 3
415
-    flip = Flipbook(seconds, 'dvd', 'ntsc')
416
-
417
-    draw_text_demo(flip)
418
-
419
-    # Video clip
420
-    #clip = layer.VideoClip(video, (320, 240))
421
-    #clip.rip_frames(0, 90)
422
-    #clip.effects.append(effect.Fade(1, 90, 20))
423
-    #flip.add(clip, (260, 200))
424
-
425
-    # Render the final video
426
-    filename = flip.render_video('/tmp/flipbook.mpg')
427
-
428
-    print("Took %f seconds to render: %s" % (time.time() - start_time, filename))
429
-
430
tovid-0.34.tar.bz2/libtovid/render/layer.py Deleted
900
 
1
@@ -1,898 +0,0 @@
2
-"""This module provides a Layer class and several derivatives. A Layer
3
-is a graphical overlay that may be composited onto an image canvas.
4
-
5
-Run this script standalone for a demonstration:
6
-
7
-    $ python libtovid/layer.py
8
-
9
-Layer subclasses may combine graphical elements, including other Layers,
10
-into a single interface for drawing and customizing those elements. Layers may
11
-exhibit animation, through the use of keyframed drawing commands, or through
12
-use of the Effect class (and its subclasses, as defined in libtovid/effect.py).
13
-
14
-Each Layer subclass provides (at least) an __init__ function, and a draw
15
-function. For more on how to use Layers, see the Layer class definition and
16
-template example below.
17
-"""
18
-
19
-__all__ = [
20
-    'Layer',
21
-    'Background',
22
-    'Text',
23
-    'ShadedText',
24
-    'Label',
25
-    'VideoClip',
26
-    'Image',
27
-    'Thumb',
28
-    'ThumbGrid',
29
-    'SafeArea',
30
-    'Scatterplot',
31
-    'InterpolationGraph',
32
-    'ColorBars',
33
-]
34
-
35
-import os
36
-import sys
37
-import math
38
-import commands
39
-from libtovid.util import get_file_type
40
-from libtovid.render.drawing import Drawing, save_image
41
-from libtovid.render.effect import Effect
42
-from libtovid.render.animation import Keyframe, Tween
43
-from libtovid.media import MediaFile
44
-from libtovid.backend import transcode
45
-from libtovid import log
46
-
47
-class Layer:
48
-    """A visual element, or a composition of visual elements. Conceptually
49
-    similar to a layer in the GIMP or Photoshop, with support for animation
50
-    effects and sub-Layers.
51
-    """
52
-    def __init__(self):
53
-        """Initialize the layer. Extend this in derived classes to accept
54
-        configuration settings for drawing the layer; call this function
55
-        from any derived __init__ functions.
56
-        """
57
-        self.effects = []
58
-        self.sublayers = []
59
-        self._parent_flipbook = None
60
-        self._parent_layer = None
61
-
62
-    ###
63
-    ### Child-parent initialization
64
-    ###
65
-    def init_childs(self):
66
-        """Give access to all descendant layers and effects to their parents.
67
-
68
-        In layers, you can access your parent layer (if sublayed) with:
69
-            layer._parent_layer
70
-        and to the top Flipbook object with:
71
-            layer._parent_flipbook
72
-        """
73
-        for x in range(0, len(self.effects)):
74
-            self.effects[x].init_parent_flipbook(self._parent_flipbook)
75
-            self.effects[x].init_parent_layer(self)
76
-        for x in range(0, len(self.sublayers)):
77
-            self.sublayers[x][0].init_parent_flipbook(self._parent_flipbook)
78
-            self.sublayers[x][0].init_parent_layer(self)
79
-            self.sublayers[x][0].init_childs(self)
80
-
81
-    def init_parent_flipbook(self, flipbook):
82
-        self._parent_flipbook = flipbook
83
-
84
-    def init_parent_layer(self, layer):
85
-        self._parent_layer = layer
86
-
87
-
88
-    ###
89
-    ### Derived-class interface
90
-    ###
91
-
92
-    def draw(self, drawing, frame):
93
-        """Draw the layer and all sublayers onto the given Drawing. Override
94
-        this function in derived layers.
95
-        """
96
-        assert isinstance(drawing, Drawing)
97
-
98
-    ###
99
-    ### Sublayer and effect interface
100
-    ###
101
-
102
-    def add_sublayer(self, layer, position=(0, 0)):
103
-        """Add the given Layer as a sublayer of this one, at the given position.
104
-        Sublayers are drawn in the order they are added; each sublayer may have
105
-        its own effects, but the parent Layer's effects apply to all sublayers.
106
-        """
107
-        assert isinstance(layer, Layer)
108
-        self.sublayers.append((layer, position))
109
-
110
-    def draw_sublayers(self, drawing, frame):
111
-        """Draw all sublayers onto the given Drawing for the given frame.
112
-        """
113
-        assert isinstance(drawing, Drawing)
114
-        for sublayer, position in self.sublayers:
115
-            drawing.save()
116
-            drawing.translate(*position)
117
-            sublayer.draw(drawing, frame)
118
-            drawing.restore()
119
-
120
-    def add_effect(self, effect):
121
-        """Add the given Effect to this Layer. A Layer may have multiple effects
122
-        applied to it; all effects apply to the current layer, and all sublayers.
123
-        """
124
-        assert isinstance(effect, Effect)
125
-        self.effects.append(effect)
126
-
127
-    def draw_with_effects(self, drawing, frame):
128
-        """Render the entire layer, with all effects applied.
129
-
130
-            drawing: A Drawing object to draw the Layer on
131
-            frame:   The frame number that is being drawn
132
-
133
-        """
134
-        # Do preliminary effect rendering
135
-        for effect in self.effects:
136
-            effect.pre_draw(drawing, frame)
137
-        # Draw the layer and sublayers
138
-        self.draw(drawing, frame)
139
-        # Close out effect rendering, in reverse (nested) order
140
-        for effect in reversed(self.effects):
141
-            effect.post_draw(drawing, frame)
142
-
143
-
144
-# Layer template
145
-#
146
-# Copy and paste the following code to create your own Layer.
147
-#
148
-# Layer subclasses should define two things:
149
-#
150
-#     __init__():  How to initialize the layer with parameters
151
-#     draw():   How do draw the layer on a Drawing
152
-#
153
-# First, declare the layer class name. Include (Layer) to indicate that your
154
-# class is a Layer.
155
-
156
-class MyLayer (Layer):
157
-    """Overlapping semitransparent rectangles.
158
-    (Modify this documentation string to describe what's in your layer)"""
159
-    # Here's the class initialization function, __init__. Define here any
160
-    # parameters that might be used to configure your layer's behavior or
161
-    # appearance in some way (along with default values, if you like). Here,
162
-    # we're allowing configuration of the fill and stroke colors, with default
163
-    # values of 'blue' and 'black', respectively:
164
-
165
-    def __init__(self, fill_color='blue', stroke_color='black'):
166
-        """Create a MyLayer with the given fill and stroke colors."""
167
-        # Initialize the base Layer class. Always do this.
168
-        Layer.__init__(self)
169
-        # Store the given colors, for later use
170
-        self.fill_color = fill_color
171
-        self.stroke_color = stroke_color
172
-
173
-    # The draw() function is responsible for rendering the contents of the
174
-    # layer onto a Drawing. It will use the configuration given to __init__
175
-    # (in this case, fill and stroke colors) to render something onto a Drawing
176
-    # associated with a particular frame number:
177
-
178
-    def draw(self, drawing, frame):
179
-        """Draw MyLayer contents onto the given drawing, at the given frame
180
-        number."""
181
-
182
-        # For safety's sake, make sure you really have a Drawing object:
183
-        assert isinstance(drawing, Drawing)
184
-
185
-        # Save the drawing context. This prevents any upcoming effects or
186
-        # style changes from messing up surrounding layers in the Drawing.
187
-        drawing.save()
188
-
189
-        # Get a Cairo pattern source for the fill and stroke colors
190
-        # (TODO: Make this easier, or use a simpler example)
191
-        fc = drawing.create_source(self.fill_color, 0.6)
192
-        sc = drawing.create_source(self.stroke_color)
193
-
194
-        # And a stroke width of 1, say:
195
-        drawing.stroke_width(1)
196
-
197
-        # Now, draw something. Here, a couple of pretty semitransparent
198
-        # rectangles, using the fill and stroke color patterns created earlier:
199
-        drawing.rectangle(0, 0,  50, 20)
200
-        drawing.fill(fc)
201
-        drawing.stroke(sc)
202
-        drawing.rectangle(15, 12,  45, 28)
203
-        drawing.fill(fc)
204
-        drawing.stroke(sc)
205
-
206
-        # Be sure to restore the drawing context afterwards:
207
-        drawing.restore()
208
-
209
-
210
-class Background (Layer):
211
-    """A background that fills the frame with a solid color, or an image."""
212
-    def __init__(self, color='black', filename=''):
213
-        Layer.__init__(self)
214
-        self.color = color
215
-        self.filename = filename
216
-
217
-    def draw(self, drawing, frame):
218
-        assert isinstance(drawing, Drawing)
219
-        log.debug("Drawing Background")
220
-        width, height = drawing.size
221
-        drawing.save()
222
-        # Fill drawing with an image
223
-        if self.filename is not '':
224
-            drawing.image(0, 0, width, height, self.filename)
225
-        # Fill drawing with a solid color
226
-        elif self.color:
227
-            drawing.rectangle(0, 0, width, height)
228
-            drawing.fill(self.color)
229
-        drawing.restore()
230
-
231
-
232
-class Image (Layer):
233
-    """A rectangular image, scaled to the given size.
234
-
235
-        image_source
236
-            Can be anything Drawing::image() can accept.
237
-            See documentation in render/drawing.py.
238
-    """
239
-    def __init__(self, image_source, (x, y), (width, height)):
240
-        Layer.__init__(self)
241
-        self.size = (width, height)
242
-        self.image_source = image_source
243
-        self.position = (x, y)
244
-
245
-
246
-    def draw(self, drawing, frame=1):
247
-        assert isinstance(drawing, Drawing)
248
-        log.debug("Drawing Image")
249
-        drawing.save()
250
-        # Save the source for future calls to draw, so no further
251
-        # processing will be necessary. And other effects can be done
252
-        # without interferring with the original source.
253
-        self.image_source = drawing.image(self.position[0], self.position[1],
254
-                                          self.size[0], self.size[1],
255
-                                          self.image_source)
256
-        drawing.restore()
257
-
258
-
259
-class VideoClip (Layer):
260
-    """A rectangular video clip, scaled to the given size.
261
-
262
-    TODO: num_frames should accept a range [first, end], an int (1-INT) and
263
-    rip frames accordingly. For now, it only accepts an INT for the range 1-INT
264
-    """
265
-    def __init__(self, filename, (width, height),
266
-                 position=(0, 0), num_frames=120):
267
-        Layer.__init__(self)
268
-        self.filename = filename
269
-        self.mediafile = MediaFile(filename)
270
-        self.size = (width, height)
271
-        # List of filenames of individual frames
272
-        self.frame_files = []
273
-        # TODO: be able to change hardcoded default values
274
-        self.rip_frames(1, num_frames)
275
-        # Set (x,y) position
276
-        assert(isinstance(position, tuple))
277
-        self.position = position
278
-
279
-    def rip_frames(self, start, end):
280
-        """Rip frames from the video file, from start to end frames."""
281
-        log.info("VideoClip: Ripping frames %s to %s" % (start, end))
282
-        outdir = '/tmp/%s_frames' % self.filename
283
-        self.frame_files = transcode.rip_frames(self.mediafile, outdir,
284
-                                          [start, end])
285
-
286
-    def draw(self, drawing, frame=1):
287
-        """Draw ripped video frames to the given drawing. For now, it's
288
-        necessary to call rip_frames() before calling this function.
289
-
290
-        Video is looped.
291
-        """
292
-        assert isinstance(drawing, Drawing)
293
-        log.debug("Drawing VideoClip")
294
-        if len(self.frame_files) == 0:
295
-            log.error("VideoClip: need to call rip_frames() before drawing.")
296
-            sys.exit(1)
297
-        drawing.save()
298
-        # Loop frames (modular arithmetic)
299
-        if frame >= len(self.frame_files):
300
-            frame = frame % len(self.frame_files)
301
-        filename = self.frame_files[frame-1]
302
-        drawing.image(self.position, self.size, filename)
303
-        drawing.restore()
304
-
305
-
306
-class Text (Layer):
307
-    """A simple text string, with size, color and font.
308
-    """
309
-    def __init__(self, text, position=(0, 0), color='white', fontsize=20, \
310
-                 font='Helvetica', align='left'):
311
-        """Create a Text layer.
312
-
313
-            text
314
-                UTF8 encoded string.
315
-        """
316
-        Layer.__init__(self)
317
-        self.text = text
318
-        self.color = color
319
-        self.fontsize = fontsize
320
-        self.font = font
321
-        self.align = align
322
-        # Set (x,y) position
323
-        self.position = position
324
-
325
-    # TODO: This is gonna be pretty broken...
326
-    def extents(self, drawing):
327
-        """Return the extents of the text as a (x0, y0, x1, y1) tuple.
328
-        """
329
-        assert isinstance(drawing, Drawing)
330
-        drawing.save()
331
-        drawing.font(self.font)
332
-        drawing.font_size(self.fontsize)
333
-        x_bearing, y_bearing, width, height, x_adv, y_adv = \
334
-                 drawing.text_extents(self.text)
335
-        drawing.restore()
336
-        # Add current layer's position to the (x,y) bearing of extents
337
-        x0 = int(self.position[0] + x_bearing)
338
-        y0 = int(self.position[1] + y_bearing)
339
-        x1 = int(x0 + width)
340
-        y1 = int(y0 + height)
341
-        return (x0, y0, x1, y1)
342
-
343
-    def draw(self, drawing, frame=1):
344
-        assert isinstance(drawing, Drawing)
345
-        log.debug("Drawing Text")
346
-        # Drop in debugger
347
-        drawing.save()
348
-        drawing.font(self.font)
349
-        drawing.font_size(self.fontsize)
350
-        if self.color is not None:
351
-            drawing.set_source(self.color)
352
-        # TODO: DO something with the align !!
353
-        drawing.text(self.text, self.position[0], self.position[1], self.align)
354
-        drawing.restore()
355
-
356
-
357
-class ShadedText (Layer):
358
-    """A simple text string, with size, color and font.
359
-    """
360
-    def __init__(self, text, position=(0, 0), offset=(5, 5),
361
-                 color='white', shade_color='gray', fontsize=20,
362
-                 font='Nimbus Sans', align='left'):
363
-        Layer.__init__(self)
364
-        shade_position = (position[0] + offset[0],
365
-                          position[1] + offset[1])
366
-        self.under = Text(text, shade_position, shade_color,
367
-                          fontsize, font, align)
368
-        self.over = Text(text, position, color, fontsize, font, align)
369
-
370
-    def draw(self, drawing, frame=1):
371
-        assert isinstance(drawing, Drawing)
372
-        log.debug("Drawing Text")
373
-        drawing.save()
374
-        self.under.draw(drawing, frame)
375
-        self.over.draw(drawing, frame)
376
-        drawing.restore()
377
-
378
-
379
-class Label (Text):
380
-    """A text string with a rectangular background.
381
-
382
-    You can access Text's extents() function from within here too.
383
-    """
384
-    def __init__(self, text, position=(0, 0), color='white', bgcolor='#555',
385
-                 fontsize=20, font='NimbusSans'):
386
-        Text.__init__(self, text, position, color, fontsize, font)
387
-        self.bgcolor = bgcolor
388
-        # Set (x,y) position
389
-        assert(isinstance(position, tuple))
390
-        self.position = position
391
-
392
-    def draw(self, drawing, frame=1):
393
-        assert isinstance(drawing, Drawing)
394
-        log.debug("Drawing Label")
395
-        #(dx, dy, w, h, ax, ay) = self.extents(drawing)
396
-        (x0, y0, x1, y1) = self.extents(drawing)
397
-        # Save context
398
-        drawing.save()
399
-
400
-        # Calculate rectangle dimensions from text size/length
401
-        width = x1 - x0
402
-        height = y1 - y0
403
-        # Padding to use around text
404
-        pad = self.fontsize / 3
405
-        # Calculate start and end points of background rectangle
406
-        start = (-pad, -height - pad)
407
-        end = (width + pad, pad)
408
-
409
-        # Draw a stroked round rectangle
410
-        drawing.save()
411
-        drawing.stroke_width(1)
412
-        drawing.roundrectangle(start[0], start[1], end[0], end[1], pad, pad)
413
-        drawing.stroke('black')
414
-        drawing.fill(self.bgcolor, 0.3)
415
-        drawing.restore()
416
-
417
-        # Call base Text class to draw the text
418
-        Text.draw(self, drawing, frame)
419
-
420
-        # Restore context
421
-        drawing.restore()
422
-
423
-
424
-class Thumb (Layer):
425
-    """A thumbnail image or video.
426
-    """
427
-    def __init__(self, filename, (width, height), position=(0, 0), title=''):
428
-        Layer.__init__(self)
429
-        self.filename = filename
430
-        self.size = (width, height)
431
-        self.title = title or os.path.basename(filename)
432
-        # Set (x,y) position
433
-        assert(isinstance(position, tuple))
434
-        self.position = position
435
-
436
-        # Determine whether file is a video or image, and create the
437
-        # appropriate sublayer
438
-        filetype = get_file_type(filename)
439
-        if filetype == 'video':
440
-            self.add_sublayer(VideoClip(filename, self.size, self.position))
441
-        elif filetype == 'image':
442
-            self.add_sublayer(Image(filename, self.size, self.position))
443
-        self.lbl = Label(self.title, fontsize=15)
444
-        self.add_sublayer(self.lbl, self.position)
445
-
446
-    def draw(self, drawing, frame=1):
447
-        assert isinstance(drawing, Drawing)
448
-        log.debug("Drawing Thumb")
449
-        drawing.save()
450
-        (x0, y0, x1, y1) = self.lbl.extents(drawing)
451
-        drawing.translate(0, x1-x0)
452
-        self.draw_sublayers(drawing, frame)
453
-        drawing.restore()
454
-
455
-
456
-class ThumbGrid (Layer):
457
-    """A rectangular array of thumbnail images or videos."""
458
-    def __init__(self, files, titles=None, (width, height)=(600, 400),
459
-                 (columns, rows)=(0, 0), aspect=(4,3)):
460
-        """Create a grid of thumbnail images or videos from a list of files,
461
-        fitting in a space no larger than the given size, with the given number
462
-        of columns and rows. Use 0 to auto-layout columns or rows, or both
463
-        (default).
464
-        """
465
-        assert files != []
466
-        if titles:
467
-            assert len(files) == len(titles)
468
-        else:
469
-            titles = files
470
-        Layer.__init__(self)
471
-        self.size = (width, height)
472
-        # Auto-dimension (using desired rows/columns, if given)
473
-        self.columns, self.rows = \
474
-            self._fit_items(len(files), columns, rows, aspect)
475
-        # Calculate thumbnail size, keeping aspect
476
-        w = (width - self.columns * 16) / self.columns
477
-        h = w * aspect[1] / aspect[0]
478
-        thumbsize = (w, h)
479
-
480
-        # Calculate thumbnail positions
481
-        positions = []
482
-        for row in range(self.rows):
483
-            for column in range(self.columns):
484
-                x = column * (width / self.columns)
485
-                y = row * (height / self.rows)
486
-                positions.append((x, y))
487
-
488
-        # Add Thumb sublayers
489
-        for file, title, position in zip(files, titles, positions):
490
-            title = os.path.basename(file)
491
-            self.add_sublayer(Thumb(file, thumbsize, (0, 0), title), position)
492
-
493
-    def _fit_items(self, num_items, columns, rows, aspect=(4, 3)):
494
-        # Both fixed, nothing to calculate
495
-        if columns > 0 and rows > 0:
496
-            # Make sure num_items will fit (columns, rows)
497
-            if num_items < columns * rows:
498
-                return (columns, rows)
499
-            # Not enough room; auto-dimension both
500
-            else:
501
-                log.warning("ThumbGrid: Can't fit %s items" % num_items +\
502
-                            " in (%s, %s) grid;" % (columns, rows) +\
503
-                            " doing auto-dimensioning instead.")
504
-                columns = rows = 0
505
-        # Auto-dimension to fit num_items
506
-        if columns == 0 and rows == 0:
507
-            # TODO: Take aspect ratio into consideration to find an optimal fit
508
-            root = int(math.floor(math.sqrt(num_items)))
509
-            return ((1 + num_items / root), root)
510
-        # Rows fixed; use enough columns to fit num_items
511
-        if columns == 0 and rows > 0:
512
-            return ((1 + num_items / rows), rows)
513
-        # Columns fixed; use enough rows to fit num_items
514
-        if rows == 0 and columns > 0:
515
-            return (columns, (1 + num_items / columns))
516
-
517
-    def draw(self, drawing, frame=1):
518
-        assert isinstance(drawing, Drawing)
519
-        log.debug("Drawing ThumbGrid")
520
-        drawing.save()
521
-        self.draw_sublayers(drawing, frame)
522
-        drawing.restore()
523
-
524
-
525
-class SafeArea (Layer):
526
-    """Render a safe area box at a given percentage.
527
-    """
528
-    def __init__(self, percent, color):
529
-        self.percent = percent
530
-        self.color = color
531
-
532
-    def draw(self, drawing, frame=1):
533
-        assert isinstance(drawing, Drawing)
534
-        log.debug("Drawing SafeArea")
535
-        # Calculate rectangle dimensions
536
-        scale = float(self.percent) / 100.0
537
-        width, height = drawing.size
538
-        topleft = ((1.0 - scale) * width / 2,
539
-                  (1.0 - scale) * height / 2)
540
-        # Save context
541
-        drawing.save()
542
-        drawing.translate(topleft[0], topleft[1])
543
-        # Safe area box
544
-        drawing.stroke_width(3)
545
-        drawing.rectangle(0, 0,  width * scale, height * scale)
546
-        drawing.stroke(self.color)
547
-        # Label
548
-        drawing.font_size(18)
549
-        drawing.set_source(self.color)
550
-        drawing.text(u"%s%%" % self.percent, 10, 20)
551
-        # Restore context
552
-        drawing.restore()
553
-
554
-
555
-class Scatterplot (Layer):
556
-    """A 2D scatterplot of data.
557
-    """
558
-    def __init__(self, xy_dict, width=240, height=80, x_label='', y_label=''):
559
-        """Create a scatterplot using data in xy_dict, a dictionary of
560
-        lists of y-values, indexed by x-value.
561
-        """
562
-        self.xy_dict = xy_dict
563
-        self.width, self.height = (width, height)
564
-        self.x_label = x_label
565
-        self.y_label = y_label
566
-
567
-    def draw(self, drawing, frame):
568
-        """Draw the scatterplot."""
569
-        assert isinstance(drawing, Drawing)
570
-        log.debug("Drawing Scatterplot")
571
-        width, height = (self.width, self.height)
572
-        x_vals = self.xy_dict.keys()
573
-        max_y = 0
574
-        for x in x_vals:
575
-            largest = max(self.xy_dict[x] or [0])
576
-            if largest > max_y:
577
-                max_y = largest
578
-        # For numeric x, scale by maximum x-value
579
-        x_is_num = isinstance(x_vals[0], int) or isinstance(x_vals[0], float)
580
-        if x_is_num:
581
-            x_scale = float(width) / max(x_vals)
582
-        # For string x, scale by number of x-values
583
-        else:
584
-            x_scale = float(width) / len(x_vals)
585
-        # Scale y according to maximum value
586
-        y_scale = float(height) / max_y
587
-
588
-        # Save context
589
-        drawing.save()
590
-        drawing.rectangle(0, 0, width, height)
591
-        drawing.fill('white', 0.75)
592
-
593
-        # Draw axes
594
-        #->comment("Axes of scatterplot")
595
-        drawing.save()
596
-        drawing.stroke_width(2)
597
-        drawing.line(0, 0, 0, height)
598
-        drawing.stroke('black')
599
-        drawing.line(0, height, width, height)
600
-        drawing.stroke('black')
601
-        drawing.restore()
602
-
603
-        # Axis labels
604
-        drawing.save()
605
-        drawing.set_source('blue')
606
-
607
-        drawing.save()
608
-        for i, x in enumerate(x_vals):
609
-            drawing.save()
610
-            if x_is_num:
611
-                drawing.translate(x * x_scale, height + 15)
612
-            else:
613
-                drawing.translate(i * x_scale, height + 15)
614
-            drawing.rotate(30)
615
-            drawing.text(x, 0, 0)
616
-            drawing.restore()
617
-
618
-        drawing.font_size(20)
619
-        drawing.text(self.x_label, width/2, height+40)
620
-        drawing.restore()
621
-
622
-        drawing.save()
623
-        drawing.text(max_y, -30, 0)
624
-        drawing.translate(-25, height/2)
625
-        drawing.rotate(90)
626
-        drawing.text(self.y_label, 0, 0)
627
-        drawing.restore()
628
-
629
-        drawing.restore()
630
-
631
-        # Plot all y-values for each x (as small circles)
632
-        #->comment("Scatterplot data")
633
-        drawing.save()
634
-        for i, x in enumerate(x_vals):
635
-            if x_is_num:
636
-                x_coord = x * x_scale
637
-            else:
638
-                x_coord = i * x_scale
639
-            # Shift x over slightly
640
-            x_coord += 10
641
-            # Plot all y-values for this x
642
-            for y in self.xy_dict[x]:
643
-                y_coord = height - y * y_scale
644
-                drawing.circle(x_coord, y_coord, 3)
645
-                drawing.fill('red', 0.2)
646
-        drawing.restore()
647
-
648
-        # Restore context
649
-        drawing.restore()
650
-
651
-
652
-class InterpolationGraph (Layer):
653
-    # TODO: Support graphing of tuple data
654
-    """A graph of an interpolation curve, defined by a list of Keyframes and
655
-    an interpolation method.
656
-    """
657
-    def __init__(self, keyframes, size=(240, 80), method='linear'):
658
-        """Create an interpolation graph of the given keyframes, at the given
659
-        size, using the given interpolation method.
660
-        """
661
-        Layer.__init__(self)
662
-
663
-        self.keyframes = keyframes
664
-        self.size = size
665
-        self.method = method
666
-        # Interpolate keyframes
667
-        self.tween = Tween(keyframes, method)
668
-
669
-    def draw(self, drawing, frame):
670
-        """Draw the interpolation graph, including frame/value axes,
671
-        keyframes, and the interpolation curve."""
672
-        assert isinstance(drawing, Drawing)
673
-        log.debug("Drawing InterpolationGraph")
674
-        data = self.tween.data
675
-        # Calculate maximum extents of the graph
676
-        width, height = self.size
677
-        x_scale = float(width) / len(data)
678
-        y_scale = float(height) / max(data)
679
-
680
-        #->drawing.comment("InterpolationGraph Layer")
681
-
682
-        # Save context
683
-        drawing.save()
684
-
685
-        # Draw axes
686
-        #->drawing.comment("Axes of graph")
687
-        drawing.save()
688
-        drawing.stroke_width(3)
689
-        drawing.polyline([(0, 0), (0, height), (width, height)], False)
690
-        drawing.stroke('#ccc')
691
-        drawing.restore()
692
-
693
-        # Create a list of (x, y) points to be graphed
694
-        curve = []
695
-        x = 1
696
-        while x <= len(self.tween.data):
697
-            # y increases downwards; subtract from height to give a standard
698
-            # Cartesian-oriented graph (so y increases upwards)
699
-            point = (int(x * x_scale), int(height - data[x-1] * y_scale))
700
-            curve.append(point)
701
-            x += 1
702
-        drawing.save()
703
-        # Draw the curve
704
-        drawing.stroke_width(2)
705
-        drawing.polyline(curve, False)
706
-        drawing.stroke('blue')
707
-        drawing.restore()
708
-
709
-        # Draw Keyframes as dotted vertical lines
710
-        drawing.save()
711
-        # Vertical dotted lines
712
-        drawing.set_source('red')
713
-        drawing.stroke_width(2)
714
-        for key in self.keyframes:
715
-            x = int(key.frame * x_scale)
716
-            drawing.line(x, 0,   x, height)
717
-            drawing.stroke('red')
718
-
719
-        # Draw Keyframe labels
720
-        drawing.set_source('white')
721
-        for key in self.keyframes:
722
-            x = int(key.frame * x_scale)
723
-            y = int(height - key.data * y_scale - 3)
724
-            drawing.text(u"(%s,%s)" % (key.frame, key.data), x, y)
725
-
726
-        drawing.restore()
727
-
728
-        # Draw a yellow dot for current frame
729
-        #->drawing.comment("Current frame marker")
730
-        drawing.save()
731
-        pos = (frame * x_scale, height - data[frame-1] * y_scale)
732
-        drawing.circle(pos[0], pos[1], 2)
733
-        drawing.fill('yellow')
734
-        drawing.restore()
735
-
736
-        # Restore context
737
-        drawing.restore()
738
-
739
-
740
-class ColorBars (Layer):
741
-    """Standard SMPTE color bars
742
-    (http://en.wikipedia.org/wiki/SMPTE_color_bars)
743
-    """
744
-    def __init__(self, size, position=(0, 0)):
745
-        """Create color bars in a region of the given size and position.
746
-        """
747
-        Layer.__init__(self)
748
-        self.size = size
749
-        # Set (x,y) position
750
-        assert(isinstance(position, tuple))
751
-        self.position = position
752
-
753
-    def draw(self, drawing, frame=1):
754
-        assert isinstance(drawing, Drawing)
755
-        log.debug("Drawing ColorBars")
756
-        x, y = self.position
757
-        width, height = self.size
758
-
759
-        drawing.save()
760
-        # Get to the right place and size
761
-        drawing.translate(x, y)
762
-        drawing.scale(width, height)
763
-        # Video-black background
764
-        drawing.rectangle(0, 0, 1, 1)
765
-        drawing.fill('rgb(16, 16, 16)')
766
-
767
-        # Top 67% of picture: Color bars at 75% amplitude
768
-        top = 0
769
-        bottom = 2.0 / 3
770
-        seventh = 1.0 / 7
771
-        size = (seventh, bottom)
772
-        bars = [(0, top, seventh, bottom, 'rgb(191, 191, 191)'),
773
-                (seventh, top, seventh, bottom, 'rgb(191, 191, 0)'),
774
-                (2*seventh, top, seventh, bottom, 'rgb(0, 191, 191)'),
775
-                (3*seventh, top, seventh, bottom, 'rgb(0, 191, 0)'),
776
-                (4*seventh, top, seventh, bottom, 'rgb(191, 0, 191)'),
777
-                (5*seventh, top, seventh, bottom, 'rgb(191, 0, 0)'),
778
-                (6*seventh, top, seventh, bottom, 'rgb(0, 0, 191)')]
779
-
780
-        # Next 8% of picture: Reverse blue bars
781
-        top = bottom
782
-        bottom = 0.75
783
-        height = bottom - top
784
-        bars.extend([(0, top, seventh, height, 'rgb(0, 0, 191)'),
785
-                (seventh, top, seventh, height, 'rgb(16, 16, 16)'),
786
-                (2*seventh, top, seventh, height, 'rgb(191, 0, 191)'),
787
-                (3*seventh, top, seventh, height, 'rgb(16, 16, 16)'),
788
-                (4*seventh, top, seventh, height, 'rgb(0, 191, 191)'),
789
-                (5*seventh, top, seventh, height, 'rgb(16, 16, 16)'),
790
-                (6*seventh, top, seventh, height, 'rgb(191, 191, 191)')])
791
-
792
-        # Lower 25%: Pluge signal
793
-        top = bottom
794
-        bottom = 1.0
795
-        sixth = 1.0 / 6
796
-        height = bottom - top
797
-        bars.extend([(0, top, 1.0, height, 'rgb(16, 16, 16)'),
798
-                (0, top, sixth, height, 'rgb(0, 29, 66)'),
799
-                (sixth, top, sixth, height, 'rgb(255, 255, 255)'),
800
-                (2*sixth, top, sixth, height, 'rgb(44, 0, 92)'),
801
-                # Sub- and super- black narrow bars
802
-                (4*sixth, top, 0.33*sixth, height, 'rgb(7, 7, 7)'),
803
-                (4.33*sixth, top, 0.33*sixth, height,'rgb(16, 16, 16)'),
804
-                (4.66*sixth, top, 0.33*sixth, height, 'rgb(24, 24, 24)')])
805
-
806
-        # Draw and fill all bars
807
-        for x, y, width, height, color in bars:
808
-            drawing.rectangle(x, y, width, height)
809
-            drawing.fill(color)
810
-
811
-        drawing.restore()
812
-
813
-
814
-
815
-
816
-if __name__ == '__main__':
817
-    images = None
818
-    # Get arguments, if any
819
-    if len(sys.argv) > 1:
820
-        # Use all args as image filenames to ThumbGrid
821
-        images = sys.argv[1:]
822
-
823
-    # A Drawing to render Layer demos to
824
-    drawing = Drawing(800, 600)
825
-
826
-    # Draw a background layer
827
-    bgd = Background(color='#7080A0')
828
-    bgd.draw(drawing, 1)
829
-
830
-    # Draw color bars
831
-    bars = ColorBars((320, 240), (400, 100))
832
-    bars.draw(drawing, 1)
833
-
834
-    # Draw a label
835
-    drawing.save()
836
-    drawing.translate(460, 200)
837
-    label = Label("tovid loves Linux")
838
-    label.draw(drawing, 1)
839
-    drawing.restore()
840
-
841
-    # Draw a text layer, with position.
842
-    text = Text("Jackdaws love my big sphinx of quartz",
843
-                (82, 62), '#bbb')
844
-    text.draw(drawing, 1)
845
-
846
-    # Draw a text layer
847
-    drawing.save()
848
-    drawing.translate(80, 60)
849
-    text = Text("Jackdaws love my big sphinx of quartz")
850
-    text.draw(drawing, 1)
851
-    drawing.restore()
852
-
853
-    # Draw a template layer (overlapping semitransparent rectangles)
854
-    template = MyLayer('white', 'darkblue')
855
-    # Scale and translate the layer before drawing it
856
-    drawing.save()
857
-    drawing.translate(50, 100)
858
-    drawing.scale(3.0, 3.0)
859
-    template.draw(drawing, 1)
860
-    drawing.restore()
861
-
862
-    # Draw a safe area test (experimental)
863
-    safe = SafeArea(93, 'yellow')
864
-    safe.draw(drawing, 1)
865
-
866
-    # Draw a thumbnail grid (if images were provided)
867
-    if images:
868
-        drawing.save()
869
-        drawing.translate(350, 300)
870
-        thumbs = ThumbGrid(images, (320, 250))
871
-        thumbs.draw(drawing, 1)
872
-        drawing.restore()
873
-
874
-    # Draw an interpolation graph
875
-    drawing.save()
876
-    drawing.translate(60, 400)
877
-    # Some random keyframes to graph
878
-    keys = [Keyframe(1, 25), Keyframe(10, 5), Keyframe(30, 35),
879
-            Keyframe(40, 35), Keyframe(45, 20), Keyframe(60, 40)]
880
-    interp = InterpolationGraph(keys, (400, 120), method="cosine")
881
-    interp.draw(drawing, 25)
882
-    drawing.restore()
883
-
884
-    # Draw a scatterplot
885
-    drawing.save()
886
-    xy_data = {
887
-        5: [2, 4, 6, 8],
888
-        10: [3, 5, 7, 9],
889
-        15: [5, 9, 13, 17],
890
-        20: [8, 14, 20, 26]}
891
-    drawing.translate(550, 350)
892
-    #drawing.scale(200, 200)
893
-    plot = Scatterplot(xy_data, 200, 200, "Spam", "Eggs")
894
-    plot.draw(drawing, 1)
895
-    drawing.restore()
896
-
897
-    log.info("Output to /tmp/my.png")
898
-    save_image(drawing, '/tmp/my.png', 800, 600)
899
-
900
tovid-0.34.tar.bz2/libtovid/runtest.py Deleted
66
 
1
@@ -1,64 +0,0 @@
2
-# runtest.py
3
-
4
-"""libtovid test script
5
-
6
-Execute this script to run tests on the modules in libtovid. These tests
7
-consist of executing each libtovid module standalone; it is presumed that
8
-each module to be tested contains at least the following::
9
-
10
-    import unittest
11
-    if __name__ == '__main__':
12
-        unittest.main()
13
-
14
-which runs unit tests, or::
15
-
16
-    import doctest
17
-    if __name__ == '__main__':
18
-        doctest.testmod(verbose=True)
19
-
20
-which does an automated verification of the docstrings in each module.
21
-
22
-NB -- You're going to get lots of output, so a ``> log.txt`` is advised.
23
-"""
24
-
25
-import os
26
-import commands
27
-from glob import glob
28
-
29
-libtovid_modules = [
30
-    'author.py',
31
-    'cli.py',
32
-    'deps.py',
33
-    'encode.py',
34
-    'media.py',
35
-    'odict.py',
36
-    'opts.py',
37
-    'standard.py',
38
-    'stats.py',
39
-    'xml.py',
40
-]
41
-
42
-subdirs = [
43
-    'backend',
44
-    'metagui',
45
-    'render',
46
-    'template',
47
-    'test',
48
-    'util',
49
-]
50
-
51
-subdir_modules = []
52
-for subdir in subdirs:
53
-    subdir_modules.extend(glob('%s/*.py' % subdir))
54
-
55
-all_modules = libtovid_modules + subdir_modules
56
-
57
-if __name__ == '__main__':
58
-    # Execute each module
59
-    for mod in all_modules:
60
-        print("Testing: %s" % mod)
61
-        try:
62
-            print(commands.getoutput('python %s' % mod))
63
-        except KeyboardInterrupt:
64
-            print("Test interrupted.")
65
-            exit()
66
tovid-0.34.tar.bz2/libtovid/standard.py Deleted
149
 
1
@@ -1,147 +0,0 @@
2
-# standard.py
3
-
4
-"""This module defines functions for retrieving information about multimedia
5
-standards, including functions for determining the appropriate resolution,
6
-video and audio codec, fps, and bitrates for a given format.
7
-"""
8
-
9
-__all__ = [
10
-    'abitrate',
11
-    'acodec',
12
-    'fps',
13
-    'fps_ratio',
14
-    'resolution',
15
-    'samprate',
16
-    'vbitrate',
17
-    'vcodec',
18
-]
19
-
20
-def resolution(format, tvsys):
21
-    """Return the pixel resolution (x,y) for the given format and TV system.
22
-    For example::
23
-
24
-        >>> resolution('dvd', 'pal')
25
-        (720, 576)
26
-        >>> resolution('half-dvd', 'ntsc')
27
-        (352, 480)
28
-    """
29
-    # Valid resolutions, indexed by format and tvsys
30
-    valid_size = {
31
-        'vcd':
32
-            {'pal': (352, 288), 'ntsc': (352, 240)},
33
-        'dvd-vcd':
34
-            {'pal': (352, 288), 'ntsc': (352, 240)},
35
-        'svcd':
36
-            {'pal': (480, 576), 'ntsc': (480, 480)},
37
-        'half-dvd':
38
-            {'pal': (352, 576), 'ntsc': (352, 480)},
39
-        'dvd':
40
-            {'pal': (720, 576), 'ntsc': (720, 480)}
41
-        }
42
-    return valid_size[format][tvsys]
43
-
44
-
45
-def vcodec(format):
46
-    """Return the video codec used by the given format.
47
-    For example::
48
-
49
-        >>> vcodec('vcd')
50
-        'mpeg1'
51
-        >>> vcodec('svcd')
52
-        'mpeg2'
53
-    """
54
-    if format == 'vcd':
55
-        return 'mpeg1'
56
-    else:
57
-        return 'mpeg2'
58
-
59
-
60
-def acodec(format):
61
-    """Return the audio codec (or codecs) supported by the given format.
62
-    For example::
63
-
64
-        >>> acodec('vcd')
65
-        'mp2'
66
-        >>> acodec('dvd')
67
-        'ac3'
68
-    """
69
-    if format in ['vcd', 'svcd']:
70
-        return 'mp2'
71
-    else:
72
-        return 'ac3'
73
-
74
-
75
-def samprate(format):
76
-    """Return the audio sampling rate used by the given format.
77
-    """
78
-    if format in ['vcd', 'svcd']:
79
-        return 44100
80
-    else:
81
-        return 48000
82
-
83
-
84
-def fps(tvsys):
85
-    """Return the number of frames per second for the given TV system.
86
-    For example::
87
-
88
-        >>> print(fps('ntsc'))
89
-        29.97
90
-        >>> print(fps('pal'))
91
-        25.0
92
-    """
93
-    # Valid frames per second, by TV system
94
-    _fps = {
95
-        'pal': 25.0,
96
-        'ntsc': 29.97,
97
-        'ntscfilm': 23.976,
98
-        }
99
-    return _fps[tvsys]
100
-
101
-
102
-def fps_ratio(tvsys):
103
-    """Return the number of frames per second for the given TV system,
104
-    in ratio form. For example::
105
-
106
-        >>> fps_ratio('ntsc')
107
-        '30000:1001'
108
-        >>> fps_ratio('pal')
109
-        '25:1'
110
-    """
111
-    # Valid frames per second, by TV system
112
-    _fps = {
113
-        'pal': '25:1',
114
-        'ntsc': '30000:1001',
115
-        'ntscfilm': '24000:1001',
116
-        }
117
-    return _fps[tvsys]
118
-
119
-
120
-def vbitrate(format):
121
-    """Return the range (min, max) of valid video bitrates (in kilobits per
122
-    second) for the given format. min and max are the same for constant-bitrate
123
-    formats.
124
-    """
125
-    # Valid video bitrates, indexed by format
126
-    valid_bitrates = {
127
-        'vcd': (1150, 1150),
128
-        'svcd': (0, 2600),
129
-        'dvd-vcd': (0, 9800),
130
-        'half-dvd': (0, 9800),
131
-        'dvd': (0, 9800)
132
-        }
133
-    return valid_bitrates[format]
134
-
135
-
136
-def abitrate(format):
137
-    """Return the range (min, max) of valid audio bitrates (in kilobits per
138
-    second) for the given format. For constant-bitrate formats, min == max.
139
-    """
140
-    if format == 'vcd':
141
-        return (224, 224)
142
-    elif format == 'svcd':
143
-        return (32, 384)
144
-    else:
145
-        return (32, 1536)
146
-
147
-
148
-
149
tovid-0.34.tar.bz2/libtovid/stats.py Deleted
240
 
1
@@ -1,238 +0,0 @@
2
-# stats.py
3
-
4
-"""Classes and functions for dealing with tovid statistics.
5
-
6
-Future interface ideas:
7
-
8
-* Display certain records, or a range of records (records 1-10; last 15 records;
9
-  records with a certain field (or any field) matching given text/regexp
10
-* Display formatted output of all records, or a selection of records,
11
-  with control over which fields are displayed
12
-
13
-"""
14
-
15
-import csv
16
-import sys
17
-from copy import copy
18
-
19
-# Order of fields in stats.tovid
20
-FIELDS = [
21
-    'tovid_version',
22
-    'final_name',
23
-    'length',          # a.k.a. CUR_LENGTH
24
-    'format',          # RES
25
-    'tvsys',
26
-    'final_size',
27
-    'tgt_bitrate',
28
-    'avg_bitrate',
29
-    'peak_bitrate',
30
-    'gop_minsize',
31
-    'gop_maxsize',
32
-    'encoding_time',   # SCRIPT_TOT_TIME
33
-    'cpu_model',
34
-    'cpu_speed',
35
-    'in_vcodec',
36
-    'in_acodec',
37
-    'encoding_mode',
38
-    'in_md5',
39
-    'in_width',
40
-    'in_height',
41
-    'quant',
42
-    'kbpm',
43
-    'enc_time_ratio',
44
-    'backend',
45
-    ]
46
-
47
-# Integer numeric fields
48
-int_fields = [
49
-    'length',
50
-    'avg_bitrate',
51
-    'tgt_bitrate',
52
-    'peak_bitrate',
53
-    'encoding_time',
54
-    'final_size',
55
-    'cpu_speed',
56
-    'in_width',
57
-    'in_height',
58
-    'quant',
59
-    'kbpm',
60
-    ]
61
-
62
-class Statlist:
63
-    """A list of statistics that may be queried with a simple database-like
64
-    interface."""
65
-    def __init__(self, records=None, filename=''):
66
-        """Create a Statlist, using the given list of records, or by reading
67
-        from the given filename (CSV text).
68
-        """
69
-        # Use provided records, if any
70
-        if records:
71
-            self.records = copy(records)
72
-        # Otherwise, read from any provided filename
73
-        else:
74
-            self.records = []
75
-            if filename != '':
76
-                self.read_csv(filename)
77
-
78
-
79
-    def read_csv(self, filename):
80
-        """Import stats from a CSV (comma-delimited quoted text) file."""
81
-        self.records = []
82
-        statfile = open(filename, 'r')
83
-        csv_reader = csv.DictReader(statfile, FIELDS, skipinitialspace=True)
84
-        for line in csv_reader:
85
-            # Convert some string and numeric fields
86
-            line['format'] = str.lower("%s" % line['format'])
87
-            line['tvsys'] = str.lower("%s" % line['tvsys'])
88
-            for field in int_fields:
89
-                try:
90
-                    num = int("%s" % line[field])
91
-                except (ValueError, TypeError):
92
-                    num = 0
93
-                line[field] = num
94
-            self.records.append(line)
95
-
96
-        statfile.close()
97
-        print("Read %s lines from %s" % (len(self.records), filename))
98
-
99
-
100
-    def unique(self, field):
101
-        """Return a list of unique values of the given field."""
102
-        unique_values = []
103
-        for record in self.records:
104
-            if record[field] not in unique_values:
105
-                unique_values.append(record[field])
106
-        return unique_values
107
-
108
-
109
-    def count_unique(self, field):
110
-        """Count the occurrences of each unique value of the given field.
111
-        Return a dictionary of unique values and the number of occurrences
112
-        of each."""
113
-        counts = {}
114
-        # Go through all records and total up occurrences of each value
115
-        for record in self.records:
116
-            value = record[field]
117
-            if value is None or value == '':
118
-                pass
119
-            elif value not in counts:
120
-                counts[value] = 1
121
-            else:
122
-                counts[value] += 1
123
-        return counts
124
-
125
-
126
-    def average(self, attribute):
127
-        """Calculate the average value for a given numeric VidStat attribute.
128
-        For example, average('bitrate') returns the average overall bitrate of
129
-        all videos in the list."""
130
-        # Error if attribute is non-numeric
131
-        if attribute not in int_fields:
132
-            print("Can't average %s: not defined as a numeric field")
133
-            sys.exit()
134
-
135
-        values = []
136
-        for record in self.records:
137
-            # Only append non-zero values
138
-            if record[attribute] != 0:
139
-                values.append(record[attribute])
140
-        if len(values) > 0:
141
-            return float(sum(values) / len(values))
142
-        else:
143
-            return 0.0
144
-
145
-
146
-    def average_by(self, attribute, by_attribute):
147
-        """Return a dictionary of averages of an attribute, indexed by another
148
-        attribute. For example, average_by('bitrate', 'format') returns average
149
-        bitrates for each format."""
150
-        # Error if attribute is non-numeric
151
-        if attribute not in int_fields:
152
-            print("Can't average %s: not defined as a numeric field")
153
-            sys.exit()
154
-
155
-        values_by = self.list_by(attribute, by_attribute)
156
-        # Calculate averages for each value-list
157
-        averages = {}
158
-        if len(values_by) > 0:
159
-            for key, samples in values_by.iteritems():
160
-                try:
161
-                    averages[key] = float(sum(samples) / len(samples))
162
-                except ZeroDivisionError:
163
-                    averages[key] = 0.0
164
-        return averages
165
-
166
-
167
-    def list_by(self, attribute, by_attribute, sort_lists=False):
168
-        """Return a dictionary of lists of values of the given attribute,
169
-        indexed by another attribute. If sort_lists is True, sort all lists."""
170
-        # Create a dictionary of value-lists, indexed by by_attribute
171
-        values_by = {}        
172
-        for record in self.records:
173
-            byval = record[by_attribute]
174
-            if not values_by.has_key(byval):
175
-                values_by[byval] = []
176
-            # Only include non-zero values
177
-            if record[attribute] != 0:
178
-                values_by[byval].append(record[attribute])
179
-        if sort_lists:
180
-            for index in values_by.iterkeys():
181
-                values_by[index].sort()
182
-        return values_by
183
-
184
-
185
-    def get_matching(self, attribute, value):
186
-        """Return a list of records where the given attribute equals the given
187
-        value. Records are field-indexed dictionaries of values.
188
-        """
189
-        # List of matching records
190
-        matches = []
191
-        for record in self.records:
192
-            if record[attribute] == value:
193
-                matches.append(record)
194
-        return matches
195
-
196
-
197
-    def length(self, field):
198
-        """Return the length of the longest record in the given field, or the
199
-        width of the field name itself, whichever is greater."""
200
-        longest = len(field)
201
-        for record in self.records:
202
-            cur_len = len(str(record[field]))
203
-            if cur_len > longest:
204
-                longest = cur_len
205
-        return longest
206
-
207
-
208
-    def show(self, show_records='all', show_fields='all'):
209
-        """Print records matching given criteria, showing only the given fields.
210
-
211
-            show_records
212
-                Number of record to show, or range of numbers
213
-            show_fields
214
-                List of fields, by name as shown in FIELDS
215
-        """
216
-        # Remember field sizes (character widths)
217
-        size = {}
218
-        # Create field headings
219
-        heading = ''
220
-        if show_fields == 'all':
221
-            show_fields = FIELDS
222
-        for field in show_fields:
223
-            if field in FIELDS:
224
-                size[field] = self.length(field)
225
-                heading += "%s " % str.ljust(field, size[field])
226
-            else:
227
-                print("Error: field '%s' does not exist" % field)
228
-                sys.exit()
229
-        print(heading)
230
-        # Print fields from matching records
231
-        for record in self.records:
232
-            # TODO: support show_records
233
-            line = ''
234
-            for field in show_fields:
235
-                line += "%s " % str.ljust(str(record[field]), size[field])
236
-            print(line)
237
-        # Print heading at end too
238
-        print(heading)
239
-
240
tovid-0.34.tar.bz2/libtovid/xml.py Deleted
140
 
1
@@ -1,138 +0,0 @@
2
-"""This module is for defining XML elements and attributes, and for creating
3
-element hierarchies.
4
-
5
-To create a new element, use the `Element` constructor, providing at
6
-least the element name::
7
-
8
-    >>> video = Element('video')
9
-
10
-To see an XML representation of the Element::
11
-
12
-    >>> print(video)
13
-    <video></video>
14
-
15
-Since this is an empty element with no attributes yet, it's pretty boring.
16
-You can add or change attributes using the `~Element.set` method::
17
-
18
-    >>> video.set(file="Brian.mpg")
19
-    >>> print(video)
20
-    <video file="Brian.mpg"></video>
21
-
22
-To add children to an element, use the `~Element.add` method::
23
-
24
-    >>> length = video.add('length', '15')
25
-    >>> print(video)
26
-    <video file="Brian.mpg">
27
-      <length>15</length>
28
-    </video>
29
-
30
-See `libtovid.author` and `libtovid.backend.spumux` for additional
31
-examples.
32
-"""
33
-
34
-__all__ = ['Element']
35
-
36
-class Element (object):
37
-    """A named XML element having optional content, attributes, and children.
38
-
39
-    Attribute values may be set in the constructor, or by calling `set` with a
40
-    dictionary and/or attribute=value keywords.
41
-
42
-    Use `add` or `add_child` to create a hierarchy of Elements.
43
-    """
44
-    def __init__(self, name, content='', **attributes):
45
-        """Create a new Element with the given attributes.
46
-
47
-            name
48
-                Name of the Element
49
-            content
50
-                Text content of the Element
51
-            attributes
52
-                Keyword=value for specific attributes
53
-        """
54
-        self.name = name
55
-        self.content = content
56
-        self.attributes = {}
57
-        self.children = []
58
-        # Set attributes from those provided
59
-        self.set(**attributes)
60
-
61
-
62
-    def set(self, **attributes):
63
-        """Set values for one or more attributes.
64
-
65
-            attributes
66
-                Keyword arguments for setting specific attributes
67
-
68
-        Underscores in attribute names are converted to hyphens. If you don't
69
-        like this behavior, please suggest a workaround :-)
70
-        """
71
-        # Set attribute values; convert underscores to hyphens
72
-        for key, value in attributes.iteritems():
73
-            key = key.replace('_', '-')
74
-            self.attributes[key] = value
75
-
76
-
77
-    def add(self, child_name, content='', **attributes):
78
-        """Create and add a new child Element by providing its name, content,
79
-        and attributes. Return the newly-added Element.
80
-
81
-            child
82
-                String name of child element
83
-            content
84
-                String content of child element
85
-            attributes
86
-                Keyword arguments for setting child's attributes
87
-
88
-        This is a convenience function for creating and adding children
89
-        on-the-fly.
90
-        """
91
-        child = Element(child_name, content, **attributes)
92
-        self.children.append(child)
93
-        return child
94
-
95
-
96
-    def add_child(self, element):
97
-        """Add the given Element as a child of this Element.
98
-        """
99
-        assert isinstance(element, Element)
100
-        self.children.append(element)
101
-
102
-
103
-    def xml(self, indent_level=0):
104
-        """Return formatted XML for this Element and all descendants.
105
-        """
106
-        indent = '  ' * indent_level
107
-        # No children; write a single line
108
-        if len(self.children) == 0:
109
-            text = indent + self._open() + self.content + self._close() + '\n'
110
-        # If children, write an indented block
111
-        else:
112
-            text = indent + self._open() + self.content + '\n'
113
-            for child in self.children:
114
-                text += child.xml(indent_level + 1)
115
-            text += indent + self._close() + '\n'
116
-        return text
117
-
118
-
119
-    def __str__(self):
120
-        """Return a string containing formatted XML for the Element.
121
-        """
122
-        return self.xml().rstrip('\n')
123
-
124
-
125
-    def _open(self):
126
-        """Return the XML opening tag for the Element.
127
-        """
128
-        attribs = ''
129
-        for key, value in self.attributes.items():
130
-            attribs += ' %s="%s"' % (key, value)
131
-        return '<' + self.name + attribs + '>'
132
-
133
-
134
-    def _close(self):
135
-        """Return the XML closing tag for the Element.
136
-        """
137
-        return '</' + self.name + '>'
138
-
139
-
140
tovid-0.34.tar.bz2/src/make_titlesets Deleted
261
 
1
@@ -1,259 +0,0 @@
2
-#!/bin/bash
3
-# Part of the tovid suite
4
-# =======================
5
-# A bash script that calls the tovid GUI in order to allow titlesets,
6
-# something the GUI is not capable of on its own at the moment.
7
-# This script depends on the GUI, in addition to the other command
8
-# line scripts of the tovid suite such as todisc, makempg, and idvid.
9
-#
10
-# Project homepage: http://tovid.wikia.com
11
-#
12
-# Copyright (C) 2005-2010
13
-#
14
-# This program is free software; you can redistribute it and/or
15
-# modify it under the terms of the GNU General Public License
16
-# as published by the Free Software Foundation; either
17
-# version 2 of the License, or (at your option) any later
18
-# version.
19
-#
20
-# This program is distributed in the hope that it will be useful,
21
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
22
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23
-# GNU General Public License for more details.
24
-#
25
-# You should have received a copy of the GNU General Public License
26
-# along with this program; if not, write to the Free Software
27
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Or see:
28
-#
29
-#     http://www.gnu.org/licenses/gpl.txt
30
-
31
-
32
-# Written by Robert ("grepper") Sohn
33
-# grepper at gmail dot com
34
-
35
-#############################################################################
36
-###############################Variables ####################################
37
-#############################################################################
38
-path=$(tovid -prefix)
39
-PATH=$path:$PATH
40
-SEP=$(for i in {1..79}; do printf '='; done)
41
-final_tmp_script=$(mktemp -t todisc.XXXXXXXX)
42
-final_script="$PWD/todisc_commands.bash"
43
-
44
-##############################################################################
45
-################################## Functions #################################
46
-##############################################################################
47
-# read_script name
48
-read_script()
49
-{
50
-    script_exists=0
51
-    script_name="$1"
52
-    # if user just pressed enter, test that the default name exists (it should)
53
-    if [[ -z $script_name ]]; then
54
-        script_name="$final_script"
55
-        [[ -e $script_name ]] && script_exists=1
56
-    fi
57
-    # else test if the file name path passed in exists
58
-    while ! (( script_exists )); do
59
-        read script_name
60
-        script_name=$(readlink -f "$script_name")
61
-        if  [[ -e "$script_name" ]] ; then
62
-            script_exists=1
63
-        else
64
-            echo "Sorry, $script_name does not point to an existing file."
65
-            echo "Please re-enter the path to the script."
66
-            echo "You can use the full path or the path relative to $PWD"
67
-        fi
68
-    done
69
-    SCRIPT="$script_name"
70
-}
71
-
72
-run_gui()
73
-{    
74
-    todiscgui &>/dev/null &
75
-    tovid_pid=$!
76
-    sleep 2
77
-    echo $SEP
78
-    echo "Make your selections, then save your script and exit GUI to continue..."
79
-    wait $tovid_pid
80
-    echo $SEP
81
-    echo "Press <ENTER> to accept the default path and filename "
82
-    echo "for the file you just saved."
83
-    echo "Or enter the relative or full path"
84
-    echo "[${final_script}]"
85
-    read script
86
-    read_script "$script"
87
-        
88
-    todisc_tmp=$(mktemp todisc_tmpXXXXXX)
89
-    mv "$SCRIPT" "$todisc_tmp"
90
-    echo $SEP
91
-    echo "Okay, the content is saved, please save to the same file next time."
92
-    echo "Press <ENTER> to continue"
93
-    read cont
94
-}
95
-
96
-# clean_script file
97
-clean_script()
98
-{
99
-    file="$1"
100
-    # remove shebang and PATH
101
-    sed -i '/\#\!\/usr\/bin\/env bash/d;/PATH/d' "$file"
102
-    # remove todisc command
103
-    sed -i '/^todisc \\$/d' "$file"
104
-    # remove opening blank lines
105
-    sed -i '/./,/^$/!d' "$file"
106
-}
107
-
108
-##############################################################################
109
-############################ Main body starts here ###########################
110
-##############################################################################
111
-
112
-##############################################################################
113
-############################## General Options ###############################
114
-##############################################################################
115
-cat <<EOF
116
-
117
-$SEP
118
-We are going to create a complete DVD with titlesets and menus.
119
-
120
-I am going to start tovid gui.  Please enter the general
121
-options there that you would like to apply to every titleset.  
122
-"Output name" (bottom of main screen) is the only required general
123
-option.  When you are done, press the 'Save script' button and save to
124
-"${final_script}"
125
-accepting the default filename and making sure you are
126
-in the correct directory.  You must then close the GUI in order to continue.
127
-
128
-Press <ENTER> to continue...
129
-EOF
130
-read cont
131
-if [[ -e $final_script ]]; then
132
-    new_name=$(TMPDIR=`pwd` mktemp -t todisc_commands.bash.XXXXXX)
133
-    echo "The file we will use to save options: \"${final_script}\", 
134
-     exists in the current directory. It will be renamed: 
135
-    to $new_name if you continue." |sed 's/^[ \t]*//;s/[ \t]*$//'
136
-    echo "press <ENTER> to continue..."
137
-    read cont
138
-fi
139
-[[ -e "$final_script" ]] && mv "$final_script" "$new_name"
140
-
141
-run_gui
142
-##############################################################################
143
-################################# VMGM Menu ##################################
144
-##############################################################################
145
-
146
-####################### Titleset Titles for VMGM menu ########################
147
-cat <<EOF
148
-
149
-Now we will save options for your root (VMGM) menu
150
-The only option you really need is the titleset titles.
151
-Since you can not save titles in the GUI without loading videos
152
-you will need to enter them here.
153
-These titleset names will appear as menu titles for the respective menu
154
-in your DVD
155
-EOF
156
-echo $SEP
157
-echo "Press <ENTER> to continue..."
158
-read cont
159
-cat <<EOF
160
-
161
-Enter the names of your titlesets, one per line pressing <ENTER> each time.
162
-Do not use quotes unless you want them to appear literally in the title.
163
-Type "done" when you are finished.
164
-EOF
165
-
166
-done=0
167
-while ! ((done)); do
168
-    read title
169
-    if [[ $title == "done" ]]; then
170
-        done=1
171
-    else
172
-        MENU_TITLES+=("$title")
173
-    fi
174
-done
175
-# add backslash to last line; add -vmgm and -titles; add menu titles
176
-sed -i "\$s/$/ \\\/" "$todisc_tmp"
177
-sed -i '$ a -vmgm \\' "$todisc_tmp"
178
-sed -i '$ a -titles \\'  "$todisc_tmp"
179
-printf '"%s" \\\n' "${MENU_TITLES[@]}" >> "$todisc_tmp"
180
-mv "$todisc_tmp" "$final_tmp_script"
181
-
182
-############################# VMGM Menu options ##############################
183
-cat <<EOF
184
-
185
-Now I will bring the GUI up again - enter options for your root 
186
-(VMGM) menu.
187
-Remember that this menu (VMGM) does not need video files.
188
-You still have many options, but none are strictly necessary.  For example
189
-you may wish to use background (audio and/or image/video), a
190
-showcased image/video, set the fonts, use a "Playall" button...
191
-You should also set the menu title to a new name.  When you are done save
192
-the script again to
193
-$final_script
194
-and close the GUI to continue.
195
-EOF
196
-echo "Press <ENTER> to continue..."
197
-read cont
198
-run_gui
199
-clean_script "$todisc_tmp"
200
-# add backslash to last line
201
-sed -i "\$s/$/ \\\/" "$todisc_tmp"
202
-# add -end-vmgm as last line
203
-sed -i '$ a -end-vmgm \\' "$todisc_tmp"
204
-cat "$todisc_tmp" >> "$final_tmp_script"
205
-rm -f "$todisc_tmp"
206
-done=0
207
-
208
-##############################################################################
209
-################################## Titlesets #################################
210
-##############################################################################
211
-
212
-echo "Now finally we will make your titlesets"
213
-get_message()
214
-{
215
-    message=$(
216
-    cat <<EOF
217
-
218
-Bringing up the GUI for titleset $tset.
219
-Make your titleset, leaving out the general options you gave earlier
220
-unless you wish to change them (-out can not be changed).
221
-Press <ENTER> to continue or type "done" if you have no more titlesets
222
-EOF
223
-    )
224
-    echo "$message"
225
-}
226
-while ! ((done)); do
227
-    ((tset++))
228
-    get_message
229
-    read title
230
-    if [[ $title == "done" ]]; then
231
-        done=1
232
-    else
233
-        run_gui
234
-        clean_script "$todisc_tmp"
235
-        # add backslash to last line of temp file
236
-        sed -i "\$s/$/ \\\/" "$todisc_tmp"
237
-        # add "-titleset \" as 1st line
238
-        sed -i '1i -titleset \\' "$todisc_tmp"
239
-        # add "-end-titleset" as last line
240
-        sed -i '$a -end-titleset \\' "$todisc_tmp"
241
-        # concatenate
242
-        cat "$todisc_tmp" >> "$final_tmp_script"
243
-        rm -f "$todisc_tmp"
244
-    fi
245
-done
246
-
247
-###############################################################################
248
-############################## Run Final Script ###############################
249
-###############################################################################
250
-
251
-# remove backslash on last line
252
-sed -i "\$s/\\\//" "$final_tmp_script"
253
-echo $SEP
254
-mv "$final_tmp_script" "$final_script"
255
-echo final script is "$final_script"
256
-echo "Do you want to run it now?, type yes if you do, or press <ENTER> to leave"
257
-read answer
258
-if [[ $answer == "yes" ]]; then
259
-    bash "$final_script"
260
-fi
261
tovid-0.34.tar.bz2/src/makemenu Deleted
880
 
1
@@ -1,878 +0,0 @@
2
-#!/usr/bin/env bash
3
-ME="[makemenu]:"
4
-. tovid-init 2>/dev/null ||
5
-{ echo -e "===============================================================\n"
6
-echo -e "'tovid-init' not found.  Was tovid improperly installed?"
7
-echo -e "Or are you trying to run the script directly?"
8
-echo -e "Please run makemenu as:\ntovid menu OPTIONS"
9
-exit 1 ; }
10
-
11
-# version $Id: makemenu 3336 2011-06-30 21:49:22Z grepper $
12
-# makemenu
13
-# Part of the tovid suite
14
-# =======================
15
-# A bash script for generating menus for use with DVD, VCD, or SVCD.
16
-# Given a background image and a list of titles, and an optional audio
17
-# file to use as background music, this script produces an MPEG video
18
-# displaying the specified text, with subtitle-multiplexed menu
19
-# highlights (for DVD) or enumerated titles (for (S)VCD).
20
-#
21
-# Project homepage: http://tovid.wikia.com
22
-#
23
-# Copyright (C) 2005-2010
24
-#
25
-# This program is free software; you can redistribute it and/or
26
-# modify it under the terms of the GNU General Public License
27
-# as published by the Free Software Foundation; either
28
-# version 2 of the License, or (at your option) any later
29
-# version.
30
-#
31
-# This program is distributed in the hope that it will be useful,
32
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
33
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34
-# GNU General Public License for more details.
35
-#
36
-# You should have received a copy of the GNU General Public License
37
-# along with this program; if not, write to the Free Software
38
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Or see:
39
-#
40
-#     http://www.gnu.org/licenses/gpl.txt
41
-
42
-# Options to consider
43
-# font selection
44
-# font color, highlight color, selection color
45
-# font shadow, border
46
-# icons, graphic overlays
47
-# Support for full-motion video menus
48
-
49
-SCRIPT_NAME=`cat << EOF
50
---------------------------------
51
-tovid menu
52
-Generate DVD/(S)VCD menus
53
-Version $TOVID_VERSION
54
-$TOVID_HOME_PAGE
55
---------------------------------
56
-EOF`
57
-
58
-USAGE=`cat << EOF
59
-Usage: tovid menu [OPTIONS] "Title1" "Title2" ... -out {output prefix}
60
-
61
-Common options:
62
-
63
-    -pal | -ntsc | -ntscfilm            Set TV standard
64
-    -dvd | -vcd | -svcd                 Encode to standard format
65
-    -background IMAGE                   ex: -background star_field.png
66
-    -audio AUDIOFILE                    ex: -audio foo_fighters.mp3
67
-    -font "FONTNAME"                    ex: -font Courier
68
-
69
-Example:
70
-
71
-    tovid menu -background ocean.jpg "First" "Second" "Third" -out mymenu
72
-        Create 'mymenu.mpg' with three titles and a custom background image.
73
-
74
-See the tovid manual page ('man tovid') for additional documentation.
75
-
76
-EOF`
77
-
78
-# Defaults and function definitions
79
-
80
-# Print script name, usage notes, and optional error message, then exit.
81
-# Args: $@ == text string containing error message
82
-usage_error ()
83
-{
84
-    printf "%s\n" "$USAGE"
85
-    printf "%s\n" "$SEPARATOR"
86
-    printf "*** %s\n" "$@"
87
-    exit 1
88
-}
89
-
90
-# Clean up the temporary files
91
-function cleanup()
92
-{
93
-    if $DEBUG; then
94
-        echo "Leaving temporary files in $TMP_DIR"
95
-        echo "Debugging log saved to $LOG_FILE"
96
-    else
97
-        echo "Cleaning up...   "
98
-        rm -rf "$TMP_DIR"
99
-    fi
100
-}
101
-
102
-# Initializations
103
-
104
-# No background image or audio
105
-BG_IMAGE=""
106
-BG_AUDIO=""
107
-MENU_LENGTH=""
108
-# NTSC DVD
109
-TVSYS="ntsc"
110
-RES="dvd"
111
-# Use a safe area
112
-SAFE_AREA=:
113
-# Number of titles
114
-NUM_TITLES=0
115
-MAX_VCD_TITLES=9
116
-MAX_DVD_TITLES=36
117
-OVER_MAX_TITLES=false
118
-# Scale up and crop non-4:3 images by default
119
-SCALECROP="crop"
120
-# Colors for menu items (RGB)
121
-TEXT_COLOR="white"
122
-HIGHLIGHT_COLOR="yellow"
123
-SELECT_COLOR="red"
124
-# Default title font and point size
125
-TITLE_FONT="Helvetica"
126
-TITLE_SIZE="24"
127
-FONT_DECO="-stroke black -strokewidth 1"
128
-TEXT_ALIGN="northwest"
129
-# Default menu title settings
130
-MAKE_TITLE=false
131
-# Button char
132
-BUTTON_FONT=""
133
-BUTTON_CHAR=">"
134
-BTN_STROKE="none"
135
-# NTSC DVD
136
-SAMPRATE="48000"
137
-ASUF="ac3"
138
-VSUF="m2v"
139
-FPS="2997"
140
-MPEG2ENC_FMT="-f 8"
141
-MPLEX_OPTS="-V"
142
-MPEG2ENC_SYS="-F 4 -n n"
143
-# Figure out what version of ppmtoy4m is in use;
144
-# mjpegtools 1.6.2 seems to require 420_mpeg2
145
-if mplex 2>&1 | grep -q "version 1.6.2"; then
146
-    CHROMA_MODE="420_mpeg2"
147
-else
148
-    CHROMA_MODE="420mpeg2"
149
-fi
150
-IM_VERSION=$(convert -list configure | awk '/LIB_VERSION_NUMBER/ {print $2}')
151
-if test_version $IM_VERSION 6.3.5.7; then
152
-    IM_LISTARG='font'
153
-else
154
-    IM_LISTARG='type'
155
-fi
156
-# imagemagick's font listing structure depends on version
157
-if test_version $IM_VERSION 6.4.0.0; then
158
-    im_field=2
159
-else
160
-    im_field=1
161
-fi
162
-PPM_OPTS="-S $CHROMA_MODE -A 10:11 -F 30000:1001"
163
-# Direct stuff to /dev/null
164
-REDIR="/dev/null"
165
-# Not doing debugging
166
-DEBUG=false
167
-QUIET=false
168
-# Don't overwrite output files
169
-OVERWRITE=false
170
-OUT_PREFIX=""
171
-LOG_FILE="makemenu.log"
172
-NOASK=false
173
-# How far to space titles and buttons
174
-TITLE_BOTTOM_SPACE=12
175
-TITLE_LEFT_SPACE=10
176
-
177
-
178
-# =========================================================================\
179
-# E X E C U T I O N   B E G I N S   H E R E
180
-#
181
-#
182
-
183
-echo "$SCRIPT_NAME"
184
-
185
-assert_dep "$magick" "You are missing dependencies required for making menus!"
186
-
187
-# Process all options
188
-while test $# -gt 0; do
189
-    case "$1" in
190
-        "-ntsc" | "-ntscfilm" )
191
-            TVSYS="ntsc"
192
-            MPEG2ENC_SYS="-F 4 -n n"
193
-            PPM_OPTS="-S $CHROMA_MODE -A 10:11 -F 30000:1001"
194
-            FPS="2997"
195
-            ;;
196
-        "-pal" )
197
-            TVSYS="pal"
198
-            MPEG2ENC_SYS="-F 3 -n p"
199
-            PPM_OPTS="-S $CHROMA_MODE -A 59:54 -F 25:1"
200
-            FPS="2500"
201
-            ;;
202
-        "-dvd" )
203
-            RES="dvd"
204
-            MPEG2ENC_FMT="-f 8"
205
-            # Variable bitrate
206
-            MPLEX_OPTS="-V"
207
-            VSUF="m2v"
208
-            ;;
209
-        "-vcd" )
210
-            RES="vcd"
211
-            MPEG2ENC_FMT="-f 1"
212
-            # Constant bitrate
213
-            MPLEX_OPTS=""
214
-            VSUF="m1v"
215
-            ;;
216
-        "-svcd" )
217
-            RES="vcd"
218
-            MPEG2ENC_FMT="-f 4"
219
-            # Variable bitrate
220
-            MPLEX_OPTS="-V"
221
-            VSUF="m2v"
222
-            ;;
223
-        "-audio" )
224
-            shift
225
-            # Make sure file exists
226
-            if test -f "$1"; then
227
-                BG_AUDIO=$1
228
-            else
229
-                usage_error "Can't find background audio file: $1"
230
-            fi
231
-            ;;
232
-        "-background" )
233
-            shift
234
-            # Make sure file exists
235
-            if test -f "$1"; then
236
-                BG_IMAGE=$1
237
-            else
238
-                usage_error "Can't find background image file: $1"
239
-            fi
240
-            ;;
241
-        "-overwrite" ) OVERWRITE=: ;;
242
-        "-crop" ) SCALECROP="crop" ;;
243
-        "-scale" ) SCALECROP="scale" ;;
244
-        "-nosafearea" ) SAFE_AREA=false ;;
245
-        "-font" )
246
-            shift
247
-            TITLE_FONT="$1"
248
-            ;;
249
-        "-fontsize" )
250
-            shift
251
-            TITLE_SIZE="$1"
252
-            ;;
253
-        "-fontdeco" )
254
-            shift
255
-            FONT_DECO="$1"
256
-            ;;
257
-        "-textcolor" )
258
-            shift
259
-            TEXT_COLOR="$1"
260
-            ;;
261
-        "-highlightcolor" )
262
-            shift
263
-            HIGHLIGHT_COLOR="$1"
264
-            ;;
265
-        "-selectcolor" )
266
-            shift
267
-            SELECT_COLOR="$1"
268
-            ;;
269
-        "-align" )
270
-            shift
271
-            case "$1" in
272
-                "left" ) TEXT_ALIGN="northwest" ;;
273
-                "right" ) TEXT_ALIGN="northeast" ;;
274
-                "center" ) TEXT_ALIGN="north" ;;
275
-                "middle" ) TEXT_ALIGN="center" ;;
276
-                * ) TEXT_ALIGN=$(echo "$1" | tr A-Z a-z)
277
-            esac
278
-            ;;
279
-        "-button" )
280
-            shift
281
-            case "$1" in
282
-                "play" )
283
-                    BUTTON_FONT="Webdings"
284
-                    BUTTON_CHAR=4
285
-                    ;;
286
-                "movie" )
287
-                    BUTTON_FONT="Webdings"
288
-                    OFFICIAL_PRINTF=$(which printf)
289
-                    BUTTON_CHAR=$($OFFICIAL_PRINTF '\u00b8')
290
-                    ;;
291
-                "utf8" )
292
-                    shift
293
-                    OFFICIAL_PRINTF=$(which printf)
294
-                    BUTTON_CHAR=$($OFFICIAL_PRINTF "\u$1")
295
-                    ;;
296
-                * )
297
-                    BUTTON_CHAR="$1"
298
-                    if test $(echo -n "$BUTTON_CHAR" | wc -c ) -ne 1; then
299
-                        usage_error "Buttons must have only _one_ characater."
300
-                    fi
301
-                    ;;
302
-            esac
303
-            ;;
304
-        "-debug" )
305
-            DEBUG=:
306
-            REDIR="$LOG_FILE"
307
-            ;;
308
-        "-quiet" )
309
-            QUIET=:
310
-            ;;
311
-        "-out" )
312
-            shift
313
-            OUT_PREFIX="$1"
314
-            ;;
315
-        "-noask" ) NOASK=: ;;
316
-        "-button-outline" )
317
-            shift
318
-            BTN_STROKE="$1"
319
-            ;;
320
-        "-button-font" )
321
-            shift
322
-            BUTTON_FONT="$1"
323
-            ;;
324
-        "-menu-title" )
325
-            shift
326
-            MENU_TITLE="$1"
327
-            MAKE_TITLE=:
328
-            ;;
329
-        "-menu-title-fontsize" )
330
-            shift
331
-            MENU_TITLE_SIZE="$1"
332
-            ;;
333
-        "-length" )
334
-            shift
335
-            MENU_LENGTH="-t $1"
336
-            ;;
337
-        # Assume anything in quotes is a video title
338
-        ""*"" )
339
-            TITLES=("${TITLES[@]}" "$1")
340
-            ;;
341
-        * )
342
-            test -n "$1" && usage_error "Unrecognized command-line option: $1"
343
-            ;;
344
-    esac
345
-
346
-    # Get the next argument
347
-    shift
348
-done
349
-
350
-NUM_TITLES=${#TITLES[@]}
351
-# If no titles were provided, exit with error
352
-if test $NUM_TITLES -eq 0; then
353
-    usage_error "Please provide at least one title string, enclosed in double-quotes."
354
-fi
355
-
356
-# If output prefix was not provided, exit with error
357
-if test -z "$OUT_PREFIX"; then
358
-    usage_error "Please provide an output prefix with the -out option."
359
-fi
360
-
361
-# Make sure we're not overwriting an existing menu
362
-if test -f "$OUT_PREFIX.mpg"; then
363
-    if $OVERWRITE; then
364
-        rm -f "$OUT_PREFIX.mpg"
365
-    else
366
-        echo "There is already a file named \"$OUT_PREFIX.mpg\" in this directory!"
367
-        echo "Use '-overwrite' to replace this file. (tovid menu -overwrite ...)"
368
-        echo "Exiting..."
369
-        exit 1
370
-    fi
371
-fi
372
-
373
-
374
-OUT_FILENAME="$OUT_PREFIX.mpg"
375
-# Temporary directory named after the given -out prefix
376
-OUTNAME=$(basename "$OUT_PREFIX")
377
-TMP_DIR=$(tempdir "$WORKING_DIR/$OUTNAME")
378
-$DEBUG && echo "Storing temporary files in $TMP_DIR"
379
-BG_CANVAS="$TMP_DIR/bg_canvas.png"
380
-MENU_PPM="$TMP_DIR/menu.ppm"
381
-MENU_MPEG="$TMP_DIR/menu.mpg"
382
-SPUMUX_XML="$TMP_DIR/menu_buttons.xml"
383
-
384
-SELECT_PNG="$TMP_DIR/select.png"
385
-HIGHLIGHT_PNG="$TMP_DIR/highlight.png"
386
-TILE_CANVAS="$TMP_DIR/00_tile_canvas.png"
387
-BUTTON_PAD="$TMP_DIR/00_button_pad.png"
388
-BUTTON_PLACEHOLDER="$TMP_DIR/00_button-placeholder.png"
389
-HIGHLIGHT_BUTTON="$TMP_DIR/00_highlight-button.png"
390
-SELECT_BUTTON="$TMP_DIR/00_select-button.png"
391
-HIGHLIGHT_TEXT="$TMP_DIR/02_highlight-text.png"
392
-MENU_TEXT="$TMP_DIR/02_menu-text.png"
393
-SAFETY_CANVAS="$TMP_DIR/02_safety-canvas.png"
394
-SELECT_TEXT="$TMP_DIR/02_select-text.png"
395
-ACTIVE_TEXT="$TMP_DIR/03_active-text.png"
396
-ACTIVE_HIGHLIGHT="$TMP_DIR/03_active-highlight.png"
397
-ACTIVE_SELECT="$TMP_DIR/03_active-select.png"
398
-MENU_TITLE_TEXT="$TMP_DIR/02_menu-title.png"
399
-MENU_TITLE_PLACEHOLDER="$TMP_DIR/02_menu-title-placeholder.png"
400
-
401
-# Use appropriate settings for DVD
402
-if test $RES = "dvd"; then
403
-    assert_dep "$dvd" "You are missing dependencies required for making DVD menus!"
404
-    WIDTH="720"
405
-    SAMPRATE="48000"
406
-    test $TVSYS = "ntsc" && HEIGHT="480"
407
-    test $TVSYS = "pal" && HEIGHT="576"
408
-# And for (S)VCD
409
-else
410
-    WIDTH="352"
411
-    SAMPRATE="44100"
412
-    test $TVSYS = "ntsc" && HEIGHT="240"
413
-    test $TVSYS = "pal" && HEIGHT="288"
414
-    # Reduce font size and spacing
415
-    TITLE_SIZE=$(expr $TITLE_SIZE \/ 2)
416
-fi
417
-
418
-# Set audio stream format
419
-if test "$RES" = "dvd"; then
420
-    ASUF="ac3"
421
-else
422
-    ASUF="mp2"
423
-fi
424
-VIDEO_STREAM="$TMP_DIR/video.$VSUF"
425
-AUDIO_STREAM="$TMP_DIR/audio.$ASUF"
426
-
427
-# Make sure there are 9 or fewer titles for VCD and 36 or fewere for DVD
428
-if test "$RES" = "vcd" && test "$NUM_TITLES" -gt $MAX_VCD_TITLES; then
429
-    OVER_MAX_TITLES=:
430
-    DISC_TYPE="(S)VCD"
431
-    MAX_TITLES=$MAX_VCD_TITLES
432
-elif test "$RES" = "dvd" && test "$NUM_TITLES" -gt $MAX_DVD_TITLES; then
433
-    OVER_MAX_TITLES=:
434
-    DISC_TYPE="DVD"
435
-    MAX_TITLES=$MAX_DVD_TITLES
436
-fi
437
-if $OVER_MAX_TITLES; then
438
-    echo $SEPARATOR
439
-    echo "I read $NUM_TITLES titles for your $DISC_TYPE menu, which is more than the maximum number"
440
-    echo "of titles allowed on one menu for ${DISC_TYPE}s ($MAX_TITLES is the limit)."
441
-    echo "Please try using fewer titles on this menu."
442
-    cleanup
443
-    exit 1
444
-fi
445
-
446
-# Use a foreground canvas the size of the background minus safe area
447
-if $SAFE_AREA; then
448
-    FG_WIDTH=$(expr $WIDTH \* 4 \/ 5)
449
-    FG_HEIGHT=$(expr $HEIGHT \* 4 \/ 5)
450
-else
451
-    FG_WIDTH=$(expr $WIDTH \- 10)
452
-    FG_HEIGHT=$(expr $HEIGHT \- 10)
453
-fi
454
-
455
-# If no button font was given with -button-font, default to the title font
456
-if test -z "$BUTTON_FONT"; then
457
-    BUTTON_FONT=$TITLE_FONT
458
-fi
459
-
460
-# Confirm the title font, or use a similar one
461
-if test -s "$TITLE_FONT"; then
462
-    # Using ttf font file for ImageMagick
463
-    USE_TITLE_FONT="$TITLE_FONT"
464
-else
465
-    # Check to see if the given font name is available in ImageMagick
466
-    # (only return the first exact match)
467
-    USE_TITLE_FONT=$( convert -list $IM_LISTARG | \
468
-    grep -m 1 "$TITLE_FONT" | awk -v f=$im_field '{print $f}' )
469
-
470
-   # If not available, try to use something similar
471
-    if test -z $USE_TITLE_FONT ; then
472
-        echo $SEPARATOR
473
-        echo "Font: \"$TITLE_FONT\" does not appear to be either a font file or registered with ImageMagick."
474
-        USE_TITLE_FONT=$( convert -list $IM_LISTARG | \
475
-        grep -i -m 1 "${TITLE_FONT:0:20}" | awk -v f=$im_field '{print $f}' )
476
-
477
-        # If a similarly-named one does't exist, default to Helvetica
478
-        if test -z "$USE_TITLE_FONT"; then
479
-            echo "A similarly-named font was not found. Sorry!"
480
-            USE_TITLE_FONT="Helvetica"
481
-        fi
482
-        echo "The font \"$USE_TITLE_FONT\" will be used instead."
483
-        echo $SEPARATOR
484
-    fi
485
-fi
486
-
487
-# Set the title font with the one that was found/compatible
488
-TITLE_FONT="$USE_TITLE_FONT"
489
-
490
-# Confirm the button font and button's existance in the font
491
-if test $RES = 'dvd'; then
492
-    # Confirm the button font, or use a similar one
493
-    if test -s "$BUTTON_FONT"; then
494
-        # Using ttf font file for ImageMagick
495
-        USE_BUTTON_FONT="$BUTTON_FONT"
496
-    else
497
-        # Check to see if the given button font is available in ImageMagick
498
-        # (only return the first exact match)
499
-        USE_BUTTON_FONT=$( convert -list $IM_LISTARG | \
500
-        grep -m 1 "$BUTTON_FONT" | awk -v f=$im_field '{print $f}' )
501
-
502
-        # If not available, try to use something similar
503
-        if test -z $USE_BUTTON_FONT ; then
504
-            echo $SEPARATOR
505
-            echo "Button: \"$BUTTON_FONT\" does not appear to be either a font file or registered with ImageMagick."
506
-            USE_BUTTON_FONT=$( convert -list $IM_LISTARG | \
507
-            grep -i -m 1 "${BUTTON_FONT:0:20}" | awk -v f=$im_field '{print $f}' )
508
-
509
-            # If a similarly-named one does't exist, default to Helvetica
510
-            if test -z "$USE_BUTTON_FONT"; then
511
-                echo "A similarly-named font was not found. Sorry!"
512
-                USE_BUTTON_FONT="$TITLE_FONT"
513
-            fi
514
-            echo "The font \"$USE_BUTTON_FONT\" will be used instead."
515
-        echo $SEPARATOR
516
-        fi
517
-    fi
518
-
519
-# Confirm that the button character exists in the font
520
-    if convert -size 720x200 xc:none -fill white \
521
-        -font $USE_BUTTON_FONT -pointsize $TITLE_SIZE -weight bold \
522
-        +antialias -annotate +20+80 "$BUTTON_CHAR" -trim +repage \
523
-        -bordercolor none -border 10 info: >> /dev/null 2>&1; then :
524
-    else
525
-        echo $SEPARATOR
526
-        echo "The button \"$BUTTON_CHAR\" doesn't exist in \"$USE_BUTTON_FONT\""
527
-        USE_BUTTON_FONT="$TITLE_FONT"
528
-        echo "The font \"$USE_BUTTON_FONT\" will be used instead."
529
-        echo $SEPARATOR
530
-    fi
531
-fi
532
-
533
-# Set the button font with the one that was found/compatible
534
-BUTTON_FONT="$USE_BUTTON_FONT"
535
-
536
-# ==========================================================================\
537
-# M E N U   D R A W I N G
538
-#
539
-#
540
-
541
-# Measure the font's vertical height
542
-TILE_HEIGHT=$(convert -format %h -size 720x200 xc:none -fill white -pointsize $TITLE_SIZE -font $TITLE_FONT -antialias $FONT_DECO -annotate +20+80 "Al" -trim +repage info:)
543
-
544
-let "TILE_HEIGHT=TILE_HEIGHT+TITLE_BOTTOM_SPACE"
545
-
546
-# Make text 'tiles' for each title. These will be pieced together later on.
547
-echo "Adding $NUM_TITLES titles to the menu:"
548
-for ((i=0; i<$NUM_TITLES; i++)); do
549
-    SEQNUM=$(printf "%02d" ${i})
550
-    let "j=i+1"
551
-    echo "    $j: ${TITLES[i]}"
552
-    # Enumerate (S)VCD titles
553
-    if test $RES = "vcd" ; then
554
-        ENTRY="${j}. ${TITLES[i]}"
555
-
556
-        # Get the width of text and pad it
557
-        TILE_WIDTH=$(convert -format %w -size 720x200 xc:none -fill $TEXT_COLOR -pointsize $TITLE_SIZE -font $TITLE_FONT -antialias $FONT_DECO -annotate +20+80 "$ENTRY" -trim +repage info:)
558
-        let "TILE_WIDTH=TILE_WIDTH+TITLE_LEFT_SPACE"
559
-
560
-        # Draw the text, and put it on a blank tile
561
-        convert -size 720x100 xc:none -font $TITLE_FONT -antialias $FONT_DECO -fill $TEXT_COLOR -pointsize $TITLE_SIZE -annotate +20+80 "$ENTRY" -trim +repage "$TMP_DIR/01_entry-$SEQNUM.png"
562
-        convert -size ${TILE_WIDTH}x${TILE_HEIGHT} xc:none "$TILE_CANVAS"
563
-        composite -compose Over -gravity north "$TMP_DIR/01_entry-$SEQNUM.png" \
564
-            "$TILE_CANVAS" "$TMP_DIR/01_entry-$SEQNUM.png"
565
-
566
-    # Use a highlight cursor for DVD titles (drawn later, for now just text)
567
-    else
568
-        ENTRY="${TITLES[i]}"
569
-
570
-        # Get the width of the text and pad it
571
-        TILE_WIDTH=$(convert -format %w -size 720x200 xc:none -fill $TEXT_COLOR -pointsize $TITLE_SIZE -font $TITLE_FONT -antialias $FONT_DECO -annotate +20+80 "$ENTRY" -trim +repage info:)
572
-        let "TILE_WIDTH=TILE_WIDTH+TITLE_LEFT_SPACE"
573
-
574
-        # Draw the text, and put it on a blank tile
575
-        convert -size 720x100 xc:none -font $TITLE_FONT -antialias $FONT_DECO -fill $TEXT_COLOR -pointsize $TITLE_SIZE -annotate +20+80 "$ENTRY" -trim +repage "$TMP_DIR/00_title-$SEQNUM.png"
576
-        convert -size ${TILE_WIDTH}x${TILE_HEIGHT} xc:none "$TILE_CANVAS"
577
-        composite -compose Over -gravity northeast \
578
-            "$TMP_DIR/00_title-$SEQNUM.png" "$TILE_CANVAS" \
579
-            "$TMP_DIR/00_title-$SEQNUM.png"
580
-
581
-        # Blank placeholder: no font decorations or color
582
-        DIMS=$(identify "$TMP_DIR/00_title-$SEQNUM.png" | grep -o -e " [0-9]\{1,\}x[0-9]\{1,\} " | tr -d ' ')
583
-        convert \
584
-            -size $DIMS xc:none "$TMP_DIR/00_title-${SEQNUM}_placeholder.png"
585
-    fi
586
-done
587
-
588
-# Finish DVD menu entries (all we have so far is text, no buttons!)
589
-if test $RES = "dvd"; then
590
-    echo "Making the DVD buttons...   "
591
-
592
-    # Get the dimensions of the button
593
-    TILE_WIDTH=$(convert -format %w -size 720x200 xc:none -fill white -stroke $BTN_STROKE -strokewidth 1 -pointsize $TITLE_SIZE -font $BUTTON_FONT +antialias -weight bold -annotate +20+80 "$BUTTON_CHAR" -trim +repage info:)
594
-    BUTTON_HEIGHT=$(convert -format %w -size 720x200 xc:none -fill white -stroke $BTN_STROKE -strokewidth 1 -pointsize $TITLE_SIZE -font $BUTTON_FONT +antialias -weight bold -annotate +20+80 "$BUTTON_CHAR" -trim +repage info:)
595
-    # Find how much to pad the top of the button and make the pad
596
-    let "BUTTON_PADDING=(TILE_HEIGHT-BUTTON_HEIGHT-TITLE_BOTTOM_SPACE)/2"
597
-    convert -size ${TILE_WIDTH}x${BUTTON_PADDING} xc:none "$BUTTON_PAD"
598
-
599
-    # Draw the buttons
600
-    convert -size 720x100 xc:none -font $BUTTON_FONT -stroke $BTN_STROKE -strokewidth 1 +antialias -weight bold -fill $HIGHLIGHT_COLOR -pointsize $TITLE_SIZE -annotate +20+80 "$BUTTON_CHAR" -trim +repage "$HIGHLIGHT_BUTTON"
601
-    convert -size 720x100 xc:none -font $BUTTON_FONT -stroke $BTN_STROKE -strokewidth 1 +antialias -weight bold -fill $SELECT_COLOR -pointsize $TITLE_SIZE -annotate +20+80 "$BUTTON_CHAR" -trim +repage "$SELECT_BUTTON"
602
-
603
-    # Pad the buttons so that they line up with the font's baseline
604
-    convert -background none "$BUTTON_PAD" "$HIGHLIGHT_BUTTON" -append \
605
-        "$HIGHLIGHT_BUTTON"
606
-    convert -background none "$BUTTON_PAD" "$SELECT_BUTTON" -append \
607
-        "$SELECT_BUTTON"
608
-
609
-    # Make a blank button tile according to measured dimensions
610
-    convert -size ${TILE_WIDTH}x${TILE_HEIGHT} xc:none "$TILE_CANVAS"
611
-
612
-    # Put padded buttons on the blank tile
613
-    composite -compose Over -gravity north "$HIGHLIGHT_BUTTON" \
614
-        "$TILE_CANVAS" "$HIGHLIGHT_BUTTON"
615
-    composite -compose Over -gravity north "$SELECT_BUTTON" \
616
-        "$TILE_CANVAS" "$SELECT_BUTTON"
617
-
618
-    # A placeholder to space the title text correctly
619
-    DIMS=$(identify "$HIGHLIGHT_BUTTON" | grep -o -e " [0-9]\{1,\}x[0-9]\{1,\} " | tr -d ' ')
620
-    convert -size $DIMS xc:none "$BUTTON_PLACEHOLDER"
621
-
622
-    # Next, join the button tiles with the title tiles:
623
-    i=0
624
-    while test $i -lt $NUM_TITLES; do
625
-        SEQNUM=$(printf "%02d" $i)
626
-        # Text entries
627
-        convert -background none "$BUTTON_PLACEHOLDER" \
628
-            "$TMP_DIR/00_title-$SEQNUM.png" +append \
629
-            "$TMP_DIR/01_entry-$SEQNUM.png"
630
-        # Highlight entries
631
-        convert -background none "$HIGHLIGHT_BUTTON" \
632
-            "$TMP_DIR/00_title-${SEQNUM}_placeholder.png" \
633
-            +append "$TMP_DIR/01_highlight_entry-$SEQNUM.png"
634
-        # Select entries
635
-        convert -background none "$SELECT_BUTTON" \
636
-            "$TMP_DIR/00_title-${SEQNUM}_placeholder.png" \
637
-            +append "$TMP_DIR/01_select_entry-$SEQNUM.png"
638
-        let "i=i+1"
639
-    done
640
-fi
641
-
642
-# Stack all 01_entry-N.png lines
643
-echo "Creating the text menu...   "
644
-convert -background none "$TMP_DIR/01_entry-*.png" -append "$MENU_TEXT"
645
-
646
-# Stack all DVD button lines
647
-if test $RES = "dvd"; then
648
-echo "Creating the DVD button overlays...   "
649
-    convert -background none "$TMP_DIR/01_highlight_entry-*.png" -append \
650
-        "$HIGHLIGHT_TEXT"
651
-    convert -background none "$TMP_DIR/01_select_entry-*.png" -append \
652
-        "$SELECT_TEXT"
653
-fi
654
-
655
-# If specified, add a menu title
656
-if $MAKE_TITLE; then
657
-    echo "Adding the menu title..."
658
-
659
-    # Default title font size = current text size + 4
660
-    if test -z "$MENU_TITLE_SIZE"; then
661
-        let "MENU_TITLE_SIZE=TITLE_SIZE+8"
662
-    fi
663
-
664
-    # Calculate number of \n characters in title, so menu title height
665
-    # will be set correctly
666
-    TITLE_LINES=$(echo "$MENU_TITLE" | sed 's/!//g;s/\\n/!/g;s/[^!]//g' | wc -c)
667
-    TITLE_HEIGHT=$((100 * $TITLE_LINES))
668
-
669
-    # Draw the menu title and pad the bottom with TILE_HEIGHT pixels
670
-    convert -size 720x$TITLE_HEIGHT xc:none -font $TITLE_FONT -antialias $FONT_DECO -fill $TEXT_COLOR -pointsize $MENU_TITLE_SIZE -annotate +20+80 "$MENU_TITLE" -trim +repage "$MENU_TITLE_TEXT"
671
-
672
-    convert "$MENU_TITLE_TEXT" -gravity south -background none -splice 0x$TILE_HEIGHT "$MENU_TITLE_TEXT"
673
-
674
-    # Put the menu title above the menu text (and buttons for DVDs)
675
-    convert -background none "$MENU_TITLE_TEXT" "$MENU_TEXT" -append \
676
-        "$MENU_TEXT"
677
-    if test $RES = "dvd"; then
678
-        # DVD menus need an empty placeholder for the buttons
679
-        DIMS=$(identify "$MENU_TITLE_TEXT" | grep -o -e " [0-9]\{1,\}x[0-9]\{1,\} " | tr -d ' ')
680
-        convert -size $DIMS xc:none "$MENU_TITLE_PLACEHOLDER"
681
-        convert -background none "$MENU_TITLE_PLACEHOLDER" "$HIGHLIGHT_TEXT" \
682
-            -append "$HIGHLIGHT_TEXT"
683
-        convert -background none "$MENU_TITLE_PLACEHOLDER" "$SELECT_TEXT" \
684
-            -append "$SELECT_TEXT"
685
-    fi
686
-
687
-fi
688
-
689
-# Put the text menus inside the safety area
690
-if $SAFE_AREA; then FRAME_TYPE="safe area"; else FRAME_TYPE="frame"; fi
691
-echo "Placing text menu in the $FRAME_TYPE...   "
692
-convert -size ${FG_WIDTH}x${FG_HEIGHT} xc:none "$SAFETY_CANVAS"
693
-composite -compose Over -gravity $TEXT_ALIGN \
694
-    "$MENU_TEXT" "$SAFETY_CANVAS" "$ACTIVE_TEXT"
695
-
696
-# Same for DVD buttons: into the safety area
697
-if test $RES = 'dvd'; then
698
-    echo "Placing DVD buttons in the $FRAME_TYPE...   "
699
-    composite -compose Over -gravity $TEXT_ALIGN \
700
-        "$HIGHLIGHT_TEXT" "$SAFETY_CANVAS" "$ACTIVE_HIGHLIGHT"
701
-    composite -compose Over -gravity $TEXT_ALIGN \
702
-        "$SELECT_TEXT" "$SAFETY_CANVAS" "$ACTIVE_SELECT"
703
-fi
704
-
705
-# Background image:
706
-# If none was provided, create a default one (blue-black gradient)
707
-if test -z "$BG_IMAGE"; then
708
-    BG_CMD="convert -size ${WIDTH}x${HEIGHT} gradient:blue-black \
709
-        -gravity center -matte \"$BG_CANVAS\""
710
-# Otherwise, scale/crop the provided image
711
-else
712
-    if test "$SCALECROP" = "crop"; then
713
-        SCALECROP="-resize ${WIDTH}x -resize \"x${HEIGHT}<\" -gravity center \
714
-            -crop ${WIDTH}x${HEIGHT}+0+0"
715
-    else
716
-        SCALECROP="-resize ${WIDTH}x${HEIGHT}!"
717
-    fi
718
-        BG_CMD="convert \"$BG_IMAGE\" $SCALECROP -matte \"$BG_CANVAS\""
719
-fi
720
-echo "Working on the background...   "
721
-$DEBUG && echo -e "\n\nBackground:\n$BG_CMD" >> $REDIR
722
-eval $BG_CMD
723
-
724
-# Put menu text over the background image
725
-MAGICK_CMD="composite -compose Over -gravity center \
726
-    \"$ACTIVE_TEXT\" \"$BG_CANVAS\" -depth 8 \"$MENU_PPM\""
727
-echo "Centering the $FRAME_TYPE over the background...   "
728
-$DEBUG && echo -e "\n\nMenu Text:\n$MAGICK_CMD" >> $REDIR
729
-eval $MAGICK_CMD
730
-
731
-# Same for DVDs
732
-if test $RES = 'dvd'; then
733
-    echo "Positioning the DVD button overlays on the background...   "
734
-    composite -compose Src -gravity center \
735
-        "$ACTIVE_HIGHLIGHT" "$BG_CANVAS" "$HIGHLIGHT_PNG"
736
-    composite -compose Src -gravity center \
737
-        "$ACTIVE_SELECT" "$BG_CANVAS" "$SELECT_PNG"
738
-fi
739
-
740
-
741
-# ======================================================================\
742
-# P R E V I E W   &   F I N I S H
743
-#
744
-#
745
-
746
-if ! $NOASK; then
747
-    echo "Generating preview..."
748
-    echo "Type 'q' to close the preview window."
749
-    if test "$RES" = vcd; then
750
-        display "$MENU_PPM"
751
-    else
752
-        composite -compose Over -gravity center "$HIGHLIGHT_PNG" \
753
-            "$MENU_PPM" miff: | display
754
-    fi
755
-    wait
756
-    echo -n "Was the preview ok [y/N]?  "
757
-    ANSWER="N"
758
-    read ANSWER
759
-    if ! ( test "$ANSWER" = "y" || test "$ANSWER" = "Y" ); then
760
-        echo "Preview was not OK, exiting..."
761
-        cleanup
762
-        echo
763
-        echo "Try:  -font FONT -fontsize NUM -textcolor '#RGB'"
764
-        echo "      -fontdeco 'ImageMagick instr' -align left|center|right"
765
-        echo "      -background IMAGE -audio AUDIOFILE"
766
-        echo "to change the appearance. More in 'man tovid'"
767
-        exit 0
768
-    else
769
-        echo "Preview was OK. Continuing..."
770
-    fi
771
-fi
772
-
773
-# Background audio:
774
-# If no background audio was provided, generate 4 seconds of silence
775
-if test -z "$BG_AUDIO"; then
776
-    if test -z "$MENU_LENGTH"; then
777
-        MENU_LENGTH="-t 4"
778
-    fi
779
-    echo "Creating $(echo "$MENU_LENGTH" | cut -c 4-)-second silent $ASUF audio...   "
780
-    AUDIO_CMD="ffmpeg -f s16le -i /dev/zero -ac 2 -ar $SAMPRATE -ab 224k \
781
-        $MENU_LENGTH -acodec $ASUF -y \"$AUDIO_STREAM\""
782
-    $DEBUG && echo -e "\n\nBG audio:\n$AUDIO_CMD" >> $REDIR
783
-    eval $AUDIO_CMD >> $REDIR 2>&1
784
-# Otherwise, convert provided audio to the target format
785
-else
786
-    echo "Converting \"$BG_AUDIO\" to $ASUF...   "
787
-    AUDIO_CMD="ffmpeg -i \"$BG_AUDIO\" -ac 2 -ar $SAMPRATE -ab 224k \
788
-        $MENU_LENGTH -acodec $ASUF -y \"$AUDIO_STREAM\""
789
-    $DEBUG && echo -e "\n\nBG audio:\n$AUDIO_CMD" >> $REDIR
790
-    eval $AUDIO_CMD >> $REDIR 2>&1
791
-fi
792
-
793
-# Calculate video length from length of audio
794
-VID_LENGTH=$(mplayer -quiet -nomsgcolor -identify -frames 0 -vo null -ao null \
795
-    "$AUDIO_STREAM" 2>&1 | grep '^ID_LENGTH' | awk -F '=' '{print $2}' | \
796
-    sed -e "s/\.[0-9]*//g")
797
-VID_LENGTH=$(expr "$VID_LENGTH" \* $FPS \/ 100)
798
-
799
-# Make sure VID_LENGTH is nonzero
800
-if test "$VID_LENGTH" -eq 0 ; then
801
-    # Use 30 seconds as a sensible default
802
-    VID_LENGTH=$(expr 30 \* $FPS \/ 100)
803
-fi
804
-
805
-# Make video of specified length from PPM background image
806
-echo "Converting menu image to video. This may take a while...   "
807
-VIDEO_CMD="ppmtoy4m $PPM_OPTS -n $VID_LENGTH -r \"$MENU_PPM\" 2>>$REDIR | \
808
-  mpeg2enc -a 2 $MPEG2ENC_FMT $MPEG2ENC_SYS -o \"$VIDEO_STREAM\" >> $REDIR 2>&1"
809
-$DEBUG && echo -e "\n\nTo mpeg:\n$VIDEO_CMD" >> $REDIR
810
-eval $VIDEO_CMD
811
-
812
-# Multiplex audio and video
813
-echo "Multiplexing video and audio streams...   "
814
-MPLEX_CMD="mplex $MPLEX_OPTS $MPEG2ENC_FMT -o \"$MENU_MPEG\" \
815
-  \"$VIDEO_STREAM\" \"$AUDIO_STREAM\" >> $REDIR 2>&1"
816
-$DEBUG && echo -e "\n\nMux:\n$MPLEX_CMD" >> $REDIR
817
-eval $MPLEX_CMD
818
-
819
-# For DVD, create spumux XML
820
-if test "$RES" = "dvd"; then
821
-
822
-(cat << EOF
823
-<subpictures>
824
-  <stream>
825
-  <spu force="yes" start="00:00:00.00"
826
-       highlight="$HIGHLIGHT_PNG"
827
-       select="$SELECT_PNG"
828
-       autooutline="infer">
829
-  </spu>
830
-  </stream>
831
-</subpictures>
832
-EOF
833
-) > "$SPUMUX_XML"
834
-    wait
835
-    SPUMUX_CMD="spumux \"$SPUMUX_XML\" < \"$MENU_MPEG\" > \"$OUT_FILENAME\" 2>>$REDIR"
836
-    echo "Adding the DVD buttons to menu...   "
837
-    $DEBUG && echo -e "\n\nSpumux buttons:\n$SPUMUX_CMD" >> $REDIR
838
-    eval $SPUMUX_CMD
839
-
840
-# Rename the output menu for VCD and SVCD
841
-else
842
-    mv "$MENU_MPEG" "$OUT_FILENAME"
843
-fi
844
-
845
-cleanup
846
-
847
-echo $SEPARATOR
848
-if test -s "$OUT_FILENAME"; then
849
-    if ! $QUIET; then
850
-        echo "Finished! Your menu should be in the file \"$OUT_FILENAME\"."
851
-        if test "$RES" = "vcd"; then
852
-            echo "You can use this menu on an SVCD or VCD disc with:"
853
-            echo
854
-            echo "  tovid xml -vcd -menu \"$OUT_FILENAME\" <title 1> <title 2> ... \\"
855
-            echo "          <output name>"
856
-        else
857
-            echo "You can use this menu on a DVD disc with:"
858
-            echo
859
-            echo "  tovid xml -dvd -menu \"$OUT_FILENAME\" <title 1> <title 2> ... \\"
860
-            echo "          -out <output name>"
861
-        fi
862
-
863
-        echo
864
-        echo "where <title N> is an MPEG video file corresponding to title N as listed"
865
-        echo "on your menu. Run tovid xml' without any options for more usage information."
866
-    else
867
-        echo "Done!"
868
-    fi
869
-else
870
-    echo "It looks like something went wrong, because there is no output file."
871
-    echo "Please submit a bug report to http://code.google.com/p/tovid/issues."
872
-    echo "Please add -debug to your command (tovid menu -debug ...) and post the"
873
-    echo "log file and terminal output. Sorry for the inconvenience."
874
-    exit 1
875
-fi
876
-
877
-$QUIET || echo $SEPARATOR
878
-$QUIET || echo "Thanks for using makemenu!"
879
-exit 0
880
tovid-0.34.tar.bz2/src/makevcd Deleted
232
 
1
@@ -1,230 +0,0 @@
2
-#!/usr/bin/env bash
3
-ME="[makevcd]:"
4
-. tovid-init 2>/dev/null ||
5
-{ echo -e "===============================================================\n"
6
-echo -e "'tovid-init' not found.  Was tovid improperly installed?"
7
-echo -e "Or are you trying to run the script directly?"
8
-echo -e "Please run makevcd as:\ntovid vcd OPTIONS"
9
-exit 1 ; }
10
-
11
-# makevcd
12
-# Part of the tovid suite
13
-# =======================
14
-# A bash script for creating a VCD cue/bin set and burning it
15
-# to a recordable CD.
16
-#
17
-# Project homepage: http://tovid.wikia.com
18
-#
19
-# Copyright (C) 2005-2010
20
-#
21
-# This program is free software; you can redistribute it and/or
22
-# modify it under the terms of the GNU General Public License
23
-# as published by the Free Software Foundation; either
24
-# version 2 of the License, or (at your option) any later
25
-# version.
26
-#
27
-# This program is distributed in the hope that it will be useful,
28
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
29
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30
-# GNU General Public License for more details.
31
-#
32
-# You should have received a copy of the GNU General Public License
33
-# along with this program; if not, write to the Free Software
34
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Or see:
35
-#
36
-#     http://www.gnu.org/licenses/gpl.txt
37
-
38
-SCRIPTNAME=`cat << EOF
39
---------------------------------
40
-tovid vcd
41
-Create cue/bin files for a (S)VCD and burn them to a CD
42
-Version $TOVID_VERSION
43
-$TOVID_HOME_PAGE
44
---------------------------------
45
-EOF`
46
-
47
-USAGE=`cat << EOF
48
-Usage: tovid vcd [OPTIONS] {VCDIMAGER.xml}
49
-
50
-Where OPTIONS may be any of the following:
51
-
52
-  -overwrite         Overwrite existing cue/bin image
53
-  -burn              (default only make image)
54
-  -device DEVICE     (default /dev/cdrw)
55
-  -speed NUM         (default 12)
56
-  -force             Add --force to cdrdao command (needed for short slides)
57
-
58
-And:
59
-
60
-  VCDIMAGER.xml is the name of a file containing a VCDImager XML
61
-      description (For XML format, see http://www.vcdimager.org/).
62
-      If you use(d) 'makexml' to create the XML file, you can use
63
-      that as input here.
64
-
65
-See the tovid manual page ('man tovid') for additional documentation.
66
-
67
-EOF`
68
-
69
-SEPARATOR="=========================================="
70
-
71
-# Print script name, usage notes, and optional error message, then exit.
72
-# Args: $1 == text string containing error message
73
-usage_error ()
74
-{
75
-  echo "$USAGE"
76
-  echo $SEPARATOR
77
-  echo "$@"
78
-  exit 1
79
-}
80
-
81
-# Print out a runtime error specified as an argument, and exit
82
-runtime_error ()
83
-{
84
-    killsubprocs
85
-    echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
86
-    echo "makevcd encountered an error during the VCD creation process:"
87
-    echo $@
88
-    echo "See if anything in the above output helps you diagnose the"
89
-    echo "problem, and please file a bug report containing the above"
90
-    echo "output to http://code.google.com/p/tovid/issues."
91
-    echo "Sorry for the inconvenience!"
92
-    echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
93
-    exit 1
94
-}
95
-# Defaults
96
-QUIET=false
97
-IMAGE=:
98
-CDRW_DEVICE="/dev/cdrw"
99
-BURN_SPEED=12
100
-OVERWRITE=false
101
-BURN=false
102
-
103
-# ==========================================================
104
-# EXECUTION BEGINS HERE
105
-echo $"$SCRIPTNAME"
106
-
107
-assert_dep "$vcd" "You are missing dependencies required to image and burn (S)VCDs!"
108
-
109
-# check for valid CD burner.  This may fail but at least we tried
110
-OIFS=$IFS \
111
-IFS=$'\n' device=($(find -L /dev -type b -name 'cdrw*' 2>/dev/null )) IFS=$OIFS
112
-CDRW_DEVICE=${device:-$CDRW_DEVICE}
113
-
114
-while test x"${1:0:1}" = "x-"; do
115
-    case "$1" in
116
-      "-quiet" ) QUIET=: ;;
117
-      "-overwrite" )
118
-        OVERWRITE=:
119
-        ;;
120
-      "-burn" )
121
-        BURN=:
122
-        ;;
123
-      "-device" )
124
-        shift
125
-        CDRW_DEVICE="$1"
126
-        ;;
127
-      "-speed" )
128
-        shift
129
-        BURN_SPEED=$1
130
-        ;;
131
-      "-force" )
132
-        FORCE="--force"
133
-        ;;
134
-      * )
135
-        usage_error "Error: Unrecognized command-line option $1"
136
-        ;;
137
-    esac
138
-
139
-    # Get next argument
140
-    shift
141
-done
142
-
143
-if test $# -ne 1; then
144
-    usage_error "Please provide the name of a VCDimager XML file \
145
-containing the (S)VCD description."
146
-else
147
-    # XML input is last argument
148
-    VCDIMAGER_XML="$1"
149
-fi
150
-
151
-# Look for earlier attempts to image this VCD
152
-for prev_try in "$VCDIMAGER_XML.cue" "$VCDIMAGER_XML.bin"; do
153
-    if test -f "$prev_try"; then
154
-        echo "Found a previous makevcd attempt: $prev_try!"
155
-        if $OVERWRITE; then
156
-            echo -n "Removing it...  "
157
-            rm -fv "$prev_try"
158
-        elif $BURN; then
159
-            echo "Will use this for burning the disc."
160
-            IMAGE=false
161
-        else
162
-            echo "Use '-overwrite' to override and re-image; or"
163
-            echo "use '-burn' to write this existing image."
164
-            echo "Exiting..."
165
-            exit 1
166
-        fi
167
-    fi
168
-done
169
-
170
-
171
-# Create the cue/bin image
172
-if $IMAGE; then
173
-    # TODO: Warn if there isn't enough space to make cue/bin
174
-    VCDIMAGER_CMD="vcdxbuild -c \"$VCDIMAGER_XML.cue\" -b \
175
-        \"$VCDIMAGER_XML.bin\" \"$VCDIMAGER_XML\""
176
-    echo $SEPARATOR
177
-    echo "Creating cue/bin disc image with the following command:"
178
-    echo $VCDIMAGER_CMD
179
-    if eval $VCDIMAGER_CMD; then
180
-        echo "Done."
181
-        $QUIET || echo "Use 'tovid vcd -burn $VCDIMAGER_XML' to burn your VCD."
182
-        $QUIET || echo "Thanks for using tovid!"
183
-    else
184
-        runtime_error "Imaging failed, please see vcdxbuild output above."
185
-    fi
186
-fi
187
-
188
-# Burn the VCD
189
-if $BURN; then
190
-    # Sanity check: Make sure given device is valid (somehow)
191
-    # before creating the cue/bin. Give option to proceed anyway?
192
-    # (i.e., could there be any point to proceeding?)
193
-    # Here's a simple way: just quit
194
-    if test -b $CDRW_DEVICE; then :
195
-       else
196
-       echo "Couldn't find $CDRW_DEVICE! Stopping here."
197
-       exit 1
198
-    fi
199
-
200
-    # Remind user to insert a CD
201
-    $QUIET || echo "Please insert a blank CD-R(W) disc into your CD-recorder"
202
-    $QUIET || echo "($CDRW_DEVICE) if you have not already done so."
203
-
204
-    # check for cdrw and blank if so
205
-    if cdrdao disk-info --device $CDRW_DEVICE --driver generic-mmc 2>&1 |
206
-    grep -q CD-RW.*yes; then
207
-    echo $SEPARATOR
208
-    echo "Found rewritable CD - starting to blank in 10 seconds - press ctrl-c to quit"
209
-    countdown 10
210
-        cdrdao blank --driver generic-mmc  $CDRW_DEVICE
211
-    fi
212
-    # Burn the disc
213
-    CDRDAO_CMD="cdrdao write --device $CDRW_DEVICE --driver generic-mmc \
214
-        --speed $BURN_SPEED $FORCE \"$VCDIMAGER_XML.cue\""
215
-    echo $SEPARATOR
216
-    echo "Burning cue/bin image to $CDRW_DEVICE with the following command:"
217
-    echo $CDRDAO_CMD
218
-    if eval $CDRDAO_CMD; then
219
-        if ! $QUIET; then
220
-            echo "Done. You should now have a working VCD or SVCD. Please report"
221
-            echo "any problems to http://code.google.com/p/tovid/issues."
222
-            echo "Thanks for using tovid!"
223
-        else
224
-            echo "Done."
225
-        fi
226
-    else
227
-        runtime_error "Could not burn the disc to $CDRW_DEVICE at speed $BURN_SPEED."
228
-    fi
229
-fi
230
-
231
-exit 0
232
tovid-0.34.tar.bz2/src/makexml Deleted
831
 
1
@@ -1,829 +0,0 @@
2
-#!/usr/bin/env bash
3
-ME="[makexml]:"
4
-. tovid-init 2>/dev/null ||
5
-{ echo -e "===============================================================\n"
6
-echo -e "'tovid-init' not found.  Was tovid improperly installed?"
7
-echo -e "Or are you trying to run the script directly?"
8
-echo -e "Please run makexml as:\ntovid xml OPTIONS"
9
-exit 1 ; }
10
-
11
-# makexml
12
-# Part of the tovid suite
13
-# =======================
14
-# This bash script generates XML output describing the structure of
15
-# a VCD, SVCD, or DVD disc. The resulting output can be given as input
16
-# to vcdxbuild or dvdauthor. Format, and a list of menus and
17
-# video files in MPEG format, are specified on the command-line, and
18
-# the resulting XML is written to the specified file. Currently
19
-# supports an optional top-level menu, any number of optional sub-menus,
20
-# and any number of videos reachable through those menus.
21
-#
22
-# Project homepage: http://tovid.wikia.com
23
-#
24
-# Copyright (C) 2005-2010
25
-#
26
-# This program is free software; you can redistribute it and/or
27
-# modify it under the terms of the GNU General Public License
28
-# as published by the Free Software Foundation; either
29
-# version 2 of the License, or (at your option) any later
30
-# version.
31
-#
32
-# This program is distributed in the hope that it will be useful,
33
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
34
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
35
-# GNU General Public License for more details.
36
-#
37
-# You should have received a copy of the GNU General Public License
38
-# along with this program; if not, write to the Free Software
39
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Or see:
40
-#
41
-#     http://www.gnu.org/licenses/gpl.txt
42
-
43
-SCRIPTNAME=`cat << EOF
44
---------------------------------
45
-tovid xml
46
-Generate XML for authoring a VCD, SVCD, or DVD.
47
-Version $TOVID_VERSION
48
-$TOVID_HOME_PAGE
49
---------------------------------
50
-EOF`
51
-
52
-USAGE=`cat << EOF
53
-Usage:  tovid xml [OPTIONS] {video1.mpg video2.mpg ...} -out OUT_PREFIX
54
-
55
-Common OPTIONS:
56
-
57
-    -dvd | -vcd | -svcd       Specify the target disc format
58
-    -overwrite                Overwrite any existing output files
59
-
60
-Provide a list of .mpg video files, and they will be played back in
61
-sequence. You may organize several lists of videos into menus by
62
-providing the name of a menu .mpg:
63
-
64
-    tovid xml -menu menu1.mpg \\\\
65
-        video1.mpg video2.mpg video3.mpg \\\\
66
-        -out mydisc
67
-    tovid xml -topmenu topmenu.mpg \\\\
68
-        -menu submenu1.mpg vid1.mpg vid2.mpg vid3.mpg \\\\
69
-        -menu submenu2.mpg vid4.mpg vid5.mpg vid6.mpg \\\\
70
-        -out mydisc2
71
-
72
-See the tovid manual page ('man tovid') for additional documentation.
73
-
74
-EOF`
75
-
76
-SEPARATOR="=========================================="
77
-
78
-# Print script name, usage notes, and optional error message, then exit.
79
-# Args: $1 == text string containing error message
80
-usage_error ()
81
-{
82
-  echo "$USAGE"
83
-  echo $SEPARATOR
84
-  echo "$@"
85
-  exit 1
86
-}
87
-
88
-QUIET=false
89
-# Currently-numbered titleset (must have at least 1 titleset)
90
-CUR_TS=1
91
-# Currently-numbered video title under a titleset menu (0 for no titles)
92
-CUR_TITLE=0
93
-# Do we have a top menu yet?
94
-HAVE_TOP_MENU=false
95
-# Do we have any menus yet?
96
-HAVE_MENU=false
97
-# Do not overwrite by default
98
-OVERWRITE=false
99
-# Use dvdauthor XML for DVD authoring
100
-XML_FORMAT="dvd"
101
-# No un-found files yet
102
-FILE_NOT_FOUND=false
103
-# Not doing still titles
104
-STILL_TITLES=false
105
-FIRST_TITLE=:
106
-# Avoid some unbound variables
107
-TOP_MENU_XML=""
108
-TOP_MENU_BUTTONS=""
109
-MENU_BUTTONS=""
110
-TS_TITLES=""
111
-ALL_MENU_XML=""
112
-SEGMENT_ITEMS_XML=""
113
-SEQUENCE_ITEMS_XML=""
114
-PBC_XML=""
115
-PLAYLIST_XML=""
116
-
117
-MAKE_GROUP=false
118
-MAKE_CHAPTERS=:
119
-FORCE_TITLESETS=false
120
-CUR_VIDEO=0
121
-CHAPTER_INTERVAL=5
122
-
123
-STANDARD=133
124
-WIDESCREEN=177
125
-NOPANSCAN=''
126
-TV_FORMAT=ntsc
127
-PAUSE=0
128
-
129
-# ==========================================================
130
-# Backslash-escape the given special character (and any EOLs)
131
-# Usage:
132
-#    sedprep "$TEXT" /
133
-#    echo $TEXT | sed "s/PATTERN/$(sedprep "$REPLACEMENT" /)/"
134
-function sedprep ()
135
-{
136
-    delim=${2:-/}
137
-    echo "$1" |sed -e 's/[\&'"$delim"']/\\&/g' -e '$!s,$,\\,';
138
-}
139
-
140
-# ==========================================================
141
-# Check for the existence of a file and print an error if it
142
-# does not exist in the current directory
143
-# Args: $1 = file to look for
144
-function checkExistence ()
145
-{
146
-    if test -e "$1"; then :
147
-    else
148
-        echo "The file "$1" was not found.  Exiting."
149
-        FILE_NOT_FOUND=:
150
-        exit 1
151
-    fi
152
-}
153
-
154
-# ==========================================================
155
-# Find a video's aspect ratio and set dvd behavior accordingly
156
-# Args: $1 = video file to find aspect for
157
-# Usage: noPanScan foo.avi
158
-# Sets NOPANSCAN to either: widescreen="nopanscan"
159
-#                       or: <null>
160
-function noPanScan ()
161
-{
162
-    ASPECT=$(idvid -fast -terse "$1" | grep "ASPECT" | awk -F '=' '{print $2}')
163
-    $QUIET || echo -n "    $1 has aspect $ASPECT "
164
-    if test $ASPECT -eq $WIDESCREEN; then
165
-        NOPANSCAN='widescreen="nopanscan"'
166
-        $QUIET || echo "(widescreen)."
167
-    else
168
-        NOPANSCAN=''
169
-        $QUIET || echo "(standard)."
170
-    fi
171
-
172
-}
173
-
174
-function getFormat ()
175
-{
176
-    # Set TV format - default is ntsc
177
-    VID_INFO=$(tovid id -fast -terse "$1")
178
-    grep -q PAL_DVD <<< "$VID_INFO" && TV_FORMAT=pal
179
-}
180
-
181
-# ==========================================================
182
-# Add a top-level VMGM menu to the DVD
183
-# Args: $1 = video file to use for top menu
184
-function addTopMenu ()
185
-{
186
-  HAVE_TOP_MENU=:
187
-  echo "Adding top-level menu using file: $1"
188
-
189
-  # --------------------------
190
-  # For DVD
191
-  if test $XML_FORMAT = "dvd"; then
192
-    # Set NOPANSCAN
193
-    noPanScan "$1"
194
-    # Generate XML for the top menu, with a placeholder for
195
-    # the titleset menu buttons (to be replaced later by sed)
196
-    TOP_MENU_XML=`cat << EOF
197
-  <menus>
198
-  <video $NOPANSCAN />
199
-  <pgc entry="title">
200
-  <vob file="$1" />
201
-__TOP_MENU_BUTTONS__
202
-  </pgc>
203
-  </menus>
204
-EOF`
205
-
206
-  # --------------------------
207
-  # For (S)VCD
208
-  else
209
-
210
-    # Generate XML for the segment-item
211
-    SEGMENT_ITEMS_XML=`cat << EOF
212
-$SEGMENT_ITEMS_XML
213
-  <segment-item src="$1" id="seg-top-menu"/>
214
-EOF`
215
-
216
-    # Generate XML for the selection to go in pbc
217
-    TOP_MENU_XML=`cat << EOF
218
-  <selection id="select-top-menu">
219
-    <bsn>1</bsn>
220
-    <loop jump-timing="immediate">0</loop>
221
-    <play-item ref="seg-top-menu"/>
222
-__TOP_MENU_BUTTONS__
223
-  </selection>
224
-EOF`
225
-
226
-  fi
227
-}
228
-
229
-# ==========================================================
230
-# Add a menu to the disc.
231
-# Args: $1 = video file to use for the menu
232
-function addMenu ()
233
-{
234
-  # --------------------------
235
-  # For DVD
236
-  if test $XML_FORMAT = "dvd"; then
237
-    echo "Adding a titleset-level menu using file: $1"
238
-
239
-    # Generate XML for the button linking to this titleset menu from the top menu
240
-    TOP_MENU_BUTTONS=`cat << EOF
241
-  $TOP_MENU_BUTTONS
242
-    <button>jump titleset $CUR_TS menu;</button>
243
-EOF`
244
-
245
-    # Set NOPANSCAN
246
-    noPanScan "$1"
247
-    # Set TV_FORMAT
248
-    getFormat "$1"
249
-
250
-    # Generate XML for the menu header, with a placeholder for
251
-    # the video segment buttons (to be replaced later by sed)
252
-    MENU_XML=`cat << EOF
253
-  <menus>
254
-    <video $NOPANSCAN format="$TV_FORMAT"/>
255
-    <pgc entry="root">
256
-      <vob file="$1" />
257
-__MENU_BUTTONS__
258
-    </pgc>
259
-  </menus>
260
-EOF`
261
-
262
-  # --------------------------
263
-  # For (S)VCD
264
-  else
265
-    echo "Adding a menu using file: $1"
266
-
267
-    # Generate XML for the button linking to this menu from the top menu
268
-    TOP_MENU_BUTTONS=`cat << EOF
269
-$TOP_MENU_BUTTONS
270
-    <select ref="select-menu-$CUR_TS"/>
271
-EOF`
272
-
273
-    # Generate XML for the segment item
274
-    SEGMENT_ITEMS_XML=`cat << EOF
275
-$SEGMENT_ITEMS_XML
276
-  <segment-item src="$1" id="seg-menu-$CUR_TS"/>
277
-EOF`
278
-
279
-    # Generate XML for the selection to go in pbc
280
-    # If there's a top menu, "return" goes back to it.
281
-    # Otherwise, don't use a "return" command.
282
-    if $HAVE_TOP_MENU; then
283
-      RETURN_CMD="<return ref=\"select-top-menu\"/>"
284
-    else
285
-      RETURN_CMD=""
286
-    fi
287
-    SELECTION_XML=`cat << EOF
288
-  <selection id="select-menu-$CUR_TS">
289
-    <bsn>1</bsn>
290
-    $RETURN_CMD
291
-    <loop jump-timing="immediate">0</loop>
292
-    <play-item ref="seg-menu-$CUR_TS"/>
293
-__MENU_BUTTONS__
294
-  </selection>
295
-EOF`
296
-
297
-  fi
298
-}
299
-
300
-# ==========================================================
301
-# Add a video title to a titleset menu, or a still image to
302
-# a slideshow
303
-# Args: $1 = video file to use for the title
304
-function addTitle ()
305
-{
306
-  if $FORCE_TITLESETS && test $CUR_VIDEO -eq 0; then
307
-    closeTitleset
308
-  fi
309
-  # Increment the current title number
310
-  if ! $MAKE_GROUP; then
311
-    (( CUR_TITLE++ ))
312
-  else
313
-    # Grouping several videos within one title
314
-    if test $CUR_VIDEO -eq 0; then
315
-       (( CUR_TITLE++ ))
316
-    fi
317
-    (( CUR_VIDEO++ ))
318
-  fi
319
-  # --------------------------
320
-  # For DVD
321
-  if test $XML_FORMAT = "dvd"; then
322
-    if ! $MAKE_GROUP; then
323
-      echo "Adding title: $1 as title number $CUR_TITLE of titleset $CUR_TS"
324
-    else
325
-      if test $CUR_VIDEO -eq 1; then
326
-        echo "Adding title number $CUR_TITLE of titleset $CUR_TS"
327
-      fi
328
-      echo "Adding $1 as video $CUR_VIDEO of title $CUR_TITLE"
329
-    fi
330
-
331
-    # Set NOPANSCAN
332
-    noPanScan "$1"
333
-
334
-    # Generate XML for the button linking to this title from the titleset menu
335
-    if ! $FORCE_TITLESETS; then
336
-      if test $CUR_VIDEO -lt 2; then
337
-        MENU_BUTTONS=`cat << EOF
338
-$MENU_BUTTONS
339
-        <button>jump title $CUR_TITLE;</button>
340
-EOF`
341
-      fi
342
-    else
343
-      # Add a button for the current titleset to the top menu
344
-      if test $CUR_VIDEO -le 1; then
345
-        TOP_MENU_BUTTONS=`cat << EOF
346
-$TOP_MENU_BUTTONS
347
-        <button>jump titleset $CUR_TS menu;</button>
348
-EOF`
349
-      fi
350
-    fi
351
-
352
-    # Generate the chapters tag
353
-    # If file exists, get duration and add appropriate chapter breaks
354
-    if test -e "$1" && $MAKE_CHAPTERS; then
355
-        CMD="idvid -terse \"$1\""
356
-        echo "    Calculating the duration of the video with:"
357
-        echo "        $CMD"
358
-        echo "    This may take a few minutes, so please be patient..."
359
-        DURATION=$(eval $CMD | grep DURATION | awk -F '=' '{print $2}')
360
-        echo $DURATION | awk '{hh=int($1/3600);mm=int(($1-hh*3600)/60);ss=$1-hh*3600-mm*60;\
361
-            printf "    The duration of the video is %02d:%02d:%02d\n",hh,mm,ss}'
362
-
363
-        CHAPTERS=$(make_chapters $DURATION $CHAPTER_INTERVAL)
364
-    # If file doesn't exist, or -nochapters was passed, use 0 chapters
365
-    else
366
-        CHAPTERS="0"
367
-    fi
368
-
369
-    # Generate the XML for the title itself, appending to existing titles
370
-    if $MAKE_GROUP; then
371
-      if test $CUR_VIDEO -eq 1; then
372
-        TS_TITLES=`cat << EOF
373
-$TS_TITLES
374
-    <pgc>
375
-EOF`
376
-      fi
377
-      TS_TITLES=`cat << EOF
378
-                 $TS_TITLES
379
-      <vob file="$1" chapters="$CHAPTERS" />
380
-EOF`
381
-    else
382
-      TS_TITLES=`cat << EOF
383
-$TS_TITLES
384
-    <pgc>
385
-      <vob file="$1" chapters="$CHAPTERS" />
386
-      __POST_CMD__
387
-    </pgc>
388
-EOF`
389
-    fi
390
-
391
-  # --------------------------
392
-  # For (S)VCD
393
-  else
394
-
395
-    # If there's a menu, "return" goes back to it; if not,
396
-    # do not generate a "return" command
397
-    if $HAVE_MENU; then
398
-      RETURN_CMD="<return ref=\"select-menu-$CUR_TS\"/>"
399
-    else
400
-      RETURN_CMD=""
401
-    fi
402
-    # If this is the first title or slide in a series
403
-    if $FIRST_TITLE; then
404
-      # For the first titles, PREV stays on the current title
405
-      let "PREV_TITLE=$CUR_TITLE"
406
-    # For all other titles
407
-    else
408
-      # PREV goes to the previous slide
409
-      let "PREV_TITLE=$CUR_TITLE - 1"
410
-    fi
411
-
412
-    # Fill in the NEXT command for the previous slide, if there was one
413
-    NEXT_TITLE="<next ref=\"play-title-$CUR_TITLE\"\/>"
414
-    SELECTION_XML=$( echo "$SELECTION_XML" | sed -e "s/__NEXT_TITLE__/$NEXT_TITLE/g" )
415
-    PLAYLIST_XML=$( echo "$PLAYLIST_XML" | sed -e "s/__NEXT_TITLE__/$NEXT_TITLE/g" )
416
-
417
-    # --------------------------
418
-    # If doing a still-image slideshow, use segment/selection
419
-    if $STILL_TITLES; then
420
-      echo "Adding title: $1 as number $CUR_TITLE in a slideshow"
421
-
422
-      # Generate XML for the selection (menu) "buttons" that will
423
-      # jump to this slideshow. Only the first slide gets a button.
424
-      if $FIRST_TITLE; then
425
-        MENU_BUTTONS=`cat << EOF
426
-$MENU_BUTTONS
427
-    <select ref="play-title-$CUR_TITLE"/>
428
-EOF`
429
-      fi
430
-
431
-      # Generate XML for the segment item
432
-      SEGMENT_ITEMS_XML=`cat << EOF
433
-$SEGMENT_ITEMS_XML
434
-  <segment-item src="$1" id="seg-slide-$CUR_TITLE"/>
435
-EOF`
436
-
437
-      # Generate XML for the selection to go in pbc
438
-      # The slide will play indefinitely until NEXT, PREV,
439
-      # or RETURN is pressed. __NEXT_TITLE__ is a placeholder
440
-      # until we're sure there is a next slide; it will be
441
-      # filled in on the next addition if there is.
442
-      SELECTION_XML=`cat << EOF
443
-$SELECTION_XML
444
-  <playlist id="play-title-$CUR_TITLE">
445
-    <prev ref="play-title-$PREV_TITLE"/>
446
-    __NEXT_TITLE__
447
-    $RETURN_CMD
448
-    <wait>-1</wait>
449
-    <play-item ref="seg-slide-$CUR_TITLE"/>
450
-  </playlist>
451
-EOF`
452
-
453
-    # --------------------------
454
-    # If doing normal video titles, use select/playlist
455
-    else
456
-
457
-      echo "Adding title: $1 as title number $CUR_TITLE"
458
-
459
-      # Generate XML for the selection (menu) "buttons" that will
460
-      # jump to this playlist (title)
461
-      MENU_BUTTONS=`cat << EOF
462
-$MENU_BUTTONS
463
-    <select ref="play-title-$CUR_TITLE"/>
464
-EOF`
465
-
466
-      # Generate XML for the sequence item
467
-      SEQUENCE_ITEMS_XML=`cat << EOF
468
-$SEQUENCE_ITEMS_XML
469
-  <sequence-item src="$1" id="seq-title-$CUR_TITLE"/>
470
-EOF`
471
-
472
-      # Generate XML for the playlist for this title
473
-      PLAYLIST_XML=`cat << EOF
474
-$PLAYLIST_XML
475
-  <playlist id="play-title-$CUR_TITLE">
476
-    <prev ref="play-title-$PREV_TITLE"/>
477
-    __NEXT_TITLE__
478
-    $RETURN_CMD
479
-    <wait>$PAUSE</wait>
480
-    <play-item ref="seq-title-$CUR_TITLE"/>
481
-  </playlist>
482
-EOF`
483
-
484
-    fi # (S)VCD slides or normal titles
485
-
486
-  fi # DVD or (S)VCD
487
-
488
-  FIRST_TITLE=false
489
-}
490
-
491
-# ==========================================================
492
-# Finalize the XML for a titleset, containing a menu and titles
493
-function closeTitleset ()
494
-{
495
-  # Proceed only if there are titles in this titleset
496
-  if (( $CUR_TITLE > 0 )); then
497
-
498
-  # --------------------------
499
-  # For DVD
500
-  if test $XML_FORMAT = "dvd"; then
501
-    echo "Closing titleset $CUR_TS with $CUR_TITLE title(s)."
502
-
503
-    # Give each menu a button linking back to the top menu, if there is one
504
-    if $HAVE_TOP_MENU; then
505
-      MENU_BUTTONS=`cat << EOF
506
-$MENU_BUTTONS
507
-        <button>jump vmgm menu;</button>
508
-
509
-EOF`
510
-    fi
511
-
512
-    # Fill in titleset menu buttons
513
-    MENU_XML=$(echo "$MENU_XML" | \
514
-        sed -e "s/__MENU_BUTTONS__/$(sedprep "$MENU_BUTTONS" /)/g")
515
-
516
-    # Fill in the POST command. If there is a menu to jump back to, use that;
517
-    # otherwise, do not insert a POST command.
518
-    if $HAVE_MENU; then
519
-      POST_CMD="<post>call menu;<\/post>"
520
-    elif $FORCE_TITLESETS && $HAVE_TOP_MENU; then
521
-      POST_CMD="<post>call vmgm menu;<\/post>"
522
-    else
523
-      POST_CMD=""
524
-    fi
525
-    TS_TITLES=$( echo "$TS_TITLES" | sed -e "s/__POST_CMD__/$POST_CMD/g" )
526
-
527
-    # Append titleset info to ALL_MENU_XML
528
-    if ! $FORCE_TITLESETS || ! $HAVE_TOP_MENU; then
529
-      ALL_MENU_XML=`cat << EOF
530
-$ALL_MENU_XML
531
-<titleset>
532
-$MENU_XML
533
-  <titles>
534
-    <video $NOPANSCAN format="$TV_FORMAT" />
535
-$TS_TITLES
536
-  </titles>
537
-</titleset>
538
-EOF`
539
-    else
540
-      # One titleset for each title -> add a dummy menu to the titleset
541
-      ALL_MENU_XML=`cat << EOF
542
-$ALL_MENU_XML
543
-<titleset>
544
-  <menus>
545
-    <pgc>
546
-      <post>
547
-        jump title 1;
548
-      </post>
549
-    </pgc>
550
-  </menus>
551
-  <titles>
552
-    <video $NOPANSCAN format="$TV_FORMAT"/>
553
-$TS_TITLES
554
-  </titles>
555
-</titleset>
556
-EOF`
557
-    fi
558
-    # Clear existing XML to prepare for next titleset
559
-    MENU_XML=""
560
-    TS_TITLES=""
561
-    CUR_TITLE=0
562
-    MENU_BUTTONS=""
563
-
564
-  # --------------------------
565
-  # For (S)VCD
566
-  else
567
-
568
-    # Fill in menu title selections ("buttons")
569
-    # and remove any remaining __NEXT_TITLE__s
570
-    SELECTION_XML=$(echo "$SELECTION_XML" | \
571
-        sed -e "s/__MENU_BUTTONS__/$(sedprep "$MENU_BUTTONS" /)/g" -e "s/__NEXT_TITLE__//g")
572
-    PLAYLIST_XML=$(echo "$PLAYLIST_XML" | sed -e "s/__NEXT_TITLE__//g")
573
-
574
-    # Append new PBC menus/playlists to PBC_XML
575
-    PBC_XML=`cat << EOF
576
-$PBC_XML
577
-$SELECTION_XML
578
-$PLAYLIST_XML
579
-
580
-EOF`
581
-
582
-    # Clear existing XML to prepare for next menu/titles
583
-    SELECTION_XML=""
584
-    PLAYLIST_XML=""
585
-    MENU_BUTTONS=""
586
-    # Go back to doing normal video titles
587
-    STILL_TITLES=false
588
-  fi
589
-
590
-  # Increment the current titleset number
591
-  (( CUR_TS++ ))
592
-
593
-  fi # End if there are titles
594
-}
595
-
596
-# ==========================================================
597
-# EXECUTION BEGINS HERE
598
-echo "$SCRIPTNAME"
599
-
600
-if test $# -lt 1; then
601
-    usage_error "Please provide at least one video to author, and the name of an output file to use."
602
-fi
603
-
604
-while test $# -gt 0; do
605
-    case "$1" in
606
-        "-quiet" )
607
-            QUIET=:
608
-            ;;
609
-        "-out" )
610
-            shift
611
-            OUT_PREFIX="$1"
612
-            ;;
613
-        "-pause" )
614
-            shift
615
-            PAUSE="$1"
616
-            ;;
617
-        # Format and overwriting options
618
-        "-dvd" ) XML_FORMAT="dvd" ;;
619
-        "-vcd" ) XML_FORMAT="vcd" ;;
620
-        "-svcd" ) XML_FORMAT="svcd" ;;
621
-        "-overwrite" ) OVERWRITE=: ;;
622
-        # Menus and video titles
623
-        "-topmenu" )
624
-            shift
625
-            if ! $HAVE_TOP_MENU; then
626
-                checkExistence "$1"
627
-                addTopMenu "$1"
628
-            else
629
-              usage_error "Please specify only one -topmenu option. If you would like to have multiple menus, please use the -menu option."
630
-            fi
631
-            ;;
632
-        "-menu" )
633
-            if $FORCE_TITLESETS; then
634
-              usage_error "You can not use -titlesets with -menu. Please use -topmenu instead."
635
-            fi
636
-            shift
637
-            HAVE_MENU=:
638
-            FIRST_TITLE=:
639
-            checkExistence "$1"
640
-            closeTitleset
641
-            addMenu "$1"
642
-            ;;
643
-        "-slides" )
644
-            STILL_TITLES=:
645
-            FIRST_TITLE=:
646
-            ;;
647
-        "-group" )
648
-            MAKE_GROUP=:
649
-            CUR_VIDEO=0
650
-            ;;
651
-        "-endgroup" )
652
-            if $MAKE_GROUP; then
653
-                TS_TITLES=`cat << EOF
654
-                $TS_TITLES
655
-                __POST_CMD__
656
-                </pgc>
657
-EOF`
658
-            fi
659
-            MAKE_GROUP=false
660
-            CUR_VIDEO=0
661
-            ;;
662
-        "-chapter-points" )
663
-            # Space-separated list of comma-separated chapter points
664
-            MAKE_CHAPTERS=:
665
-            shift
666
-            IFS=""; while test $# -gt 0 && test ${1:0:1} != "-"; do
667
-                CHAPTER_POINTS=("${CHAPTER_POINTS[@]}" "$1")
668
-                shift
669
-            done
670
-            if test $# -gt 0 && test ${1:0:1} = "-"; then
671
-                DO_SHIFT=false;
672
-            fi
673
-            unset IFS
674
-            ;;
675
-        "-chapters" )
676
-            # Fixed chapter intervals
677
-            MAKE_CHAPTERS=:
678
-            shift
679
-            CHAPTER_INTERVAL=$1
680
-            if test "$CHAPTER_INTERVAL" -lt "0" || \
681
-               test "$CHAPTER_INTERVAL" -gt "9999";
682
-            then
683
-               usage_error "Please use a -chapters interval between 0 and 9999."
684
-            fi
685
-            ;;
686
-        "-nochapters" )
687
-            MAKE_CHAPTERS=false
688
-            ;;
689
-        "-titlesets" )
690
-            if $HAVE_MENU; then
691
-              usage_error "You can not use -titlesets with -menu. Please use -topmenu instead."
692
-            fi
693
-            FORCE_TITLESETS=:
694
-            echo "Creation of titlesets forced ..."
695
-            ;;
696
-        * )
697
-            checkExistence "$1"
698
-            addTitle "$1"
699
-            ;;
700
-    esac
701
-    # Get the next argument
702
-    shift
703
-done
704
-
705
-# Last argument should be the name of the output file
706
-if test -z "$OUT_PREFIX"; then
707
-    usage_error "Please provide an output filename with -out."
708
-fi
709
-
710
-# See if selected output file exists. If so, confirm for overwrite.
711
-if test -e "$OUT_PREFIX.xml"; then
712
-    echo $SEPARATOR
713
-    echo "*** The output file you specified: $OUT_PREFIX.xml already exists."
714
-    if $OVERWRITE; then
715
-        echo "Overwriting existing file."
716
-    else
717
-        echo "Please re-run the script with the -overwrite option to overwrite."
718
-        exit 1
719
-    fi
720
-    echo $SEPARATOR
721
-fi
722
-
723
-
724
-# Close current titleset
725
-closeTitleset
726
-
727
-# Fill in top menu buttons
728
-TOP_MENU_XML=$(echo "$TOP_MENU_XML" | \
729
-    sed -e "s/__TOP_MENU_BUTTONS__/$(sedprep "$TOP_MENU_BUTTONS" /)/g")
730
-
731
-# If there is a top menu with no other menus, print an error and
732
-# a suggestion that user specify -menu instead of -topmenu
733
-if $HAVE_TOP_MENU && ! $HAVE_MENU && ! $FORCE_TITLESETS; then
734
-  echo "You have specified a top menu without any other menus. If you only want to have one menu, please use the -menu option instead of -topmenu."
735
-  echo "Exiting without writing XML file."
736
-  exit 1
737
-fi
738
-
739
-# Assemble the final XML file
740
-
741
-# dvdauthor format for a DVD
742
-if test $XML_FORMAT = "dvd" ; then
743
-FINAL_DISC_XML=`cat << EOF
744
-<dvdauthor dest="$OUT_PREFIX">
745
-<!-- makexml $TOVID_VERSION -->
746
-<vmgm>
747
-$TOP_MENU_XML
748
-</vmgm>
749
-$ALL_MENU_XML
750
-</dvdauthor>
751
-EOF`
752
-
753
-# vcdxbuild (vcdimager) format for a VCD or SVCD
754
-else
755
-  # Determine what version number to use
756
-  if test $XML_FORMAT = "vcd" ; then
757
-    VCD_VERSION="2.0"
758
-    OPTION_LINE=''
759
-  # Use 1.0 for SVCD
760
-  else
761
-    VCD_VERSION="1.0"
762
-    OPTION_LINE='<option name="update scan offsets" value="true" />'
763
-  fi
764
-
765
-  # Make sure there are segment-items and sequence-items
766
-  if test -n "$SEGMENT_ITEMS_XML" ; then
767
-    SEGMENT_ITEMS_XML=`cat << EOF
768
-<segment-items>
769
-$SEGMENT_ITEMS_XML
770
-</segment-items>
771
-EOF`
772
-  fi
773
-  if test -n "$SEQUENCE_ITEMS_XML" ; then
774
-    SEQUENCE_ITEMS_XML=`cat << EOF
775
-<sequence-items>
776
-$SEQUENCE_ITEMS_XML
777
-</sequence-items>
778
-EOF`
779
-  fi
780
-
781
-FINAL_DISC_XML=`cat << EOF
782
-<?xml version="1.0"?>
783
-<!DOCTYPE videocd PUBLIC "-//GNU/DTD VideoCD//EN"
784
-  "http://www.gnu.org/software/vcdimager/videocd.dtd">
785
-<videocd xmlns="http://www.gnu.org/software/vcdimager/1.0/"
786
-  class="$XML_FORMAT" version="$VCD_VERSION">
787
-$OPTION_LINE
788
-<info>
789
-  <album-id>VIDEO_DISC</album-id>
790
-  <volume-count>1</volume-count>
791
-  <volume-number>1</volume-number>
792
-  <restriction>0</restriction>
793
-</info>
794
-
795
-<pvd>
796
-  <volume-id>VIDEO_DISC</volume-id>
797
-  <system-id>CD-RTOS CD-BRIDGE</system-id>
798
-</pvd>
799
-
800
-$SEGMENT_ITEMS_XML
801
-
802
-$SEQUENCE_ITEMS_XML
803
-
804
-<pbc>
805
-$TOP_MENU_XML
806
-
807
-$PBC_XML
808
-</pbc>
809
-</videocd>
810
-EOF`
811
-fi
812
-
813
-# Remove blank lines and write final result to output file
814
-echo "$FINAL_DISC_XML" | sed -e '/^ *$/d' > "$OUT_PREFIX.xml"
815
-
816
-echo "Done. The resulting XML was written to $OUT_PREFIX.xml."
817
-
818
-if ! $QUIET; then
819
-    if test $XML_FORMAT = "dvd" ; then
820
-        echo "You can now author, image and/or burn the disc by running:"
821
-        echo "    tovid dvd \"$OUT_PREFIX.xml\""
822
-    else
823
-        echo "You can create the (S)VCD .bin and .cue files by running the command:"
824
-        echo "    tovid vcd \"$OUT_PREFIX.xml\""
825
-    fi
826
-    echo "Thanks for using makexml!"
827
-fi
828
-
829
-exit 0
830
-
831
tovid-0.34.tar.bz2/src/postproc Deleted
298
 
1
@@ -1,296 +0,0 @@
2
-#!/usr/bin/env bash
3
-ME="[postproc]:"
4
-. tovid-init 2>/dev/null ||
5
-{ echo -e "===============================================================\n"
6
-echo -e "'tovid-init' not found.  Was tovid improperly installed?"
7
-echo -e "Or are you trying to run the script directly?"
8
-echo -e "Please run postproc as:\ntovid postproc OPTIONS"
9
-exit 1 ; }
10
-
11
-# postproc
12
-# Part of the tovid suite
13
-# =======================
14
-# A bash script for doing post-encoding processing on
15
-# MPEG video files. Can requantize (shrink) video and
16
-# adjust A/V sync.
17
-#
18
-# Project homepage: http://tovid.wikia.com
19
-#
20
-# Copyright (C) 2005-2010
21
-#
22
-# This program is free software; you can redistribute it and/or
23
-# modify it under the terms of the GNU General Public License
24
-# as published by the Free Software Foundation; either
25
-# version 2 of the License, or (at your option) any later
26
-# version.
27
-#
28
-# This program is distributed in the hope that it will be useful,
29
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
30
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31
-# GNU General Public License for more details.
32
-#
33
-# You should have received a copy of the GNU General Public License
34
-# along with this program; if not, write to the Free Software
35
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Or see:
36
-#
37
-#     http://www.gnu.org/licenses/gpl.txt
38
-
39
-SCRIPT_NAME=`cat << EOF
40
---------------------------------
41
-tovid postproc
42
-Post-process video files
43
-Version $TOVID_VERSION
44
-$TOVID_HOME_PAGE
45
---------------------------------
46
-EOF`
47
-
48
-USAGE=`cat << EOF
49
-Usage: tovid postproc [OPTIONS] {input file} {output file}
50
-
51
-Where OPTIONS may be any of the following:
52
-
53
-  -audiodelay NUM    Delay audio by NUM milliseconds
54
-  -normalize         Normalize the audio
55
-  -amplitudeNUM[dB]  Apply a gain of NUM (0 - 1.0, add dB for decibel gain)
56
-  -shrink NUM        Shrink video by factor NUM (1.0 - 2.0)
57
-  -parallel          Run all processes in parallel (can save time)
58
-  -debug             Keep a log of actions and output
59
-
60
-See the tovid manual page ('man tovid') for additional documentation.
61
-
62
-EOF`
63
-
64
-SEPARATOR="========================================================="
65
-
66
-# Default values
67
-TMP_FILE="postproc.fileinfo.$PPID"
68
-AUDIO_DELAY=""
69
-SHRINK_FACTOR=""
70
-DO_NORM=false
71
-AUDIO_AMPLITUDE=""
72
-DO_SHRINK=false
73
-MUX_OPTS=""
74
-DEBUG=false
75
-# File to use for saving postprocessing statistics
76
-STAT_DIR=$HOME/.tovid
77
-STAT_FILE="$STAT_DIR/stats.postproc"
78
-SHRINK_PERCENT="0"
79
-PARALLEL=false
80
-# Video format in use
81
-VIDEO_FORMAT="DVD"
82
-BACKGR=""
83
-
84
-# Print script name, usage notes, and optional error message, then exit.
85
-# Args: $1 == text string containing error message
86
-usage_error ()
87
-{
88
-  echo "$USAGE"
89
-  echo "$SEPARATOR"
90
-  echo "$@"
91
-  exit 1
92
-}
93
-
94
-# Remove temporary files
95
-cleanup ()
96
-{
97
-    echo "Cleaning up..."
98
-    rm -fv video_shrink video_dump audio_dump normed_audio
99
-
100
-}
101
-
102
-
103
-# ***********************************
104
-# EXECUTION BEGINS HERE
105
-# ***********************************
106
-
107
-echo "$SCRIPT_NAME"
108
-
109
-# Make sure there are at least two arguments (infile and outfile)
110
-if test $# -lt 2; then
111
-  usage_error "Error: Please provide an input filename and an output filename."
112
-fi
113
-
114
-while test ${1:0:1} = "-"; do
115
-    case "$1" in
116
-        "-audiodelay" )
117
-            shift
118
-            AUDIO_DELAY="-O ${1}ms"
119
-            ;;
120
-        "-shrink" )
121
-            shift
122
-            DO_SHRINK=:
123
-            SHRINK_FACTOR="$1"
124
-            assert_dep "$transcode" "You are missing dependencies required for shrinking video!"
125
-            ;;
126
-        "-parallel" )
127
-            PARALLEL=:
128
-            cleanup
129
-            mkfifo video_dump
130
-            mkfifo audio_dump
131
-            mkfifo video_shrink
132
-            BACKGR="&"
133
-            ;;
134
-        "-normalize" )
135
-            DO_NORM=:
136
-            ;;
137
-        "-amplitude" )
138
-            shift
139
-            AUDIO_AMPLITUDE="--amplitude=$1"
140
-            DO_NORM=:
141
-            ;;
142
-        "-debug" )
143
-            DEBUG=:
144
-            ;;
145
-    esac
146
-
147
-    # Get next argument
148
-    shift
149
-done
150
-
151
-
152
-IN_FILE="$1"
153
-shift
154
-OUT_FILE="$1"
155
-
156
-echo $SEPARATOR
157
-
158
-$DO_NORM && assert_dep "sox" "You are missing dependancies necessarily for processing audio wav's"
159
-if $DO_NORM && $PARALLEL; then
160
-   echo "Cannot normalize audio in parallel mode! Turning off -parallel."
161
-   PARALLEL=false
162
-   cleanup
163
-fi
164
-
165
-# Figure out what format it is. 44.1khz audio can be VCD or SVCD,
166
-# 48khz audio is DVD.
167
-echo "Gathering file information. This may take a while."
168
-if eval $(idvid -terse "$IN_FILE"); then :; else
169
-    echo "Could not identify source video: $IN_FILE"
170
-    exit 1
171
-fi
172
-video_format=$(tr A-Z a-z <<< $ID_VIDEO_FORMAT)video
173
-
174
-if test $ID_AUDIO_RATE -eq "48000"; then
175
-    MUX_OPTS="-V -f 8"
176
-    VIDEO_FORMAT="DVD"
177
-elif test $ID_AUDIO_RATE -eq "44100"; then
178
-    # VCD is 352 wide, SVCD is 480 wide
179
-    if test $ID_VIDEO_WIDTH -eq "352"; then
180
-        MUX_OPTS="-f 1"
181
-        VIDEO_FORMAT="VCD"
182
-    elif test $ID_VIDEO_WIDTH -eq "480"; then
183
-        MUX_OPTS="-V -f 4"
184
-        VIDEO_FORMAT="SVCD"
185
-    fi
186
-fi
187
-
188
-echo "Dumping audio and video streams with the following commands:"
189
-
190
-# Dump audio and video
191
-if $DO_NORM; then
192
-    AUDIO_DUMP="ffmpeg -i  \"$IN_FILE\" -vn -f wav -y audio_dump"
193
-else
194
-    #AUDIO_DUMP="mplayer \"$IN_FILE\" -quiet -dumpaudio -dumpfile audio_dump"
195
-    AUDIO_DUMP="ffmpeg -i \"$IN_FILE\" -vn -f $ID_AUDIO_CODEC -acodec copy -y audio_dump"
196
-fi
197
-VIDEO_DUMP="ffmpeg -i \"$IN_FILE\" -an -f $video_format -vcodec copy -y video_dump"
198
-VID_STREAM="video_dump"
199
-
200
-echo "$AUDIO_DUMP"
201
-echo "$VIDEO_DUMP"
202
-# Should always be safe to put audio decode in the background
203
-eval $AUDIO_DUMP > $TMP_FILE 2>&1 &
204
-eval $VIDEO_DUMP >> $TMP_FILE 2>&1 $BACKGR
205
-
206
-# Let the audio process finish if not in parallel mode (should always finish
207
-# before video, so this is just precautionary)
208
-$PARALLEL || wait
209
-
210
-# Normalize/gain
211
-if $DO_NORM; then
212
-   AUDIO_NORM="$NORMALIZE $AUDIO_AMPLITUDE audio_dump"
213
-
214
-   echo "Normalizing audio/applying gain with the following command:"
215
-   echo "$AUDIO_NORM"
216
-   eval $AUDIO_NORM
217
-
218
-   # Re-encode audio
219
-   mv -v audio_dump normed_audio
220
-   AUDIO_BITRATE=$(expr $ID_AUDIO_BITRATE / 1000)
221
-   AUDIO_ENC="ffmpeg -i normed_audio -vn -ab ${AUDIO_BITRATE}k -ar $ID_AUDIO_RATE"
222
-   AUDIO_ENC="$AUDIO_ENC -ac $ID_AUDIO_NCH -acodec $ID_AUDIO_CODEC"
223
-   AUDIO_ENC="$AUDIO_ENC -y audio_dump.$ID_AUDIO_CODEC"
224
-
225
-   echo "Encoding the normalized/gained audio stream with the following command:"
226
-   echo "$AUDIO_ENC"
227
-   eval $AUDIO_ENC
228
-
229
-   mv -v audio_dump.$ID_AUDIO_CODEC audio_dump
230
-fi
231
-
232
-# Shrink, if requested
233
-if $DO_SHRINK; then
234
-    # Can't shrink VCD
235
-    if test $VIDEO_FORMAT = "VCD"; then
236
-        echo $SEPARATOR
237
-        echo "This file appears to be in VCD format. Unfortunately, the"
238
-        echo "VCD specification does not allow shrinking (requantization)."
239
-        echo "Shrinking will be skipped."
240
-        echo $SEPARATOR
241
-    else
242
-        START_SIZE=$( ls -l video_dump | awk '{print $5}' )
243
-        echo $SEPARATOR
244
-        echo "Shrinking video stream by a factor of $SHRINK_FACTOR"
245
-        SHRINK_CMD="tcrequant -i video_dump -o video_shrink -f $SHRINK_FACTOR"
246
-        echo "$SHRINK_CMD"
247
-        eval $SHRINK_CMD $BACKGR
248
-        VID_STREAM="video_shrink"
249
-        if $PARALLEL; then
250
-            :
251
-        else
252
-            wait
253
-            SHRINK_SIZE=$( ls -l video_shrink | awk '{print $5}' )
254
-            SHRINK_PERCENT=$(expr 100 \- \( 100 \* $SHRINK_SIZE \/ $START_SIZE \))
255
-            echo "Video stream was shrunk by $SHRINK_PERCENT%"
256
-        fi
257
-    fi
258
-fi
259
-
260
-echo $SEPARATOR
261
-
262
-# Multiplex audio and video back together
263
-echo "Multiplexing audio and video streams with the following command:"
264
-MPLEX_CMD="mplex $VID_STREAM audio_dump -o \"$OUT_FILE\" $MUX_OPTS $AUDIO_DELAY"
265
-echo "$MPLEX_CMD"
266
-eval $MPLEX_CMD >> $TMP_FILE 2>&1
267
-
268
-# For parallel, compare infile and outfile sizes
269
-if $PARALLEL; then
270
-    START_SIZE=$( ls -l "$IN_FILE" | awk '{print $5}' )
271
-    SHRINK_SIZE=$( ls -l "$OUT_FILE" | awk '{print $5}' )
272
-    SHRINK_PERCENT=$(expr 100 \- \( 100 \* $SHRINK_SIZE \/ $START_SIZE \))
273
-    echo "Video stream was shrunk by $SHRINK_PERCENT%"
274
-fi
275
-
276
-echo $SEPARATOR
277
-
278
-cleanup
279
-
280
-# Create stats directory and save video statistics
281
-mkdir -p $STAT_DIR
282
-FINAL_STATS=`cat << EOF
283
-postproc $TOVID_VERSION
284
-File: $OUT_FILE
285
-Shrink factor: $SHRINK_FACTOR
286
-Shrunk by: $SHRINK_PERCENT%
287
-EOF`
288
-echo $"$FINAL_STATS" >> $STAT_FILE
289
-
290
-# If doing debugging, keep log and print message
291
-if $DEBUG; then
292
-  echo "All output has been saved in the file: $TMP_FILE."
293
-else
294
-  rm $TMP_FILE
295
-fi
296
-
297
-echo "Done. Thanks for using postproc!"
298
tovid-0.34.tar.bz2/src/tovid-batch Deleted
98
 
1
@@ -1,96 +0,0 @@
2
-#!/usr/bin/env bash
3
-ME="[tovid-batch]:"
4
-. tovid-init 2>/dev/null ||
5
-{ echo -e "===============================================================\n"
6
-echo -e "'tovid-init' not found.  Was tovid improperly installed?"
7
-echo -e "Or are you trying to run the script directly?"
8
-echo -e "Please run tovid-batch as:\ntovid batch OPTIONS"
9
-exit 1 ; }
10
-
11
-# tovid-batch
12
-# Part of the tovid suite
13
-# =======================
14
-# A bash script for batch video conversion.
15
-#
16
-# Project homepage: http://tovid.wikia.com
17
-#
18
-# Copyright (C) 2005-2010
19
-#
20
-# This program is free software; you can redistribute it and/or
21
-# modify it under the terms of the GNU General Public License
22
-# as published by the Free Software Foundation; either
23
-# version 2 of the License, or (at your option) any later
24
-# version.
25
-#
26
-# This program is distributed in the hope that it will be useful,
27
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
28
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29
-# GNU General Public License for more details.
30
-#
31
-# You should have received a copy of the GNU General Public License
32
-# along with this program; if not, write to the Free Software
33
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Or see:
34
-#
35
-#     http://www.gnu.org/licenses/gpl.txt
36
-
37
-SCRIPT_NAME=`cat << EOF
38
---------------------------------
39
-tovid-batch
40
-A batch conversion script using tovid
41
-Part of the tovid suite, version $TOVID_VERSION
42
-$TOVID_HOME_PAGE
43
---------------------------------
44
-EOF`
45
-
46
-USAGE=`cat << EOF
47
-Usage: tovid batch [OPTIONS] -infiles <input files>
48
-
49
-OPTIONS may be any options that tovid accepts. See 'man tovid'.
50
-
51
-EOF`
52
-
53
-SEPARATOR="=============================================================================="
54
-
55
-# No tovid arguments to start with
56
-TOVID_ARGS=""
57
-
58
-# ***********************************
59
-# EXECUTION BEGINS HERE
60
-# ***********************************
61
-
62
-precho "$SCRIPT_NAME"
63
-
64
-# Get all arguments up to -infiles
65
-while test $# -gt 0; do
66
-    if test "$1" = "-infiles"; then
67
-        shift
68
-        break
69
-    else
70
-        TOVID_ARGS="$TOVID_ARGS $1"
71
-    fi
72
-
73
-    # Get next argument
74
-    shift
75
-done
76
-
77
-# If no infiles, print usage notes
78
-if test $# -le 0; then
79
-    precho "$USAGE"
80
-    echo "$SEPARATOR"
81
-    echo "Please provide a list of files to encode using -infiles"
82
-    exit 1
83
-fi
84
-
85
-# For every input filename provided, run tovid with the given options
86
-for FILE in "$@"; do
87
-    echo $SEPARATOR
88
-    if test -e "$FILE"; then
89
-       EXT=$(echo "$FILE" | awk -F '.' '{ print $NF }')
90
-       FILENAME=$(basename "$FILE" ."$EXT")
91
-       TOVID_CMD="tovid mpg -noask $TOVID_ARGS -in \"$FILE\" -out \"$FILENAME.tovid_encoded\""
92
-       precho $TOVID_CMD
93
-       eval $TOVID_CMD
94
-    else
95
-       echo "Couldn't find file \"$FILE\", not encoding it."
96
-    fi
97
-done
98
tovid-0.34.tar.bz2/src/tovid-interactive Deleted
183
 
1
@@ -1,181 +0,0 @@
2
-#!/usr/bin/env bash
3
-ME="[tovid-interactive]:"
4
-. tovid-init 2>/dev/null ||
5
-{ echo -e "===============================================================\n"
6
-echo -e "'tovid-init' not found.  Was tovid improperly installed?"
7
-echo -e "Or are you trying to run the script directly?"
8
-echo -e "Please run tovid-interactive as:\ntovid interactive OPTIONS"
9
-exit 1 ; }
10
-
11
-# tovid-interactive
12
-# Part of the tovid suite
13
-# =======================
14
-# A bash script with an interactive frontend to the tovid
15
-# script. This script prompts the user for all options, and
16
-# then runs the tovid script with the selected options.
17
-#
18
-# Project homepage: http://tovid.wikia.com
19
-#
20
-# Copyright (C) 2005-2010
21
-#
22
-# This program is free software; you can redistribute it and/or
23
-# modify it under the terms of the GNU General Public License
24
-# as published by the Free Software Foundation; either
25
-# version 2 of the License, or (at your option) any later
26
-# version.
27
-#
28
-# This program is distributed in the hope that it will be useful,
29
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
30
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31
-# GNU General Public License for more details.
32
-#
33
-# You should have received a copy of the GNU General Public License
34
-# along with this program; if not, write to the Free Software
35
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Or see:
36
-#
37
-#     http://www.gnu.org/licenses/gpl.txt
38
-
39
-WELCOME=`cat << EOF
40
---------------------------------
41
-tovid-interactive
42
-Interactive CLI front-end to tovid
43
-Part of the tovid suite, version $TOVID_VERSION
44
-$TOVID_HOME_PAGE
45
---------------------------------
46
-
47
-Welcome to the tovid-interactive script. This script is an interactive front-end for the tovid video conversion script. I will ask you several questions about the video you want to encode, and then run the tovid script with the options you choose.
48
-
49
-EOF`
50
-
51
-SEPARATOR="==============================================================================="
52
-
53
-precho $"$WELCOME"
54
-echo $SEPARATOR
55
-
56
-# Make sure tovid is in the path
57
-if ! test -x $(which tovid); then
58
-  precho "Oops! I can't find tovid in your path. Before you use this script, please install the tovid suite by running the 'configure' script from the directory where you unzipped tovid."
59
-  exit 1
60
-fi
61
-
62
-# 7 Get the file to encode
63
-echo "Step 1 of 7:"
64
-if test $# -eq 1; then
65
-  INFILE="$1"
66
-  echo "Encoding the filename provided on the command-line:"
67
-  echo "$1"
68
-  echo $SEPARATOR
69
-else
70
-  INFILE=""
71
-  if test $# -gt 1; then
72
-    echo "I found more than one command line paramter! Please give only one"
73
-    echo "video to encode. You gave me $#:"
74
-    echo "$@"
75
-  fi
76
-  precho "What video file do you want to encode? Please use the full path name if the file is not in the current directory. Hint: if you don't know the full name of the file, you can press [control]-C now, and run tovid-interactive followed by the name of the file."
77
-  while ! test -e "$INFILE"; do
78
-    echo -n "filename: "
79
-    read INFILE
80
-    if ! test -e "$INFILE"; then
81
-       echo "Cannot find \"$INFILE\"! Please try again."
82
-    fi
83
-  done
84
-  echo $SEPARATOR
85
-fi
86
-
87
-# 6 Ask for format
88
-echo "Step 2 of 7:"
89
-echo "You can encode this video to one of the following formats:"
90
-echo "For burning onto DVD:"
91
-echo "   dvd       DVD format             720x480 NTSC, 720x576 PAL"
92
-echo "   half-dvd  Half-DVD format        352x480 NTSC, 352x576 PAL"
93
-echo "   dvd-vcd   VCD-on-DVD format      352x240 NTSC, 352x288 PAL"
94
-echo "For burning onto CD:"
95
-echo "   vcd       Video CD format        352x240 NTSC, 352x288 PAL"
96
-echo "   svcd      Super Video CD format  480x480 NTSC, 480x576 PAL"
97
-
98
-VIDFORMAT="none"
99
-until $(verify $VIDFORMAT set "dvd half-dvd dvd-vcd vcd svcd")
100
-do
101
-  echo "Please enter one of the formats listed (dvd, half-dvd, dvd-vcd, vcd, svcd)."
102
-  echo -n "format: "
103
-  read VIDFORMAT
104
-done
105
-  echo $SEPARATOR
106
-
107
-# 5 Ask for NTSC or PAL
108
-echo "Step 3 of 7:"
109
-precho "Do you want the video to be NTSC or PAL? If you live in the Americas or Japan, you probably want NTSC; if you live in Europe, Australia, or New Zealand, you probably want PAL."
110
-
111
-TVSYS="none"
112
-until $(verify $TVSYS set "ntsc pal")
113
-do
114
-  echo "Please use lowercase (ntsc, pal)."
115
-  echo -n "ntsc or pal: "
116
-  read TVSYS
117
-done
118
-echo $SEPARATOR
119
-
120
-# 4 Ask for aspect ratio
121
-echo "Step 4 of 7:"
122
-echo "You can encode to three different screen formats:"
123
-echo "   full        If your video is full-screen (4:3 aspect ratio)"
124
-echo "   wide        If your video is wide-screen (16:9 aspect ratio)"
125
-echo "   panavision  If your video is theatrical wide-screen (2.35:1 aspect ratio)"
126
-precho "If you choose wide or panavision, the video will be 'letterboxed' to fit a standard TV screen. Most TV programs are 'full'; many movies are 'wide', and some movies are 'panavision' (if they look very wide and skinny)."
127
-
128
-ASPECT="none"
129
-until $(verify $ASPECT set "full wide panavision")
130
-do
131
-echo "Please enter one of the screen formats listed (full, wide, panavision)."
132
-echo -n "screen format: "
133
-read ASPECT
134
-done
135
-echo $SEPARATOR
136
-
137
-# 3 Normalize audio?
138
-echo "Step 5 of 7:"
139
-precho "In some videos, the volume may be too quiet or too loud. You can fix this by normalizing the audio."
140
-
141
-NORMALIZE="none"
142
-until $(verify $NORMALIZE set "n N y Y yes Yes")
143
-do
144
-echo -n "normalize audio (default yes) [y/n]? "
145
-read NORMALIZE
146
-done
147
-if test "x$NORMALIZE" = "xn" || test "x$NORMALIZE" = "xN"; then
148
-  NORMALIZE=""
149
-else
150
-  NORMALIZE="-normalize"
151
-fi
152
-echo $SEPARATOR
153
-
154
-# 2 Any custom options?
155
-echo "Step 6 of 7:"
156
-precho "Would you like to pass other options to tovid? (see man tovid for more) Add any other options you want as if you were calling tovid. For example, if you wanted to add subtitles, you would type '-subtitles <file>'. Type [enter] for no custom options."
157
-echo -n "custom tovid options: "
158
-read CUSTOM_OPTIONS
159
-echo $SEPARATOR
160
-
161
-# 1 Get output prefix
162
-echo "Step 7 of 7:"
163
-precho "You are almost ready to encode your video. All I need now is the name you want to use for the output file. You don't need to give a filename extension (like .mpg); just type a name like 'MyVideo1'."
164
-echo -n "output name: "
165
-read OUT_PREFIX
166
-echo $SEPARATOR
167
-
168
-# Print last message and call tovid
169
-echo "Great! I will now start tovid with the options you chose. Here is the"
170
-echo "command that will be executed:"
171
-TOVID_CMD="tovid $NORMALIZE -$VIDFORMAT -$TVSYS -$ASPECT $CUSTOM_OPTIONS -in \"$INFILE\" -out \"$OUT_PREFIX\""
172
-echo $SEPARATOR
173
-precho "$TOVID_CMD"
174
-echo $SEPARATOR
175
-echo "Starting tovid in 5 seconds..."
176
-for COUNTER in 5 4 3 2 1; do
177
-  sleep 1s
178
-  echo -n "$COUNTER "
179
-done
180
-echo "Here goes!"
181
-eval $TOVID_CMD
182
-exit 0
183
tovid-0.34.tar.bz2/INSTALL -> tovid-0.35.tar.gz/INSTALL Changed
32
 
1
@@ -6,13 +6,6 @@
2
 
3
 This file contains configuration and installation instructions for tovid.
4
 
5
-!!!!
6
-NOTE: Prior releases of tovid used autoconf and automake, but these will
7
-be discontinued in a future release. As of tovid-0.33, setup.py is the
8
-recommended installation method.
9
-!!!!
10
-
11
-
12
 =====================================================
13
 INSTALLING FROM DISTRIBUTED SOURCE (*.tar.gz)
14
 =====================================================
15
@@ -25,6 +18,16 @@
16
     or
17
     $ sudo ./setup.py install
18
 
19
+If you want to install to somewhere other than /usr/local, you can use:
20
+    $ su -c './setup.py install --prefix=/opt' for example.
21
+Note: with some versions of python's distutils this will by default install
22
+modules to .../site-packages rather than .../dist-packages even if that is
23
+where your system's python looks for them.  See:
24
+https://bugs.launchpad.net/ubuntu/+source/python2.6/+bug/362570
25
+As a workaround, if you are using --prefix you can add:
26
+ --install-layout=deb .
27
+
28
+
29
 If you want to uninstall tovid, do this:
30
 
31
     $ su -c './setup.py uninstall'
32
tovid-0.34.tar.bz2/PKG-INFO -> tovid-0.35.tar.gz/PKG-INFO Changed
9
 
1
@@ -1,6 +1,6 @@
2
 Metadata-Version: 1.0
3
 Name: tovid
4
-Version: 0.34
5
+Version: 0.35
6
 Summary: UNKNOWN
7
 Home-page: http://tovid.wikia.com/
8
 Author: Eric Pierce
9
tovid-0.34.tar.bz2/docs/man/tovid.1 -> tovid-0.35.tar.gz/docs/man/tovid.1 Changed
1712
 
1
@@ -1,10 +1,13 @@
2
 .TH "tovid manual" 1 "" ""
3
 
4
+
5
 .SH Name
6
+
7
 .P
8
 tovid: Make DVDs from video files
9
 
10
 .SH Description
11
+
12
 .P
13
 \fBtovid\fR is a command\-line tool for creating DVDs. It can encode your video
14
 files to DVD\-compliant MPEG format, generate simple or complex DVD menus,
15
@@ -12,12 +15,17 @@
16
 graphical interface is also provided to make the process even easier.
17
 
18
 .P
19
-\fBNOTE\fR: As of tovid 0.32, this is the only manual page provided by tovid.
20
-There is now a single executable frontend to all functionality in the suite, so
21
-if you were expecting to find manpages for \fBtodisc\fR, \fBidvid\fR, \fBmakemenu\fR
22
-and their kin, they can all be found in the \fBtovid\fR manpage you are reading now.
23
+\fBNOTE\fR: As of tovid 0.35, the legacy scripts \fBmakemenu\fR and \fBmakexml\fR
24
+have been removed and no longer appear in this manpage.
25
+All of their functions and more can be done with the 'tovid disc' command,
26
+(todisc script). See \fBCommand:disc\fR and the wiki (http://tovid.wikia.com)
27
+for more info.
28
 
29
 .P
30
+Also note that as of tovid 0.32, this is the only manual page provided by tovid.
31
+There is now a single executable frontend to all functionality in the suite, so
32
+if you were expecting to find manpages for \fBtodisc\fR, \fBidvid\fR, \fBmakempg\fR
33
+and their kin, they can all be found in the \fBtovid\fR manpage you are reading now.
34
 And yes, this makes for a pretty large manual page. If you are viewing this
35
 manpage from the command\-line \fBman\fR utility, which normally pages through the
36
 \fBless\fR utility, you can skip to a section by searching with the \fB/\fR key,
37
@@ -26,104 +34,152 @@
38
 to navigate.
39
 
40
 .SH Usage
41
+
42
 .P
43
 \fBtovid\fR \fICOMMAND\fR [\fIOPTIONS\fR]
44
 
45
 .P
46
 Where \fICOMMAND\fR is one of the following:
47
 
48
+.P
49
+    Main Commands
50
+
51
+.TP
52
+\fBdisc\fR
53
+Encode, make menus, author, burn. (was \fBtodisc\fR. See \fBCommand:disc\fR)
54
 .TP
55
 \fBgui\fR
56
 Start the tovid GUI (was \fBtodiscgui\fR. See \fBCommand:gui\fR)
57
 .TP
58
 \fBtitlesets\fR
59
-A tovid GUI wizard for multiple titlesets. (new: See \fBCommand:titlesets\fR)
60
-.TP
61
-\fBdisc\fR
62
-Create a DVD with menus (was \fBtodisc\fR. See \fBCommand:disc\fR)
63
+A GUI wizard for multiple titlesets. (new: See \fBCommand:titlesets\fR)
64
+
65
+.P
66
+    Helper Commands
67
+
68
 .TP
69
 \fBmpg\fR
70
 Encode videos to MPEG format (was \fBtovid\fR. See \fBCommand:mpg\fR)
71
 .TP
72
-\fBid\fR
73
-Identify one or more video files (was \fBidvid\fR. See \fBCommand:id\fR)
74
-.TP
75
-\fBmenu\fR
76
-Create an MPEG menu (was \fBmakemenu\fR. See \fBCommand:menu\fR)
77
-.TP
78
-\fBxml\fR
79
-Create (S)VCD or DVD .xml file (was \fBmakexml\fR. See \fBCommand:xml\fR)
80
-.TP
81
 \fBdvd\fR
82
 Author and/or burn a DVD (was \fBmakedvd\fR. See \fBCommand:dvd\fR)
83
 .TP
84
-\fBvcd\fR
85
-Author and/or burn a VCD (was \fBmakevcd\fR. See \fBCommand:vcd\fR)
86
-.TP
87
-\fBpostproc\fR
88
-Post\-process an MPEG video file (was \fBpostproc\fR. See \fBCommand:postproc\fR)
89
+\fBid\fR
90
+Identify one or more video files (was \fBidvid\fR. See \fBCommand:id\fR)
91
 .TP
92
 \fBchapters\fR
93
 A GUI using mplayer for setting chapter points.  It will return a string of
94
-chapter points in a format recognized by 'tovid disc' (todisc) or
95
-by 'tovid gui', for the  \fB\-chapters\fR option.
96
+chapter points to the terminal, in a format recognized by 'tovid disc'
97
+(todisc) or by 'tovid gui', for the  \fB\-chapters\fR option.
98
 
99
 .P
100
 The \fIOPTIONS\fR differ for each command; run \fBtovid <command>\fR with no
101
 further arguments to get help on a command, and what options it expects.
102
 
103
 .SH Configuration
104
+
105
 .P
106
 Two configuration files are created the first time you run tovid:
107
 
108
 .TP
109
 \fB~/.tovid/preferences\fR
110
 Defines working directory for all scripts.
111
-In addition you can define the output directory for makempg here.
112
+You can define the output directory for makempg here.
113
+The 'ffmpeg' executable can be set here: ffmpeg or avconv (TOVID_FFMPEG)
114
 .TP
115
 \fB~/.tovid/tovid.ini\fR
116
 Includes command\-line options that should be passed to the various
117
-\fBtovid\fR sub\-commands.
118
+\fBtovid\fR sub\-commands.  Note: each sub\-command has its own section,
119
+starting with the line [sub\-command], for example:
120
+.nf
121
+    [disc]
122
+    ; -no-warn
123
+    -static
124
+    -no-ask
125
+.fi
126
+
127
 
128
+
129
+.P
130
 Edit these files if you wish to change your configuration.
131
 
132
+.P
133
 The following environment variables are also honoured:
134
-TOVID_WORKING_DIR (working directory for all scripts).
135
-TOVID_OUTPUT_DIR (output directory for the makempg script).
136
+
137
+.nf
138
+    TOVID_HOME (directory containing preferences: ~/.tovid)
139
+    TOVID_WORKING_DIR (working directory for all scripts).
140
+    TOVID_OUTPUT_DIR (output directory for the makempg script).
141
+    TOVID_FFMPEG_CMD (the 'ffmpeg' executable to use: ffmpeg or avconv)
142
+.fi
143
+
144
+
145
+.P
146
+These will override 'TOVID_HOME', 'WORKING_DIR', 'OUTPUT_DIR',
147
+and 'TOVID_FFMPEG' if set in ~/.tovid/preferences.
148
 
149
 .SH Command:gui
150
+
151
+.SH Usage
152
+
153
+.P
154
+\fBtovid gui\fR [\fIOPTIONS\fR]
155
+
156
 .P
157
 \fBtovid gui\fR starts the graphical user interface (GUI) for tovid. This is
158
-the easiest way to start creating DVDs with tovid. At this time, there are no
159
-additional command\-line options; the GUI controls take care of everything,
160
-and all help is integrated in the form of tooltips.  You can also see
161
-**Command:disc ** for more detail about the options.  Note: if you wish to
162
-make multiple titlesets on the same DVD use 'tovid titlesets', which is a wizard
163
-that uses the the tovid GUI.  Chapter submenus can be made with 'tovid gui'
164
-however.
165
+the easiest way to start creating DVDs with tovid. The optional arguments
166
+\fIOPTIONS\fR are any option used by todisc ('tovid disc') which will save
167
+entering it manually, OR the full path to a saved script from the GUI.
168
+You can also combine these, but the script must be the FIRST option
169
+directly after \fBtovid gui\fR .  (This option to save the contents of your
170
+project allows you to use it as a bash script later, or to reload the
171
+project to continue working with it at another time.)
172
+
173
+.P
174
+\fBtovid gui\fR will also take the option \fB\-\-position\fR, which denotes the
175
+screen position that the GUI will start at, in the form '+X+Y', similar to
176
+this part of the Xorg \-geometry string.
177
+
178
+.P
179
+All help is integrated in the form of tooltips.  You can also see
180
+**Command:disc ** for more detail about the options.  Note: if you wish to use
181
+a GUI to make multiple titlesets on the same DVD use \fB*tovid titlesets*\fR,
182
+which is a wizard that uses the the 'tovid gui. See \fB*Command:titlesets*\fR.
183
+
184
+.P
185
+Please note that although the interface may seem complex with so many options,
186
+you can create a fully functional DVD with only a few options on the opening
187
+tab of the GUI (select video files and an output name).
188
 
189
 .SH Command:titlesets
190
+
191
 .P
192
 \fBtovid titlesets\fR will assist in making a DVD with multiple titlesets.  It can
193
 be started without any options, or you can feed it the path to a saved titleset
194
-script as an option.
195
+script as an option.  The option to save a script is also useful as the resulting
196
+script can be run later from a terminal.
197
 
198
 .SH Command:disc
199
+
200
 .P
201
-\fBtovid disc\fR creates a DVD file\-system with menus, from a list of multimedia
202
-video files and their titles.  As this is a low level script it is the easiest
203
-command line program for creating a DVD from start to finish, including
204
-automatically converting non\-compliant videos and prompting to burn at
205
-completion.  It does animated menus, static thumbnail menus and text only
206
-menus.  In addition, it can do slideshows, using images as input, and combine
207
-slideshows with videos.  It supports sub\-menus for chapter breaks, configurable
208
-menu style, animated backgrounds and transparency effects.
209
+\fBtovid disc\fR creates a DVD file\-system with optional menus, from a list of
210
+multimedia video files and their titles.  As todisc can function as a master
211
+script, calling other scripts as it needs them, it is the easiest command line
212
+program for creating a DVD from start to finish, including automatically
213
+converting non\-compliant videos and prompting to burn at completion.  It can do
214
+animated menus, static thumbnail menus, text\-only menus, or author with no menu.
215
+In addition, it can do slideshows, using images as input, and even combine
216
+slideshows with videos.  It supports sub\-menus for chapter breaks,
217
+configurable menu style, animated backgrounds and transparency effects.
218
+From simple (no menu) to complex (switched menus and titlesets), you should
219
+be able to do what you want with 'tovid disc'.
220
 
221
 .SS Usage
222
+
223
 .nf
224
-   tovid disc [OPTIONS] \e
225
-      -files <file list> -titles <title list>
226
-      -out OUT_PREFIX
227
+ tovid disc [OPTIONS] \e
228
+    -files <file list> -titles <title list>
229
+    -out mydvd
230
 .fi
231
 
232
 
233
@@ -131,9 +187,9 @@
234
 For example:
235
 
236
 .nf
237
-   $ tovid disc -files File1.mpg File2.mpg File3.mpg \e
238
-        -titles "Episode 1" "Episode 2" "Episode 3" \e
239
-        -out Season_one
240
+ $ tovid disc -files File1.mpg File2.mpg File3.mpg \e
241
+      -titles "Episode 1" "Episode 2" "Episode 3" \e
242
+      -out Season_one
243
 .fi
244
 
245
 
246
@@ -143,12 +199,15 @@
247
 as titles.  If you are doing a slideshow or multiple slideshows, use
248
 \fB\-slides\fR rather than \fB\-files\fR for passing in the images.  You may use
249
 \-files and \-slides more than once to create an ordering in a mixed
250
-slideshows/videos menu.  See SLIDESHOWS part of Usage section, below.
251
+slideshows/videos menu.  See Slideshows part of Usage section, below.
252
 
253
 .P
254
 If the input files are not mpeg, you will have the option to auto\-encode them.
255
 
256
 .P
257
+General Options
258
+
259
+.P
260
 \fBAt present there are 2 display arrangements or "templates":\fR
261
 
262
 .TP
263
@@ -184,19 +243,40 @@
264
 sub\-menus, which can display longer titles, for example:
265
 
266
 .nf
267
-   $ tovid disc -submenus \e
268
-        -files file1.mpg file2.mpg ... \e
269
-        -titles "Short 1" "Short 2" \e
270
-        -submenu-titles "Long Title One" "Long Title Two" \e
271
-        -out foo
272
-  
273
+ $ tovid disc -submenus \e
274
+      -files file1.mpg file2.mpg ... \e
275
+      -titles "Short 1" "Short 2" \e
276
+      -submenus \e
277
+      -submenu-titles "Long Title One" "Long Title Two" \e
278
+      -out foo
279
+
280
 .fi
281
 
282
 
283
 .P
284
 The \fB\-align\fR argument will position both titles and thumbs either south,
285
 north east, west, southwest, northwest, southeast, northeast, subject to
286
-certain constraints of each arrangement.
287
+certain constraints of each arrangement. For example a showcase style with
288
+a showcase thumb can only do north|south|center.
289
+
290
+.P
291
+More Examples:
292
+
293
+.P
294
+A text\-only menu:
295
+
296
+.nf
297
+ $ tovid disc -textmenu ...
298
+.fi
299
+
300
+
301
+.P
302
+No menu:
303
+
304
+.nf
305
+ $ tovid -nomenu -files file1.mpg file2.mp4 "file 3.avi" -out mydvd
306
+.fi
307
+
308
 
309
 .P
310
 \fBTitlesets\fR
311
@@ -216,9 +296,9 @@
312
 
313
 .P
314
 Any options outside the \fB\-titleset\fR \fB\-end\-titleset\fR and \fB\-vmgm\fR
315
-\fB\-end\-vmgm\fR areas will be general options applying to every titleset.
316
-If a general option is duplicated inside a \fB\-titleset\fR or \fB\-vmgm\fR area, the
317
-general option will be overridden.
318
+\fB\-end\-vmgm\fR areas will be global options applying to every titleset.
319
+If a global option is duplicated inside a \fB\-titleset\fR or \fB\-vmgm\fR area, the
320
+global option will be overridden.
321
 
322
 .P
323
 Note: you do not need titlesets for a single menu with chapter break menus, for
324
@@ -228,24 +308,26 @@
325
 Example of using \fBtovid disc\fR with titlesets:
326
 
327
 .nf
328
-   $ tovid disc -static -out MY_DVD \e
329
-      \e
330
-     -titleset -files 1.mpg 2.mpg 3.mpg \e
331
-     -titles "Title One" "Title Two" "Title Three" \e
332
-     -end-titleset \e
333
-     \e
334
-     -titleset -files 4.mpg 5.mpg \e
335
-     -titles "Title Four" "Title Five" \e
336
-      -background foo.jpg \e
337
-      -showcase bar.png \e
338
-      -end-titleset \e
339
-      \e
340
-      -vmgm \e
341
-      -titles "Season One" "Season Two" \e
342
-      -background bg.jpg \e
343
-      -bgaudio foo.mp3 \e
344
-      -titles-fontsize 20 \e
345
-      -end-vmgm
346
+ $ tovid disc -static -out MY_DVD \e
347
+   \e
348
+   -titleset \e
349
+   -files 1.mpg 2.mpg 3.mpg \e
350
+   -titles "Title One" "Title Two" "Title Three" \e
351
+   -end-titleset \e
352
+   \e
353
+   -titleset \e
354
+   -files 4.mpg 5.mpg \e
355
+   -titles "Title Four" "Title Five" \e
356
+   -background foo.jpg \e
357
+   -showcase bar.png \e
358
+   -end-titleset \e
359
+   \e
360
+   -vmgm \e
361
+   -titles "Season One" "Season Two" \e
362
+   -background bg.jpg \e
363
+   -bgaudio foo.mp3 \e
364
+   -titles-fontsize 20 \e
365
+   -end-vmgm
366
 .fi
367
 
368
 
369
@@ -285,42 +367,44 @@
370
 Example of a single slideshow with an animated menu with transitions:
371
 
372
 .nf
373
-   $ tovid disc -menu-title "Autumn in Toronto" -slides images/*.jpg \e
374
-      -menu-slide-total 20 -slide-transition crossfade -bgaudio slideshow.wav \e
375
-      -out myslideshow
376
+ $ tovid disc -menu-title "Autumn in Toronto" -slides images/*.jpg \e
377
+    -menu-slide-total 20 -slide-transition crossfade -bgaudio slideshow.wav \e
378
+    -out myslideshow
379
 .fi
380
 
381
+
382
 .P
383
 Example of multiple slideshows on one menu:
384
 
385
 .nf
386
-   $ tovid disc -menu-title "Autumn in Toronto" \e
387
-     -slides photos/september/*.jpg \e
388
-     -slides photos/october/*.jpg \e
389
-     -slides photos/november/*.jpg \e
390
-     -tile3x1 -rotate -5 5 -5 -align center \e
391
-     -bgaudio background.wav \e
392
-     -out myslideshow
393
+ $ tovid disc -menu-title "Autumn in Toronto" \e
394
+   -slides photos/september/*.jpg \e
395
+   -slides photos/october/*.jpg \e
396
+   -slides photos/november/*.jpg \e
397
+   -tile3x1 -rotate -5 5 -5 -align center \e
398
+   -bgaudio background.wav \e
399
+   -out myslideshow
400
 .fi
401
 
402
+
403
 .P
404
 Example of mixed videos and slideshows:
405
 
406
 .nf
407
-   $ tovid disc -menu-title "Autumn in Toronto" \e
408
-     -files fall_fair.mov \e
409
-     -slides  photos/september/*.jpg \e
410
-     -files harvest.mpg \e
411
-     -slides photos/october/*.jpg \e
412
-     -titles "Fall Fair" "September" "Harvest" "October" \e
413
-     -background autumn.png \e
414
-     -bgaudio bg.mp3 \e
415
-     -out myslideshow
416
+ $ tovid disc -menu-title "Autumn in Toronto" \e
417
+   -files fall_fair.mov \e
418
+   -slides  photos/september/*.jpg \e
419
+   -files harvest.mpg \e
420
+   -slides photos/october/*.jpg \e
421
+   -titles "Fall Fair" "September" "Harvest" "October" \e
422
+   -background autumn.png \e
423
+   -bgaudio bg.mp3 \e
424
+   -out myslideshow
425
 .fi
426
 
427
 
428
 .P
429
-See the other slideshow options in the SLIDESHOWS options section.
430
+See the other slideshow options in the Slideshows options section.
431
 
432
 .P
433
 \fBEncoding Options\fR
434
@@ -336,16 +420,47 @@
435
     \fB\-vbitrate\fR, \fB\-quality\fR, \fB\-safe\fR, \fB\-crop\fR, \fB\-filters\fR,
436
     \fB\-abitrate\fR, \fB\-priority\fR, \fB\-deinterlace\fR, \fB\-progressive\fR,
437
     \fB\-interlaced\fR, \fB\-interlaced_bf\fR, \fB\-type\fR, \fB\-fit\fR, \fB\-discsize\fR,
438
-    \fB\-parallel\fR, \fB\-mkvsub\fR, \fB\-autosubs\fR, \fB\-subtitles\fR, \fB\-update\fR, \e
439
+    \fB\-parallel\fR, \fB\-mkvsub\fR, \fB\-autosubs\fR, \fB\-subtitles\fR, \fB\-update\fR,
440
     \fB\-mplayeropts\fR, \fB\-audiotrack\fR, \fB\-downmix\fR, \fB\-ffmpeg\fR, \fB\-nofifo\fR,
441
     \fB\-from\-gui\fR, \fB\-slice\fR, \fB\-quiet\fR,
442
     \fB\-fake\fR, \fB\-keepfiles\fR
443
 
444
-.SS Options
445
+.SS General Options
446
+
447
 .TP
448
 \fB\-keep\-files\fR, \fB\-keepfiles\fR
449
 Keep all intermediate/temporary files (helps with debugging)
450
 .TP
451
+\fB\-no\-ask\fR | \fB\-noask\fR
452
+Skip all interactive questions.  No preview, automatic re\-encoding with
453
+tovid if needed, no interactive option to use background video for bgaudio.
454
+.TP
455
+\fB\-no\-warn\fR, \fB\-nowarn\fR
456
+Don't pause after outputting warning or info messages
457
+.TP
458
+\fB\-jobs\fR
459
+By default, \fBtovid disc\fR starts a parallel job for each processor
460
+detected.  With this option you can manually set the number of jobs.  For
461
+example if you have a computer with 2 CPUs you can set "\-jobs 1" to keep
462
+one processor free for other things.  At present this applies to the time
463
+consuming imagemagick loops: you will notice a substantial speedup now if
464
+you have a multi\-cpu system.
465
+.TP
466
+\fB\-grid\fR
467
+Show a second preview image with a grid and numbers that will help in finding
468
+coordinates for options that might use them, like \fB\-text\-start\fR
469
+.TP
470
+\fB\-no\-confirm\-backup\fR
471
+This option is for when your DVD contains images for a slideshow.
472
+Slideshows are an experimental (but well tested) feature.  Todisc is
473
+unlikely to overwrite your personal files, but you should take precautions
474
+and backup your images, as you would with any beta software.  Todisc
475
+will prompt you to backup your files normally.  If you have already backed
476
+up your images, use this option to disable the prompt.
477
+
478
+==Options==
479
+
480
+.TP
481
 \fB\-ntsc\fR
482
 720x480 output, compatible with NTSC standard (default)
483
 .TP
484
@@ -362,21 +477,31 @@
485
 \fB\-no\-menu | \-nomenu\fR
486
 With this option todisc will just create a DVD file system, ready for
487
 burning, with NO MENU, just the supplied video files.  These do not need
488
-to be compliant, as non\-compliant files will be encoded as usual.  Each
489
-video will be a chapter unless \fB\-chapters\fR OPTION is passed.  The
490
-\fB\-chapters\fR option is a number indicating the chapter interval in
491
-minutes, or a HH:MM:SS string indicating chapter points.  See \fB\-chapters\fR
492
+to be compliant, as non\-compliant files will be encoded as usual.  The
493
+\fB\-out\fR option is not required.  Each  video will be a chapter unless
494
+\fB\-chapters\fR OPTION is passed.  The  \fB\-chapters\fR option is a number
495
+indicating the chapter interval in minutes, or a HH:MM:SS string
496
+indicating chapter points.  See \fB\-chapters\fR
497
+.TP
498
+\fB\-encode\-only\fR
499
+This option was originally meant for the GUI, to allow it to be used for
500
+just encoding rather than making a DVD structure.  But it works well from
501
+the command line as well as it has the added advantage that you can input
502
+a list of files.  Remember any makempg ('tovid mpg') options you use will
503
+be passed on to the makempg script when encoding.
504
 
505
 .SS Menu style
506
+
507
 .TP
508
 \fB\-showcase\fR IMAGE|VIDEO
509
 If used without an argument, use showcase style without a central thumb.
510
 This is a different arrangement of images for the menu: small thumbnails
511
 go at left (and right) side of screen, with a larger image in the centre.
512
 Maximum of 10 videos.  If the provided argument is a video file, the
513
-central thumb will be animated. Only 4:3 or 16:9 videos and images are
514
-accepted for the showcase file: if not one of these todisc will assume it
515
-is the same ratio as the videos in the titleset.
516
+central thumb will be animated (regardless of whether \fB\-static\fR is part
517
+of the command line). Only 4:3 or 16:9 videos and images are accepted for
518
+for the showcase file: if not one of these todisc will assume it is the
519
+aspect ratio as the videos in the titleset.
520
 .TP
521
 \fB\-textmenu\fR, \fB\-text\-menu\fR NUM
522
 If used without an argument, create a textmenu out of the supplied titles
523
@@ -384,9 +509,9 @@
524
 i.e. giving 4 titles and using "\-textmenu 2" would make 2 columns of 2
525
 titles. The default is to put all titles up to 13 in the first column
526
 before starting a second column.  Maximum: 2 columns and 26 titles.
527
-Note that column 2 titles are aligned to the right.
528
-If no video files for either \fB\-background\fR or \fB\-showcase\fR are supplied,
529
-the menu will be static.
530
+Note that column 2 titles are justified to the left unless you add
531
+\fB\-edge\-justify\fR to the command line. The menu will be static if no video
532
+files are supplied with either \fB\-background\fR or \fB\-showcase\fR options.
533
 .TP
534
 \fB\-quick\-menu\fR
535
 If you are using ffmpeg 0.8 or newer you can use this option.  This will
536
@@ -397,21 +522,22 @@
537
 text\-menu style of menu, with no video thumbs, and a central showcase
538
 IMAGE(static) | VIDEO(animated).
539
 (i) see \fB\-bg\-color\fR if you are not using a \fB\-background\fR and want to
540
-change the default black )
541
-(ii) Note: todisc will still work with vhooks if you have an old ffmpeg with
542
-vhooks compiled in.
543
+change the default.  (default is dark blue for \-quick\-menu arrangements). )
544
+(ii) Note: todisc will still work with 'vhooks' if you have an old ffmpeg
545
+with vhooks compiled in.
546
 
547
 Specifying the IMAGE|VIDEO argument to \fB\-showcase\fR is mandatory for this
548
 style of menu, unless used in conjunction with \fB\-switched\-menus\fR
549
 in which case the videos passed with \fB\-files\fR automatically become the
550
-showcase videos.  If this is used in combination with \fB\-switched\-menus\fR
551
-it can really speed up an otherwise time consuming process.
552
+showcase videos.  If \fB\-quick\-menu\fR is used in combination with
553
+\fB\-switched\-menus\fR it really speeds up an otherwise time consuming process.
554
 
555
 Example:
556
 .nf
557
-      -quick-menu -showcase /home/robert/showcase.mpg
558
+    -quick-menu -showcase /home/grepper/showcase.mpg
559
 .fi
560
 
561
+
562
 See \fB\-switched\-menus\fR for example of making switched menus with
563
 \fB\-quick\-menu\fR
564
 
565
@@ -420,7 +546,8 @@
566
 The color to use for the menu background. (default: ntsc\-safe black)
567
 Note: use a color a great deal darker than you want, as it appears quite
568
 a bit lighter in the video version.  You can use hexadecimal ('#ffac5f')
569
-or named colors notation.
570
+notation or named colors ('Lime').  convert \-list color will show them.
571
+See colors (http://www.imagemagick.org/script/color.php) for more details.
572
 .TP
573
 \fB\-submenu\-bg\-color\fR, \fB\-submenu\-bg\-colour\fR
574
 The color to use as background for the  submenu(s).
575
@@ -432,7 +559,7 @@
576
 a 'moving' menu, in spite of the static buttons.  This option also does
577
 double duty for the \fB\-switched\-menus\fR option, and will create static
578
 "switched" images.
579
-See also \fB\-switched\-menu\fR
580
+See also \fB\-switched\-menus\fR
581
 .TP
582
 \fB\-background\fR IMAGE|VIDEO
583
 Menu background.  This can be a image file or an video file.  If it is a
584
@@ -448,25 +575,26 @@
585
 \fB\-menu\-title\fR
586
 Title for the root menu \- may be longer than thumbnail labels
587
 Also if you use \en in the title, you can use multi line titles, but you
588
-would need to adjust \fB\-menu\-fontsize\fR to something smaller than default
589
+would need to adjust \fB\-title\-fontsize\fR to something smaller than default
590
 for example:
591
 
592
 .nf
593
-      $ tovid disc ... -menu-title "A\enMultilined\enTitle" -menu-fontsize 24
594
+    $ tovid disc ... -menu-title "A\enMultilined\enTitle" -title-fontsize 24
595
 .fi
596
 
597
+
598
 .TP
599
-\fB\-menu\-font\fR FONT
600
+\fB\-title\-font\fR, \fB\-menu\-font\fR FONT
601
 Font to use for titles, either by ImageMagick font name (ex., "Arial") or
602
 explicit pathname (ex., "/full/path/to/arial.ttf"). To see a complete
603
 list of acceptable ImageMagick font names, run \fBconvert \-list type\fR, and
604
 refer to the leftmost column
605
 .TP
606
-\fB\-menu\-fontsize\fR
607
+\fB\-title\-fontsize\fR, \fB\-menu\-fontsize\fR
608
 Font size for main menu \- best to \-preview if you use this
609
 .TP
610
 \fB\-submenu\-font\fR
611
-Font to use for the sub\-menu main titles.  See \fB\-menu\-font\fR
612
+Font to use for the sub\-menu main titles.  See \fB\-title\-font\fR
613
 .TP
614
 \fB\-submenu\-fontsize\fR
615
 Font size for the sub\-menu main titles
616
@@ -525,7 +653,7 @@
617
 \fB\-skip\-vmgm\fR
618
 Start DVD from the first titleset instead of the VMGM ( root ) menu.
619
 .TP
620
-\fB\-switched\-menus\fR
621
+\fB\-switched\-menus\fR, \fB\-switched\-menu\fR
622
 This will make a "switched menu": there will be a central image where the
623
 showcase image would go, and text menu titles along the menu edge where
624
 textmenu titles go.  As you select a video title with the down or up arrow
625
@@ -543,11 +671,19 @@
626
 
627
 Example for using with \fB\-quick\-menu\fR:
628
 .nf
629
-      -switched-menus -quick-menu
630
+    -switched-menus -quick-menu
631
 .fi
632
 
633
 
634
+
635
 .SS Thumbnail style
636
+
637
+.TP
638
+\fB\-titles\-font\fR FONT
639
+Display thumbnail or textmenu titles in the given font
640
+.TP
641
+\fB\-titles\-fontsize\fR POINTS
642
+Font size to use for thumbnail or textmenu titles
643
 .TP
644
 \fB\-thumb\-shape\fR
645
 normal|oval|vignette|plectrum|arch|spiral|blob|star|flare
646
@@ -573,14 +709,9 @@
647
 \fB\-3d\-thumbs\fR, \fB\-3dthumbs\fR
648
 This will give an illusion of 3D to the thumbnails: dynamic lighting on
649
 rounded thumbs, and a raised effect on rectangular thumbs.  Try it !
650
-.TP
651
-\fB\-titles\-font\fR FONT
652
-Display thumbnail or textmenu titles in the given font
653
-.TP
654
-\fB\-titles\-fontsize\fR POINTS
655
-Font size to use for thumbnail or textmenu titles
656
 
657
 .SS Slideshows
658
+
659
 .TP
660
 \fB\-slides\fR IMAGES
661
 Use \fB\-slides\fR IMAGES to pass in images for a slideshow.  The default is
662
@@ -682,7 +813,7 @@
663
 be static.  If you used with a mixed menu of videos and slideshows, then
664
 the video thumbs WILL be animated, so you may wish to use \-static or
665
 \-textmenu with the option in that case.  If you want to use the
666
-**\-switched\-menus option with a mixed menu leave this option out. 
667
+**\-switched\-menus option with a mixed menu leave this option out.
668
 
669
 .TP
670
 \fB\-background\-slideshow\fR, \fB\-bg\-slideshow\fR
671
@@ -697,6 +828,7 @@
672
 and backup your images, as you would with any beta software.  Todisc
673
 will prompt you to backup your files normally.  If you have already backed
674
 up your images, use this option to disable the prompt.
675
+See \fBGeneral Options\fR
676
 
677
 .TP
678
 \fB\-use\-dvd\-slideshow\fR CONFIG (FILE)
679
@@ -709,6 +841,7 @@
680
 override many of the above options for slideshows.
681
 
682
 .SS Burning the disc
683
+
684
 .TP
685
 \fB\-burn\fR
686
 Prompt to burn the DVD directory on completion.
687
@@ -721,8 +854,10 @@
688
 \fB\-speed\fR
689
 The speed to use for burning the disc.
690
 
691
-.SS ADVANCED USAGE
692
+.SS Advanced usage
693
+
694
 .SS Options
695
+
696
 .TP
697
 \fB\-menu\-length\fR
698
 The desired animated main menu length in seconds
699
@@ -733,13 +868,13 @@
700
 The default is to use 10 seconds of audio for static menus.
701
 .TP
702
 \fB\-submenu\-stroke\fR COLOR
703
-The color for the sub\-menu font outline (stroke)
704
+The color for the sub\-menu font shadow
705
 .TP
706
 \fB\-submenu\-title\-color\fR, \fB\-submenu\-title\-colour\fR
707
 The fill color used for sub\-menu title fonts
708
 .TP
709
 \fB\-submenu\-titles\fR
710
-You can supple a list of titles here for sub\-menus without the length
711
+You can supply a list of titles here for sub\-menus without the length
712
 restrictions found in thumb titles.  Must equal number of videos
713
 .TP
714
 \fB\-chapters\fR [ NUM | CHAPTER POINTS in HH:MM:SS ]
715
@@ -776,26 +911,29 @@
716
 
717
 Example for passing just number of chapters ( 4 videos ):
718
 .nf
719
-      -chapters 5 2 4 8
720
+    -chapters 5 2 4 8
721
 .fi
722
 
723
 
724
+
725
 Example of passing chapter points ( 4 videos ):
726
 .nf
727
-      -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45 \e
728
-      00:00:00,00:04:25.623,00:09:12,00:15:51 \e
729
-      00:00:00,00:05:10,00:13:41,00:18:13.033 \e
730
-      00:00:00,00:15:23.342,00:26:42.523
731
+    -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45 \e
732
+    00:00:00,00:04:25.623,00:09:12,00:15:51 \e
733
+    00:00:00,00:05:10,00:13:41,00:18:13.033 \e
734
+    00:00:00,00:15:23.342,00:26:42.523
735
 .fi
736
 
737
 
738
+
739
 Example of passing grouped chapters using the '+' separator:
740
 .nf
741
-      -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45+00:04:23,00:09:35 \e
742
-      00:00:00... etc.
743
+    -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45+00:04:23,00:09:35 \e
744
+    00:00:00... etc.
745
 .fi
746
 
747
 
748
+
749
 .TP
750
 \fB\-chapter\-titles\fR LIST
751
 If you are using submenus, you can pass a list of titles for the
752
@@ -819,7 +957,7 @@
753
 The color for the chapters font.
754
 .TP
755
 \fB\-chapter\-stroke\fR COLOR
756
-The color for the chapters font outline (stroke)
757
+The color for the chapters font shadow
758
 
759
 .TP
760
 \fB\-seek\fR NUM | "NUM1 NUM2 NUM3 . . ."
761
@@ -859,43 +997,27 @@
762
 video. Example:
763
 
764
 .nf
765
-      -group 2 2.mpg 3.mpg 4.mpg
766
+    -group 2 2.mpg 3.mpg 4.mpg
767
 .fi
768
 
769
 
770
+
771
 will group these 3 videos with the 2nd video given with \fB\-files\fR, so that
772
 they will play sequentially as one title.  Only one thumbnail and/or title
773
 will appear on the menu for the group: it will be made from the 1st video
774
 in the group.  In the above example if you passed:
775
 .nf
776
-      -files foo.mpg bar.mpg baz.mpg -group 2 2.mpg 3.mpg 4.mpg
777
+    -files foo.mpg bar.mpg baz.mpg -group 2 2.mpg 3.mpg 4.mpg
778
 .fi
779
 
780
+
781
 then the group will consist of bar.mpg  2.mpg, 3.mpg and 4.mpg, and only the
782
 title and/or thumbnail for bar.mpg will appear in the menu.  You can use
783
 \fB\-group\fR more than once for multiple groups.  Be  sure to quote video
784
 filenames if they contain  spaces.
785
-.TP
786
-\fB\-jobs\fR
787
-By default, \fBtovid disc\fR starts a parallel job for each processor
788
-detected.  With this option you can manually set the number of jobs.  For
789
-example if you have a computer with 2 CPUs you can set "\-jobs 1" to keep
790
-one processor free for other things.  At present this applies to the time
791
-consuming imagemagick loops: you will notice a substantial speedup now if
792
-you have a multi\-cpu system.
793
-.TP
794
-\fB\-no\-ask\fR, \fB\-noask\fR
795
-Skip all interactive questions.  No preview, automatic re\-encoding with
796
-tovid if needed, no interactive option to use background video for bgaudio.
797
-.TP
798
-\fB\-no\-warn\fR, \fB\-nowarn\fR
799
-Don't pause after outputting warning or info messages
800
-.TP
801
-\fB\-grid\fR
802
-Show a second preview image with a grid and numbers that will help in finding
803
-coordinates for options that might use them, like \fB\-text\-start\fR
804
 
805
 .SS Menu Style
806
+
807
 .TP
808
 \fB\-menu\-title\-geo\fR north|south|east|west|center [south]
809
 The position of the menu title.  You may need to use \-align as well if
810
@@ -907,11 +1029,11 @@
811
 may need to use \-align as well if you don't want your title covering other
812
 parts of your menu.  See \fB\-align\fR
813
 .TP
814
-\fB\-button\-style\fR rect|text|line|text\-rect
815
+\fB\-button\-style\fR line|rect|text|text\-rect [line]
816
 The style of button that you will see when you play the DVD.
817
-"rect" draws a rectangle around the thumb when you select it
818
-in the DVD player.  "text" highlights the video title text, "line"
819
-underlines the title, and "text\-rect" draws a rectangle around the title
820
+"line" style underlines the title, "rect" draws a rectangle around the
821
+thumb when you select it in the DVD player, "text" highlights the video
822
+title text, and "text\-rect" draws a rectangle around the title
823
 text.
824
 .TP
825
 \fB\-title\-color\fR, \fB\-title\-colour\fR COLOR
826
@@ -920,12 +1042,27 @@
827
 http://www.imagemagick.org/script/color.php
828
 .TP
829
 \fB\-title\-stroke\fR COLOR
830
-Outline color for the main menu's title font. Use "none" for transparent
831
-outline  (see title\-color)
832
+Shadow color for the main menu's title font. Use "none" for transparent
833
+outline  (see title\-color).  Note: this is not a \-stroke in the sense that
834
+imagemagick uses the term, but a shadow (the font is drawn twice).  To get
835
+a true imagemagick stroke see \fB\-title\-font\-deco\fR
836
+.TP
837
+\fB\-title\-font\-deco\fR, \fB\-title\-fontdeco\fR "IMAGEMAGICK STRING"
838
+Sets the font decoration method to FONTDECORATION. It is used by the 'convert'
839
+ImageMagick command to draw the menu text. You can add colored text
840
+outlines, gradient fills, and many others. See \fBUsage notes\fR
841
 .TP
842
 \fB\-titles\-stroke\fR COLOR
843
-Outline color for the thumb or textmenu video titles font. Use "none" for
844
-transparent outline  (see \fB\-titles\-color\fR).
845
+Shadow color for the thumb or textmenu video titles font. Use "none" for
846
+transparent outline  (see \fB\-titles\-color\fR).  Note: this is not a \-stroke
847
+in the sense that imagemagick uses the term, but a shadow
848
+(the font is drawn twice).  To get a true imagemagick stroke,
849
+see \fB\-titles\-font\-deco\fR
850
+.TP
851
+\fB\-titles\-font\-deco\fR, \fB\-titles\-fontdeco\fR "IMAGEMAGICK STRING"
852
+Sets the font decoration method to FONTDECORATION. It is used by the 'convert'
853
+ImageMagick command to draw the menu text. You can add colored text
854
+outlines, gradient fills, and others. See \fBUsage notes\fR for more info.
855
 .TP
856
 \fB\-highlight\-color\fR, \fB\-highlight\-colour\fR
857
 Color to use for the menu buttons that your DVD remote uses to navigate.
858
@@ -968,7 +1105,8 @@
859
 At present it must be a DVD compatible video at the correct resolution etc.
860
 Only 4:3 aspect is supported: 16:9 will give unexpected results.
861
 
862
-.SS Menu Style options specific to showcase and textmenu arrangements
863
+.SS Style options specific to showcase/textmenu arrangements
864
+
865
 .TP
866
 \fB\-text\-start\fR N
867
 This option is for \fB\-textmenu\fR menus.  The titles will start at the Nth
868
@@ -984,7 +1122,8 @@
869
 this will not turn a portait image into a landscape image!
870
 .TP
871
 \fB\-showcase\-geo\fR GEOMETRY
872
-The position of the showcase image.  ( XxY position )
873
+The position of the showcase image.  ( +X+Y  position )
874
+For example: \fB\-showcase\-geo\fR +300+200
875
 .TP
876
 \fB\-wave\fR default|GEOMETRY
877
 Wave effect for showcase image|video.  Alters thumbs along a sine wave using
878
@@ -1025,12 +1164,14 @@
879
 rounded thumbs, and a raised effect on rectangular thumbs.  Try it !
880
 
881
 .SS Thumbnail Style
882
+
883
 .TP
884
-\fB\-user\-thumbs\fR IMAGE
885
+\fB\-user\-thumbs\fR IMAGE(S)
886
 Supply your own images for menu buttons, rather than relying on todisc to
887
 generate them from the video.  They must be the same aspect ratio as the
888
 videos in the titleset (4:3 or 16:9), as todisc will resize them without
889
-checking and cropping.
890
+checking and cropping.  There must be on image for each thumb that will be
891
+displayed on the menu (ie. one thumb for each video in a titleset).
892
 .TP
893
 \fB\-opacity\fR [0\-100] (default 100)
894
 Opacity of thumbnail videos as a percentage (no percent sign).
895
@@ -1048,10 +1189,27 @@
896
 values between 0.1 and 2.0.  This option has no effect on \fB\-3d\-showcase\fR.
897
 See \fB\-thumb\-blur\fR for more info.
898
 .TP
899
-\fB\-align\fR north|south
900
-This will align  thumbs/titles north or south.
901
+\fB\-align\fR DIRECTION
902
+This will align  thumbs/titles in DIRECTION, which is a compass direction
903
+as used by imagemagick: ie. north|south|east|west|northeast|northwest etc.
904
 If \fB\-align\fR south then menu title will align north, unless you manually
905
 set one or both of \fB\-menu\-title\-geo\fR or \fB\-menu\-title\-offset\fR.
906
+Only \fB\-align\fR north|south|center has any effect on showcase with thumb,
907
+or with the default montage arrangement of central thumbs. The most
908
+apparent changes with be with textmenu, though with 2 column arrangements
909
+only the north* and south* changes will show an effect.
910
+
911
+Diagram:
912
+.TP
913
+   . northwest   north   northeast .
914
+.TP
915
+   .                               .
916
+.TP
917
+   . west        center       east .
918
+.TP
919
+   .                               .
920
+.TP
921
+   . southwest   south    souteast .
922
 .TP
923
 \fB\-thumb\-mist\fR [COLOR]
924
 Use a mist behind thumbnails.  The optional argument is the color of the
925
@@ -1099,12 +1257,14 @@
926
 showcase template the titles will remain the same size. Example:
927
 
928
 .nf
929
-      -rotate-thumbs -10 10 -10 10 -10  (for 5 files)
930
+    -rotate-thumbs -10 10 -10 10 -10  (for 5 files)
931
 .fi
932
 
933
+
934
 **Note: this option will not turn a portrait image into a landscape image!
935
 
936
 .SS Dvdauthor options
937
+
938
 .TP
939
 \fB\-loop\fR PAUSE
940
 Pause in seconds at end of menu.  Use "inf" if you wish indefinite pause.
941
@@ -1118,7 +1278,7 @@
942
 the \fB\-vmgm\fR ... \fB\-end\-vmgm\fR options to allow playing ALL titlesets.
943
 (If you want also to have a playall button in each titleset you could use
944
 this option between each \fB\-titleset\fR ... \fB\-end\-titleset\fR option or put
945
-it outside of the vmgm and titlset options as a general option.
946
+it outside of the vmgm and titlset options as a global option.
947
 .TP
948
 \fB\-videos\-are\-chapters\fR
949
 A button will be made on the main menu for each video, which you can use as
950
@@ -1153,9 +1313,10 @@
951
 xml file.  It will affect all videos in the titleset.  Example:
952
 
953
 .nf
954
-      -aspect 16:9
955
+    -aspect 16:9
956
 .fi
957
 
958
+
959
 .TP
960
 \fB\-widescreen\fR nopanscan|noletterbox [nopanscan]
961
 This will output a <video widescreen=nopanscan /> tag (for example)
962
@@ -1164,9 +1325,10 @@
963
 Example:
964
 
965
 .nf
966
-      -aspect 16:9 -widescreen
967
+    -aspect 16:9 -widescreen
968
 .fi
969
 
970
+
971
 .TP
972
 \fB\-quick\-nav\fR
973
 This option will allow navigation of a menu with more than one titleset by
974
@@ -1194,13 +1356,42 @@
975
 for the last video in the group.  If providing a list of values they must
976
 equal the number of grouped videos.
977
 
978
+.SS Usage notes
979
+
980
+.P
981
+The argument given to various *\-font options that set the font to use must be
982
+one of the fonts listed by the command 'convert \-list type'. Please note that
983
+many of your installed fonts may not be available; if you want to maximize the
984
+number of fonts available to todisc, download and run
985
+Anthony Thyssen's (http://www.cit.gu.edu.au/~anthony/anthony.html)
986
+imagick_type_gen (http://www.imagemagick.org/Usage/scripts/imagick_type_gen)
987
+script and run it like this:
988
+imagick_type_gen > ~/.magick/type.xml.
989
+If that doesn't work, try imagick_type_gen > ~/.magick/type.mgk.
990
+
991
+.P
992
+Or you can specify a ttf font file directly to the *\-font options if you don't
993
+want to install fonts to ImageMagick.
994
+
995
+.P
996
+The *\-stroke options in todisc are not a stroke in the sense that ImageMagick
997
+uses the term, but rather a font shadow (the text is drawn twice)  To get a
998
+truer Imagemagick \-stroke try something like:
999
+\-title\-font\-deco "\-stroke black" (or \-titles\-font\-deco "\-stroke black").  The
1000
+\fB\-fontdeco\fR option is quite flexible and takes a lot of ImageMagick's
1001
+\fIconvert\fR options. Please refer to the tovid
1002
+wiki (http://tovid.wikia.com/wiki/Making_a_DVD_with_text_menus) and Anthony
1003
+Thyssen's guide [http://www.imagemagick.org/Usage] for further explanation and examples.
1004
+
1005
 .SH Command:mpg
1006
+
1007
 .P
1008
 \fBtovid mpg\fR converts arbitrary video files into (S)VCD/DVD\-compliant
1009
 MPEG format, suitable for burning to CD/DVD\-R for playback on a
1010
 standalone DVD player.
1011
 
1012
 .SS Usage
1013
+
1014
 .P
1015
 \fBtovid mpg\fR [\fIOPTIONS\fR] \fB\-in\fR \fIINFILE\fR \fB\-out\fR \fIOUTPREFIX\fR
1016
 
1017
@@ -1226,6 +1417,7 @@
1018
 Convert 'foo.avi' to PAL VCD format, saving to 'foo_encoded.mpg'.
1019
 
1020
 .SS Basic options
1021
+
1022
 .TP
1023
 \fB\-v\fR, \fB\-version\fR
1024
 Print tovid version number only, then exit.
1025
@@ -1245,6 +1437,7 @@
1026
 \fB\-subtitles\fR or  \fB\-filters\fR.
1027
 
1028
 .SS Television standards
1029
+
1030
 .TP
1031
 \fB\-ntsc\fR
1032
 NTSC format video (USA, Americas) (default)
1033
@@ -1256,6 +1449,7 @@
1034
 PAL format video (Europe and others)
1035
 
1036
 .SS Formats
1037
+
1038
 .P
1039
 Standard formats, should be playable in most DVD players:
1040
 
1041
@@ -1302,7 +1496,9 @@
1042
 format.
1043
 
1044
 .SS Advanced options
1045
+
1046
 .SS Aspect ratios
1047
+
1048
 .P
1049
 tovid automatically determines aspect ratio of the input video by playing it in
1050
 mplayer. If your video plays with correct aspect in mplayer, you should not
1051
@@ -1332,6 +1528,7 @@
1052
 for a widescreen monitor or TV.
1053
 
1054
 .SS Video stream options
1055
+
1056
 .TP
1057
 \fB\-quality\fR \fINUM\fR (default 6)
1058
 Desired output quality, on a scale of 1 to 10, with 10 giving the best
1059
@@ -1438,6 +1635,7 @@
1060
 \fB\-bdvd\fR), for optimal viewing on a widescreen monitor or TV.
1061
 
1062
 .SS Audio stream options
1063
+
1064
 .TP
1065
 \fB\-normalize\fR
1066
 Analyze the audio stream and then normalize the volume of the audio.
1067
@@ -1479,6 +1677,7 @@
1068
 will revert to the default behavior of using the original channels.
1069
 
1070
 .SS Other options
1071
+
1072
 .TP
1073
 \fB\-config\fR \fIFILE\fR
1074
 Read configuration from \fIFILE\fR, containing 'tovid' alone on the first
1075
@@ -1535,7 +1734,7 @@
1076
 seconds.
1077
 
1078
 .TP
1079
-\fB\-mplayeropts\fR \fB"\fR\fIOPTIONS\fR\fB"\fR
1080
+\fB\-mplayeropts\fR \fIOPTIONS\fR
1081
 Append \fIOPTIONS\fR to the mplayer command run during video encoding.  Use
1082
 this if you want to add specific video filters (documented in the mplayer
1083
 manual page). Overriding some options will cause encoding to fail, so use
1084
@@ -1570,12 +1769,14 @@
1085
 answers.
1086
 
1087
 .SH Command:id
1088
+
1089
 .P
1090
 \fBtovid id\fR identifies each multimedia video file in a
1091
 list, and reports its compliance with video disc standards such as VCD,
1092
 SVCD, and DVD.
1093
 
1094
 .SS Usage
1095
+
1096
 .P
1097
 \fBtovid id\fR [\fIOPTIONS\fR] \fIVIDEO_FILE(s)\fR
1098
 
1099
@@ -1588,6 +1789,7 @@
1100
 tovid id \-tabluar videos/*.mpg
1101
 
1102
 .SS Options
1103
+
1104
 .TP
1105
 \fB\-terse\fR
1106
 Print raw video characteristics, no formatting. Helpful when
1107
@@ -1614,6 +1816,10 @@
1108
 when identifying multiple video files.
1109
 
1110
 .TP
1111
+\fB\-keepfiles\fR
1112
+Keep temporary directory for debugging.
1113
+
1114
+.TP
1115
 \fB\-isformat\fR [\fIpal\-dvd\fR|\fIntsc\-dvd\fR] (same syntax for vcd and svcd)
1116
 Check \fIVIDEO_FILE\fR for compliance with the given disc format.
1117
 If \fIVIDEO_FILE\fR matches the given format, then \fBtovid id\fR reports "true"
1118
@@ -1622,6 +1828,7 @@
1119
 and pal/ntsc.
1120
 
1121
 .SS Examples
1122
+
1123
 .TP
1124
 tovid id \-verbose homevideo.avi
1125
 Report everything mplayer, ffmpeg, and transcode can determine about
1126
@@ -1631,390 +1838,19 @@
1127
 tovid id \-isformat dvd homevideo.mpg
1128
 Check to see if homevideo.mpg is compliant with the DVD standard.
1129
 
1130
-.SH Command:menu
1131
-.P
1132
-\fBtovid menu\fR generates textual (S)VCD\- or DVD\-compliant MPEG videos for use
1133
-as navigational menus, given a list of text strings to use for title names. You
1134
-can customize the menu by providing an optional background image or audio clip,
1135
-or by using custom font and font color.
1136
-
1137
-.SS Usage
1138
-.P
1139
-\fBtovid menu\fR [\fIOPTIONS\fR] \fITITLES\fR \fB\-out\fR \fIOUT_PREFIX\fR
1140
-
1141
-.P
1142
-For example:
1143
-
1144
-.TP
1145
-tovid menu "Season One" "Season Two" "Featurettes" \-out MainMenu
1146
-
1147
-.SS Options
1148
-.TP
1149
-\fB\-ntsc\fR (default)
1150
-Generate an NTSC\-format menu
1151
-.TP
1152
-\fB\-ntscfilm\fR
1153
-Generate an NTSC\-format menu (24000/1001fps)
1154
-.TP
1155
-\fB\-pal\fR
1156
-Generate a PAL\-format menu
1157
-.TP
1158
-\fB\-dvd\fR (default)
1159
-Generate a DVD\-format menu, with highlighted text included
1160
-as a multiplexed subtitle stream.
1161
-.TP
1162
-\fB\-vcd\fR
1163
-.TP
1164
-\fB\-svcd\fR
1165
-Generate a VCD/SVCD menu; each menu option will have a
1166
-number associated with it. You can have up to nine menu
1167
-options per menu.
1168
-
1169
-.P
1170
-Menu background/audio options:
1171
-
1172
-.TP
1173
-\fB\-background\fR \fIIMAGE\fR
1174
-Use \fIIMAGE\fR (in most any graphic format) as a background. If image is not
1175
-the correct aspect ratio (4:3), it will be scaled and/or cropped,
1176
-depending on the \fB\-crop\fR and \fB\-scale\fR options. If no background is
1177
-supplied, a default background will be created.
1178
-
1179
-.TP
1180
-\fB\-crop\fR (default)
1181
-If provided background image is not 4:3 aspect ratio, crop edges
1182
-to make it so. Image will be scaled up if it is too small. Cropping
1183
-keeps the center area of image. If you want to do cropping/scaling
1184
-yourself in another program, provide an image of 768x576 pixels.
1185
-
1186
-.TP
1187
-\fB\-scale\fR
1188
-If provided background image is not 4:3 aspect ratio, scale/stretch
1189
-it to make it fit. May cause visible distortion!
1190
-
1191
-.TP
1192
-\fB\-audio\fR \fIAUDIOFILE\fR
1193
-Use \fIAUDIOFILE\fR (in most any audio format) for background music. The
1194
-menu will play for long enough to hear the whole audio clip. If
1195
-one is not provided, 4 seconds of silence will be used.
1196
-
1197
-.TP
1198
-\fB\-length\fR \fINUM\fR
1199
-Make the menu \fINUM\fR seconds long. Useful for menus with \fB\-audio\fR:
1200
-if you don't want the entire \fIAUDIOFILE\fR in the menu, then you can trim
1201
-the length of the menu with \fB\-length\fR.
1202
-
1203
-.P
1204
-Menu text options:
1205
-
1206
-.TP
1207
-\fB\-menu\-title\fR \fB"\fR\fIMENU TITLE TEXT\fR\fB"\fR
1208
-Add \fIMENU TITLE TEXT\fR as a title/header to the menu.
1209
-
1210
-.TP
1211
-\fB\-font\fR \fIFONTNAME\fR (default Helvetica)
1212
-Use \fIFONTNAME\fR for the menu text. Run 'convert \-list type' to see a
1213
-list of the fonts that you can use; choose a font name from the
1214
-leftmost column that is displayed. Or you can specify a ttf font file instead.
1215
-E.g., '\-font /path/to/myfont.ttf'.
1216
-
1217
-.TP
1218
-\fB\-fontsize\fR \fINUM\fR (default 24)
1219
-Sets the size for the font to \fINUM\fR pixels.
1220
-
1221
-.TP
1222
-\fB\-menu\-title\-fontsize\fR \fINUM\fR (default \fB\-fontsize\fR + 8)
1223
-Sets the size of the menu title.
1224
-
1225
-.TP
1226
-\fB\-fontdeco\fR \fB'\fR\fIFONTDECORATION\fR\fB'\fR
1227
-Sets the font decoration method to \fIFONTDECORATION\fR. It is used by the
1228
-'convert' ImageMagick command to draw the menu text. You can add colored
1229
-text outlines, gradient fills, and many others. See \fBUsage notes\fR.
1230
-
1231
-.TP
1232
-\fB\-align\fR {\fBleft\fR|\fBcenter\fR|\fBmiddle\fR|\fBright\fR}
1233
-Align the text at the top left, top center, very middle, or top right
1234
-side of the screen. You may also substitute any "gravity" keyword
1235
-allowed by ImageMagick (north|south|east|west|northeast|southwest|...).
1236
-
1237
-.TP
1238
-\fB\-textcolor\fR {\fB#\fR\fIRRGGBB\fR|\fB#\fR\fIRGB\fR|\fICOLORNAME\fR}
1239
-Use specified color for menu text. #\fIRRGGBB\fR and #\fIRGB\fR are
1240
-hexadecimal triplets (e.g., #FF8035). \fICOLORNAME\fR may be any of
1241
-several hundred named colors; run 'convert \-list color' to see them.
1242
-White (#FFF) is the default color.
1243
-
1244
-.P
1245
-DVD\-only options:
1246
-
1247
-.TP
1248
-\fB\-button\fR \fIBUTTON\fR (default '>')
1249
-Specify the button used for menu selection. Specify either a _single_
1250
-character or one of the shortcuts:
1251
-.RS
1252
-.IP \(bu 3
1253
-\fBplay\fR \-\- Use a button shaped like 'Play' on many A/V electronics:
1254
-a triangle pointing to the right. (uses the font Webdings)
1255
-.IP \(bu 3
1256
-\fBmovie\fR \-\- Use a button shaped like an old movie projector.
1257
-(uses the font Webdings)
1258
-.IP \(bu 3
1259
-\fButf8\fR \-\- Use your own non\-keyboard character as a button. Provide
1260
-only the four hex digits: eg '\-button utf8 00b7'. Beware that
1261
-ImageMagick's utf8 characters aren't the same as those drawn in
1262
-character browsers like gucharmap.
1263
-.RE
1264
-
1265
-.TP
1266
-\fB\-highlightcolor\fR {\fB#\fR\fIRRGGBB\fR|\fB#\fR\fIRGB\fR|\fICOLORNAME\fR}
1267
-Use the specified color for button highlighting. Yellow (#FF0) is the
1268
-default color.
1269
-
1270
-.TP
1271
-\fB\-selectcolor\fR {\fB#\fR\fIRRGGBB\fR|\fB#\fR\fIRGB\fR|\fICOLORNAME\fR}
1272
-Use the specified color for button selections (when a menu item is played
1273
-or activated). Red (#F00) is the default color.
1274
-
1275
-.TP
1276
-\fB\-button\-outline\fR {\fB#\fR\fIRRGGBB\fR|\fB#\fR\fIRGB\fR|\fICOLORNAME\fR}
1277
-Outline buttons with the specified color. 'none' is the default.
1278
-
1279
-.TP
1280
-\fB\-button\-font\fR \fIFONTNAME\fR
1281
-Specify a differnt font to use for the buttons. By default, the button
1282
-font will be inherited from the title font (see \fB\-font\fR). Use this
1283
-option to use a different font for the buttons. The button font size is
1284
-inherited from \fB\-fontsize\fR and cannot be changed.
1285
-
1286
-.P
1287
-Other options:
1288
-
1289
-.TP
1290
-\fB\-debug\fR
1291
-Print extra debugging information to the log file. Useful in
1292
-diagnosing problems if they occur. This option also leaves
1293
-the log file (with a .log extension) in the directory after
1294
-encoding finishes as well as all the temporary files created.
1295
-
1296
-.TP
1297
-\fB\-nosafearea\fR
1298
-Do not attempt to put text inside a TV\-safe viewing area. Most
1299
-television sets cut off about 10% of the image border, so the script
1300
-automatically leaves a substantial margin. This option turns that
1301
-behavior off, leaving only a tiny margin. Use at your own risk.
1302
-
1303
-.TP
1304
-\fB\-overwrite\fR
1305
-Overwrite any existing output menu.
1306
-
1307
-.TP
1308
-\fB\-noask\fR
1309
-Don't ask interactive questions, and assume answers that will
1310
-continue making the menu until completion.
1311
-
1312
-.TP
1313
-\fB\-quiet\fR
1314
-Limit output to essential messages.
1315
-
1316
-.P
1317
-If the word "\fBback\fR" is given as an episode title, a "back" button for
1318
-returning to a higher\-level menu will be added at the end of the list
1319
-of titles. "\fBBack\fR" \fImust be the last title listed\fR.
1320
-
1321
-.SS Examples
1322
-.P
1323
-Make an NTSC VCD menu with white Helvetica text containing three centered
1324
-selections: Episode 1, Episode 2, and Episode 3. The finished menu will be
1325
-called Season\-1.mpg:
1326
-
1327
-.nf
1328
-  tovid menu -ntsc -vcd \e
1329
-      -align center -textcolor white -font "Helvetica" \e
1330
-      "Episode 1" "Episode 2" "Episode 3" \e
1331
-      -out "Season-1"
1332
-.fi
1333
-
1334
-
1335
-.P
1336
-Make an NTSC DVD menu with white Kirsty text containing three lower\-left
1337
-aligned selections: Episode 1, Episode 2, and Episode 3. Items under the cursor
1338
-will be highlighted a pale blue, and selected items will be a pale orange
1339
-(before going to the selected title). The finished menu will be called
1340
-Main\-menu.mpg:
1341
-
1342
-.nf
1343
-  tovid menu -ntsc -dvd \e
1344
-      -align southwest \e
1345
-      -textcolor white \e
1346
-      -highlightcolor "#5f65ff" \e
1347
-      -selectcolor "#ffac5f" \e
1348
-      -font "Kirsty" \e
1349
-      "Episode 1" "Episode 2" "Episode 3" \e
1350
-      -out "Main_menu"
1351
-.fi
1352
-
1353
-
1354
-.SS Usage notes
1355
-.P
1356
-The argument given to \fB\-font\fR must be one of the fonts listed
1357
-by the command 'convert \-list type'. Please note that many of
1358
-your installed fonts may not be available; if you want to maximize the
1359
-number of fonts available, download and run
1360
-Anthony Thyssen's (http://www.cit.gu.edu.au/~anthony/anthony.html)
1361
-imagick_type_gen.pl (http://www.cit.gu.edu.au/~anthony/software/imagick_type_gen.pl)
1362
-script and run it like this:
1363
-imagick_type_gen.pl > ~/.magick/type.xml.
1364
-If that doesn't work, try
1365
-imagick_type_gen.pl > ~/.magick/type.mgk.
1366
-
1367
-.P
1368
-Or you can specify a ttf font file directly to the \fB\-font\fR options if you
1369
-don't want to install fonts to ImageMagick.
1370
-
1371
-.P
1372
-The \fB\-fontdeco\fR option is quite flexible and takes a lot of ImageMagick's
1373
-\fIconvert\fR options. Please refer to the tovid
1374
-wiki (http://tovid.wikia.com/wiki/Making_a_DVD_with_text_menus)
1375
-and Anthony Thyssen's guide for further explanation and examples.
1376
-
1377
-.SH Command:xml
1378
-.P
1379
-\fBtovid xml\fR generates XML output describing an (S)VCD
1380
-or DVD file structure and navigation hierarchy in the format expected by
1381
-dvdauthor (http://dvdauthor.sourceforge.net/) or
1382
-vcdxbuild (http://www.vcdimager.org/).
1383
-
1384
-.SS Usage
1385
-.P
1386
-\fBtovid xml\fR [\fIOPTIONS\fR] \fIVIDEOS\fR \-out \fIOUTFILE\fR
1387
-
1388
-.P
1389
-For example:
1390
-
1391
-.nf
1392
-  $ tovid xml -menu MainMenu.mpg \e
1393
-      Season1.mpg Season2.mpg Featurettes.mpg \e
1394
-      -out MyDisc
1395
-.fi
1396
-
1397
-
1398
-.SS Options
1399
-.TP
1400
-\fB\-dvd\fR (default)
1401
-Generate the XML for a DVD disc, to be used with dvdauthor or \fBtovid dvd\fR.
1402
-.TP
1403
-\fB\-vcd\fR
1404
-Generate the XML for a VCD disc, to be used with vcdxbuild or \fBtovid vcd\fR.
1405
-.TP
1406
-\fB\-svcd\fR
1407
-Generate the XML for an SVCD disc, to be used with vcdxbuild or \fBtovid vcd\fR.
1408
-.TP
1409
-\fB\-overwrite\fR
1410
-Overwrite any existing output files.
1411
-.TP
1412
-\fB\-quiet\fR
1413
-Limit output to essential messages.
1414
-
1415
-.P
1416
-\fIVIDEOS\fR may be any of the following:
1417
-
1418
-.TP
1419
-\fI<file list>\fR
1420
-List of one or more video files to include, separated by spaces. At
1421
-minimum, a DVD must have one video file. You can use shell wildcards
1422
-(i.e., "*.mpg") to include multiple files easily. Put filenames in
1423
-quotes if they have spaces in them.
1424
-
1425
-.TP
1426
-\fB\-menu\fR \fIVIDEO\fR \fI<file list>\fR
1427
-Use video file \fIVIDEO\fR as a menu from which you can jump to each of
1428
-the listed video files. If you have multiple menus, include a
1429
-top menu so they are reachable.
1430
-
1431
-.TP
1432
-\fB\-slides\fR \fI<file list>\fR
1433
-Create a slide\-show of still images
1434
-
1435
-.P
1436
-DVD\-only options
1437
-
1438
-.TP
1439
-\fB\-group\fR \fI<file list>\fR \fB\-endgroup\fR
1440
-(DVD only) List of video files to include as one single title. This is useful
1441
-if you have split a movie into several video files.
1442
-
1443
-.TP
1444
-\fB\-topmenu\fR \fIVIDEO\fR [\fB\-menu\fR \fIVIDEO\fR \fI<file list>\fR] [\fB\-menu\fR \fIVIDEO\fR \fI<file list>\fR]...
1445
-(DVD only) Use video file \fIVIDEO\fR for the top\-level (VMGM) menu. The
1446
-top menu will jump to each of the subsequent [\-menu...] videos listed.
1447
-Use this only if you have multiple sub\-menus to jump to. You can only
1448
-have one top menu.
1449
-
1450
-.TP
1451
-\fB\-titlesets\fR
1452
-(DVD only) Forces the creation of a separate titleset per title. This
1453
-is useful if the titles of a DVD have different video formats,
1454
-e.g. PAL + NTSC or 4:3 + 16:9. If used with menus, there must be a
1455
-\fB\-topmenu\fR option that specifies a menu file with an entry for each of the
1456
-titlesets.
1457
-
1458
-.TP
1459
-\fB\-chapters\fR \fIINTERVAL\fR
1460
-(DVD only) Creates a chapter every \fIINTERVAL\fR minutes (default 5 minutes:
1461
-without \fB\-chapters\fR, each movie will be divided into 5\-minute chapters).
1462
-This option can be put at any position in a \fI<file list>\fR and is valid
1463
-for all subsequent titles until a new \fB\-chapters\fR option is encountered.
1464
-Using this option may take some time, since the duration of the video is
1465
-calculated.
1466
-
1467
-.TP
1468
-\fB\-nochapters\fR
1469
-(DVD only) Don't create chapters for the videos.
1470
-
1471
-.P
1472
-\fIOUT_PREFIX\fR is the file that will receive the resulting XML.
1473
-
1474
-.SS Usage notes
1475
-.P
1476
-The 'xml' command checks to make sure the video filenames you
1477
-give it exist, but it does not check whether they are valid for the
1478
-chosen disc format. MPEG videos of menus should have the specified
1479
-number of buttons for reaching each of the videos, and, if you're
1480
-using DVD, should be multiplexed with their corresponding subtitles
1481
-using spumux of the dvdauthor 0.6.0 package prior to
1482
-authoring using dvdauthor. If you use the 'tovid menu'
1483
-component to generate the menu, this should all be handled for you.
1484
-
1485
-.SS Examples
1486
-.TP
1487
-tovid xml \-dvd title\-1.mpg title\-2.mpg title\-3.mpg \-out My_DVD
1488
-Make a DVD without a menu. Title 1, 2, and 3 will play in sequence.
1489
-
1490
-.TP
1491
-tovid xml \-dvd \-group chapter\-1.mpg chapter\-2.mpg chapter\-3.mpg \-endgroup \-out My_DVD
1492
-Group the file chapter\-1|2|3.mpg into one title and make a DVD without a menu.
1493
-
1494
-.TP
1495
-tovid xml \-dvd \-menu main_menu.mpg \-chapters 3 movie\-1.mpg \-chapters 10 movie\-2.mpg \-out My_DVD
1496
-Make a DVD with a main menu that points to two movies, with movie\-1.mpg
1497
-divided into 3\-minute chapters, and movie\-2.mpg into 10\-minute chapters.
1498
-
1499
 .SH Command:dvd
1500
+
1501
 .P
1502
-\fBtovid dvd\fR takes a dvdauthor XML file (as generated by the \fBtovid xml\fR
1503
-command) and authors a DVD filesytem. This command can also burn a DVD disc
1504
-from either the XML file or from an existing DVD file\-system.
1505
+\fBtovid dvd\fR takes a DVD directory as generated by tovid with 'tovid disc' or
1506
+one of the GUI frontends like 'tovid gui' or 'tovid titlesets' and burns
1507
+it to appropriate media.  This will also work if the DVD directory is
1508
+generated by the dvdauthor backend that tovid also uses.
1509
 
1510
 .P
1511
-To ensure that this script successfully executes, please run it from a
1512
-directory with plenty of free space. "Plenty" would be 10 GB for single\-layer
1513
-discs, and 20 GB for dual\-layer discs.  Running this program may slow down your
1514
-other applications, due to intense disk activity.
1515
+Running this program may slow down your other applications, due to intense
1516
+disk activity.
1517
 
1518
 .SS Usage
1519
-.P
1520
-\fBtovid dvd\fR [\fIOPTIONS\fR] \fIFILE.xml\fR
1521
 
1522
 .P
1523
 \fBtovid dvd\fR [\fIOPTIONS\fR] \fIDVD_DIR\fR
1524
@@ -2023,19 +1859,16 @@
1525
 For example:
1526
 
1527
 .TP
1528
-tovid dvd \-burn MyDisc.xml
1529
-.TP
1530
-tovid dvd \-burn /path/to/DVD/directory
1531
+tovid dvd /path/to/DVD/directory
1532
 
1533
 .SS Options
1534
-.TP
1535
-\fB\-author\fR
1536
-Author the DVD described by \fIFILE.xml\fR. Overwrites an existing
1537
-directory containing the dvdauthor output if already present.
1538
 
1539
 .TP
1540
 \fB\-burn\fR
1541
 Burn a DVD file\-system in \fIDVD_DIR\fR (must contain a VIDEO_TS folder).
1542
+This option is currently not necessary as the makedvd script ONLY burns
1543
+now that legacy scripts like makexml have been removed.  Left for
1544
+compatibility only.
1545
 
1546
 .TP
1547
 \fB\-eject\fR
1548
@@ -2068,147 +1901,39 @@
1549
 Don't ask interactive questions and assume answers that will continue
1550
 execution.
1551
 
1552
-.SS Examples
1553
-.TP
1554
-tovid dvd \-burn \-device /dev/dvdrw foo.xml
1555
-Author the dvd file\-system and burn to /dev/dvdrw. This will
1556
-automatically call dvdauthor to make the file\-system. \fB\-author\fR
1557
-is not explicitly needed. If there's an existing file\-system, it
1558
-will be burned.
1559
-
1560
-.TP
1561
-tovid dvd \-author foo.xml
1562
-Author the DVD file\-system and exit without burning. If the output
1563
-directory given in foo.xml already exists, then the contents are
1564
-removed before authoring. At this point, the DVD can be previewed
1565
-by calling \fI\fBxine\fR dvd:/path/to/output/directory\fR.
1566
-
1567
-.SH Command:vcd
1568
 .P
1569
-\fBtovid vcd\fR takes an XML file (which may be generated by \fBtovid xml\fR) and
1570
-creates a cue/bin (S)VCD image. It can also burn (S)VCD discs.
1571
+    After burning, the DVD can be previewed by calling:
1572
+    \fI\fBxine\fR dvd:/path/to/output/directory\fR
1573
+    or:
1574
+    \fI\fBvlc\fR /path/to/output/directory\fR
1575
 
1576
-.P
1577
-To ensure that this script successfully executes, please run it from a directory
1578
-with plenty of free space. "Plenty" would be about 1 GB. Running this program
1579
-may slow down your other applications, due to intense disk activity.
1580
+.SH Command:chapters
1581
 
1582
-.SS Usage
1583
 .P
1584
-\fBtovid vcd\fR [\fIOPTIONS\fR] \fIVCDIMAGER.xml\fR
1585
+\fBtovid chapters\fR will start a GUI using mplayer to set chapter points in a
1586
+video.  If the video plays through and you want to add more chapters you can
1587
+press the play button again, but remember that new chapter points will be
1588
+appended (in correct sequential order).  It will display the resulting chapter
1589
+points, and also output to a terminal (useful for scripts).  As well it will
1590
+give the option of saving the chapters string to a text file.
1591
 
1592
 .P
1593
-For example:
1594
-
1595
-.TP
1596
-tovid vcd \-burn MyDisc.xml
1597
-
1598
-.SS Options
1599
-.TP
1600
-\fB\-overwrite\fR (default off \-\- nothing is overwritten)
1601
-Overwrite any existing cue/bin files matching \fIVCDIMAGER.xml\fR. Useful
1602
-if you modified the xml file and wish to re\-image or burn the new (S)VCD.
1603
-
1604
-.TP
1605
-\fB\-burn\fR (default off \-\- no images are burned)
1606
-Burn the (S)VCD described by \fIVCDIMAGER.xml\fR.
1607
-
1608
-.TP
1609
-\fB\-device\fR \fIDEVICE\fR (default /dev/cdrw)
1610
-Burn the disc image to \fIDEVICE\fR, the Linux device file\-system
1611
-name of your CD\-recorder. Common examples might be /dev/cdrw,
1612
-/dev/scd1, and /dev/hdc.
1613
-
1614
-.TP
1615
-\fB\-speed\fR \fINUM\fR (default 12)
1616
-Burn the disc at speed \fINUM\fR.
1617
-
1618
-.TP
1619
-\fB\-quiet\fR
1620
-Limit output to essential messages.
1621
+Note that the 'tovid gui' now features a similar widget when you press the
1622
+chapters button on the opening page.
1623
 
1624
 .SS Examples
1625
-.TP
1626
-tovid vcd \-burn \-device /dev/cdrw foo.xml
1627
-Create the (S)VCD image and burn it to /dev/cdrw. This will
1628
-automatically call vcdxbuild to make the image. If there is an existing
1629
-image, it will be burned.
1630
-
1631
-.TP
1632
-tovid vcd \-overwrite foo.xml
1633
-Create the (S)VCD image and exit without burning. If the image
1634
-already exists, then it is removed before re\-imaging.
1635
-
1636
-.SH Command:postproc
1637
-.P
1638
-\fBtovid postproc\fR is designed to do simple post\-processing on MPEG video files, such
1639
-as those generated by tovid. It can adjust audio/video sync, and re\-quantize
1640
-(shrink) without re\-encoding.
1641
-
1642
-.SS Usage
1643
-.P
1644
-\fBtovid postproc\fR [\fIOPTIONS\fR] \fIIN_FILE\fR \fIOUT_FILE\fR
1645
-
1646
-.SS Options
1647
-.TP
1648
-\fB\-audiodelay\fR \fINUM\fR
1649
-Delay the audio stream by \fINUM\fR milliseconds. Use this if
1650
-your final output has audio that is not synced with the
1651
-video. For example, if the audio comes 2 seconds sooner than
1652
-the video, use "\-audiodelay 2000". Use a negative number for
1653
-audio that comes later than the video.
1654
-
1655
-.TP
1656
-\fB\-normalize\fR
1657
-Analyze the audio stream and then normalize the volume of the audio.
1658
-This is useful if the audio is too quiet or too loud, or you want to
1659
-make volume consistent for a bunch of videos. Similar to running
1660
-normalize without any parameters. The default is \-12dB average level
1661
-with 0dB gain.
1662
-
1663
-.TP
1664
-\fB\-amplitude\fR \fINUM\fR[dB]
1665
-In addition to analyzing and normalizing, apply the gain to the audio
1666
-such that the 'average' (RMS) sound level is \fINUM\fR. Valid values
1667
-range 0.0 \- 1.0, with 0.0 being silent and 1.0 being full scale. Use
1668
-\fINUM\fRdB for a decibel gain below full scale (the default without
1669
-\-amplitude is \-12dB).
1670
-
1671
-.TP
1672
-\fB\-shrink\fR \fINUM\fR
1673
-Shrink the video stream by a factor of \fINUM\fR. May be a decimal
1674
-value. A value of 1.0 means the video will be the same size;
1675
-larger values cause more reduction in size. Beyond 2.0, the
1676
-returns are diminishing.
1677
 
1678
 .TP
1679
-\fB\-parallel\fR
1680
-Run all processes in parallel and pipe into multiplexer, should
1681
-increase speed significantly.
1682
-
1683
-.TP
1684
-\fB\-debug\fR
1685
-Save output in a temporary file, for later viewing if
1686
-something goes wrong.
1687
-
1688
-.SH Command:chapters
1689
-.P
1690
-\fBtovid chapters\fR will start a GUI using mplayer to set chapter points in a
1691
-video.  Its only (mandatory) option is the path to a video file.
1692
-
1693
-.SS Examples
1694
-.TP
1695
 tovid chapters foo.avi
1696
 
1697
 .TP
1698
-tovid chapters /home/grepper/videos/foo.avi
1699
+chapters=$(tovid chapters /home/grepper/videos/foo.avi)
1700
 
1701
 .SH CONTACT
1702
+
1703
 .P
1704
 For further assistance, contact information, forum and IRC links,
1705
 please refer to the tovid homepage (http://tovid.wikia.com/).
1706
 
1707
-
1708
-.\" man code generated by txt2tags 2.5 (http://txt2tags.sf.net)
1709
+.\" man code generated by txt2tags 2.6 (http://txt2tags.org)
1710
 .\" cmdline: txt2tags -t man -i docs/src/en/tovid.t2t -o docs/man/tovid.1
1711
-
1712
tovid-0.34.tar.bz2/docs/sphinx/conf.py -> tovid-0.35.tar.gz/docs/sphinx/conf.py Changed
13
 
1
@@ -52,9 +52,9 @@
2
 # built documents.
3
 #
4
 # The short X.Y version.
5
-version = '0.33'
6
+version = '0.34'
7
 # The full version, including alpha/beta/rc tags.
8
-release = '0.33'
9
+release = '0.34'
10
 
11
 # The language for content autogenerated by Sphinx. Refer to documentation
12
 # for a list of supported languages.
13
tovid-0.34.tar.bz2/docs/sphinx/man/tovid.rst -> tovid-0.35.tar.gz/docs/sphinx/man/tovid.rst Changed
3149
 
1
@@ -1,305 +1,358 @@
2
-===============================================================
3
-tovid manual
4
-===============================================================
5
+Name
6
+====
7
 
8
+tovid: Make DVDs from video files
9
 
10
 Description
11
-===============================================================================
12
+===========
13
+
14
+**tovid** is a command-line tool for creating DVDs. It can encode your
15
+video files to DVD-compliant MPEG format, generate simple or complex DVD
16
+menus, author and burn a ready-to-watch DVD, with just a few shell
17
+commands. A graphical interface is also provided to make the process
18
+even easier.
19
+
20
+**NOTE**: As of tovid 0.35, the legacy scripts **makemenu**,
21
+**makexml**, **makevcd** have been deprecated and no longer appear in
22
+this manpage. They are still included with tovid for now, and can be
23
+used by doing: tovid menu|xml|vcd|postproc
24
+as done in the previous 3 versions of tovid.
25
+
26
+Also note that as of tovid 0.32, this is the only manual page provided
27
+by tovid. There is now a single executable frontend to all functionality
28
+in the suite, so if you were expecting to find manpages for **todisc**,
29
+**idvid**, **makempg** and their kin, they can all be found in the
30
+**tovid** manpage you are reading now.
31
+
32
+And yes, this makes for a pretty large manual page. If you are viewing
33
+this manpage from the command-line **man** utility, which normally pages
34
+through the **less** utility, you can skip to a section by searching
35
+with the **/** key, followed by a **^** to match the given section name.
36
+For example, to skip to the **mpg** command, type **/^Command:mpg**. See
37
+**man less** for more on how to navigate.
38
 
39
-**tovid** is a command-line tool for creating DVDs. It can encode your video
40
-files to DVD-compliant MPEG format, generate simple or complex DVD menus,
41
-author and burn a ready-to-watch DVD, with just a few shell commands. A
42
-graphical interface is also provided to make the process even easier.
43
+Usage
44
+=====
45
 
46
-**NOTE**: As of tovid 0.32, this is the only manual page provided by tovid.
47
-There is now a single executable frontend to all functionality in the suite, so
48
-if you were expecting to find manpages for **todisc**, **idvid**, **makemenu**
49
-and their kin, they can all be found in the **tovid** manpage you are reading now.
50
+**tovid** *COMMAND* [*OPTIONS*]
51
 
52
-And yes, this makes for a pretty large manual page. If you are viewing this
53
-manpage from the command-line **man** utility, which normally pages through the
54
-**less** utility, you can skip to a section by searching with the **/** key,
55
-followed by a **^** to match the given section name. For example, to skip to
56
-the **mpg** command, type **/^Command:mpg**. See :manpage:`less(1)` for more on how
57
-to navigate.
58
+Where *COMMAND* is one of the following:
59
 
60
-Usage
61
-===============================================================================
62
+Main Commands
63
 
64
-::
65
+**disc**
66
+    Encode, make menus, author, burn. (was **todisc**. See
67
+    **Command:disc**)
68
 
69
- tovid COMMAND [OPTIONS]
70
+**gui**
71
+    Start the tovid GUI (was **todiscgui**. See **Command:gui**)
72
 
73
-Where *COMMAND* is one of the following:
74
+**titlesets**
75
+    A GUI wizard for multiple titlesets. (new: See
76
+    **Command:titlesets**)
77
 
78
-    gui
79
-        Start the tovid GUI (was **todiscgui**. See :ref:`command-gui`)
80
-    disc
81
-        Create a DVD with menus (was **todisc**. See :ref:`command-disc`)
82
-    mpg
83
-        Encode videos to MPEG format (was **tovid**. See :ref:`command-mpg`)
84
-    id
85
-        Identify one or more video files (was **idvid**. See :ref:`command-id`)
86
-    menu
87
-        Create an MPEG menu (was **makemenu**. See :ref:`command-menu`)
88
-    xml
89
-        Create (S)VCD or DVD .xml file (was **makexml**. See :ref:`command-xml`)
90
-    dvd
91
-        Author and/or burn a DVD (was **makedvd**. See :ref:`command-dvd`)
92
-    vcd
93
-        Author and/or burn a VCD (was **makevcd**. See :ref:`command-vcd`)
94
-    postproc
95
-        Post-process an MPEG video file (was **postproc**. See :ref:`command-postproc`)
96
-
97
-The *OPTIONS* differ for each command; run **tovid <command>** with no
98
-further arguments to get help on a command, and what options it expects.
99
+Helper Commands
100
 
101
-Configuration
102
-===============================================================================
103
+**mpg**
104
+    Encode videos to MPEG format (was **tovid**. See **Command:mpg**)
105
 
106
-Two configuration files are created the first time you run tovid:
107
+**dvd**
108
+    Author and/or burn a DVD (was **makedvd**. See **Command:dvd**)
109
 
110
-``~/.tovid/preferences``
111
-    Defines working directory for all scripts.
112
-    In addition you can define the output directory for makempg here.
113
-``~/.tovid/tovid.config``
114
-    Includes command-line options that should always be passed to
115
-    makempg.
116
+**id**
117
+    Identify one or more video files (was **idvid**. See **Command:id**)
118
 
119
-    Edit these files if you wish to change your configuration.
120
+**chapters**
121
+    A GUI using mplayer for setting chapter points. It will return a
122
+    string of chapter points to the terminal, in a format recognized by
123
+    ’tovid disc’ (todisc) or by ’tovid gui’, for the **-chapters**
124
+    option.
125
 
126
-The following environment variables are also honoured:
127
+The *OPTIONS* differ for each command; run **tovid
128
+<command>** with no further arguments to get help on
129
+a command, and what options it expects.
130
 
131
-``TOVID_WORKING_DIR``
132
-    working directory for all scripts
133
-``TOVID_OUTPUT_DIR``
134
-    output directory for the makempg script
135
+Configuration
136
+=============
137
 
138
+Two configuration files are created the first time you run tovid:
139
 
140
-.. _command-gui:
141
+**~{**/.tovid/preferences}
142
+    Defines working directory for all scripts. In addition you can
143
+    define the output directory for makempg here.
144
 
145
-Command:gui
146
-===============================================================================
147
+**~{**/.tovid/tovid.ini}
148
+    Includes command-line options that should be passed to the various
149
+    **tovid** sub-commands.
150
 
151
-**tovid gui** starts the graphical user interface (GUI) for tovid. This is
152
-the easiest way to start creating DVDs with tovid. At this time, there are no
153
-additional command-line options; the GUI controls take care of everything,
154
-and all help is integrated in the form of tooltips.  You can also see
155
-:ref:`command-disc` for more detail about the options.  Note: one limitation of
156
-the gui at present is that it does not do multiple titlesets (though it will do
157
-chapter menus).  Use the **tovid disc** command (below) for titlesets.
158
+    Edit these files if you wish to change your configuration.
159
 
160
+    The following environment variables are also honoured:
161
+    TOVID\_WORKING\_DIR (working directory for all scripts).
162
+    TOVID\_OUTPUT\_DIR (output directory for the makempg script).
163
 
164
-.. _command-disc:
165
+Command:gui
166
+===========
167
+
168
+**tovid gui** starts the graphical user interface (GUI) for tovid. This
169
+is the easiest way to start creating DVDs with tovid. The optional
170
+arguments are any option used by todisc (’tovid disc’) which will save
171
+entering it manually, OR the full path to a saved script from the GUI.
172
+This option to save the contents of your project allows you to use it as
173
+a bash script later, or to reload the project to continue working with
174
+it at another time. Note: this feature is still in development so some
175
+options may not load properly - make sure to check that your selections
176
+were all loaded.
177
+
178
+All help is integrated in the form of tooltips. You can also see
179
+\*\*Command:disc \*\* for more detail about the options. Note: if you
180
+wish to use a GUI to make multiple titlesets on the same DVD use ’tovid
181
+titlesets’, which is a wizard that uses the the ’tovid gui.
182
+
183
+Command:titlesets
184
+=================
185
+
186
+**tovid titlesets** will assist in making a DVD with multiple titlesets.
187
+It can be started without any options, or you can feed it the path to a
188
+saved titleset script as an option. The option to save a script is also
189
+useful as the resulting script can be run later from a terminal.
190
 
191
 Command:disc
192
-===============================================================================
193
-
194
-**tovid disc** creates a DVD file-system with menus, from a list of multimedia
195
-video files and their titles.  As this is a low level script it is the easiest
196
-command line program for creating a DVD from start to finish, including
197
-automatically converting non-compliant videos and prompting to burn at
198
-completion.  It does animated menus, static thumbnail menus and text only
199
-menus.  In addition, it can do slideshows, using images as input, and combine
200
-slideshows with videos.  It supports sub-menus for chapter breaks, configurable
201
-menu style, animated backgrounds and transparency effects.
202
+============
203
+
204
+**tovid disc** creates a DVD file-system with optional menus, from a
205
+list of multimedia video files and their titles. As todisc can function
206
+as a master script, calling other scripts as it needs them, it is the
207
+easiest command line program for creating a DVD from start to finish,
208
+including automatically converting non-compliant videos and prompting to
209
+burn at completion. It can do animated menus, static thumbnail menus,
210
+text-only menus, or author with no menu. In addition, it can do
211
+slideshows, using images as input, and even combine slideshows with
212
+videos. It supports sub-menus for chapter breaks, configurable menu
213
+style, animated backgrounds and transparency effects. From simple (no
214
+menu) to complex (switched menus and titlesets), you should be able to
215
+do what you want with ’tovid disc’.
216
+
217
+Please note that although the interface may seem complex with so many
218
+options, you can create a fully functional DVD with only a few options
219
+on the opening tab of the GUI (select video files and an output name).
220
 
221
 Usage
222
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
223
+-----
224
 
225
 ::
226
 
227
- tovid disc [OPTIONS] \
228
-   -files <file list> -titles <title list>
229
-   -out OUT_PREFIX
230
-
231
-For example::
232
+     tovid disc [OPTIONS] \
233
+        -files <file list> -titles <title list>
234
+        -out OUT_PREFIX
235
 
236
- tovid disc -files File1.mpg File2.mpg File3.mpg \
237
-   -titles "Episode 1" "Episode 2" "Episode 3" \
238
-   -out Season_one
239
+For example:
240
 
241
-The number of **-files** and **-titles** must be equal, though if you do not
242
-include any titles **tovid disc** will use the basename of the included files
243
-as titles.  If you are doing a slideshow or multiple slideshows, use
244
-**-slides** rather than **-files** for passing in the images.  You may use
245
--files and -slides more than once to create an ordering in a mixed
246
-slideshows/videos menu.  See :ref:`usage-slideshows` under usage below.
247
+::
248
 
249
-If the input files are not mpeg, you will have the option to auto-encode them.
250
+     $ tovid disc -files File1.mpg File2.mpg File3.mpg \
251
+          -titles "Episode 1" "Episode 2" "Episode 3" \
252
+          -out Season_one
253
 
254
+The number of **-files** and **-titles** must be equal, though if you do
255
+not include any titles **tovid disc** will use the basename of the
256
+included files as titles. If you are doing a slideshow or multiple
257
+slideshows, use **-slides** rather than **-files** for passing in the
258
+images. You may use -files and -slides more than once to create an
259
+ordering in a mixed slideshows/videos menu. See Slideshows part of Usage
260
+section, below.
261
 
262
-Display arrangements
263
--------------------------------------------------------------------------------
264
+If the input files are not mpeg, you will have the option to auto-encode
265
+them.
266
 
267
-At present there are 2 display arrangements or "templates":
268
+**At present there are 2 display arrangements or "templates":**
269
 
270
 A. (Default)
271
     Thumbs will be centred, and as large as space restraints allow.
272
 
273
 B. **-showcase** IMAGE|VIDEO
274
-    Produces an arrangement with small buttons on
275
-    the side and the showcase image/video in the centre.  If no IMAGE or VIDEO
276
-    argument is supplied, the central thumb will be omitted.
277
+    Produces an arrangement with small buttons on the side and the
278
+    showcase image/video in the centre. If no IMAGE or VIDEO argument is
279
+    supplied, the central thumb will be omitted.
280
+
281
+    Note: **-textmenu**, **-quick-menu** and **-switched-menus** are all
282
+    types of showcase style menus. See descriptions under **Menu style**
283
+    section.
284
+
285
+The **-titles** arguments should be double or single quoted, or have the
286
+spaces backslash-escaped. Special characters (like ", !, \*, &, ?) may
287
+need to be backslash-escaped. To include a quoted string within a title,
288
+backslash-escape the quotes. These titles are used for labelling
289
+thumbnails on the main menu, and for the submenu title for that video. (
290
+see also **-submenu-titles** )
291
+
292
+The **-showcase** styles can use longer titles than the default
293
+arrangement. With a showcase style, use: **-showcase-titles-align west**
294
+to give more space for the title, or use **-showcase-titles-align east**
295
+to allow titles of more than one line.
296
+
297
+The default style can only show about 16 characters (depending on the
298
+number of thumbs, and what **-titles-font** and **-titles-fontsize** is
299
+being used). If your titles are too long to fit in the label area, you
300
+may try using sub-menus, which can display longer titles, for example:
301
 
302
-    Note: **-textmenu**, **-quick-menu** and **-switched-menus** are all types
303
-    of showcase style menus.  See descriptions in the :ref:`menu-style` section.
304
+::
305
 
306
-The **-titles** arguments should be double or single quoted, or have the spaces
307
-backslash-escaped. Special characters (like ", !, \*, &, ?) may need to be
308
-backslash-escaped.  To include a quoted string within a title, backslash-escape
309
-the quotes.  These titles are used for labelling thumbnails on the main menu,
310
-and for the submenu title for that video.  ( see also **-submenu-titles** )
311
+     $ tovid disc -submenus \
312
+          -files file1.mpg file2.mpg ... \
313
+          -titles "Short 1" "Short 2" \
314
+          -submenus \
315
+          -submenu-titles "Long Title One" "Long Title Two" \
316
+          -out foo
317
 
318
-The **-showcase** styles can use longer titles than the default arrangement.
319
-With a showcase style, use: **-showcase-titles-align west** to give more space
320
-for the title, or use **-showcase-titles-align east** to allow titles of more
321
-than one line.
322
+The **-align** argument will position both titles and thumbs either
323
+south, north east, west, southwest, northwest, southeast, northeast,
324
+subject to certain constraints of each arrangement.
325
 
326
-The default style can only show about 16 characters (depending on the number
327
-of thumbs, and what **-titles-font** and **-titles-fontsize** is being used).
328
-If your titles are too long to fit in the label area, you may try using
329
-sub-menus, which can display longer titles, for example::
330
+More Examples:
331
 
332
- $ tovid disc -submenus \
333
-      -files file1.mpg file2.mpg ... \
334
-      -titles "Short 1" "Short 2" \
335
-      -submenu-titles "Long Title One" "Long Title Two" \
336
-      -out foo
337
+A text-only menu:
338
 
339
-The **-align** argument will position both titles and thumbs either south,
340
-north east, west, southwest, northwest, southeast, northeast, subject to
341
-certain constraints of each arrangement.
342
+::
343
 
344
+     $ tovid disc -textmenu ...
345
 
346
-.. _usage-titlesets:
347
+No menu:
348
 
349
-Titlesets
350
--------------------------------------------------------------------------------
351
+::
352
 
353
-A word should be mentioned here about titlesets, which is really just a
354
-hierarchy of menus.  You need to use titlesets, for example, if you have videos
355
-of different resolutions, or otherwise want to arrange videos on separate menus.
356
-If you want to have titlesets you need to put all the options for each titleset
357
-menu you would like to have between **-titleset** and **-end-titleset** options.
358
+     $ tovid -nomenu -files file1.mpg [file2.mpg "file 3.mpg" ...]
359
+
360
+**Titlesets**
361
 
362
-Additionally, for the main menu (the opening menu that will let you jump to
363
-each titleset), you need to put options between **-vmgm** and **-end-vmgm**.
364
-You do not use **-files** for the opening menu options (**-vmgm**), but you
365
-will need as many TITLES after **-titles** as you have menus.
366
+A word should be mentioned here about titlesets, which is really just a
367
+hierarchy of menus. You need to use titlesets, for example, if you have
368
+videos of different resolutions, or otherwise want to arrange videos on
369
+separate menus. If you want to have titlesets you need to put all the
370
+options for each titleset menu you would like to have between
371
+**-titleset** and **-end-titleset** options.
372
+
373
+Additionally, for the main menu (the opening menu that will let you jump
374
+to each titleset), you need to put options between **-vmgm** and
375
+**-end-vmgm**. You do not use **-files** for the opening menu options
376
+(**-vmgm**), but you will need as many TITLES after **-titles** as you
377
+have menus.
378
 
379
 Any options outside the **-titleset** **-end-titleset** and **-vmgm**
380
 **-end-vmgm** areas will be general options applying to every titleset.
381
-If a general option is duplicated inside a **-titleset** or **-vmgm** area, the
382
-general option will be overridden.
383
-
384
-Note: you do not need titlesets for a single menu with chapter break menus, for
385
-that just use **-submenus** or **-ani-submenus**
386
-
387
-Example of using **tovid disc** with titlesets::
388
-
389
- $ tovid disc -static -out MY_DVD \
390
-   \
391
-   -titleset -files 1.mpg 2.mpg 3.mpg \
392
-   -titles "Title One" "Title Two" "Title Three" \
393
-   -end-titleset \
394
-   \
395
-   -titleset -files 4.mpg 5.mpg \
396
-   -titles "Title Four" "Title Five" \
397
-   -background foo.jpg \
398
-   -showcase bar.png \
399
-   -end-titleset \
400
-   \
401
-   -vmgm \
402
-   -titles "Season One" "Season Two" \
403
-   -background bg.jpg \
404
-   -bgaudio foo.mp3 \
405
-   -titles-fontsize 20 \
406
-   -end-vmgm
407
+If a general option is duplicated inside a **-titleset** or **-vmgm**
408
+area, the general option will be overridden.
409
+
410
+Note: you do not need titlesets for a single menu with chapter break
411
+menus, for that just use **-submenus** or **-ani-submenus**
412
+
413
+Example of using **tovid disc** with titlesets:
414
+
415
+::
416
+
417
+     $ tovid disc -static -out MY_DVD \
418
+        \
419
+       -titleset -files 1.mpg 2.mpg 3.mpg \
420
+       -titles "Title One" "Title Two" "Title Three" \
421
+       -end-titleset \
422
+       \
423
+       -titleset -files 4.mpg 5.mpg \
424
+       -titles "Title Four" "Title Five" \
425
+        -background foo.jpg \
426
+        -showcase bar.png \
427
+        -end-titleset \
428
+        \
429
+        -vmgm \
430
+        -titles "Season One" "Season Two" \
431
+        -background bg.jpg \
432
+        -bgaudio foo.mp3 \
433
+        -titles-fontsize 20 \
434
+        -end-vmgm
435
 
436
 See also **-titleset** and **-vmgm**
437
 
438
+**Slideshows**
439
+
440
+You can also use **tovid disc** to make slideshows. This can either be a
441
+single slideshow, or multiple slideshows on the same menu. Remember to
442
+use **-slides** rather than **-files** for passing in the images. Images
443
+can be any filetype that imagemagick supports: for example JPEG, PNG,
444
+GIF, TGA BMP etc. For a single slideshow do not use **-titles**: use
445
+-menu-title to set the slideshow title.
446
+
447
+For a single slideshow the default is an animated menu that transitions
448
+from slide to slide. The default transition type is ’crossfade’, which
449
+fades each slide into the next and loops back to the first slide at the
450
+end. If instead you use **-static**, then a static ’polaroid stack’ menu
451
+of all the slides is created, with a single spumux’ed button for
452
+navigating with the enter key. You may have to experiment to find out
453
+which DVD remote button advances the slides. Try the ’next chapter’(skip
454
+?) button and the play or enter buttons. If you want to limit the number
455
+of slides in the menu to a subset of all files entered with **-slides**,
456
+then use **-menu-slide-total** INT. Be sure to use a long enough audio
457
+file for **-bgaudio** or set **-menu-length** so the menu is long enough
458
+to support the slides plus transitions.
459
+
460
+You can also put multiple slideshows on one menu. To do this, use
461
+**-slides IMAGES** for each slideshow desired. You can even mix videos
462
+with slideshows by using **-files** **-slides** **-titles** multiple
463
+times.
464
+
465
+Example of a single slideshow with an animated menu with transitions:
466
 
467
-.. _usage-slideshows:
468
+::
469
 
470
-Slideshows
471
--------------------------------------------------------------------------------
472
-
473
-You can also use **tovid disc** to make slideshows.  This can either be a single
474
-slideshow, or multiple slideshows on the same menu.
475
-Remember to use **-slides** rather than **-files** for passing in the
476
-images.  Images can be any filetype that imagemagick supports: for example
477
-JPEG, PNG, GIF, TGA BMP etc.  For a single slideshow do not use **-titles**:
478
-use -menu-title to set the slideshow title.
479
-
480
-For a single slideshow the default is an animated menu that transitions from
481
-slide to slide.  The default transition type is 'crossfade', which fades each
482
-slide into the next and loops back to the first slide at the end.  If instead
483
-you use **-static**, then a static 'polaroid stack' menu of all the slides is
484
-created, with a single spumux'ed button for navigating with the enter key.  You
485
-may have to experiment to find out which DVD remote button advances the slides.
486
-Try the 'next chapter'(skip ?) button and the play or enter buttons.
487
-If you want to limit the number of slides in the menu to a subset of all files
488
-entered with **-slides**, then use **-menu-slide-total** INT.  Be sure to use
489
-a long enough audio file for **-bgaudio** or set **-menu-length** so the menu
490
-is long enough to support the slides plus transitions.
491
-
492
-You can also put multiple slideshows on one menu.  To do this, use
493
-**-slides IMAGES** for each slideshow desired.  You can even mix videos
494
-with slideshows by using **-files** **-slides** **-titles** multiple times.
495
-
496
-Example of a single slideshow with an animated menu with transitions::
497
-
498
- $ tovid disc -menu-title "Autumn in Toronto" -slides images/*.jpg \
499
-    -menu-slide-total 20 -slide-transition crossfade -bgaudio slideshow.wav \
500
-    -out myslideshow
501
-
502
-Example of multiple slideshows on one menu::
503
-
504
- $ tovid disc -menu-title "Autumn in Toronto" \
505
-   -slides photos/september/*.jpg \
506
-   -slides photos/october/*.jpg \
507
-   -slides photos/november/*.jpg \
508
-   -tile3x1 -rotate -5 5 -5 -align center \
509
-   -bgaudio background.wav \
510
-   -out myslideshow
511
-
512
-Example of mixed videos and slideshows::
513
-
514
- $ tovid disc -menu-title "Autumn in Toronto" \
515
-   -files fall_fair.mov \
516
-   -slides  photos/september/*.jpg \
517
-   -files harvest.mpg \
518
-   -slides photos/october/*.jpg \
519
-   -titles "Fall Fair" "September" "Harvest" "October" \
520
-   -background autumn.png \
521
-   -bgaudio bg.mp3 \
522
-   -out myslideshow
523
-
524
-See the other slideshow options in the :ref:`usage-slideshows` options section.
525
-
526
-Encoding options
527
--------------------------------------------------------------------------------
528
-
529
-These are options for reencoding your non-compliant videos.  They are passed
530
-directly to the **tovid mpg** command which is invoked by **tovid disc** when
531
-non-compliant files are found.  For details, see the :ref:`command-mpg` section.
532
-Here is a list of possible options you can pass:
533
-
534
-**-config**, **-ntscfilm**, **-dvd-vcd**, **-half-dvd**, **-kvcd**,
535
-**-kvcdx3**, **-kvcdx3a**, **-kdvd**, **-bdvd**, **-704**, **-normalize**,
536
-**-amplitude**, **-overwrite**, **-panavision**, **-force**, **-fps**,
537
-**-vbitrate**, **-quality**, **-safe**, **-crop**, **-filters**,
538
-**-abitrate**, **-priority**, **-deinterlace**, **-progressive**,
539
-**-interlaced**, **-interlaced_bf**, **-type**, **-fit**, **-discsize**,
540
-**-parallel**, **-mkvsub**, **-autosubs**, **-subtitles**, **-update**, \
541
-**-mplayeropts**, **-audiotrack**, **-downmix**, **-ffmpeg**, **-nofifo**,
542
-**-from-gui**, **-slice**, **-async**, **-quiet**,
543
-**-fake**, **-keepfiles**
544
+     $ tovid disc -menu-title "Autumn in Toronto" -slides images/*.jpg \
545
+        -menu-slide-total 20 -slide-transition crossfade -bgaudio slideshow.wav \
546
+        -out myslideshow
547
 
548
+Example of multiple slideshows on one menu:
549
 
550
-Basic options
551
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
552
+::
553
+
554
+     $ tovid disc -menu-title "Autumn in Toronto" \
555
+       -slides photos/september/*.jpg \
556
+       -slides photos/october/*.jpg \
557
+       -slides photos/november/*.jpg \
558
+       -tile3x1 -rotate -5 5 -5 -align center \
559
+       -bgaudio background.wav \
560
+       -out myslideshow
561
+
562
+Example of mixed videos and slideshows:
563
+
564
+::
565
+
566
+     $ tovid disc -menu-title "Autumn in Toronto" \
567
+       -files fall_fair.mov \
568
+       -slides  photos/september/*.jpg \
569
+       -files harvest.mpg \
570
+       -slides photos/october/*.jpg \
571
+       -titles "Fall Fair" "September" "Harvest" "October" \
572
+       -background autumn.png \
573
+       -bgaudio bg.mp3 \
574
+       -out myslideshow
575
+
576
+See the other slideshow options in the Slideshows options section.
577
+
578
+**Encoding Options**
579
+
580
+These are options for reencoding your non-compliant videos. They are
581
+passed directly to the **tovid mpg** command which is invoked by **tovid
582
+disc** when non-compliant files are found. For details, see the
583
+**Command:mpg** section. Here is a list of possible options you can
584
+pass: **-config**, **-ntscfilm**, **-dvd-vcd**, **-half-dvd**,
585
+**-kvcd**, **-kvcdx3**, **-kvcdx3a**, **-kdvd**, **-bdvd**, **-704**,
586
+**-normalize**, **-amplitude**, **-overwrite**, **-panavision**,
587
+**-force**, **-fps**, **-vbitrate**, **-quality**, **-safe**, **-crop**,
588
+**-filters**, **-abitrate**, **-priority**, **-deinterlace**,
589
+**-progressive**, **-interlaced**, **-interlaced\_bf**, **-type**,
590
+**-fit**, **-discsize**, **-parallel**, **-mkvsub**, **-autosubs**,
591
+**-subtitles**, **-update**, **-mplayeropts**,
592
+**-audiotrack**, **-downmix**, **-ffmpeg**, **-nofifo**, **-from-gui**,
593
+**-slice**, **-quiet**, **-fake**, **-keepfiles**
594
+
595
+Options
596
+-------
597
 
598
 **-keep-files**, **-keepfiles**
599
     Keep all intermediate/temporary files (helps with debugging)
600
@@ -311,216 +364,242 @@
601
     720x576 output, compatible with PAL standard
602
 
603
 **-submenus**
604
-    Create a sub-menu with chapters for each video (default: no sub-menus)
605
+    Create a sub-menu with chapters for each video (default: no
606
+    sub-menus)
607
 
608
 **-ani-submenus**
609
-    Create an animated sub-menu with chapters for each video (default: not
610
-    animated)
611
+    Create an animated sub-menu with chapters for each video (default:
612
+    not animated)
613
 
614
 **-no-menu | -nomenu**
615
-    With this option todisc will just create a DVD file system, ready for
616
-    burning, with NO MENU, just the supplied video files.  These do not need
617
-    to be compliant, as non-compliant files will be encoded as usual.  Each
618
-    video will be a chapter unless **-chapters** OPTION is passed.  The
619
-    **-chapters** option is a number indicating the chapter interval in
620
-    minutes, or a HH:MM:SS string indicating chapter points.  See **-chapters**
621
-
622
-
623
-.. _menu-style:
624
-
625
-Basic menu style options
626
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
627
+    With this option todisc will just create a DVD file system, ready
628
+    for burning, with NO MENU, just the supplied video files. These do
629
+    not need to be compliant, as non-compliant files will be encoded as
630
+    usual. The **-out** option is not required. Each video will be a
631
+    chapter unless **-chapters** OPTION is passed. The **-chapters**
632
+    option is a number indicating the chapter interval in minutes, or a
633
+    HH:MM:SS string indicating chapter points. See **-chapters**
634
+
635
+**-encode-only**
636
+    This option was originally meant for the GUI, to allow it to be used
637
+    for just encoding rather than making a DVD structure. But it works
638
+    well from the command line as well as it has the added advantage
639
+    that you can input a list of files. Remember any makempg (’tovid
640
+    mpg’) options you use will be passed on to the the makempg script
641
+    when encoding.
642
+
643
+Menu style
644
+----------
645
 
646
 **-showcase** IMAGE|VIDEO
647
-    If used without an argument, use showcase style without a central thumb.
648
-    This is a different arrangement of images for the menu: small thumbnails
649
-    go at left (and right) side of screen, with a larger image in the centre.
650
-    Maximum of 10 videos.  If the provided argument is a video file, the
651
-    central thumb will be animated.  Pick a file of correct aspect ratio:
652
-    i.e. it should still look good when resized to 720x480 (PAL 720x576),
653
-    then resized to proper aspect ratio.
654
+    If used without an argument, use showcase style without a central
655
+    thumb. This is a different arrangement of images for the menu: small
656
+    thumbnails go at left (and right) side of screen, with a larger
657
+    image in the centre. Maximum of 10 videos. If the provided argument
658
+    is a video file, the central thumb will be animated. Only 4:3 or
659
+    16:9 videos and images are accepted for the showcase file: if not
660
+    one of these todisc will assume it is the same ratio as the videos
661
+    in the titleset.
662
 
663
 **-textmenu**, **-text-menu** NUM
664
-    If used without an argument, create a textmenu out of the supplied titles
665
-    The optional argument specifies how many titles are in the 1st column,
666
-    i.e. giving 4 titles and using **-textmenu 2** would make 2 columns of 2
667
-    titles. The default is to put all titles up to 13 in the first column
668
-    before starting a second column.  Maximum: 2 columns and 26 titles.
669
-    Note that column 2 titles are aligned to the right.
670
-    If no video files for either **-background** or **-showcase** are supplied,
671
-    the menu will be static.
672
+    If used without an argument, create a textmenu out of the supplied
673
+    titles The optional argument specifies how many titles are in the
674
+    1st column, i.e. giving 4 titles and using "-textmenu 2" would make
675
+    2 columns of 2 titles. The default is to put all titles up to 13 in
676
+    the first column before starting a second column. Maximum: 2 columns
677
+    and 26 titles. Note that column 2 titles are aligned to the right.
678
+    If no video files for either **-background** or **-showcase** are
679
+    supplied, the menu will be static.
680
 
681
 **-quick-menu**
682
-    (Note: unfortunately ffmpeg's 'vhooks' have been removed, so this
683
-    option may not be available for you depending on your ffmpeg version)
684
-    This will make a very quick  menu by using ffmpeg instead of imagemagick.
685
-    There are two choices: you can either use **-showcase IMAGE|VIDEO** or
686
-    **-background VIDEO**.  There are no fancy effects like **-wave**
687
-    or **-rotate** available for it, but it is extremely fast.  It will be a
688
-    text-menu style of menu, with no video thumbs, and a central showcase
689
-    IMAGE (static) | VIDEO (animated).  See **-bg-color** if you are not using
690
-    a **-background** and want to change the default black.
691
-
692
-    Specifying the IMAGE|VIDEO argument to **-showcase** is mandatory for this
693
-    style of menu, unless used in conjunction with **-switched-menus**
694
-    in which case the videos passed with **-files** automatically become the
695
-    showcase videos.  If this is used in combination with **-switched-menus**
696
-    it can really speed up an otherwise time consuming process.
697
-
698
-    Example::
699
-
700
-        -quick-menu -showcase /home/robert/showcase.mpg
701
+    If you are using ffmpeg 0.8 or newer you can use this option. This
702
+    will make a very quick menu by using ffmpeg instead of imagemagick.
703
+    There are two choices: you can either use ’-showcase
704
+    IMAGE|VIDEO or ’-background VIDEO’. There are no fancy
705
+    effects like **-wave** or **-rotate** available for it, but it is
706
+    extremely fast. It will be a text-menu style of menu, with no video
707
+    thumbs, and a central showcase IMAGE(static) | VIDEO(animated). 
708
+    (i) see **-bg-color** if you are not using a **-background** and
709
+    want to change the default black ) (ii) Note: todisc will still work
710
+    with vhooks if you have an old ffmpeg with vhooks compiled in.
711
+
712
+    Specifying the IMAGE|VIDEO argument to **-showcase** is
713
+    mandatory for this style of menu, unless used in conjunction with
714
+    **-switched-menus** in which case the videos passed with **-files**
715
+    automatically become the showcase videos. If this is used in
716
+    combination with **-switched-menus** it can really speed up an
717
+    otherwise time consuming process.
718
+
719
+    Example:
720
+
721
+    ::
722
+
723
+            -quick-menu -showcase /home/robert/showcase.mpg
724
 
725
     See **-switched-menus** for example of making switched menus with
726
     **-quick-menu**
727
 
728
-**-bg-color** | **-bg-colour**
729
+**-bg-color**, **-bg-colour**
730
     The color to use for the menu background. (default: ntsc-safe black)
731
-    Note: use a color a great deal darker than you want, as it appears quite
732
-    a bit lighter in the video version.  You can use hexadecimal ('#ffac5f')
733
-    or named colors notation.
734
-
735
-**-submenu-bg-color** | **-submenu-bg-colour**
736
-    The color to use as background for the  submenu(s).
737
-    (default: ntsc-safe black)  See **-bg-color**
738
+    Note: use a color a great deal darker than you want, as it appears
739
+    quite a bit lighter in the video version. You can use hexadecimal
740
+    (’#ffac5f’) or named colors notation.
741
 
742
-**-use-makemenu**
743
-    This will use **tovid menu** to create a menu with the provided titles.
744
+**-submenu-bg-color**, **-submenu-bg-colour**
745
+    The color to use as background for the submenu(s). (default:
746
+    ntsc-safe black) See **-bg-color**
747
 
748
 **-static**
749
-    Main menu will just be static thumbs (not animated) (default: animated)
750
+    Main menu will consist of static thumbnail links. (default:
751
+    animated) If you use a video for -showcase or -background then it
752
+    will still be a ’moving’ menu, in spite of the static buttons. This
753
+    option also does double duty for the **-switched-menus** option, and
754
+    will create static "switched" images. See also **-switched-menu**
755
 
756
 **-background** IMAGE|VIDEO
757
-    Menu background.  This can be a image file or an video file.  If it is a
758
-    video file the background will be animated.  Pick a file of correct aspect
759
-    ratio: i.e. it should still look good when resized to 720x480 (PAL 720x576)
760
+    Menu background. This can be a image file or an video file. If it is
761
+    a video file the background will be animated. Pick a file of correct
762
+    aspect ratio: i.e. it should still look good when resized to 4:3
763
+    aspect ratio. It will be resized to fill the entire background.
764
 
765
 **-submenu-background** IMAGE
766
-    Submenu background.  This can be only be an image file.  Pick a file of
767
-    correct aspect ratio: i.e. it should still look good when resized to
768
-    720x480 (PAL 720x576)
769
+    Submenu background. This can be only be an image file. Pick a file
770
+    of correct aspect ratio: i.e. it should still look good when resized
771
+    to 4:3 aspect ratio. It will be resized to fill the entire
772
+    background.
773
 
774
 **-menu-title**
775
-    Title for the root menu - may be longer than thumbnail labels
776
-    Also if you use \n in the title, you can use multi line titles, but you
777
-    would need to adjust **-menu-fontsize** to something smaller than default
778
-    for example::
779
+    Title for the root menu - may be longer than thumbnail labels Also if you
780
+    use \n in the title, you can use multi line titles, but you would need to
781
+    adjust **-menu-fontsize** to something smaller than default for example:
782
 
783
-        $ tovid disc ... -menu-title "A\nMultilined\nTitle" -menu-fontsize 24
784
+    ::
785
+
786
+            $ tovid disc ... -menu-title "A\nMultilined\nTitle" -menu-fontsize 24
787
 
788
 **-menu-font** FONT
789
-    Font to use for titles, either by ImageMagick font name (ex., "Arial") or
790
-    explicit pathname (ex., "/full/path/to/arial.ttf"). To see a complete
791
-    list of acceptable ImageMagick font names, run **convert -list type**, and
792
-    refer to the leftmost column
793
+    Font to use for titles, either by ImageMagick font name (ex.,
794
+    "Arial") or explicit pathname (ex., "/full/path/to/arial.ttf"). To
795
+    see a complete list of acceptable ImageMagick font names, run
796
+    **convert -list type**, and refer to the leftmost column
797
 
798
 **-menu-fontsize**
799
-    Font size for main menu - best to **-preview** if you use this
800
+    Font size for main menu - best to -preview if you use this
801
 
802
 **-submenu-font**
803
-    Font to use for the sub-menu main titles.  See **-menu-font**
804
+    Font to use for the sub-menu main titles. See **-menu-font**
805
 
806
 **-submenu-fontsize**
807
     Font size for the sub-menu main titles
808
 
809
-**-menu-fade** ['BACKGROUND DURATION']
810
-    Fade the menu in and out The background will fade in first, then title (and
811
-    mist if called for), then the menu thumbs.  The fadeout is in reverse
812
-    order.  'BACKGROUND DURATION' is an integer denoting the amount of time the
813
-    background will play before the menu begins to fade in.  This can allow you
814
-    to do a 'transition' to the menu: if you supply a **-background VIDEO** it
815
-    will play for the indicated time before the menu fades in.  Leave the
816
-    optional argument empty (just **-menu-fade**) to get the default behavior
817
-    of showing the background for 1 second before fading the menu in.  To
818
-    disable the fadeout portion, use '**-loop** inf'.  See also:
819
+**-menu-fade** [’BACKGROUND DURATION’]
820
+    Fade the menu in and out The background will fade in first, then
821
+    title (and mist if called for), then the menu thumbs. The fadeout is
822
+    in reverse order. ’BACKGROUND DURATION’ is an integer denoting the
823
+    amount of time the background will play before the menu begins to
824
+    fade in. This can allow you to do a ’transition’ to the menu: if you
825
+    supply a -background VIDEO it will play for the indicated time
826
+    before the menu fades in. Leave the optional argument empty (just
827
+    **-menu-fade**) to get the default behavior of showing the
828
+    background for 1 second before fading the menu in. To disable the
829
+    fadeout portion, use ’**-loop** inf’. See also:
830
     **-transition-to-menu** and **-loop**
831
 
832
 **-transition-to-menu**
833
     This option goes with the **-menu-fade** option above, which must be
834
-    enabled for it to have effect.  It is a convenience option for animated
835
-    backgrounds: the background will become static at the exact point the
836
-    thumbs finish fading in. This menu does not loop unless you pass
837
-    **-loop VALUE**.  See also: **-loop**
838
+    enabled for it to have effect. It is a convenience option for
839
+    animated backgrounds: the background will become static at the exact
840
+    point the thumbs finish fading in. This menu does not loop unless
841
+    you pass **-loop** VALUE. See also: **-loop**
842
 
843
-**-bgaudio**, **-bg-audio** FILE
844
-    An file containing audio for the main menu background.  For static menus
845
-    the default is to use 20 seconds of audio.  You can change this using the
846
-    **-menu-length** option.
847
+**-bgaudio**, **-bg-audio\*** FILE
848
+    An file containing audio for the main menu background. For static
849
+    menus the default is to use 20 seconds of audio. You can change this
850
+    using the **-menu-length** option.
851
 
852
 **-submenu-audio** FILE(S)
853
-    List of files for sub-menu audio backgrounds. If one file is given, then
854
-    it will be used for all sub-menus.  Otherwise the number given must equal
855
-    the number of submenus, though the keyword "none" in this list may be used for
856
-    silence.  See also **-submenu-length**
857
+    List of files for sub-menu audio backgrounds. If one file is given,
858
+    then it will be used for all sub-menus. Otherwise the number given
859
+    must equal the number of submenus, though the keyword "none" in this
860
+    list may be used for silence. See also **-submenu-length**
861
 
862
 **-titleset** . . . **-end-titleset**
863
-    If you have more than one titleset, put options for each titleset between
864
-    **-titleset** and **-end-titleset**.  A separate menu will be created that
865
-    can be accessed from the main menu (VMGM).  You can create this main menu
866
-    using the **-vmgm** **-end-vmgm** options.  See **-vmgm** below and
867
-    :ref:`usage-titlesets` under the **Usage** section.
868
+    If you have more than one titleset, put options for each titleset
869
+    between **-titleset** and **-end-titleset**. A separate menu will be
870
+    created that can be accessed from the main menu (VMGM). You can
871
+    create this main menu using the **-vmgm** **-end-vmgm** options. See
872
+    **-vmgm** below and TITLESET paragraph opening **Usage** section.
873
 
874
 **-vmgm** . . . **-end-vmgm**
875
-    The VMGM menu is the root menu when you use titlesets.
876
-    Put your VMGM menu options between **-vmgm** and **-end-vmgm**.
877
-    You only need **-titles** "Titleset One title"  "Titleset Two title"
878
-    . . . , and not **-files**.
879
-    Any other options can be used, but the  menu will be a textmenu style by
880
-    default.  **Hint**: use **-showcase** IMAGE/VIDEO to create a fancier
881
-    VMGM menu.
882
-
883
-**-no-vmgm-menu** | **-no-vmgm**
884
-    This will skip the creation of a VMGM ( root menu ) for titlesets. The DVD
885
-    will start with the first titleset.  You can not use this option unless also
886
-    using **-quick-nav** as you would not have a way to get to other titlesets.
887
+    The VMGM menu is the root menu when you use titlesets. Put your VMGM
888
+    menu options between **-vmgm** and **-end-vmgm**. You only need
889
+    **-titles** "Titleset One title" "Titleset Two title" . . . , and
890
+    not **-files**. Any other options can be used, but the menu will be
891
+    a textmenu style by default. **Hint**: use **-showcase** IMAGE/VIDEO
892
+    to create a fancier VMGM menu.
893
+
894
+**-no-vmgm-menu**, **-no-vmgm**
895
+    This will skip the creation of a VMGM ( root menu ) for titlesets.
896
+    The DVD will start with the first titleset. You can not use this
897
+    option unless also using **-quick-nav** as you would not have a way
898
+    to get to other titlesets.
899
 
900
 **-skip-vmgm**
901
     Start DVD from the first titleset instead of the VMGM ( root ) menu.
902
 
903
 **-switched-menus**
904
-    This will make a "switched menu": there will be a central image where the
905
-    showcase image would go, and text menu titles along the menu edge where
906
-    textmenu titles go.  As you select a video title with the down or up arrow
907
-    on your DVD remote, the image in the centre will change to the image or
908
-    video made from that selected video. Do not use **-showcase** IMAGE/VIDEO
909
-    with this option.
910
+    This will make a "switched menu": there will be a central image
911
+    where the showcase image would go, and text menu titles along the
912
+    menu edge where textmenu titles go. As you select a video title with
913
+    the down or up arrow on your DVD remote, the image in the centre
914
+    will change to the image or video made from that selected video. Do
915
+    not use **-showcase** IMAGE/VIDEO with this option.
916
+
917
+    This can be a time consuming process for making animated menus as
918
+    you need to make a separate menu for each video provided with
919
+    **-files**. The process can be greatly sped up by using
920
+    **-quick-menu** in conjunction with this, though you will lose fancy
921
+    options like **-rotate** and **-wave**.
922
 
923
-    This can be a time consuming process for making animated menus as you need
924
-    to make a separate menu for each video provided with **-files**.  The
925
-    process can be greatly sped up by using **-quick-menu** in conjunction with
926
-    this, though you will lose fancy options like **-rotate** and **-wave**.
927
+    Note that if you want to just have a static rather than an
928
+    ’animated’ image, add **-static** to the command line.
929
 
930
-    Example for using with **-quick-menu**::
931
+    Example for using with **-quick-menu**:
932
 
933
-        -switched-menus -quick-menu
934
+    ::
935
 
936
+            -switched-menus -quick-menu
937
 
938
 Thumbnail style
939
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
940
-
941
-**-thumb-shape** normal|oval|vignette|plectrum|arch|spiral|blob|star|flare
942
-    Apply a shaped transparency mask to thumbnail videos.
943
-    These "feathered" shapes look best against a plain background (or used
944
-    in conjunction with **-thumb-mist** [COLOR]).  For this rectangular
945
-    semi-transparent misted background for each thumb:  see **-thumb-mist**.
946
-    Note: if you wish to make your own mask PNGS you can put them in
947
-    $PREFIX/lib/tovid/masks/ or $HOME/.tovid/masks/ and use them on the
948
-    command line using the filename minus the path and extension.
949
-    (i.e ~/.tovid/masks/tux.png becomes **-thumb-shape tux**)
950
+---------------
951
+
952
+**-thumb-shape**
953
+    normal|oval|vignette|plectrum|arch|spiral|blob|star|flare
954
+    Apply a shaped transparency mask to thumbnail videos. These
955
+    "feathered" shapes look best against a plain background (or used in
956
+    conjunction with **-thumb-mist** [COLOR]). For this rectangular
957
+    semi-transparent misted background for each thumb: see
958
+    **-thumb-mist**. Note: if you wish to make your own mask PNGS you
959
+    can put them in $PREFIX/lib/tovid/masks/ or $HOME/.tovid/masks/ and
960
+    use them on the command line using the filename minus the path and
961
+    extension. (i.e ~{}/.tovid/masks/tux.png becomes -thumb-shape tux)
962
     No frame is used for shaped thumbs.
963
 
964
 **-thumb-frame-size** INT
965
-    The size (thickness) of the thumb frames in pixels.  This will also set the
966
-    thickness of the raised "frame" of thumbs when you use **-3d-thumbs**.
967
-    See also **-showcase-frame-size** and **-thumb-frame-color**
968
+    The size (thickness) of the thumb frames in pixels. This will also
969
+    set the thickness of the raised "frame" of thumbs when you use
970
+    **-3d-thumbs**. See also **-showcase-frame-size** and
971
+    **-thumb-frame-color**
972
 
973
 **-thumb-frame-color**, **-thumb-frame-colour** COLOR
974
-    The color of frames for video thumbnails.  Use hexadecimal or named colors
975
-    notation.  Remember to quote if using hexadecimal! ( '#ffac5f' ).
976
+    The color of frames for video thumbnails. Use hexadecimal or named
977
+    colors notation. Remember to quote if using hexadecimal! ( ’#ffac5f’
978
+    ).
979
 
980
 **-3d-thumbs**, **-3dthumbs**
981
-    This will give an illusion of 3D to the thumbnails: dynamic lighting on
982
-    rounded thumbs, and a raised effect on rectangular thumbs.  Try it !
983
+    This will give an illusion of 3D to the thumbnails: dynamic lighting
984
+    on rounded thumbs, and a raised effect on rectangular thumbs. Try it
985
+    !
986
 
987
 **-titles-font** FONT
988
     Display thumbnail or textmenu titles in the given font
989
@@ -528,197 +607,233 @@
990
 **-titles-fontsize** POINTS
991
     Font size to use for thumbnail or textmenu titles
992
 
993
-
994
 Slideshows
995
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
996
+----------
997
 
998
 **-slides** IMAGES
999
-    Use **-slides** IMAGES to pass in images for a slideshow.  The default is
1000
-    to make an animated menu of the slides, moving from one slide to the
1001
-    next. If you use **-static**, a 'polaroid stack' montage is created.  This
1002
-    composites the slides onto the background in 'random' locations with random
1003
-    rotations.  **-slides**  IMAGES can be used multiple times if you wish to
1004
-    make a menu with multiple slideshows.  You can also make a menu
1005
-    of mixed videos and slideshows by using **-slides** IMAGES, and **-files**
1006
-    VIDEOS multiple times.  For such a menu, the number of **-titles**
1007
-    needs to match the number of **-files** passed in plus the number of
1008
-    slideshows.  (Each time you use **-slides** counts as one title.)  To use
1009
-    a transition between the slides, use **-slide-transition**
1010
-    crossfade|fade.  See **-slide-transition** **-menu-slide-total**
1011
+    Use **-slides** IMAGES to pass in images for a slideshow. The
1012
+    default is to make an animated menu of the slides, moving from one
1013
+    slide to the next. If you use **-static**, a ’polaroid stack’
1014
+    montage is created. This composites the slides onto the background
1015
+    in ’random’ locations with random rotations. **-slides** IMAGES can
1016
+    be used multiple times if you wish to make a menu with multiple
1017
+    slideshows. You can also make a menu of mixed videos and slideshows
1018
+    by using **-slides** IMAGES, and **-files** VIDEOS multiple times.
1019
+    For such a menu, the number of **-titles** needs to match the number
1020
+    of **-files** passed in plus the number of slideshows. (Each time
1021
+    you use **-slides** counts as one title.) To use a transition
1022
+    between the slides, use **-slide-transition**
1023
+    crossfade|fade. See **-slide-transition** **-menu-slide-total**
1024
 
1025
 **-menu-slide-total** INT
1026
-    Use INT number of the slides that were passed in with **-slides**
1027
-    to make the animated or static slide menu.  The length of the menu is
1028
-    determined by 1) **-menu-length** NUM if given,  and by 2) the length
1029
-    of the audio from **-bgaudio**.  For submenu slideshows, it is determined
1030
-    by 1) **-submenu-length** NUM if given,  and by 2) the length of the
1031
-    audio from **-submenu-audio** FILE(S).
1032
+    Use INT number of the slides that were passed in with **-slides** to
1033
+    make the animated or static slide menu. The length of the menu is
1034
+    determined by 1) **-menu-length** NUM if given, and by 2) the length
1035
+    of the audio from **-bgaudio**. For submenu slideshows, it is
1036
+    determined by 1) **-submenu-length** NUM if given, and by 2) the
1037
+    length of the audio from **-submenu-audio** FILE(S).
1038
 
1039
 **-submenu-slide-total** INT
1040
     This option is the same as **-menu-slide-total** except that it is
1041
     for submenu slideshows.
1042
 
1043
 **-slide-transition** crossfade|fade [crossfade]
1044
-    The type of fade transition between slides in a animated slide menu.  Be
1045
-    sure the menu length is long enough to support the 1 second transitions
1046
-    between the slides.  The length is determined by 1) the length of the
1047
-    **-bgaudio AUDIO** and 2) the length given with **-menu-length NUM**.  For
1048
-    submenu slideshows, it is determined by 1) **-submenu-length NUM** if
1049
-    given, and by 2) the length of the audio from **-submenu-audio** FILE(S).
1050
+    The type of fade transition between slides in a animated slide menu.
1051
+    Be sure the menu length is long enough to support the 1 second
1052
+    transitions between the slides. The length is determined by 1) the
1053
+    length of the -bgaudio AUDIO 2) the length given with -menu-length
1054
+    NUM. For submenu slideshows, it is determined by 1)
1055
+    **-submenu-length** NUM if given, and by 2) the length of the audio
1056
+    from **-submenu-audio** FILE(S).
1057
 
1058
     See **-menu-slide-total** , **-bgaudio** , **-menu-length** ,
1059
     **-submenu-length**, and **-submenu-audio**.
1060
 
1061
-    The 'crossfade' transition fades from one slide to another.  The 'fade'
1062
-    transition fades in and out from and to black.  If you don't use this
1063
-    option, the default is to use a 'crossfade' transition.
1064
+    The ’crossfade’ transition fades from one slide to another. The
1065
+    ’fade’ transition fades in and out from and to black. If you don’t
1066
+    use this option, the default is to use a ’crossfade’ transition.
1067
 
1068
 **-slideshow-menu-thumbs** FILES
1069
     Use the FILES instead of the 1st image in each slideshow as the
1070
-    thumb that shows on the menu.  This option is for multiple slideshows
1071
+    thumb that shows on the menu. This option is for multiple slideshows
1072
     or mixed slideshow/video menus only.
1073
 
1074
 **-slides-to-bin** FILES
1075
-    FILES will be resized to 640x480 using a 'box' filter - this
1076
-    is called 'binning'.  It will reduce the 'signal to noise' ratio for the
1077
-    image in the animated slide menu.  Use this if you get some unwanted
1078
-    effects for certain images, such as pixels shifting in what should be a
1079
-    static image.  See also **-slides-to-blur** and **-slide-border**
1080
+    FILES will be resized to 640x480 using a ’box’ filter - this is
1081
+    called ’binning’. It will reduce the ’signal to noise’ ratio for the
1082
+    image in the animated slide menu. Use this if you get some unwanted
1083
+    effects for certain images, such as pixels shifting in what should
1084
+    be a static image. See also **-slides-to-blur** and
1085
+    **-slide-border**
1086
 
1087
 **-slides-to-blur** FILES
1088
-    FILES will be blurred a small amount - which will help on
1089
-    slides that still have noise even after 'binning' with -slides-to-bin.
1090
-    The default blur is 0x0.2 - you can increase this with
1091
-    -slide-blur ARG.  See also **-slides-to-bin** and **-slide-border**
1092
+    FILES will be blurred a small amount - which will help on slides
1093
+    that still have noise even after ’binning’ with -slides-to-bin. The
1094
+    default blur is 0x0.2 - you can increase this with -slide-blur ARG.
1095
+    See also **-slides-to-bin** and **-slide-border**
1096
 
1097
 **-slide-blur** VALUE or LIST of VALUES [0x0.2]
1098
-    The argument to use for blurring files.  It will be passed to
1099
-    imagemagick: convert -blur ARG.  The format of the arg is {radius}x{sigma}
1100
-    and the default is 0x0.2. Using values between 0x0.1 and 0x0.9 is probably
1101
-    the best range.  Use a single value for all, or a list to have a different
1102
-    blur for each file passed with **-slides-to-blur**.  You must pass in
1103
-    **-files-to-blur** FILES to use this option.  Blurring can help 'noise'
1104
-    problems in the video.  See also **-slides-to-bin** and **-slide-border**
1105
+    The argument to use for blurring files. It will be passed to
1106
+    imagemagick: convert -blur ARG. The format of the arg is
1107
+    {radius}x{sigma} and the default is 0x0.2. Using values between
1108
+    0x0.1 and 0x0.9 is probably the best range. Use a single value for
1109
+    all, or a list to have a different blur for each file passed with
1110
+    **-slides-to-blur**. You must pass in **-files-to-blur** FILES to
1111
+    use this option. Blurring can help ’noise’ problems in the video.
1112
+    See also **-slides-to-bin** and **-slide-border**
1113
 
1114
 **-slide-border** WIDTH [100]
1115
-    Pad the slides with a border for the animated slide menu.  The default
1116
-    without using an argument is 100.  Using this option can also solve some
1117
-    noise/ringing effects if used alone or in conjunction with 'binning'
1118
-    (**-slides-to-bin**) or blurring (**-slides-to-blur**).
1119
+    Pad the slides with a border for the animated slide menu. The
1120
+    default without using an argument is 100. Using this option can also
1121
+    solve some noise/ringing effects if used alone or in conjunction
1122
+    with ’binning’ (**-slides-to-bin**) or blurring
1123
+    (**-slides-to-blur**).
1124
 
1125
 **-slide-frame** WIDTH [12]
1126
-    Frame the slides for the animated slideshow menu.  The default width
1127
-    without using an  argument is 12.  See also **-slide-frame-color**
1128
+    Frame the slides for the animated slideshow menu. The default width
1129
+    without using an argument is 12. See also **-slide-frame-color**
1130
 
1131
-**-slide-frame-color** | **-slide-frame-colour**
1132
-    The color of the slide frame if passing **-slide-frame**.  The default if
1133
-    you don't use this option is a color-safe white: rgb(235,235,235).
1134
+**-slide-frame-color**, **-slide-frame-colour**
1135
+    The color of the slide frame if passing **-slide-frame**. The
1136
+    default if you don’t use this option is a color-safe white:
1137
+    rgb(235,235,235).
1138
 
1139
 **-showcase-slideshow**
1140
-    If doing multiple slideshows or mixed videos and slideshow(s), then use
1141
-    the animated slideshow as a showcase video.  It will be composed of slides
1142
-    from each slideshow in the menu.  The thumb for each slideshow button will
1143
-    be static.  If you used with a mixed menu of videos and slideshows, then
1144
-    the video thumbs WILL be animated, so you may wish to use -static or
1145
-    -textmenu with the option in that case.
1146
+    If doing multiple slideshows or mixed videos and slideshow(s), then
1147
+    use the animated slideshow as a showcase video. It will be composed
1148
+    of slides from each slideshow in the menu. The thumb for each
1149
+    slideshow button will be static. If you used with a mixed menu of
1150
+    videos and slideshows, then the video thumbs WILL be animated, so
1151
+    you may wish to use -static or -textmenu with the option in that
1152
+    case. If you want to use the \*\*-switched-menus option with a mixed
1153
+    menu leave this option out.
1154
 
1155
 **-background-slideshow**, **-bg-slideshow**
1156
-    If doing multiple slideshows or mixed videos and slideshow(s), then use
1157
-    the animated slideshow as a background video.  See **-showcase-slideshow**
1158
-    for additional details.
1159
+    If doing multiple slideshows or mixed videos and slideshow(s), then
1160
+    use the animated slideshow as a background video. See
1161
+    **-showcase-slideshow** for additional details.
1162
 
1163
 **-no-confirm-backup**
1164
-    Slideshows are an experimental (but well tested) feature.  Todisc is
1165
-    unlikely to overwrite your personal files, but you should take precautions
1166
-    and backup your images, as you would with any beta software.  Todisc
1167
-    will prompt you to backup your files normally.  If you have already backed
1168
-    up your images, use this option to disable the prompt.
1169
-
1170
-**-use-dvd-slideshow** [FILE CONFIG]
1171
+    Slideshows are an experimental (but well tested) feature. Todisc is
1172
+    unlikely to overwrite your personal files, but you should take
1173
+    precautions and backup your images, as you would with any beta
1174
+    software. Todisc will prompt you to backup your files normally. If
1175
+    you have already backed up your images, use this option to disable
1176
+    the prompt.
1177
+
1178
+**-use-dvd-slideshow** {CONFIG} {FILE}
1179
     If you pass this option without an argument, tovid will use the
1180
-    dvd-slideshow program to create the animated slide menu, assuming you have
1181
-    this program installed.  The optional argument is the dvd-slideshow
1182
-    configuration file  - if you don't use this argument tovid will create it
1183
-    for you.  If you want to use the 'Ken Burns effect' - then the
1184
-    configuration file argument is required.  Note: the configuration file will
1185
-    override many of the above options for slideshows.
1186
+    dvd-slideshow program to create the animated slide menu, assuming
1187
+    you have this program installed. The optional argument is the
1188
+    dvd-slideshow configuration file - if you don’t use this argument
1189
+    tovid will create it for you. If you want to use the ’Ken Burns
1190
+    effect’ - then the configuration file argument is required. Note:
1191
+    the configuration file will override many of the above options for
1192
+    slideshows.
1193
+
1194
+Burning the disc
1195
+----------------
1196
 
1197
+**-burn**
1198
+    Prompt to burn the DVD directory on completion.
1199
 
1200
-Advanced Options
1201
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1202
+**-device**
1203
+    Device to use for the burning program [ /dev/dvdrw ]
1204
+
1205
+**-speed**
1206
+    The speed to use for burning the disc.
1207
+
1208
+Advanced usage
1209
+--------------
1210
+
1211
+Options
1212
+~~~~~~~
1213
 
1214
 **-menu-length**
1215
     The desired animated main menu length in seconds
1216
 
1217
 **-submenu-length**
1218
-    The desired submenu length.  This will also affect the length of submenu
1219
-    audio for static submenus.  (Assuming that -submenu-audio was passed in).
1220
-    The default is to use 10 seconds of audio for static menus.
1221
+    The desired submenu length. This will also affect the length of
1222
+    submenu audio for static submenus. (Assuming that -submenu-audio was
1223
+    passed in). The default is to use 10 seconds of audio for static
1224
+    menus.
1225
 
1226
 **-submenu-stroke** COLOR
1227
-    The color for the sub-menu font outline (stroke)
1228
+    The color for the sub-menu font shadow
1229
 
1230
 **-submenu-title-color**, **-submenu-title-colour**
1231
     The fill color used for sub-menu title fonts
1232
 
1233
 **-submenu-titles**
1234
-    You can supple a list of titles here for sub-menus without the length
1235
-    restrictions found in thumb titles.  Must equal number of videos
1236
+    You can supple a list of titles here for sub-menus without the
1237
+    length restrictions found in thumb titles. Must equal number of
1238
+    videos
1239
 
1240
 **-chapters** [ NUM | CHAPTER POINTS in HH:MM:SS ]
1241
-    The number of chapters for each video (default: 6) OR
1242
-    the actual chapter points in HH:MM:SS format.
1243
-    Chapter points will be used for generating the submenu thumbs, and for
1244
-    seeking with your DVD player.  You can pass in just one value that will
1245
-    be used for all videos, or supply a list of values (number of chapters)
1246
-    or time code strings.
1247
+    The number of chapters for each video (default: 6) OR the actual
1248
+    chapter points in HH:MM:SS format. Chapter points will be used for
1249
+    generating the submenu thumbs, and for seeking with your DVD player.
1250
+    You can pass in just one value that will be used for all videos, or
1251
+    supply a list of values (number of chapters) or time code strings.
1252
 
1253
-    If you just pass an integer for 'number of chapters', then tovid will
1254
-    make the chapter points for you by dividing the video length by the number
1255
-    you supply.  If using the **-no-menu** option, the INT passed in will be
1256
-    the chapter interval in minutes, rather than the above formula.
1257
+    If you just pass an integer for ’number of chapters’, then tovid
1258
+    will make the chapter points for you by dividing the video length by
1259
+    the number you supply. If using the **-no-menu** option, the INT
1260
+    passed in will be the chapter interval in minutes, rather than the
1261
+    above formula.
1262
 
1263
-    If passing HH:MM:SS format you need to pass the string of chapter points for
1264
-    each video and each string should have comma separated values.
1265
-    Additionally, the first chapter should always start at 00:00:00 as
1266
-    dvdauthor will add that if it is not there already.
1267
+    If passing HH:MM:SS format you need to pass the string of chapter
1268
+    points for each video and each string should have comma separated
1269
+    values. Additionally, the first chapter should always start at
1270
+    00:00:00 as dvdauthor will add that if it is not there already.
1271
 
1272
-    To get your time codes, you can play your videos in mplayer and press 'o'
1273
-    to see them on-screen.  I have found these to be very accurate in my short
1274
-    tests.  For greater frame accuracy you could try loading the file in
1275
-    avidemux and find the time codes for the frames you want.
1276
+    To get your time codes, you can play your videos in mplayer and
1277
+    press ’o’ to see them on-screen. I have found these to be very
1278
+    accurate in my short tests. For greater frame accuracy you could try
1279
+    loading the file in avidemux and find the time codes for the frames
1280
+    you want.
1281
 
1282
-    If passing grouped chapters you need to join the chapters from all the
1283
-    videos in a group with a '+' separator.  If you want to skip creating
1284
-    chapters for a video in the group use '0' for its chapters.
1285
+    If passing grouped chapters you need to join the chapters from all
1286
+    the videos in a group with a ’+’ separator. If you want to skip
1287
+    creating chapters for a video in the group use ’0’ for its chapters.
1288
 
1289
-    Note: chapters for grouped videos should probably be passed in using the
1290
-    above HH:MM:SS format. (Arbitrary chapters using just an INT for the # of
1291
-    chapters is not guaranteed to work reliably in all cases for grouped videos
1292
-    at the moment.)
1293
+    Note: chapters for grouped videos should probably be passed in using
1294
+    the above HH:MM:SS format. (Arbitrary chapters using just an INT for
1295
+    the # of chapters is not guaranteed to work reliably in all cases
1296
+    for grouped videos at the moment.)
1297
 
1298
-    Example for passing just number of chapters ( 4 videos )::
1299
+    Example for passing just number of chapters ( 4 videos ):
1300
 
1301
-        -chapters 5 2 4 8
1302
+    ::
1303
 
1304
-    Example of passing chapter points ( 4 videos )::
1305
+            -chapters 5 2 4 8
1306
 
1307
-        -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45 \
1308
-        00:00:00,00:04:25.623,00:09:12,00:15:51 \
1309
-        00:00:00,00:05:10,00:13:41,00:18:13.033 \
1310
-        00:00:00,00:15:23.342,00:26:42.523
1311
+    Example of passing chapter points ( 4 videos ):
1312
 
1313
-    Example of passing grouped chapters using the '+' separator::
1314
+    ::
1315
 
1316
-        -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45+00:04:23,00:09:35 \
1317
-        00:00:00... etc.
1318
+            -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45 \
1319
+            00:00:00,00:04:25.623,00:09:12,00:15:51 \
1320
+            00:00:00,00:05:10,00:13:41,00:18:13.033 \
1321
+            00:00:00,00:15:23.342,00:26:42.523
1322
+
1323
+    Example of passing grouped chapters using the ’+’ separator:
1324
+
1325
+    ::
1326
+
1327
+            -chapters 00:00:00,00:05:34.41,00:12:54,00:20:45+00:04:23,00:09:35 \
1328
+            00:00:00... etc.
1329
 
1330
 **-chapter-titles** LIST
1331
     If you are using submenus, you can pass a list of titles for the
1332
-    chapters.  Each title must be quoted, and the number of titles given
1333
-    must equal the total number of chapters for all videos.  In other words
1334
-    if you use -chapters 4 6 8 , you must give 18 chapter titles, in the same
1335
-    order that the videos were passed in.
1336
+    chapters. Each title must be quoted, and the number of titles given
1337
+    must equal the total number of chapters for all videos. In other
1338
+    words if you use -chapters 4 6 8 , you must give 18 chapter titles,
1339
+    in the same order that the videos were passed in. Note: if you are
1340
+    passing in options on the command line to the ’tovid disc’ GUI, you
1341
+    must repeat the option **-chapter-titles** for each video,
1342
+    accompanied by its respective chapter titles. (you can also choose
1343
+    to use this syntax for the todisc script.)
1344
 
1345
 **-chapter-font** FONT
1346
     Use FONT as the font for submenu chapters.
1347
@@ -730,15 +845,26 @@
1348
     The color for the chapters font.
1349
 
1350
 **-chapter-stroke** COLOR
1351
-    The color for the chapters font outline (stroke)
1352
+    The color for the chapters font shadow
1353
 
1354
 **-seek** NUM | "NUM1 NUM2 NUM3 . . ."
1355
-    Seek to NUM seconds before generating thumbnails (default: 2.0 seconds)
1356
-    If a quoted string of values matching the number of videos is used, then
1357
-    each video can use a different seek value
1358
-    If using switched menus, the **-seek** value(s) will be used to generate
1359
-    the showcase image that displays on switching to another video choice with
1360
-    the up/down arrow keys.
1361
+    Seek to NUM seconds before generating thumbnails (default: 2.0
1362
+    seconds) If a quoted string of values matching the number of videos
1363
+    is used, then each video can use a different seek value If using
1364
+    switched menus, the **-seek** value(s) will be used to generate the
1365
+    showcase image that displays on switching to another video choice
1366
+    with the up/down arrow keys.
1367
+
1368
+**-fast-seek**
1369
+    Use faster seek method for ffmpeg. This is not as accurate as the
1370
+    default method, and may produce grey frames.
1371
+
1372
+**-frame-safe** Instead of seeking and then outputting one frame for
1373
+    previews and static menus, output 9 frames and choose the largest.
1374
+    Not frame accurate (may be as much as 9 frames off), but safer.
1375
+    Choose this if you are getting grey frames/thumbnails with some
1376
+    videos. You can also use it to try to get the ’best’ frame. This
1377
+    option has no effect on submenus at present.
1378
 
1379
 **-showcase-seek** NUM
1380
     Seek to NUM seconds before generating thumbnails for showcase video
1381
@@ -748,96 +874,124 @@
1382
     Seek to NUM seconds before generating images for background video
1383
     (default: 2.0 seconds)
1384
 
1385
-**-bgaudio-seek**, **-bg-audio-seek** NUM
1386
-    Seek to NUM seconds before generating audio for bgaudio
1387
-    (default: 2.0 seconds)
1388
+**-bgaudio-seek**, \*\*-bg-audio-seek NUM
1389
+    Seek to NUM seconds before generating audio for bgaudio (default:
1390
+    2.0 seconds)
1391
 
1392
 **-group** N VIDEO1 VIDEO2 . . .
1393
-    Allow grouping videos in dvdauthor.xml, so they will play sequentially as
1394
-    a group.  The videos passed in after the 'N' will be grouped with the 'Nth'
1395
-    video. Example::
1396
+    Allow grouping videos in dvdauthor.xml, so they will play
1397
+    sequentially as a group. The videos passed in after the ’N’ will be
1398
+    grouped with the ’Nth’ video. Example:
1399
 
1400
-        -group 2 2.mpg 3.mpg 4.mpg
1401
+    ::
1402
 
1403
-    will group these 3 videos with the 2nd video given with **-files**, so that
1404
-    they will play sequentially as one title.  Only one thumbnail and/or title
1405
-    will appear on the menu for the group: it will be made from the 1st video
1406
-    in the group.  In the above example if you passed::
1407
+            -group 2 2.mpg 3.mpg 4.mpg
1408
 
1409
-        -files foo.mpg bar.mpg baz.mpg -group 2 2.mpg 3.mpg 4.mpg
1410
+    will group these 3 videos with the 2nd video given with **-files**,
1411
+    so that they will play sequentially as one title. Only one thumbnail
1412
+    and/or title will appear on the menu for the group: it will be made
1413
+    from the 1st video in the group. In the above example if you passed:
1414
 
1415
-    then the group will consist of bar.mpg  2.mpg, 3.mpg and 4.mpg, and only the
1416
-    title and/or thumbnail for bar.mpg will appear in the menu.  You can use
1417
-    **-group** more than once for multiple groups.  Be  sure to quote video
1418
-    filenames if they contain  spaces.
1419
+    ::
1420
+
1421
+            -files foo.mpg bar.mpg baz.mpg -group 2 2.mpg 3.mpg 4.mpg
1422
+
1423
+    then the group will consist of bar.mpg 2.mpg, 3.mpg and 4.mpg, and
1424
+    only the title and/or thumbnail for bar.mpg will appear in the menu.
1425
+    You can use **-group** more than once for multiple groups. Be sure
1426
+    to quote video filenames if they contain spaces.
1427
 
1428
 **-jobs**
1429
     By default, **tovid disc** starts a parallel job for each processor
1430
-    detected.  With this option you can manually set the number of jobs.  For
1431
-    example if you have a computer with 2 CPUs you can set **-jobs 1** to keep
1432
-    one processor free for other things.  At present this applies to the time
1433
-    consuming imagemagick loops: you will notice a substantial speedup now if
1434
-    you have a multi-cpu system.
1435
+    detected. With this option you can manually set the number of jobs.
1436
+    For example if you have a computer with 2 CPUs you can set "-jobs 1"
1437
+    to keep one processor free for other things. At present this applies
1438
+    to the time consuming imagemagick loops: you will notice a
1439
+    substantial speedup now if you have a multi-cpu system.
1440
 
1441
-**-no-ask**, **-noask**
1442
-    Skip all interactive questions.  No preview, automatic re-encoding with
1443
-    tovid if needed, no interactive option to use background video for bgaudio.
1444
+**-no-ask** | **-noask**
1445
+    Skip all interactive questions. No preview, automatic re-encoding
1446
+    with tovid if needed, no interactive option to use background video
1447
+    for bgaudio.
1448
 
1449
 **-no-warn**, **-nowarn**
1450
-    Don't pause after outputting warning or info messages
1451
+    Don’t pause after outputting warning or info messages
1452
 
1453
 **-grid**
1454
-    Show a second preview image with a grid and numbers that will help in finding
1455
-    coordinates for options that might use them, like **-text-start**
1456
-
1457
+    Show a second preview image with a grid and numbers that will help
1458
+    in finding coordinates for options that might use them, like
1459
+    **-text-start**
1460
 
1461
 Menu Style
1462
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1463
+----------
1464
 
1465
-**-menu-title-geo** north|south|east|west|center [south]
1466
-    The position of the menu title.  You may need to use **-align** as well if
1467
-    you don't want your title covering other parts of your menu.  See
1468
+**-menu-title-geo**
1469
+north|south|east|west|center|[south]
1470
+    The position of the menu title. You may need to use -align as well
1471
+    if you don’t want your title covering other parts of your menu. See
1472
     **-align**
1473
 
1474
 **-menu-title-offset** OFFSET (+X+Y)
1475
-    Move menu title by this offset from its N|S|E|W|Center position.  You
1476
-    may need to use **-align** as well if you don't want your title covering other
1477
-    parts of your menu.  See **-align**
1478
+    Move menu title by this offset from its
1479
+    N|S|E|W|Center position. You
1480
+    may need to use -align as well if you don’t want your title covering
1481
+    other parts of your menu. See **-align**
1482
 
1483
 **-button-style** rect|text|line|text-rect
1484
-    The style of button that you will see when you play the DVD.  "rect" draws
1485
-    a rectangle around the thumb when you select it in the DVD player.  "text"
1486
-    highlights the video title text, "line" underlines the title, and
1487
-    "text-rect" draws a rectangle around the title text.
1488
+    The style of button that you will see when you play the DVD. "rect"
1489
+    draws a rectangle around the thumb when you select it in the DVD
1490
+    player. "text" highlights the video title text, "line" underlines
1491
+    the title, and "text-rect" draws a rectangle around the title text.
1492
 
1493
 **-title-color**, **-title-colour** COLOR
1494
-    Color to use for the main menu title.  For list of supported colors do:
1495
-    **convert -list** color.  HTML notation may be used: "#ff0000". See:
1496
-    http://www.imagemagick.org/script/color.php
1497
+    Color to use for the main menu title. For list of supported colors
1498
+    do: **convert -list** color. HTML notation may be used: "#ff0000".
1499
+    See: {http://www.imagemagick.org/script/color.php}
1500
+    {http://www.imagemagick.org/script/color.php}
1501
 
1502
 **-title-stroke** COLOR
1503
-    Outline color for the main menu's title font. Use "none" for transparent
1504
-    outline  (see title-color)
1505
+    Shadow color for the main menu’s title font. Use "none" for
1506
+    transparent outline (see title-color). Note: this is not a -stroke
1507
+    in the sense that imagemagick uses the term, but a shadow (the font
1508
+    is drawn twice). To get a true imagemagick stroke see
1509
+    **-title-font-deco**
1510
+
1511
+**-title-font-deco**, **-title-fontdeco** "IMAGEMAGICK STRING"
1512
+    Sets the font decoration method to FONTDECORATION. It is used by the
1513
+    ’convert’ ImageMagick command to draw the menu text. You can add
1514
+    colored text outlines, gradient fills, and many others. See **Usage
1515
+    notes**
1516
 
1517
 **-titles-stroke** COLOR
1518
-    Outline color for the thumb or textmenu video titles font. Use "none" for
1519
-    transparent outline  (see **-titles-color**).
1520
+    Shadow color for the thumb or textmenu video titles font. Use "none"
1521
+    for transparent outline (see **-titles-color**). Note: this is not a
1522
+    -stroke in the sense that imagemagick uses the term, but a shadow
1523
+    (the font is drawn twice). To get a true imagemagick stroke, see
1524
+    **-titles-font-deco**
1525
+
1526
+**-titles-font-deco**, **-titles-fontdeco** "IMAGEMAGICK STRING"
1527
+    Sets the font decoration method to FONTDECORATION. It is used by the
1528
+    ’convert’ ImageMagick command to draw the menu text. You can add
1529
+    colored text outlines, gradient fills, and others. See **Usage
1530
+    notes** for more info.
1531
 
1532
 **-highlight-color**, **-highlight-colour**
1533
-    Color to use for the menu buttons that your DVD remote uses to navigate.
1534
+    Color to use for the menu buttons that your DVD remote uses to
1535
+    navigate.
1536
 
1537
 **-select-color**, **-select-colour**
1538
-    Color to use for the menu buttons that your DVD remote uses to select.
1539
+    Color to use for the menu buttons that your DVD remote uses to
1540
+    select.
1541
 
1542
 **-text-mist**
1543
-    Put a semi-transparent misted background behind the text for the menu's
1544
-    title, just slightly larger than the text area.
1545
+    Put a semi-transparent misted background behind the text for the
1546
+    menu’s title, just slightly larger than the text area.
1547
 
1548
 **-text-mist-color**, **-text-mist-colour** COLOR
1549
-    Color of the mist behind the menu's title (see title-color).
1550
+    Color of the mist behind the menu’s title (see title-color).
1551
 
1552
 **-text-mist-opacity**
1553
-    Opacity of the mist behind the menu's title - see **-opacity**
1554
+    Opacity of the mist behind the menu’s title - see **-opacity**
1555
 
1556
 **-title-opacity**
1557
     Opacity of the menu title text
1558
@@ -852,270 +1006,305 @@
1559
     Opacity of the text for submenu chapter titles
1560
 
1561
 **-menu-audio-fade**
1562
-    Number of sec to fade given menu audio in and out (default: 1.0 seconds)
1563
-    If you use **-menu-audio-fade** 0 then the audio will not be faded.
1564
+    Number of sec to fade given menu audio in and out (default: 1.0
1565
+    seconds) If you use **-menu-audio-fade** 0 then the audio will not
1566
+    be faded.
1567
 
1568
 **-submenu-audio-fade**
1569
-    Number of secs to fade sub-menu audio in and out (default: 1.0 seconds).
1570
-    See **-menu-audio-fade**
1571
+    Number of secs to fade sub-menu audio in and out (default: 1.0
1572
+    seconds). See **-menu-audio-fade**
1573
 
1574
 **-intro** VIDEO
1575
-    Use a introductory video that will play before the main menu.
1576
-    At present it must be a DVD compatible video at the correct resolution etc.
1577
-    Only 4:3 aspect is supported: 16:9 will give unexpected results.
1578
+    Use a introductory video that will play before the main menu. At
1579
+    present it must be a DVD compatible video at the correct resolution
1580
+    etc. Only 4:3 aspect is supported: 16:9 will give unexpected
1581
+    results.
1582
 
1583
-
1584
-Showcase and textmenu
1585
--------------------------------------------------------------------------------
1586
-The following menu style options are specific to showcase and textmenu arrangements:
1587
+Style options specific to showcase/textmenu arrangements
1588
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1589
 
1590
 **-text-start** N
1591
-    This option is for **-textmenu** menus.  The titles will start at the Nth
1592
-    pixel from the top of the menu ( Y axis ).
1593
+    This option is for **-textmenu** menus. The titles will start at the
1594
+    Nth pixel from the top of the menu ( Y axis ).
1595
 
1596
 **-title-gap** N
1597
-    This option is for **-textmenu** menus.  The gap is the space between
1598
+    This option is for **-textmenu** menus. The gap is the space between
1599
     titles vertically ( Y axis ).
1600
 
1601
 **-rotate** DEGREES
1602
     Rotate the showcase image|video clockwise by DEGREES.
1603
-    (default: if used without options, the rotate will be 5 degrees).  Note:
1604
-    this will not turn a portait image into a landscape image!
1605
+    (default: if used without options, the rotate will be 5 degrees).
1606
+    Note: this will not turn a portait image into a landscape image!
1607
 
1608
 **-showcase-geo** GEOMETRY
1609
-    The position of the showcase image.  ( XxY position )
1610
+    The position of the showcase image. ( XxY position )
1611
 
1612
 **-wave** default|GEOMETRY
1613
-    Wave effect for showcase image|video.  Alters thumbs along a sine wave
1614
-    using GEOMETRY. (default: no wave) "default" will produce a wave arg of
1615
-    **-20x556**, which produces a gentle wave with a small amount of
1616
-    distortion.  See: http://www.imagemagick.org/Usage/distorts/#wave if you
1617
-    want to try other values.
1618
-
1619
-**-showcase-shape**  egg|oval|plectrum|arch|spiral|galaxy|flat-tube|normal
1620
-    Apply a shaped transparency mask to showcase videos or images.
1621
-    Note: if you wish to make your own mask PNGS you can put them in
1622
+    Wave effect for showcase image|video. Alters thumbs along
1623
+    a sine wave using GEOMETRY. (default: no wave) "default" will
1624
+    produce a wave arg of -20x556, which produces a gentle wave with a
1625
+    small amount of distortion. See:
1626
+    {http://www.imagemagick.org/Usage/distorts/#wave}
1627
+    {http://www.imagemagick.org/Usage/distorts/#wave} if you want to try
1628
+    other values.
1629
+
1630
+**-showcase-shape** egg|oval|plectrum|arch|spiral|galaxy|flat-tube|normal
1631
+    Apply a shaped transparency mask to showcase videos or images. Note:
1632
+    if you wish to make your own mask PNGS you can put them in
1633
     $PREFIX/lib/tovid/masks/ or $HOME/.tovid/masks/ and use them on the
1634
-    command line using the filename minus the path and extension.
1635
-    No frame is used for shaped thumbs.
1636
-
1637
-**-showcase-framestyle**  none|glass
1638
-    For **-showcase-** style template only
1639
-    "none" will use the default frame method, using "convert -frame . . ."
1640
-    "glass" will use mplayer to make frames, which gives an interesting
1641
-    animated effect to the frames, and can be much faster ( especially if you
1642
-    don't use **-rotate** or **-wave** as thumbs will not need to be processed
1643
-    again after mplayer spits them out.  Note: you need to be using either
1644
-    **-showcase** IMAGE or **-showcase** VIDEO for this "frame style" to work.
1645
+    command line using the filename minus the path and extension. No
1646
+    frame is used for shaped thumbs.
1647
+
1648
+**-showcase-framestyle** none|glass
1649
+    For -showcase-\* style template only "none" will use the default
1650
+    frame method, using "convert -frame . . ." "glass" will use mplayer
1651
+    to make frames, which gives an interesting animated effect to the
1652
+    frames, and can be much faster ( especially if you don’t use
1653
+    **-rotate** or **-wave** as thumbs will not need to be processed
1654
+    again after mplayer spits them out. Note: you need to be using
1655
+    either **-showcase** IMAGE or **-showcase** VIDEO for this "frame
1656
+    style" to work.
1657
 
1658
 **-showcase-frame-size** PIXELS
1659
-    The size of the showcase frame.  This value will be used for both width and
1660
-    height for the 'thickness' of the frame.  This will also set the thickness
1661
-    of the raised "frame" of the showcase thumb when you use **-3d-showcase**.
1662
-    See also **-thumb-frame-size** and **-showcase-frame-color**
1663
+    The size of the showcase frame. This value will be used for both
1664
+    width and height for the ’thickness’ of the frame. This will also
1665
+    set the thickness of the raised "frame" of the showcase thumb when
1666
+    you use **-3d-showcase**. See also **-thumb-frame-size** and
1667
+    **-showcase-frame-color**
1668
 
1669
 **-showcase-frame-color**, **-showcase-frame-colour** PIXELS
1670
-    The color of the showcase frame.  Use hexadecimal or named colors notation.
1671
-    Remember to quote! ( '#ffac5f' ).
1672
+    The color of the showcase frame. Use hexadecimal or named colors
1673
+    notation. Remember to quote! ( ’#ffac5f’ ).
1674
 
1675
 **-3d-showcase**, **-3dshowcase**
1676
-    This will give an illusion of 3D to the showcase thumb: dynamic lighting on
1677
-    rounded thumbs, and a raised effect on rectangular thumbs.  Try it !
1678
+    This will give an illusion of 3D to the showcase thumb: dynamic
1679
+    lighting on rounded thumbs, and a raised effect on rectangular
1680
+    thumbs. Try it !
1681
 
1682
+Thumbnail Style
1683
+---------------
1684
 
1685
-Thumbnail style
1686
--------------------------------------------------------------------------------
1687
+**-user-thumbs** IMAGE
1688
+    Supply your own images for menu buttons, rather than relying on
1689
+    todisc to generate them from the video. They must be the same aspect
1690
+    ratio as the videos in the titleset (4:3 or 16:9), as todisc will
1691
+    resize them without checking and cropping.
1692
 
1693
 **-opacity** [0-100] (default 100)
1694
     Opacity of thumbnail videos as a percentage (no percent sign).
1695
-    Anything less than 100(%) is semi-transparent. Not recommended with dark
1696
-    backgrounds.
1697
+    Anything less than 100(%) is semi-transparent. Not recommended with
1698
+    dark backgrounds.
1699
 
1700
 **-thumb-blur**, **-blur** NUM
1701
-    The amount of feather blur to apply to the thumb-shape.  The default is 1.0
1702
-    which will more or less keep the shape and produces transparency at the
1703
-    edges.  Choose float or integer values between 0.1 and 2.0. 3D thumbs are
1704
-    set to a tiny blur, so this option doesn't affect the **-3dthumbs** option.
1705
+    The amount of feather blur to apply to the thumb-shape. The default
1706
+    is 1.0 which will more or less keep the shape and produces
1707
+    transparency at the edges. Choose float or integer values between
1708
+    0.1 and 2.0. 3D thumbs are set to a tiny blur, so this option
1709
+    doesn’t affect the **-3dthumbs** option.
1710
 
1711
 **-showcase-blur** NUM
1712
-    The amount of 'feather' blur to apply to the showcase image/video.  Choose
1713
-    values between 0.1 and 2.0.  This option has no effect on **-3d-showcase**.
1714
-    See **-thumb-blur** for more info.
1715
+    The amount of ’feather’ blur to apply to the showcase image/video.
1716
+    Choose values between 0.1 and 2.0. This option has no effect on
1717
+    **-3d-showcase**. See **-thumb-blur** for more info.
1718
 
1719
 **-align** north|south
1720
-    This will align  thumbs/titles north or south.
1721
-    If **-align** south then menu title will align north, unless you manually
1722
-    set one or both of **-menu-title-geo** or **-menu-title-offset**.
1723
+    This will align thumbs/titles north or south. If **-align** south
1724
+    then menu title will align north, unless you manually set one or
1725
+    both of **-menu-title-geo** or **-menu-title-offset**.
1726
 
1727
 **-thumb-mist** [COLOR]
1728
-    Use a mist behind thumbnails.  The optional argument is the color of the
1729
-    mist.  This option helps with contrast.  Be sure to set the font color
1730
-    to an appropriate color if using a colored mist, and/or use a bold font.
1731
+    Use a mist behind thumbnails. The optional argument is the color of
1732
+    the mist. This option helps with contrast. Be sure to set the font
1733
+    color to an appropriate color if using a colored mist, and/or use a
1734
+    bold font.
1735
 
1736
 **-titles-color**, **-titles-colour** COLOR
1737
-    Color to use for the thumb or textmenu titles.  If your titles are not
1738
-    clear enough or look washed out, try using a **-titles-stroke** that
1739
-    is the same color as used with **-titles-color**  (see **-title-color**)
1740
+    Color to use for the thumb or textmenu titles. If your titles are
1741
+    not clear enough or look washed out, try using a **-titles-stroke**
1742
+    that is the same color as used with **-titles-color** (see
1743
+    **-title-color**)
1744
 
1745
 **-showcase-titles-align** west|east (default: center [centre])
1746
-    The default is to center the text above the thumbnails.  This option will
1747
-    align the titles either to the left (west) or right (east).  Aligning west
1748
-    gives more space to the titles.  Aligning east also does so, and as well
1749
-    will facilitate using \n in your titles to achieve multi line titles.
1750
+    The default is to center the text above the thumbnails. This option
1751
+    will align the titles either to the left (west) or right (east).
1752
+    Aligning west gives more space to the titles. Aligning east also
1753
+    does so, and as well will facilitate using \n in
1754
+    your titles to achieve multi line titles.
1755
 
1756
 **-tile-3x1**, **-tile3x1**
1757
-    Use a montage tile of 3x1 instead of the usual 2x2 for 3 videos
1758
-    ie.::
1759
+    Use a montage tile of 3x1 instead of the usual 2x2 for 3 videos ie.
1760
 
1761
-        [movie1] [movie2] [movie3] instead of:
1762
+    [movie1] [movie2] [movie3] instead of:
1763
 
1764
-        [movie1] [movie2]
1765
+    [movie1] [movie2]
1766
 
1767
-        [movie3]
1768
+    [movie3]
1769
 
1770
-    This option only comes into play if the number of videos supplied equals 3
1771
-    Otherwise it will be silently ignored. Not used for **-showcase-\*** style.
1772
+    This option only comes into play if the number of videos supplied
1773
+    equals 3 Otherwise it will be silently ignored. Not used for
1774
+    -showcase-\* style.
1775
 
1776
 **-tile-4x1**, **-tile4x1**
1777
-    Same as **-tile-3x1** above, except use tile of 4x1. (one row of 4 videos)
1778
+    Same as **-tile-3x1** above, except use tile of 4x1. (one row of 4
1779
+    videos)
1780
 
1781
-**-thumb-columns** 3|4
1782
-    Same as **-tile-3x1** and **tile-4x1** above, except it accepts either '3'
1783
-    (1 row of 3 thumbs), or '4' (one row of 4 thumbs) as an argument.  This
1784
-    alternative was added to help compact the gui layout.
1785
+\*\*-thumb-columns 3|4
1786
+    Same as **-tile-3x1** and tile-4x1\*\* above, except it accepts
1787
+    either ’3’ (1 row of 3 thumbs), or ’4’ (one row of 4 thumbs) as an
1788
+    argument. This alternative was added to help compact the gui layout.
1789
 
1790
 **-rotate-thumbs** DEGREE LIST ( list of degrees, one for each thumb )
1791
-    Rotate thumbs the given amount in degrees - can be positive or negative.
1792
-    There must be one value for each file given with **-files**.
1793
-    If the values are not the same distance from zero, the thumbs will be of
1794
-    different sizes as images are necessarily resized *after* rotating.  With
1795
-    the default montage template - this will also resize the titles; with the
1796
-    showcase template the titles will remain the same size. Example::
1797
+    Rotate thumbs the given amount in degrees - can be positive or
1798
+    negative. There must be one value for each file given with
1799
+    **-files**. If the values are not the same distance from zero, the
1800
+    thumbs will be of different sizes as images are necessarily resized
1801
+    \*after\* rotating. With the default montage template - this will
1802
+    also resize the titles; with the showcase template the titles will
1803
+    remain the same size. Example:
1804
 
1805
-        -rotate-thumbs -10 10 -10 10 -10  (for 5 files)
1806
+    ::
1807
 
1808
-    **Note**: this option will not turn a portrait image into a landscape image!
1809
+            -rotate-thumbs -10 10 -10 10 -10  (for 5 files)
1810
 
1811
+    \*\*Note: this option will not turn a portrait image into a
1812
+    landscape image!
1813
 
1814
 Dvdauthor options
1815
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1816
+-----------------
1817
 
1818
 **-loop** PAUSE
1819
-    Pause in seconds at end of menu.  Use "inf" if you wish indefinite pause.
1820
-    Note: using "inf" with **-menu-fade** will disable the fadeout portion of
1821
-    the fade.  (default: "inf" for static menu, 10.0 seconds for animated.)
1822
+    Pause in seconds at end of menu. Use "inf" if you wish indefinite
1823
+    pause. Note: using "inf" with **-menu-fade** will disable the
1824
+    fadeout portion of the fade. (default: "inf" for static menu, 10.0
1825
+    seconds for animated.)
1826
 
1827
 **-playall**
1828
-    This option will create a button on the main menu that will allow going
1829
-    right to the 1st title and playing all videos in succession before
1830
-    returning to the main menu.  If doing titlesets you can use this within
1831
-    the **-vmgm** ... **-end-vmgm** options to allow playing ALL titlesets.
1832
-    (If you want also to have a playall button in each titleset you could use
1833
-    this option between each **-titleset** ... **-end-titleset** option or put
1834
-    it outside of the vmgm and titlset options as a general option.
1835
+    This option will create a button on the main menu that will allow
1836
+    going right to the 1st title and playing all videos in succession
1837
+    before returning to the main menu. If doing titlesets you can use
1838
+    this within the **-vmgm** ... **-end-vmgm** options to allow playing
1839
+    ALL titlesets. (If you want also to have a playall button in each
1840
+    titleset you could use this option between each **-titleset** ...
1841
+    **-end-titleset** option or put it outside of the vmgm and titlset
1842
+    options as a general option.
1843
 
1844
 **-videos-are-chapters**
1845
-    A button will be made on the main menu for each video, which you can use as
1846
-    a chapter button.  Selecting any video will play them all in order
1847
-    starting with the selected one.
1848
+    A button will be made on the main menu for each video, which you can
1849
+    use as a chapter button. Selecting any video will play them all in
1850
+    order starting with the selected one.
1851
 
1852
 **-chain-videos** NUM | N1-NN
1853
     Without options this will chain all videos together so they play
1854
-    sequentially without returning to the main menu, except for the last, which
1855
-    will return.  You can also specify which videos you want to behave this way
1856
-    by number or by a range. ( ie. **-chain-videos** 1 2 4-6 ).
1857
+    sequentially without returning to the main menu, except for the
1858
+    last, which will return. You can also specify which videos you want
1859
+    to behave this way by number or by a range. ( ie. **-chain-videos**
1860
+    1 2 4-6 ).
1861
 
1862
 **-subtitle-lang** "lang1 lang2 . . ."
1863
-    This allows selectable subtitles in the DVD, assuming you have optional
1864
-    subtitles muxed into your videos.  Use 2 character language codes.
1865
-
1866
-**-audio-channel** "Video1_track Video2_track Video3_track . . ."
1867
-    "VideoN_track" is the track number to use in a multi-track (multi-language)
1868
-    mpeg: usually something like **-audio-channel** "1 0 1".  The 1st track is
1869
-    0, 2nd is 1 . . . etc.  If the tracks are 0. English 1.French, then the
1870
-    above would make French the audio language on Video1 and Video3, and
1871
-    English the audio language on Video2.  You can check the mpeg with
1872
-    "mplayer -v . . .".
1873
+    This allows selectable subtitles in the DVD, assuming you have
1874
+    optional subtitles muxed into your videos. Use 2 character language
1875
+    codes.
1876
+
1877
+**-audio-channel** "Video1\_track Video2\_track Video3\_track . . ."
1878
+    "VideoN\_track" is the track number to use in a multi-track
1879
+    (multi-language) mpeg: usually something like **-audio-channel** "1
1880
+    0 1". The 1st track is 0, 2nd is 1 . . . etc. If the tracks are 0.
1881
+    English 1.French, then the above would make French the audio
1882
+    language on Video1 and Video3, and English the audio language on
1883
+    Video2. You can check the mpeg with "mplayer -v . . .".
1884
 
1885
 **-audio-lang** LANGUAGE CODES
1886
-    Identify the audio tracks on the DVD.  These language codes are used for
1887
-    each video in the titleset.  When you use the audio button on your DVD
1888
-    remote the language name is displayed.  Example: **-audio-lang** en fr
1889
+    Identify the audio tracks on the DVD. These language codes are used
1890
+    for each video in the titleset. When you use the audio button on
1891
+    your DVD remote the language name is displayed. Example:
1892
+    **-audio-lang** en fr
1893
 
1894
 **-aspect** 4:3|16:9
1895
-    This will output a <video aspect WIDTH:HEIGHT /> tag for the dvdauthor
1896
-    xml file.  It will affect all videos in the titleset.  Example::
1897
+    This will output a <video aspect WIDTH:HEIGHT />
1898
+    tag for the dvdauthor xml file. It will affect all videos in the
1899
+    titleset. Example:
1900
+
1901
+    ::
1902
 
1903
-        -aspect 16:9
1904
+            -aspect 16:9
1905
 
1906
 **-widescreen** nopanscan|noletterbox [nopanscan]
1907
-    This will output a <video widescreen=nopanscan /> tag (for example)
1908
-    for the dvdauthor xml file.  It will affect all videos in the titleset. Use
1909
-    in conjunction with **-aspect** if your dvd player is cropping your videos.
1910
-    Example::
1911
+    This will output a <video widescreen=nopanscan
1912
+    /> tag (for example) for the dvdauthor xml file. It will
1913
+    affect all videos in the titleset. Use in conjunction with
1914
+    **-aspect** if your dvd player is cropping your videos. Example:
1915
+
1916
+    ::
1917
 
1918
-        -aspect 16:9 -widescreen
1919
+            -aspect 16:9 -widescreen
1920
 
1921
 **-quick-nav**
1922
-    This option will allow navigation of a menu with more than one titleset by
1923
-    using the left and right arrow keys of your DVD remote.  When you press
1924
-    this key the highlight will go the next or previous title.  If you are at
1925
-    the end of a titleset the right key will go to the next titleset.  If you
1926
-    are at the beginning of a titleset, the left key will go to the previous
1927
-    titleset.  If no next or previous titleset it will cycle to the end or
1928
-    beginning of the titlesets.
1929
+    This option will allow navigation of a menu with more than one
1930
+    titleset by using the left and right arrow keys of your DVD remote.
1931
+    When you press this key the highlight will go the next or previous
1932
+    title. If you are at the end of a titleset the right key will go to
1933
+    the next titleset. If you are at the beginning of a titleset, the
1934
+    left key will go to the previous titleset. If no next or previous
1935
+    titleset it will cycle to the end or beginning of the titlesets.
1936
 
1937
 **-outlinewidth**, **-outline-width** WIDTH
1938
-    For spumux outlinewidth variable.  If there is a large gap between words in
1939
-    a text button, this option may help.
1940
+    For spumux outlinewidth variable. If there is a large gap between
1941
+    words in a text button, this option may help.
1942
 
1943
 **-video-pause** PAUSE (single value or list)
1944
-    The pause in seconds after playing a video title.  This is useful for
1945
-    slideshows: the 'slide' will remain on the screen for this length of time.
1946
-    If you have grouped videos you should probably not pause the videos that
1947
-    have a grouped title after it, but instead see **-grouped-video-pause**.
1948
-    Note: if you provide a list of values they must be one for each video.
1949
+    The pause in seconds after playing a video title. This is useful for
1950
+    slideshows: the ’slide’ will remain on the screen for this length of
1951
+    time. If you have grouped videos you should probably not pause the
1952
+    videos that have a grouped title after it, but instead see
1953
+    **-grouped-video-pause**. Note: if you provide a list of values they
1954
+    must be one for each video.
1955
 
1956
 **-group-video-pause** PAUSE (single value or list)
1957
-    The pause in seconds after a grouped video plays.  If you wish to pause
1958
-    after the whole group finishes, then only use a value greater than zero
1959
-    for the last video in the group.  If providing a list of values they must
1960
-    equal the number of grouped videos.
1961
+    The pause in seconds after a grouped video plays. If you wish to
1962
+    pause after the whole group finishes, then only use a value greater
1963
+    than zero for the last video in the group. If providing a list of
1964
+    values they must equal the number of grouped videos.
1965
 
1966
-
1967
-Burning the disc
1968
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1969
-
1970
-**-burn**
1971
-    Prompt to burn the DVD directory on completion.
1972
-
1973
-**-device** DEVICE [/dev/dvdrw]
1974
-    Device to use for the burning program.
1975
-
1976
-**-speed** N
1977
-    The speed to use for burning the disc.
1978
-
1979
-
1980
-
1981
-.. _command-mpg:
1982
+Usage notes
1983
+-----------
1984
+
1985
+The argument given to various \*-font options that set the font to use
1986
+must be one of the fonts listed by the command ’convert -list type’.
1987
+Please note that many of your installed fonts may not be available; if
1988
+you want to maximize the number of fonts available to todisc, download
1989
+and run {Anthony Thyssen’s}
1990
+{http://www.cit.gu.edu.au/~{}anthony/anthony.html} {imagick\_type\_gen}
1991
+{http://www.imagemagick.org/Usage/scripts/imagick\_type\_gen} script and
1992
+run it like this: imagick\_type\_gen > ~{}/.magick/type.xml.
1993
+If that doesn’t work, try imagick\_type\_gen > ~{}/.magick/type.mgk.
1994
+
1995
+Or you can specify a ttf font file directly to the \*-font options if
1996
+you don’t want to install fonts to ImageMagick.
1997
+
1998
+The \*-stroke options in todisc are not a stroke in the sense that
1999
+ImageMagick uses the term, but rather a font shadow (the text is drawn
2000
+twice) To get a truer Imagemagick -stroke try something like:
2001
+-title-font-deco "-stroke black" (or -titles-font-deco "-stroke black").
2002
+The **-fontdeco** option is quite flexible and takes a lot of
2003
+ImageMagick’s *convert* options. Please refer to the tovid {wiki}
2004
+{http://tovid.wikia.com/wiki/Making\_a\_DVD\_with\_text\_menus} and
2005
+Anthony Thyssen’s guide for further explanation and examples.
2006
 
2007
 Command:mpg
2008
-===============================================================================
2009
+-----------
2010
 
2011
 **tovid mpg** converts arbitrary video files into (S)VCD/DVD-compliant
2012
 MPEG format, suitable for burning to CD/DVD-R for playback on a
2013
 standalone DVD player.
2014
 
2015
 Usage
2016
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2017
-
2018
-::
2019
+-----
2020
 
2021
- tovid mpg [OPTIONS] -in INFILE -out OUTPREFIX
2022
+**tovid mpg** [*OPTIONS*] **-in** *INFILE* **-out** *OUTPREFIX*
2023
 
2024
-Where *INFILE* is any multimedia video file, and *OUTPREFIX* is what
2025
-you want to call the output file, minus the file extension. *OPTIONS*
2026
-are additional customizations, described below.
2027
+Where *INFILE* is any multimedia video file, and *OUTPREFIX* is what you
2028
+want to call the output file, minus the file extension. *OPTIONS* are
2029
+additional customizations, described below.
2030
 
2031
 By default, you will (hopefully) end up with an NTSC DVD-compliant
2032
 MPEG-2 video file; if you burn this file to a DVD-R, it should be
2033
@@ -1123,14 +1312,14 @@
2034
 
2035
 For example:
2036
 
2037
-``tovid mpg -in foo.avi -out foo_encoded``
2038
-    Convert 'foo.avi' to NTSC DVD format, saving to 'foo_encoded.mpg'.
2039
+{tovid mpg -in foo.avi -out foo\_encoded}
2040
+    Convert ’foo.avi’ to NTSC DVD format, saving to ’foo\_encoded.mpg’.
2041
 
2042
-``tovid mpg -pal -vcd foo.avi -out foo_encoded``
2043
-    Convert 'foo.avi' to PAL VCD format, saving to 'foo_encoded.mpg'.
2044
+{tovid mpg -pal -vcd foo.avi -out foo\_encoded}
2045
+    Convert ’foo.avi’ to PAL VCD format, saving to ’foo\_encoded.mpg’.
2046
 
2047
 Basic options
2048
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2049
+-------------
2050
 
2051
 **-v**, **-version**
2052
     Print tovid version number only, then exit.
2053
@@ -1139,18 +1328,18 @@
2054
     Reduce output to the console.
2055
 
2056
 **-fake**
2057
-    Do not actually encode; only print the commands (mplayer, mpeg2enc etc.)
2058
-    that would be executed. Useful in debugging; have tovid give you the
2059
-    commands, and run them manually.
2060
+    Do not actually encode; only print the commands (mplayer, mpeg2enc
2061
+    etc.) that would be executed. Useful in debugging; have tovid give
2062
+    you the commands, and run them manually.
2063
 
2064
 **-ffmpeg**
2065
-    Use ffmpeg for video encoding, instead of mplayer/mpeg2enc. Try this if
2066
-    you have any problems with the default encoding method. Using this option,
2067
-    encoding will be considerably faster. Currently does not work with
2068
-    **-subtitles** or  **-filters**.
2069
+    Use ffmpeg for video encoding, instead of mplayer/mpeg2enc. Try this
2070
+    if you have any problems with the default encoding method. Using
2071
+    this option, encoding will be considerably faster. Currently does
2072
+    not work with **-subtitles** or **-filters**.
2073
 
2074
 Television standards
2075
--------------------------------------------------------------------------------
2076
+~~~~~~~~~~~~~~~~~~~~
2077
 
2078
 **-ntsc**
2079
     NTSC format video (USA, Americas) (default)
2080
@@ -1162,7 +1351,7 @@
2081
     PAL format video (Europe and others)
2082
 
2083
 Formats
2084
--------------------------------------------------------------------------------
2085
+~~~~~~~
2086
 
2087
 Standard formats, should be playable in most DVD players:
2088
 
2089
@@ -1198,27 +1387,24 @@
2090
 **-bdvd**
2091
     (720x480 NTSC, 720x576 PAL) BVCD-enhanced long-playing DVD
2092
 
2093
-See kvcd.net (http://kvcd.net/) for details on the KVCD specification. Please
2094
-note that KVCD ("K Video Compression Dynamics") is the name of a compression
2095
-scheme that can be applied to any MPEG-1 or MPEG-2 video, and has little to
2096
-do with VCD ("Video Compact Disc"), which is the name of a standard video disc
2097
-format.
2098
+See {kvcd.net} {http://kvcd.net/} for details on the KVCD specification.
2099
+Please note that KVCD ("K Video Compression Dynamics") is the name of a
2100
+compression scheme that can be applied to any MPEG-1 or MPEG-2 video,
2101
+and has little to do with VCD ("Video Compact Disc"), which is the name
2102
+of a standard video disc format.
2103
 
2104
 Advanced options
2105
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2106
+----------------
2107
 
2108
 Aspect ratios
2109
--------------------------------------------------------------------------------
2110
+~~~~~~~~~~~~~
2111
 
2112
-tovid automatically determines aspect ratio of the input video by playing it in
2113
-mplayer. If your video plays with correct aspect in mplayer, you should not
2114
-need to override the default tovid behavior.
2115
+tovid automatically determines aspect ratio of the input video by
2116
+playing it in mplayer. If your video plays with correct aspect in
2117
+mplayer, you should not need to override the default tovid behavior.
2118
 
2119
-If mplayer does not play your video with correct aspect, you may provide an
2120
-explicit aspect ratio in one of several ways:
2121
-
2122
-**-aspect** *WIDTH*:*HEIGHT*
2123
-    Custom aspect, where *WIDTH* and *HEIGHT* are integers.
2124
+If mplayer does not play your video with correct aspect, you may provide
2125
+an explicit aspect ratio in one of several ways:
2126
 
2127
 **-full**
2128
     Same as **-aspect 4:3**
2129
@@ -1229,107 +1415,117 @@
2130
 **-panavision**
2131
     Same as **-aspect 235:100**
2132
 
2133
-The above are the intended INPUT aspect ratio. tovid chooses an optimal output
2134
-aspect ratio for the selected disc format (VCD, DVD, etc.) and does the
2135
-appropriate letterboxing or anamorphic scaling. Use **-widetv** to encode
2136
-for a widescreen monitor or TV.
2137
+**-aspect** *WIDTH***:***HEIGHT*
2138
+    Custom aspect, where *WIDTH* and *HEIGHT* are integers.
2139
+The above are the intended INPUT aspect ratio. tovid chooses an optimal
2140
+output aspect ratio for the selected disc format (VCD, DVD, etc.) and
2141
+does the appropriate letterboxing or anamorphic scaling. Use **-widetv**
2142
+to encode for a widescreen monitor or TV.
2143
 
2144
 Video stream options
2145
--------------------------------------------------------------------------------
2146
+~~~~~~~~~~~~~~~~~~~~
2147
 
2148
 **-quality** *NUM* (default 6)
2149
-    Desired output quality, on a scale of 1 to 10, with 10 giving the best
2150
-    quality at the expense of a larger output file. Default is 6. Output size
2151
-    can vary by approximately a factor of 4 (that is, **-quality 1** output
2152
-    can be 1/4 the size of **-quality 10** output). Your results may vary.
2153
-    WARNING: With **-quality 10**, the output bitrate may be too high for
2154
-    your hardware DVD player to handle. Stick with 9 or lower unless you
2155
-    have phenomenally good eyesight.
2156
-
2157
-    At present, this option affects both output bitrate and quantization (but
2158
-    may, in the future, affect other quality/size-related attributes). Use
2159
-    **-vbitrate** if you want to explicitly provide a maximum bitrate.
2160
+    Desired output quality, on a scale of 1 to 10, with 10 giving the
2161
+    best quality at the expense of a larger output file. Default is 6.
2162
+    Output size can vary by approximately a factor of 4 (that is,
2163
+    **-quality 1** output can be 1/4 the size of **-quality 10**
2164
+    output). Your results may vary. WARNING: With **-quality 10**, the
2165
+    output bitrate may be too high for your hardware DVD player to
2166
+    handle. Stick with 9 or lower unless you have phenomenally good
2167
+    eyesight.
2168
+
2169
+    At present, this option affects both output bitrate and quantization
2170
+    (but may, in the future, affect other quality/size-related
2171
+    attributes). Use **-vbitrate** if you want to explicitly provide a
2172
+    maximum bitrate.
2173
 
2174
 **-vbitrate** *NUM*
2175
-    Maximum bitrate to use for video (in kbits/sec). Must be within allowable
2176
-    limits for the given format. Overrides default values. Ignored for VCD,
2177
-    which must be constant bitrate.
2178
+    Maximum bitrate to use for video (in kbits/sec). Must be within
2179
+    allowable limits for the given format. Overrides default values.
2180
+    Ignored for VCD, which must be constant bitrate.
2181
 
2182
 **-interlaced**
2183
-    Do interlaced encoding of the input video (top fields first). Use this
2184
-    option if your video is  interlaced, and you want to preserve as much
2185
-    picture quality as possible. This option is ignored for VCD, which
2186
-    doesn't support it.
2187
+    Do interlaced encoding of the input video (top fields first). Use
2188
+    this option if your video is interlaced, and you want to preserve as
2189
+    much picture quality as possible. This option is ignored for VCD,
2190
+    which doesn’t support it.
2191
 
2192
-    You can tell your source video is interlaced by playing it, and pausing
2193
-    during a scene with horizontal motion; if you see a "comb" effect at the
2194
-    edges of objects in the scene, you have interlaced video. Use this option
2195
-    to encode it properly.
2196
+    You can tell your source video is interlaced by playing it, and
2197
+    pausing during a scene with horizontal motion; if you see a "comb"
2198
+    effect at the edges of objects in the scene, you have interlaced
2199
+    video. Use this option to encode it properly.
2200
 
2201
     If you would prefer to have output in progressive format, use
2202
-    **-progressive**. If you have a DV camera, use **-interlaced_bf** since
2203
-    DV footage is generally bottom fields first.
2204
+    **-progressive**. If you have a DV camera, use **-interlaced\_bf**
2205
+    since DV footage is generally bottom fields first.
2206
 
2207
-**-interlaced_bf**
2208
+**-interlaced\_bf**
2209
     Do interlaced encoding of the input video (bottom fields first).
2210
 
2211
-**-deinterlace** | **-progressive**
2212
-    Convert interlaced source video into progressive output video. Because
2213
-    deinterlacing works by averaging fields together, some picture quality is
2214
-    invariably lost. Uses an adaptive kernel deinterlacer (kerndeint), or,
2215
-    if that's not available, the libavcodec deinterlacer (lavcdeint).
2216
+**-deinterlace**, **-progressive**
2217
+    Convert interlaced source video into progressive output video.
2218
+    Because deinterlacing works by averaging fields together, some
2219
+    picture quality is invariably lost. Uses an adaptive kernel
2220
+    deinterlacer (kerndeint), or, if that’s not available, the
2221
+    libavcodec deinterlacer (lavcdeint).
2222
 
2223
 **-mkvsub** *LANG* (EXPERIMENTAL)
2224
-    Attempt to encode an integrated subtitle stream (such as may be found in
2225
-    Matroska .mkv files) in the given language code (eng, jpn, etc.) May work
2226
-    for other formats.
2227
+    Attempt to encode an integrated subtitle stream (such as may be
2228
+    found in Matroska .mkv files) in the given language code (eng, jpn,
2229
+    etc.) May work for other formats.
2230
 
2231
 **-autosubs**
2232
-    Automatically include subtitle files with the same name as the input video.
2233
+    Automatically include subtitle files with the same name as the input
2234
+    video.
2235
 
2236
 **-subtitles** *FILE*
2237
-    Get subtitles from *FILE* and encode them into the video.  WARNING: This
2238
-    hard-codes the subtitles into the video, and you cannot turn them off while
2239
-    viewing the video. By default, no subtitles are loaded. If your video is
2240
-    already compliant with the chosen output format, it will be re-encoded to
2241
-    include the subtitles.
2242
+    Get subtitles from *FILE* and encode them into the video. WARNING:
2243
+    This hard-codes the subtitles into the video, and you cannot turn
2244
+    them off while viewing the video. By default, no subtitles are
2245
+    loaded. If your video is already compliant with the chosen output
2246
+    format, it will be re-encoded to include the subtitles.
2247
 
2248
 **-type** {live|animation|bw}
2249
-    Optimize video encoding for different kinds of video. Use 'live' (default)
2250
-    for live-action video, use 'animation' for cartoons or anime, and 'bw' for
2251
-    black-and-white video.  This option currently only has an effect with
2252
-    KVCD/KSVCD output formats; other formats may support this in the future.
2253
+    Optimize video encoding for different kinds of video. Use ’live’
2254
+    (default) for live-action video, use ’animation’ for cartoons or
2255
+    anime, and ’bw’ for black-and-white video. This option currently
2256
+    only has an effect with KVCD/KSVCD output formats; other formats may
2257
+    support this in the future.
2258
 
2259
 **-safe** *PERCENT*
2260
     Fit the video within a safe area defined by *PERCENT*. For example,
2261
-    **-safe 90%** will scale the video to 90% of the width/height of the output
2262
-    resolution, and pad the edges with a black border. Use this if some of the
2263
-    picture is cut off when played on your TV.  The percent sign is optional.
2264
+    **-safe 90%** will scale the video to 90% of the width/height of the
2265
+    output resolution, and pad the edges with a black border. Use this
2266
+    if some of the picture is cut off when played on your TV. The
2267
+    percent sign is optional.
2268
 
2269
 **-filters** {none,denoise,deblock,contrast,all} (default none)
2270
-    Apply post-processing filters to enhance the video. If your input video is
2271
-    very high quality, use 'none'. If your input video is grainy, use 'denoise';
2272
-    if it looks washed out or faded, use 'contrast'. You can use multiple
2273
-    filters separated by commas. To apply all filters, use 'all'.
2274
+    Apply post-processing filters to enhance the video. If your input
2275
+    video is very high quality, use ’none’. If your input video is
2276
+    grainy, use ’denoise’; if it looks washed out or faded, use
2277
+    ’contrast’. You can use multiple filters separated by commas. To
2278
+    apply all filters, use ’all’.
2279
 
2280
 **-fps** *RATIO*
2281
-    Force input video to be interpreted as *RATIO* frames per second.  May be
2282
-    necessary for some ASF, MOV, or other videos. *RATIO* should be an
2283
-    integer ratio such as "24000:1001" (23.976fps), "30000:1001" (29.97fps), or
2284
-    "25:1" (25fps). This option is temporary, and may disappear in future
2285
-    releases. (Hint: To convert a decimal like 23.976 to an integer ratio, just
2286
-    multiply by 1000, i.e. 23976:1000)
2287
+    Force input video to be interpreted as *RATIO* frames per second.
2288
+    May be necessary for some ASF, MOV, or other videos. *RATIO* should
2289
+    be an integer ratio such as "24000:1001" (23.976fps), "30000:1001"
2290
+    (29.97fps), or "25:1" (25fps). This option is temporary, and may
2291
+    disappear in future releases. (Hint: To convert a decimal like
2292
+    23.976 to an integer ratio, just multiply by 1000, i.e. 23976:1000)
2293
 
2294
 **-crop** *WIDTH*:*HEIGHT*:*X*:*Y*
2295
     Crop a portion of the video *WIDTH* by *HEIGHT* in size, with the
2296
     top-left corner at *X*, *Y*.
2297
 
2298
 **-widetv**
2299
-    Always encode to 16:9 widescreen (only supported by **-dvd**, **-kdvd**,
2300
-    **-bdvd**), for optimal viewing on a widescreen monitor or TV.
2301
+    Always encode to 16:9 widescreen (only supported by **-dvd**,
2302
+    **-kdvd**, **-bdvd**), for optimal viewing on a widescreen monitor
2303
+    or TV.
2304
 
2305
 Audio stream options
2306
--------------------------------------------------------------------------------
2307
+~~~~~~~~~~~~~~~~~~~~
2308
 
2309
 **-normalize**
2310
     Analyze the audio stream and then normalize the volume of the audio.
2311
@@ -1338,44 +1534,42 @@
2312
     normalize without any parameters. The default is -12dB average level
2313
     with 0dB gain.
2314
 
2315
-**-amplitude** *NUM[dB]*
2316
-    In addition to analyzing and normalizing, apply the gain to the audio
2317
-    such that the 'average' (RMS) sound level is *NUM*. Valid values
2318
-    range 0.0 - 1.0, with 0.0 being silent and 1.0 being full scale. Use
2319
-    *NUMdB* for a decibel gain below full scale (the default without
2320
-    **-amplitude** is -12dB).
2321
+**-amplitude** *NUM*[dB]
2322
+    In addition to analyzing and normalizing, apply the gain to the
2323
+    audio such that the ’average’ (RMS) sound level is *NUM*. Valid
2324
+    values range 0.0 - 1.0, with 0.0 being silent and 1.0 being full
2325
+    scale. Use *NUM*dB for a decibel gain below full scale (the default
2326
+    without -amplitude is -12dB).
2327
 
2328
 **-abitrate** *NUM*
2329
-    Encode audio at *NUM* kilobits per second.  Reasonable values include
2330
-    128, 224, and 384. The default is 224 kbits/sec, good enough for most
2331
-    encodings. The value must be within the allowable range for the chosen disc
2332
-    format; Ignored for VCD, which must be 224.
2333
+    Encode audio at *NUM* kilobits per second. Reasonable values include
2334
+    128, 224, and 384. The default is 224 kbits/sec, good enough for
2335
+    most encodings. The value must be within the allowable range for the
2336
+    chosen disc format; Ignored for VCD, which must be 224.
2337
 
2338
 **-audiotrack** *NUM*
2339
-    Encode the given audio track, if the input video has multiple audio tracks.
2340
-    *NUM* is *1* for the first track, *2* for the second, etc. You may
2341
-    also provide a list of tracks, separated by spaces or commas, for example
2342
-    **-audiotrack 3,1,2**. Use **tovid id** on your source video to determine
2343
-    which audio tracks it contains.
2344
+    Encode the given audio track, if the input video has multiple audio
2345
+    tracks. *NUM* is *1* for the first track, *2* for the second, etc.
2346
+    You may also provide a list of tracks, separated by spaces or
2347
+    commas, for example **-audiotrack 3,1,2**. Use **tovid id** on your
2348
+    source video to determine which audio tracks it contains.
2349
 
2350
 **-downmix**
2351
-    Encode all audio tracks as stereo.  This can save space on your DVD if
2352
-    your player only does stereo.  The default behavior of tovid is to use
2353
-    the original number of channels in each track.  For aac audio, downmixing
2354
-    is not possible: tovid runs a quick 1 frame test to try to downmix the
2355
-    input track with the largest number of channels, and if it fails then it
2356
-    will revert to the default behavior of using the original channels.
2357
-
2358
-**-async** *NUM*
2359
-    Adjust audio synchronization by *NUM* seconds.
2360
+    Encode all audio tracks as stereo. This can save space on your DVD
2361
+    if your player only does stereo. The default behavior of tovid is to
2362
+    use the original number of channels in each track. For aac audio,
2363
+    downmixing is not possible: tovid runs a quick 1 frame test to try
2364
+    to downmix the input track with the largest number of channels, and
2365
+    if it fails then it will revert to the default behavior of using the
2366
+    original channels.
2367
 
2368
 Other options
2369
--------------------------------------------------------------------------------
2370
+~~~~~~~~~~~~~
2371
 
2372
 **-config** *FILE*
2373
-    Read configuration from *FILE*, containing 'tovid' alone on the first
2374
-    line, and free-formatted (whitespace-separated) tovid command-line options
2375
-    on remaining lines.
2376
+    Read configuration from *FILE*, containing ’tovid’ alone on the
2377
+    first line, and free-formatted (whitespace-separated) tovid
2378
+    command-line options on remaining lines.
2379
 
2380
 **-force**
2381
     Force encoding of already-compliant video or audio streams.
2382
@@ -1385,85 +1579,82 @@
2383
     **-out** option).
2384
 
2385
 **-priority** {low|medium|high}
2386
-    Sets the main encoding process to the given priority. With high priority,
2387
-    it may take other programs longer to load and respond. With lower priority,
2388
-    other programs will be more responsive, but encoding may take 30-40%
2389
-    longer.  The default is high priority.
2390
+    Sets the main encoding process to the given priority. With high
2391
+    priority, it may take other programs longer to load and respond.
2392
+    With lower priority, other programs will be more responsive, but
2393
+    encoding may take 30-40% longer. The default is high priority.
2394
 
2395
 **-discsize** *NUM*
2396
-    When encoding, tovid automatically splits the output file into several
2397
-    pieces if it exceeds the size of the target media. This option sets the
2398
-    desired target DVD/CD-R size to *NUM* mebibytes (MiB, 2^20). By default,
2399
-    splitting occurs at 700 for CD, 4300 for DVD. Use higher values at your
2400
-    own risk. Use 650 or lower if you plan to burn to smaller-capacity CDs.
2401
-    Doesn't work with the **-ffmpeg** option.
2402
+    When encoding, tovid automatically splits the output file into
2403
+    several pieces if it exceeds the size of the target media. This
2404
+    option sets the desired target DVD/CD-R size to *NUM* mebibytes
2405
+    (MiB, 2^20). By default, splitting occurs at 700 for CD, 4300 for
2406
+    DVD. Use higher values at your own risk. Use 650 or lower if you
2407
+    plan to burn to smaller-capacity CDs. Doesn’t work with the
2408
+    **-ffmpeg** option.
2409
 
2410
 **-fit** *NUM*
2411
     Fit the output file into *NUM* MiB. Rather than using default (or
2412
-    specified) video bitrates, tovid will calculate the correct video bitrate
2413
-    that will limit the final output size to *NUM* MiB. This is different
2414
-    than **-discsize**, which cuts the final file into *NUM* MiB pieces.
2415
-    **-fit** makes sure that the file never exceeds *NUM* MiB. This works
2416
-    with **-ffmpeg**, but not with **-vcd** since VCDs have a standardized
2417
-    constant bitrate.
2418
+    specified) video bitrates, tovid will calculate the correct video
2419
+    bitrate that will limit the final output size to *NUM* MiB. This is
2420
+    different than **-discsize**, which cuts the final file into *NUM*
2421
+    MiB pieces. **-fit** makes sure that the file never exceeds *NUM*
2422
+    MiB. This works with **-ffmpeg**, but not with **-vcd** since VCDs
2423
+    have a standardized constant bitrate.
2424
 
2425
 **-parallel**
2426
-    Perform ripping, encoding, and multiplexing processes in parallel using
2427
-    named pipes. Maximizes CPU utilization and minimizes disk usage. Note that
2428
-    this option simply does more tasks simultaneously, in order to make better
2429
-    use of available CPU cycles; it's unrelated to multi-CPU processing (which
2430
-    is done automatically anyway). Has no effect when **-ffmpeg** is used.
2431
+    Perform ripping, encoding, and multiplexing processes in parallel
2432
+    using named pipes. Maximizes CPU utilization and minimizes disk
2433
+    usage. Note that this option simply does more tasks simultaneously,
2434
+    in order to make better use of available CPU cycles; it’s unrelated
2435
+    to multi-CPU processing (which is done automatically anyway). Has no
2436
+    effect when **-ffmpeg** is used.
2437
 
2438
 **-update** *SECS*
2439
-    Print status updates at intervals of *SECS* seconds. This affects how
2440
-    regularly the progress-meter is updated. The default is once every five
2441
-    seconds.
2442
+    Print status updates at intervals of *SECS* seconds. This affects
2443
+    how regularly the progress-meter is updated. The default is once
2444
+    every five seconds.
2445
 
2446
-**-mplayeropts** "**OPTIONS**"
2447
-    Append *OPTIONS* to the mplayer command run during video encoding.  Use
2448
-    this if you want to add specific video filters (documented in the mplayer
2449
-    manual page). Overriding some options will cause encoding to fail, so use
2450
-    this with caution!
2451
+**-mplayeropts** **"***OPTIONS***"**
2452
+    Append *OPTIONS* to the mplayer command run during video encoding.
2453
+    Use this if you want to add specific video filters (documented in
2454
+    the mplayer manual page). Overriding some options will cause
2455
+    encoding to fail, so use this with caution!
2456
 
2457
 **-nofifo** (EXPERIMENTAL)
2458
-    Do not use a FIFO pipe for video encoding. If you are getting "Broken pipe"
2459
-    errors with normal encoding, try this option.  WARNING: This uses lots of
2460
-    disk space (about 2 GB per minute of video).
2461
+    Do not use a FIFO pipe for video encoding. If you are getting
2462
+    "Broken pipe" errors with normal encoding, try this option. WARNING:
2463
+    This uses lots of disk space (about 2 GB per minute of video).
2464
 
2465
 **-keepfiles**
2466
-    Keep the intermediate files after encoding. Usually, this means the audio
2467
-    and video streams are kept (eg the .ac3 and .m2v files for an NTSC DVD).
2468
-    This doesn't work with **-parallel** because the intermediate files are named
2469
-    pipes, and not real files.
2470
+    Keep the intermediate files after encoding. Usually, this means the
2471
+    audio and video streams are kept (eg the .ac3 and .m2v files for an
2472
+    NTSC DVD). This doesn’t work with -parallel because the intermediate
2473
+    files are named pipes, and not real files.
2474
 
2475
 **-slice** *START*-*END*
2476
     Encode a segment from *START* to *END* (in seconds). Only works with
2477
-    **-ffmpeg**.
2478
+    -ffmpeg.
2479
 
2480
 **-from-gui**
2481
-    Put makempg into a fully non-interactive state, suitable for calling from
2482
-    a gui.
2483
+    Put makempg into a fully non-interactive state, suitable for calling
2484
+    from a gui.
2485
 
2486
 **-noask**
2487
-    Don't ask questions when choices need to be made. Assume reasonable
2488
+    Don’t ask questions when choices need to be made. Assume reasonable
2489
     answers.
2490
 
2491
-
2492
-.. _command-id:
2493
-
2494
 Command:id
2495
-===============================================================================
2496
+==========
2497
 
2498
-**tovid id** identifies each multimedia video file in a
2499
-list, and reports its compliance with video disc standards such as VCD,
2500
-SVCD, and DVD.
2501
+**tovid id** identifies each multimedia video file in a list, and
2502
+reports its compliance with video disc standards such as VCD, SVCD, and
2503
+DVD.
2504
 
2505
 Usage
2506
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2507
-
2508
-::
2509
+-----
2510
 
2511
- tovid id [OPTIONS] VIDEO_FILE(s)
2512
+**tovid id** [*OPTIONS*] *VIDEO\_FILE(s)*
2513
 
2514
 For example:
2515
 
2516
@@ -1471,37 +1662,39 @@
2517
 ``tovid id -tabluar videos/*.mpg``
2518
 
2519
 Options
2520
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2521
+-------
2522
 
2523
 **-terse**
2524
-    Print raw video characteristics, no formatting. Helpful when
2525
-    calling from other scripts.
2526
+    Print raw video characteristics, no formatting. Helpful when calling
2527
+    from other scripts.
2528
 
2529
 **-verbose**
2530
     Print extra information from mplayer, tcprobe, and ffmpeg.
2531
 
2532
 **-accurate**
2533
-    Do lengthy play-time estimation by scanning through the entire video file.
2534
-    Use this if the default behavior is giving you inaccurate play times.
2535
+    Do lengthy play-time estimation by scanning through the entire video
2536
+    file. Use this if the default behavior is giving you inaccurate play
2537
+    times.
2538
 
2539
 **-fast**
2540
     Skip lengthy play-time estimation, and go with what mplayer reports
2541
     as being the video duration. Unlike pre-0.32 versions of tovid, this
2542
-    is now the default behavior, and the **-fast** option doesn't do anything.
2543
+    is now the default behavior, and the **-fast** option doesn’t do
2544
+    anything.
2545
 
2546
 **-tabular**
2547
     Display output in a table format for easier comparison. Most useful
2548
     when identifying multiple video files.
2549
 
2550
-**-isformat** [pal-dvd|ntsc-dvd] (same syntax for vcd and svcd)
2551
-    Check *VIDEO_FILE* for compliance with the given disc format.
2552
-    If *VIDEO_FILE* matches the given format, then **tovid id** reports "true"
2553
-    and exits successfully. Otherwise, **tovid id** reports "false" and exits
2554
-    with status 1 (failure).  This checks and reports both vcd/svcd/dvd
2555
-    and pal/ntsc.
2556
+**-isformat** [*pal-dvd*|*ntsc-dvd*] (same syntax for vcd and svcd)
2557
+    Check *VIDEO\_FILE* for compliance with the given disc format. If
2558
+    *VIDEO\_FILE* matches the given format, then **tovid id** reports
2559
+    "true" and exits successfully. Otherwise, **tovid id** reports
2560
+    "false" and exits with status 1 (failure). This checks and reports
2561
+    both vcd/svcd/dvd and pal/ntsc.
2562
 
2563
 Examples
2564
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2565
+--------
2566
 
2567
 ``tovid id -verbose homevideo.avi``
2568
     Report everything mplayer, ffmpeg, and transcode can determine about
2569
@@ -1510,528 +1703,102 @@
2570
 ``tovid id -isformat dvd homevideo.mpg``
2571
     Check to see if homevideo.mpg is compliant with the DVD standard.
2572
 
2573
-
2574
-.. _command-menu:
2575
-
2576
-Command:menu
2577
-===============================================================================
2578
-
2579
-**tovid menu** generates textual (S)VCD- or DVD-compliant MPEG videos for use
2580
-as navigational menus, given a list of text strings to use for title names. You
2581
-can customize the menu by providing an optional background image or audio clip,
2582
-or by using custom font and font color.
2583
-
2584
-Usage
2585
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2586
-
2587
-::
2588
-
2589
- tovid menu [OPTIONS] TITLES -out OUT_PREFIX
2590
-
2591
-For example:
2592
-
2593
-``tovid menu "Season One" "Season Two" "Featurettes" -out MainMenu``
2594
-
2595
-Options
2596
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2597
-
2598
-**-ntsc** (default)
2599
-    Generate an NTSC-format menu
2600
-
2601
-**-ntscfilm**
2602
-    Generate an NTSC-format menu (24000/1001fps)
2603
-
2604
-**-pal**
2605
-    Generate a PAL-format menu
2606
-
2607
-**-dvd** (default)
2608
-    Generate a DVD-format menu, with highlighted text included
2609
-    as a multiplexed subtitle stream.
2610
-
2611
-**-vcd** or **-svcd**
2612
-    Generate a VCD/SVCD menu; each menu option will have a
2613
-    number associated with it. You can have up to nine menu
2614
-    options per menu.
2615
-
2616
-Menu background/audio options:
2617
-
2618
-**-background** *IMAGE*
2619
-    Use *IMAGE* (in most any graphic format) as a background. If image is not
2620
-    the correct aspect ratio (4:3), it will be scaled and/or cropped,
2621
-    depending on the **-crop** and **-scale** options. If no background is
2622
-    supplied, a default background will be created.
2623
-
2624
-**-crop** (default)
2625
-    If provided background image is not 4:3 aspect ratio, crop edges
2626
-    to make it so. Image will be scaled up if it is too small. Cropping
2627
-    keeps the center area of image. If you want to do cropping/scaling
2628
-    yourself in another program, provide an image of 768x576 pixels.
2629
-
2630
-**-scale**
2631
-    If provided background image is not 4:3 aspect ratio, scale/stretch
2632
-    it to make it fit. May cause visible distortion!
2633
-
2634
-**-audio** *AUDIOFILE*
2635
-    Use *AUDIOFILE* (in most any audio format) for background music. The
2636
-    menu will play for long enough to hear the whole audio clip. If
2637
-    one is not provided, 4 seconds of silence will be used.
2638
-
2639
-**-length** *NUM*
2640
-    Make the menu *NUM* seconds long. Useful for menus with **-audio**:
2641
-    if you don't want the entire *AUDIOFILE* in the menu, then you can trim
2642
-    the length of the menu with **-length**.
2643
-
2644
-Menu text options:
2645
-
2646
-**-menu-title** "*MENU TITLE TEXT*"
2647
-    Add *MENU TITLE TEXT* as a title/header to the menu.
2648
-
2649
-**-font** *FONTNAME* (default Helvetica)
2650
-    Use *FONTNAME* for the menu text. Run 'convert -list type' to see a
2651
-    list of the fonts that you can use; choose a font name from the
2652
-    leftmost column that is displayed. Or you can specify a ttf font file instead.
2653
-    E.g., **-font /path/to/myfont.ttf**.
2654
-
2655
-**-fontsize** *NUM* (default 24)
2656
-    Sets the size for the font to *NUM* pixels.
2657
-
2658
-**-menu-title-fontsize** *NUM* (default **-fontsize** + 8)
2659
-    Sets the size of the menu title.
2660
-
2661
-**-fontdeco** '*FONTDECORATION*'
2662
-    Sets the font decoration method to *FONTDECORATION*. It is used by the
2663
-    'convert' ImageMagick command to draw the menu text. You can add colored
2664
-    text outlines, gradient fills, and many others. See **Usage notes**.
2665
-
2666
-**-align** {left|center|middle|right}
2667
-    Align the text at the top left, top center, very middle, or top right
2668
-    side of the screen. You may also substitute any "gravity" keyword
2669
-    allowed by ImageMagick (north|south|east|west|northeast|southwest|...).
2670
-
2671
-**-textcolor** {#RRGGBB|#RGB|COLORNAME}
2672
-    Use specified color for menu text. #RRGGBB and #RGB are
2673
-    hexadecimal triplets (e.g., #FF8035). COLORNAME may be any of
2674
-    several hundred named colors; run 'convert -list color' to see them.
2675
-    White (#FFF) is the default color.
2676
-
2677
-DVD-only options:
2678
-
2679
-**-button** *BUTTON* (default '>')
2680
-    Specify the button used for menu selection. Specify either a *single*
2681
-    character or one of the shortcuts:
2682
-
2683
-    **play**
2684
-        Use a button shaped like 'Play' on many A/V electronics:
2685
-        a triangle pointing to the right. (uses the font Webdings)
2686
-    **movie**
2687
-        Use a button shaped like an old movie projector.
2688
-        (uses the font Webdings)
2689
-    **utf8**
2690
-        Use your own non-keyboard character as a button. Provide
2691
-        only the four hex digits: eg **-button utf8 00b7**. Beware that
2692
-        ImageMagick's utf8 characters aren't the same as those drawn in
2693
-        character browsers like gucharmap.
2694
-
2695
-**-highlightcolor** {#RRGGBB|#RGB|COLORNAME}
2696
-    Use the specified color for button highlighting. Yellow (#FF0) is the
2697
-    default color.
2698
-
2699
-**-selectcolor** {#RRGGBB|#RGB|COLORNAME}
2700
-    Use the specified color for button selections (when a menu item is played
2701
-    or activated). Red (#F00) is the default color.
2702
-
2703
-**-button-outline** {#RRGGBB|#RGB|COLORNAME}
2704
-    Outline buttons with the specified color. 'none' is the default.
2705
-
2706
-**-button-font** *FONTNAME*
2707
-    Specify a differnt font to use for the buttons. By default, the button
2708
-    font will be inherited from the title font (see **-font**). Use this
2709
-    option to use a different font for the buttons. The button font size is
2710
-    inherited from **-fontsize** and cannot be changed.
2711
-
2712
-Other options:
2713
-
2714
-**-debug**
2715
-    Print extra debugging information to the log file. Useful in
2716
-    diagnosing problems if they occur. This option also leaves
2717
-    the log file (with a .log extension) in the directory after
2718
-    encoding finishes as well as all the temporary files created.
2719
-
2720
-**-nosafearea**
2721
-    Do not attempt to put text inside a TV-safe viewing area. Most
2722
-    television sets cut off about 10% of the image border, so the script
2723
-    automatically leaves a substantial margin. This option turns that
2724
-    behavior off, leaving only a tiny margin. Use at your own risk.
2725
-
2726
-**-overwrite**
2727
-    Overwrite any existing output menu.
2728
-
2729
-**-noask**
2730
-    Don't ask interactive questions, and assume answers that will
2731
-    continue making the menu until completion.
2732
-
2733
-**-quiet**
2734
-    Limit output to essential messages.
2735
-
2736
-If the word "**back**" is given as an episode title, a "back" button for
2737
-returning to a higher-level menu will be added at the end of the list
2738
-of titles. "**Back**" *must be the last title listed*.
2739
-
2740
-Examples
2741
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2742
-
2743
-Make an NTSC VCD menu with white Helvetica text containing three centered
2744
-selections: Episode 1, Episode 2, and Episode 3. The finished menu will be
2745
-called Season-1.mpg::
2746
-
2747
- $ tovid menu -ntsc -vcd \
2748
-    -align center -textcolor white -font "Helvetica" \
2749
-    "Episode 1" "Episode 2" "Episode 3" \
2750
-    -out "Season-1"
2751
-
2752
-Make an NTSC DVD menu with white Kirsty text containing three lower-left
2753
-aligned selections: Episode 1, Episode 2, and Episode 3. Items under the cursor
2754
-will be highlighted a pale blue, and selected items will be a pale orange
2755
-(before going to the selected title). The finished menu will be called
2756
-Main-menu.mpg::
2757
-
2758
- $ tovid menu -ntsc -dvd \
2759
-    -align southwest \
2760
-    -textcolor white \
2761
-    -highlightcolor "#5f65ff" \
2762
-    -selectcolor "#ffac5f" \
2763
-    -font "Kirsty" \
2764
-    "Episode 1" "Episode 2" "Episode 3" \
2765
-    -out "Main_menu"
2766
-
2767
-Usage notes
2768
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2769
-
2770
-The argument given to **-font** must be one of the fonts listed by the command
2771
-'convert -list type'. Please note that many of your installed fonts may not be
2772
-available; if you want to maximize the number of fonts available, download and
2773
-run Anthony Thyssen's (http://www.cit.gu.edu.au/~anthony/anthony.html)
2774
-imagick_type_gen.pl (http://www.cit.gu.edu.au/~anthony/software/imagick_type_gen.pl)
2775
-script and run it like this::
2776
-
2777
-    imagick_type_gen.pl > ~/.magick/type.xml.
2778
-
2779
-If that doesn't work, try::
2780
-
2781
-    imagick_type_gen.pl > ~/.magick/type.mgk.
2782
-
2783
-Or you can specify a ttf font file directly to the **-font** options if you
2784
-don't want to install fonts to ImageMagick.
2785
-
2786
-The **-fontdeco** option is quite flexible and takes a lot of ImageMagick's
2787
-*convert* options. Please refer to the tovid wiki
2788
-(http://tovid.wikia.com/wiki/Making_a_DVD_with_text_menus)
2789
-and Anthony Thyssen's guide for further explanation and examples.
2790
-
2791
-
2792
-.. _command-xml:
2793
-
2794
-Command:xml
2795
-===============================================================================
2796
-
2797
-**tovid xml** generates XML output describing an (S)VCD
2798
-or DVD file structure and navigation hierarchy in the format expected by
2799
-dvdauthor (http://dvdauthor.sourceforge.net/) or
2800
-vcdxbuild (http://www.vcdimager.org/).
2801
-
2802
-Usage
2803
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2804
-
2805
-::
2806
-
2807
- tovid xml [OPTIONS] VIDEOS -out OUTFILE
2808
-
2809
-For example::
2810
-
2811
- tovid xml -menu MainMenu.mpg \
2812
-   Season1.mpg Season2.mpg Featurettes.mpg \
2813
-   -out MyDisc
2814
-
2815
-Options
2816
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2817
-
2818
-**-dvd** (default)
2819
-    Generate the XML for a DVD disc, to be used with dvdauthor or **tovid dvd**.
2820
-
2821
-**-vcd**
2822
-    Generate the XML for a VCD disc, to be used with vcdxbuild or **tovid vcd**.
2823
-
2824
-**-svcd**
2825
-    Generate the XML for an SVCD disc, to be used with vcdxbuild or **tovid vcd**.
2826
-
2827
-**-overwrite**
2828
-    Overwrite any existing output files.
2829
-
2830
-**-quiet**
2831
-    Limit output to essential messages.
2832
-
2833
-*VIDEOS* may be any of the following:
2834
-
2835
-*<file list>*
2836
-    List of one or more video files to include, separated by spaces. At
2837
-    minimum, a DVD must have one video file. You can use shell wildcards
2838
-    (i.e., "\*.mpg") to include multiple files easily. Put filenames in
2839
-    quotes if they have spaces in them.
2840
-
2841
-**-menu** *VIDEO* *<file list>*
2842
-    Use video file *VIDEO* as a menu from which you can jump to each of
2843
-    the listed video files. If you have multiple menus, include a
2844
-    top menu so they are reachable.
2845
-
2846
-**-slides** *<file list>*
2847
-    Create a slide-show of still images
2848
-
2849
-DVD-only options
2850
-
2851
-**-group** *<file list>* **-endgroup**
2852
-    (DVD only) List of video files to include as one single title. This is useful
2853
-    if you have split a movie into several video files.
2854
-
2855
-**-topmenu** *VIDEO* [**-menu** *VIDEO* *<file list>*] [**-menu** *VIDEO* *<file list>*]...
2856
-    (DVD only) Use video file *VIDEO* for the top-level (VMGM) menu. The
2857
-    top menu will jump to each of the subsequent [-menu...] videos listed.
2858
-    Use this only if you have multiple sub-menus to jump to. You can only
2859
-    have one top menu.
2860
-
2861
-**-titlesets**
2862
-    (DVD only) Forces the creation of a separate titleset per title. This
2863
-    is useful if the titles of a DVD have different video formats,
2864
-    e.g. PAL + NTSC or 4:3 + 16:9. If used with menus, there must be a
2865
-    **-topmenu** option that specifies a menu file with an entry for each of the
2866
-    titlesets.
2867
-
2868
-**-chapters** *INTERVAL*
2869
-    (DVD only) Creates a chapter every *INTERVAL* minutes (default 5 minutes:
2870
-    without **-chapters**, each movie will be divided into 5-minute chapters).
2871
-    This option can be put at any position in a *<file list>* and is valid
2872
-    for all subsequent titles until a new **-chapters** option is encountered.
2873
-    Using this option may take some time, since the duration of the video is
2874
-    calculated.
2875
-
2876
-**-nochapters**
2877
-    (DVD only) Don't create chapters for the videos.
2878
-
2879
-*OUT_PREFIX* is the file that will receive the resulting XML.
2880
-
2881
-Usage notes
2882
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2883
-
2884
-The 'xml' command checks to make sure the video filenames you
2885
-give it exist, but it does not check whether they are valid for the
2886
-chosen disc format. MPEG videos of menus should have the specified
2887
-number of buttons for reaching each of the videos, and, if you're
2888
-using DVD, should be multiplexed with their corresponding subtitles
2889
-using spumux of the dvdauthor 0.6.0 package prior to
2890
-authoring using dvdauthor. If you use the 'tovid menu'
2891
-component to generate the menu, this should all be handled for you.
2892
-
2893
-Examples
2894
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2895
-
2896
-``tovid xml -dvd title-1.mpg title-2.mpg title-3.mpg -out My_DVD``
2897
-    Make a DVD without a menu. Title 1, 2, and 3 will play in sequence.
2898
-
2899
-``tovid xml -dvd -group chapter-1.mpg chapter-2.mpg chapter-3.mpg -endgroup -out My_DVD``
2900
-    Group the file chapter-1|2|3.mpg into one title and make a DVD without a menu.
2901
-
2902
-``tovid xml -dvd -menu main_menu.mpg -chapters 3 movie-1.mpg -chapters 10 movie-2.mpg -out My_DVD``
2903
-    Make a DVD with a main menu that points to two movies, with movie-1.mpg
2904
-    divided into 3-minute chapters, and movie-2.mpg into 10-minute chapters.
2905
-
2906
-
2907
-.. _command-dvd:
2908
-
2909
 Command:dvd
2910
-===============================================================================
2911
+===========
2912
 
2913
-**tovid dvd** takes a dvdauthor XML file (as generated by the **tovid xml**
2914
-command) and authors a DVD filesytem. This command can also burn a DVD disc
2915
-from either the XML file or from an existing DVD file-system.
2916
+**tovid dvd** takes a dvdauthor XML file (as generated by the **tovid
2917
+xml** command) and authors a DVD filesytem. This command can also burn a
2918
+DVD disc from either the XML file or from an existing DVD file-system.
2919
 
2920
 To ensure that this script successfully executes, please run it from a
2921
-directory with plenty of free space. "Plenty" would be 10 GB for single-layer
2922
-discs, and 20 GB for dual-layer discs.  Running this program may slow down your
2923
-other applications, due to intense disk activity.
2924
+directory with plenty of free space. "Plenty" would be 10 GB for
2925
+single-layer discs, and 20 GB for dual-layer discs. Running this program
2926
+may slow down your other applications, due to intense disk activity.
2927
 
2928
 Usage
2929
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2930
-
2931
-::
2932
+-----
2933
 
2934
- tovid dvd [OPTIONS] FILE.xml
2935
- tovid dvd [OPTIONS] DVD_DIR
2936
+**tovid dvd** [*OPTIONS*] *DVD\_DIR* **tovid dvd** [*OPTIONS*]
2937
+*FILE.xml*
2938
 
2939
 For example:
2940
 
2941
-``tovid dvd -burn MyDisc.xml``
2942
 ``tovid dvd -burn /path/to/DVD/directory``
2943
+``tovid dvd -burn MyDisc.xml``
2944
 
2945
 Options
2946
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2947
+-------
2948
 
2949
 **-author**
2950
     Author the DVD described by *FILE.xml*. Overwrites an existing
2951
     directory containing the dvdauthor output if already present.
2952
 
2953
 **-burn**
2954
-    Burn a DVD file-system in *DVD_DIR* (must contain a VIDEO_TS folder).
2955
+    Burn a DVD file-system in *DVD\_DIR* (must contain a VIDEO\_TS
2956
+    folder).
2957
+
2958
+**-eject**
2959
+    Eject the DVD tray after burning is complete. By default, the DVD is
2960
+    not ejected.
2961
 
2962
 **-device** *DEVICE* (default /dev/dvdrw)
2963
-    Burn the disc image to *DEVICE*, the Linux device file-system
2964
-    name of your DVD-recorder. Common examples might be /dev/dvdrw,
2965
-    /dev/scd1, and /dev/hdc. You can also use a bus/id/lun triple
2966
-    such as ATAPI:0,1,0
2967
+    Burn the disc image to *DEVICE*, the Linux device file-system name
2968
+    of your DVD-recorder. Common examples might be /dev/dvdrw,
2969
+    /dev/scd1, and /dev/hdc. You can also use a bus/id/lun triple such
2970
+    as ATAPI:0,1,0
2971
 
2972
 **-speed** *NUM* (default 1)
2973
     Burn disc at speed *NUM*.
2974
 
2975
-**-label** *DISC_LABEL*
2976
-    Uses *DISC_LABEL* as the volume ID. This appears as the mount
2977
-    name of the disc on some computer platforms. Must be <=32
2978
+**-label** *DISC\_LABEL*
2979
+    Uses *DISC\_LABEL* as the volume ID. This appears as the mount name
2980
+    of the disc on some computer platforms. Must be <=32
2981
     alphanumeric digits without spaces.
2982
 
2983
 **-quiet**
2984
     Limit output to essential messages.
2985
 
2986
 **-noask**
2987
-    Don't ask interactive questions and assume answers that will continue
2988
-    execution.
2989
+    Don’t ask interactive questions and assume answers that will
2990
+    continue execution.
2991
 
2992
 Examples
2993
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2994
+--------
2995
 
2996
 ``tovid dvd -burn -device /dev/dvdrw foo.xml``
2997
     Author the dvd file-system and burn to /dev/dvdrw. This will
2998
-    automatically call dvdauthor to make the file-system. **-author**
2999
-    is not explicitly needed. If there's an existing file-system, it
3000
-    will be burned.
3001
+    automatically call dvdauthor to make the file-system. **-author** is
3002
+    not explicitly needed. If there’s an existing file-system, it will
3003
+    be burned.
3004
 
3005
 ``tovid dvd -author foo.xml``
3006
     Author the DVD file-system and exit without burning. If the output
3007
     directory given in foo.xml already exists, then the contents are
3008
-    removed before authoring. At this point, the DVD can be previewed
3009
-    by calling ``xine dvd:/path/to/output/directory``.
3010
-
3011
-
3012
-.. _command-vcd:
3013
-
3014
-Command:vcd
3015
-===============================================================================
3016
-
3017
-**tovid vcd** takes an XML file (which may be generated by **tovid xml**) and
3018
-creates a cue/bin (S)VCD image. It can also burn (S)VCD discs.
3019
-
3020
-To ensure that this script successfully executes, please run it from a directory
3021
-with plenty of free space. "Plenty" would be about 1 GB. Running this program
3022
-may slow down your other applications, due to intense disk activity.
3023
-
3024
-Usage
3025
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3026
-
3027
-::
3028
-
3029
- tovid vcd [OPTIONS] VCDIMAGER.xml
3030
-
3031
-For example:
3032
-
3033
-``tovid vcd -burn MyDisc.xml``
3034
-
3035
-Options
3036
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3037
-
3038
-**-overwrite** (default off -- nothing is overwritten)
3039
-    Overwrite any existing cue/bin files matching *VCDIMAGER.xml*. Useful
3040
-    if you modified the xml file and wish to re-image or burn the new (S)VCD.
3041
-
3042
-**-burn** (default off -- no images are burned)
3043
-    Burn the (S)VCD described by *VCDIMAGER.xml*.
3044
+    removed before authoring. At this point, the DVD can be previewed by
3045
+    calling ***xine** dvd:/path/to/output/directory*.
3046
 
3047
-**-device** *DEVICE* (default /dev/cdrw)
3048
-    Burn the disc image to *DEVICE*, the Linux device file-system
3049
-    name of your CD-recorder. Common examples might be /dev/cdrw,
3050
-    /dev/scd1, and /dev/hdc.
3051
+Command:chapters
3052
+================
3053
 
3054
-**-speed** *NUM* (default 12)
3055
-    Burn the disc at speed *NUM*.
3056
+**tovid chapters** will start a GUI using mplayer to set chapter points
3057
+in a video. If the video plays through and you want to add more chapters
3058
+you can press the play button again, but remember that new chapter
3059
+points will be appended (in correct sequential order). It will display
3060
+the resulting chapter points, and also output to a terminal (useful for
3061
+scripts). As well it will give the option of saving the chapters string
3062
+to a text file.
3063
 
3064
-**-quiet**
3065
-    Limit output to essential messages.
3066
+Note that the ’tovid gui’ now features a similar widget when you press
3067
+the chapters button on the opening page.
3068
 
3069
 Examples
3070
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3071
-
3072
-``tovid vcd -burn -device /dev/cdrw foo.xml``
3073
-    Create the (S)VCD image and burn it to /dev/cdrw. This will
3074
-    automatically call vcdxbuild to make the image. If there is an existing
3075
-    image, it will be burned.
3076
-
3077
-``tovid vcd -overwrite foo.xml``
3078
-    Create the (S)VCD image and exit without burning. If the image
3079
-    already exists, then it is removed before re-imaging.
3080
-
3081
-
3082
-.. _command-postproc:
3083
-
3084
-Command:postproc
3085
-===============================================================================
3086
-
3087
-**tovid postproc** is designed to do simple post-processing on MPEG video files, such
3088
-as those generated by tovid. It can adjust audio/video sync, and re-quantize
3089
-(shrink) without re-encoding.
3090
-
3091
-Usage
3092
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3093
-
3094
-::
3095
-
3096
- tovid postproc [OPTIONS] IN_FILE OUT_FILE
3097
-
3098
-Options
3099
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3100
-
3101
-**-audiodelay** *NUM*
3102
-    Delay the audio stream by *NUM* milliseconds. Use this if
3103
-    your final output has audio that is not synced with the
3104
-    video. For example, if the audio comes 2 seconds sooner than
3105
-    the video, use **-audiodelay 2000**. Use a negative number for
3106
-    audio that comes later than the video.
3107
-
3108
-**-normalize**
3109
-    Analyze the audio stream and then normalize the volume of the audio.
3110
-    This is useful if the audio is too quiet or too loud, or you want to
3111
-    make volume consistent for a bunch of videos. Similar to running
3112
-    normalize without any parameters. The default is -12dB average level
3113
-    with 0dB gain.
3114
-
3115
-**-amplitude** *NUM[dB]*
3116
-    In addition to analyzing and normalizing, apply the gain to the audio
3117
-    such that the 'average' (RMS) sound level is *NUM*. Valid values
3118
-    range 0.0 - 1.0, with 0.0 being silent and 1.0 being full scale. Use
3119
-    *NUMdB[dB]* for a decibel gain below full scale (the default without
3120
-    -amplitude is -12dB).
3121
-
3122
-**-shrink** *NUM*
3123
-    Shrink the video stream by a factor of *NUM*. May be a decimal
3124
-    value. A value of 1.0 means the video will be the same size;
3125
-    larger values cause more reduction in size. Beyond 2.0, the
3126
-    returns are diminishing.
3127
-
3128
-**-parallel**
3129
-    Run all processes in parallel and pipe into multiplexer, should
3130
-    increase speed significantly.
3131
-
3132
-**-debug**
3133
-    Save output in a temporary file, for later viewing if
3134
-    something goes wrong.
3135
+--------
3136
 
3137
-Contact
3138
-===============================================================================
3139
+``tovid chapters foo.avi``
3140
+{chapters=$(tovid chapters /home/grepper/videos/foo.avi)}
3141
 
3142
-For further assistance, contact information, forum and IRC links,
3143
-please refer to the tovid homepage (http://tovid.wikia.com/).
3144
+CONTACT
3145
+=======
3146
 
3147
+For further assistance, contact information, forum and IRC links, please
3148
+refer to the {tovid homepage} {http://tovid.wikia.com/}.
3149
tovid-0.34.tar.bz2/docs/src/en/tovid.t2t -> tovid-0.35.tar.gz/docs/src/en/tovid.t2t Changed
1249
 
1
@@ -13,11 +13,16 @@
2
 author and burn a ready-to-watch DVD, with just a few shell commands. A
3
 graphical interface is also provided to make the process even easier.
4
 
5
-**NOTE**: As of tovid 0.32, this is the only manual page provided by tovid.
6
+**NOTE**: As of tovid 0.35, the legacy scripts **makemenu** and **makexml**
7
+have been removed and no longer appear in this manpage.
8
+All of their functions and more can be done with the 'tovid disc' command,
9
+(todisc script). See **Command:disc** and the [wiki http://tovid.wikia.com]
10
+for more info.
11
+
12
+Also note that as of tovid 0.32, this is the only manual page provided by tovid.
13
 There is now a single executable frontend to all functionality in the suite, so
14
-if you were expecting to find manpages for **todisc**, **idvid**, **makemenu**
15
+if you were expecting to find manpages for **todisc**, **idvid**, **makempg**
16
 and their kin, they can all be found in the **tovid** manpage you are reading now.
17
-
18
 And yes, this makes for a pretty large manual page. If you are viewing this
19
 manpage from the command-line **man** utility, which normally pages through the
20
 **less** utility, you can skip to a section by searching with the **/** key,
21
@@ -32,31 +37,27 @@
22
 
23
 Where //COMMAND// is one of the following:
24
 
25
+    Main Commands
26
+: **disc**
27
+    Encode, make menus, author, burn. (was **todisc**. See **Command:disc**)
28
 : **gui**
29
     Start the tovid GUI (was **todiscgui**. See **Command:gui**)
30
 : **titlesets**
31
-    A tovid GUI wizard for multiple titlesets. (new: See **Command:titlesets**)
32
-: **disc**
33
-    Create a DVD with menus (was **todisc**. See **Command:disc**)
34
+    A GUI wizard for multiple titlesets. (new: See **Command:titlesets**)
35
+
36
+
37
+    Helper Commands
38
 : **mpg**
39
     Encode videos to MPEG format (was **tovid**. See **Command:mpg**)
40
-: **id**
41
-    Identify one or more video files (was **idvid**. See **Command:id**)
42
-: **menu**
43
-    Create an MPEG menu (was **makemenu**. See **Command:menu**)
44
-: **xml**
45
-    Create (S)VCD or DVD .xml file (was **makexml**. See **Command:xml**)
46
 : **dvd**
47
     Author and/or burn a DVD (was **makedvd**. See **Command:dvd**)
48
-: **vcd**
49
-    Author and/or burn a VCD (was **makevcd**. See **Command:vcd**)
50
-: **postproc**
51
-    Post-process an MPEG video file (was **postproc**. See **Command:postproc**)
52
+: **id**
53
+    Identify one or more video files (was **idvid**. See **Command:id**)
54
 : **chapters**
55
     A GUI using mplayer for setting chapter points.  It will return a string of
56
-    chapter points in a format recognized by 'tovid disc' (todisc) or
57
-    by 'tovid gui', for the  **-chapters** option.
58
-    
59
+    chapter points to the terminal, in a format recognized by 'tovid disc'
60
+    (todisc) or by 'tovid gui', for the  **-chapters** option.
61
+
62
 
63
 The //OPTIONS// differ for each command; run **tovid <command>** with no
64
 further arguments to get help on a command, and what options it expects.
65
@@ -69,47 +70,86 @@
66
 
67
 : **~/.tovid/preferences**
68
     Defines working directory for all scripts.
69
-    In addition you can define the output directory for makempg here.
70
+    You can define the output directory for makempg here.
71
+    The 'ffmpeg' executable can be set here: ffmpeg or avconv (TOVID_FFMPEG)
72
 : **~/.tovid/tovid.ini**
73
     Includes command-line options that should be passed to the various
74
-    **tovid** sub-commands.
75
+    **tovid** sub-commands.  Note: each sub-command has its own section,
76
+    starting with the line [sub-command], for example:
77
+```
78
+    [disc]
79
+    ; -no-warn
80
+    -static
81
+    -no-ask
82
+```
83
+
84
 
85
 Edit these files if you wish to change your configuration.
86
 
87
+
88
 The following environment variables are also honoured:
89
-TOVID_WORKING_DIR (working directory for all scripts).
90
-TOVID_OUTPUT_DIR (output directory for the makempg script).
91
+```
92
+    TOVID_HOME (directory containing preferences: ~/.tovid)
93
+    TOVID_WORKING_DIR (working directory for all scripts).
94
+    TOVID_OUTPUT_DIR (output directory for the makempg script).
95
+    TOVID_FFMPEG_CMD (the 'ffmpeg' executable to use: ffmpeg or avconv)
96
+```
97
+These will override 'TOVID_HOME', 'WORKING_DIR', 'OUTPUT_DIR',
98
+and 'TOVID_FFMPEG' if set in ~/.tovid/preferences.
99
 
100
 
101
 =Command:gui=
102
 
103
+=Usage=
104
+
105
+**tovid gui** [//OPTIONS//]
106
+
107
 **tovid gui** starts the graphical user interface (GUI) for tovid. This is
108
-the easiest way to start creating DVDs with tovid. At this time, there are no
109
-additional command-line options; the GUI controls take care of everything,
110
-and all help is integrated in the form of tooltips.  You can also see
111
-**Command:disc ** for more detail about the options.  Note: if you wish to
112
-make multiple titlesets on the same DVD use 'tovid titlesets', which is a wizard
113
-that uses the the tovid GUI.  Chapter submenus can be made with 'tovid gui'
114
-however.
115
+the easiest way to start creating DVDs with tovid. The optional arguments
116
+//OPTIONS// are any option used by todisc ('tovid disc') which will save
117
+entering it manually, OR the full path to a saved script from the GUI.
118
+You can also combine these, but the script must be the FIRST option
119
+directly after **tovid gui** .  (This option to save the contents of your
120
+project allows you to use it as a bash script later, or to reload the
121
+project to continue working with it at another time.)
122
+
123
+
124
+**tovid gui** will also take the option **--position**, which denotes the
125
+screen position that the GUI will start at, in the form '+X+Y', similar to
126
+this part of the Xorg -geometry string.
127
+
128
+All help is integrated in the form of tooltips.  You can also see
129
+**Command:disc ** for more detail about the options.  Note: if you wish to use
130
+a GUI to make multiple titlesets on the same DVD use ***tovid titlesets***,
131
+which is a wizard that uses the the 'tovid gui. See ***Command:titlesets***.
132
+
133
+
134
+Please note that although the interface may seem complex with so many options,
135
+you can create a fully functional DVD with only a few options on the opening
136
+tab of the GUI (select video files and an output name).
137
 
138
 
139
 =Command:titlesets=
140
 
141
 **tovid titlesets** will assist in making a DVD with multiple titlesets.  It can
142
 be started without any options, or you can feed it the path to a saved titleset
143
-script as an option.
144
+script as an option.  The option to save a script is also useful as the resulting
145
+script can be run later from a terminal.
146
 
147
 
148
 =Command:disc=
149
 
150
-**tovid disc** creates a DVD file-system with menus, from a list of multimedia
151
-video files and their titles.  As this is a low level script it is the easiest
152
-command line program for creating a DVD from start to finish, including
153
-automatically converting non-compliant videos and prompting to burn at
154
-completion.  It does animated menus, static thumbnail menus and text only
155
-menus.  In addition, it can do slideshows, using images as input, and combine
156
-slideshows with videos.  It supports sub-menus for chapter breaks, configurable
157
-menu style, animated backgrounds and transparency effects.
158
+**tovid disc** creates a DVD file-system with optional menus, from a list of
159
+multimedia video files and their titles.  As todisc can function as a master
160
+script, calling other scripts as it needs them, it is the easiest command line
161
+program for creating a DVD from start to finish, including automatically
162
+converting non-compliant videos and prompting to burn at completion.  It can do
163
+animated menus, static thumbnail menus, text-only menus, or author with no menu.
164
+In addition, it can do slideshows, using images as input, and even combine
165
+slideshows with videos.  It supports sub-menus for chapter breaks,
166
+configurable menu style, animated backgrounds and transparency effects.
167
+From simple (no menu) to complex (switched menus and titlesets), you should
168
+be able to do what you want with 'tovid disc'.
169
 
170
 
171
 ==Usage==
172
@@ -117,7 +157,7 @@
173
 ```
174
  tovid disc [OPTIONS] \
175
     -files <file list> -titles <title list>
176
-    -out OUT_PREFIX
177
+    -out mydvd
178
 ```
179
 
180
 For example:
181
@@ -133,10 +173,12 @@
182
 as titles.  If you are doing a slideshow or multiple slideshows, use
183
 **-slides** rather than **-files** for passing in the images.  You may use
184
 -files and -slides more than once to create an ordering in a mixed
185
-slideshows/videos menu.  See SLIDESHOWS part of Usage section, below.
186
+slideshows/videos menu.  See Slideshows part of Usage section, below.
187
 
188
 If the input files are not mpeg, you will have the option to auto-encode them.
189
 
190
+General Options
191
+
192
 **At present there are 2 display arrangements or "templates":**
193
 
194
 : A. (Default)
195
@@ -172,6 +214,7 @@
196
  $ tovid disc -submenus \
197
       -files file1.mpg file2.mpg ... \
198
       -titles "Short 1" "Short 2" \
199
+      -submenus \
200
       -submenu-titles "Long Title One" "Long Title Two" \
201
       -out foo
202
 
203
@@ -179,7 +222,22 @@
204
 
205
 The **-align** argument will position both titles and thumbs either south,
206
 north east, west, southwest, northwest, southeast, northeast, subject to
207
-certain constraints of each arrangement.
208
+certain constraints of each arrangement. For example a showcase style with
209
+a showcase thumb can only do north|south|center.
210
+
211
+More Examples:
212
+
213
+A text-only menu:
214
+
215
+```
216
+ $ tovid disc -textmenu ...
217
+```
218
+No menu:
219
+
220
+```
221
+ $ tovid -nomenu -files file1.mpg file2.mp4 "file 3.avi" -out mydvd
222
+```
223
+
224
 
225
 **Titlesets**
226
 
227
@@ -195,9 +253,9 @@
228
 will need as many TITLES after **-titles** as you have menus.
229
 
230
 Any options outside the **-titleset** **-end-titleset** and **-vmgm**
231
-**-end-vmgm** areas will be general options applying to every titleset.
232
-If a general option is duplicated inside a **-titleset** or **-vmgm** area, the
233
-general option will be overridden.
234
+**-end-vmgm** areas will be global options applying to every titleset.
235
+If a global option is duplicated inside a **-titleset** or **-vmgm** area, the
236
+global option will be overridden.
237
 
238
 Note: you do not need titlesets for a single menu with chapter break menus, for
239
 that just use **-submenus** or **-ani-submenus**
240
@@ -207,23 +265,25 @@
241
 
242
 ```
243
  $ tovid disc -static -out MY_DVD \
244
-    \
245
-   -titleset -files 1.mpg 2.mpg 3.mpg \
246
+   \
247
+   -titleset \
248
+   -files 1.mpg 2.mpg 3.mpg \
249
    -titles "Title One" "Title Two" "Title Three" \
250
    -end-titleset \
251
    \
252
-   -titleset -files 4.mpg 5.mpg \
253
+   -titleset \
254
+   -files 4.mpg 5.mpg \
255
    -titles "Title Four" "Title Five" \
256
-    -background foo.jpg \
257
-    -showcase bar.png \
258
-    -end-titleset \
259
-    \
260
-    -vmgm \
261
-    -titles "Season One" "Season Two" \
262
-    -background bg.jpg \
263
-    -bgaudio foo.mp3 \
264
-    -titles-fontsize 20 \
265
-    -end-vmgm
266
+   -background foo.jpg \
267
+   -showcase bar.png \
268
+   -end-titleset \
269
+   \
270
+   -vmgm \
271
+   -titles "Season One" "Season Two" \
272
+   -background bg.jpg \
273
+   -bgaudio foo.mp3 \
274
+   -titles-fontsize 20 \
275
+   -end-vmgm
276
 ```
277
 
278
 See also **-titleset** and **-vmgm**
279
@@ -283,7 +343,7 @@
280
    -out myslideshow
281
 ```
282
 
283
-See the other slideshow options in the SLIDESHOWS options section.
284
+See the other slideshow options in the Slideshows options section.
285
 
286
 
287
 
288
@@ -299,15 +359,40 @@
289
     **-vbitrate**, **-quality**, **-safe**, **-crop**, **-filters**,
290
     **-abitrate**, **-priority**, **-deinterlace**, **-progressive**,
291
     **-interlaced**, **-interlaced_bf**, **-type**, **-fit**, **-discsize**,
292
-    **-parallel**, **-mkvsub**, **-autosubs**, **-subtitles**, **-update**, \
293
+    **-parallel**, **-mkvsub**, **-autosubs**, **-subtitles**, **-update**,
294
     **-mplayeropts**, **-audiotrack**, **-downmix**, **-ffmpeg**, **-nofifo**,
295
     **-from-gui**, **-slice**, **-quiet**,
296
     **-fake**, **-keepfiles**
297
 
298
-==Options==
299
+==General Options==
300
 
301
 : **-keep-files**, **-keepfiles**
302
     Keep all intermediate/temporary files (helps with debugging)
303
+: **-no-ask** | **-noask**
304
+    Skip all interactive questions.  No preview, automatic re-encoding with
305
+    tovid if needed, no interactive option to use background video for bgaudio.
306
+: **-no-warn**, **-nowarn**
307
+    Don't pause after outputting warning or info messages
308
+: **-jobs**
309
+    By default, **tovid disc** starts a parallel job for each processor
310
+    detected.  With this option you can manually set the number of jobs.  For
311
+    example if you have a computer with 2 CPUs you can set "-jobs 1" to keep
312
+    one processor free for other things.  At present this applies to the time
313
+    consuming imagemagick loops: you will notice a substantial speedup now if
314
+    you have a multi-cpu system.
315
+: **-grid**
316
+    Show a second preview image with a grid and numbers that will help in finding
317
+    coordinates for options that might use them, like **-text-start**
318
+: **-no-confirm-backup**
319
+    This option is for when your DVD contains images for a slideshow.
320
+    Slideshows are an experimental (but well tested) feature.  Todisc is
321
+    unlikely to overwrite your personal files, but you should take precautions
322
+    and backup your images, as you would with any beta software.  Todisc
323
+    will prompt you to backup your files normally.  If you have already backed
324
+    up your images, use this option to disable the prompt.
325
+
326
+==Options==
327
+
328
 : **-ntsc**
329
     720x480 output, compatible with NTSC standard (default)
330
 : **-pal**
331
@@ -320,10 +405,17 @@
332
 : **-no-menu | -nomenu**
333
     With this option todisc will just create a DVD file system, ready for
334
     burning, with NO MENU, just the supplied video files.  These do not need
335
-    to be compliant, as non-compliant files will be encoded as usual.  Each
336
-    video will be a chapter unless **-chapters** OPTION is passed.  The
337
-    **-chapters** option is a number indicating the chapter interval in
338
-    minutes, or a HH:MM:SS string indicating chapter points.  See **-chapters**
339
+    to be compliant, as non-compliant files will be encoded as usual.  The
340
+    **-out** option is not required.  Each  video will be a chapter unless
341
+    **-chapters** OPTION is passed.  The  **-chapters** option is a number
342
+    indicating the chapter interval in minutes, or a HH:MM:SS string
343
+    indicating chapter points.  See **-chapters**
344
+: **-encode-only**
345
+    This option was originally meant for the GUI, to allow it to be used for
346
+    just encoding rather than making a DVD structure.  But it works well from
347
+    the command line as well as it has the added advantage that you can input
348
+    a list of files.  Remember any makempg ('tovid mpg') options you use will
349
+    be passed on to the makempg script when encoding.
350
 
351
 
352
 ==Menu style==
353
@@ -333,18 +425,19 @@
354
     This is a different arrangement of images for the menu: small thumbnails
355
     go at left (and right) side of screen, with a larger image in the centre.
356
     Maximum of 10 videos.  If the provided argument is a video file, the
357
-    central thumb will be animated. Only 4:3 or 16:9 videos and images are
358
-    accepted for the showcase file: if not one of these todisc will assume it
359
-    is the same ratio as the videos in the titleset.
360
+    central thumb will be animated (regardless of whether **-static** is part
361
+    of the command line). Only 4:3 or 16:9 videos and images are accepted for
362
+    for the showcase file: if not one of these todisc will assume it is the
363
+    aspect ratio as the videos in the titleset.
364
 : **-textmenu**, **-text-menu** NUM
365
     If used without an argument, create a textmenu out of the supplied titles
366
     The optional argument specifies how many titles are in the 1st column,
367
     i.e. giving 4 titles and using "-textmenu 2" would make 2 columns of 2
368
     titles. The default is to put all titles up to 13 in the first column
369
     before starting a second column.  Maximum: 2 columns and 26 titles.
370
-    Note that column 2 titles are aligned to the right.
371
-    If no video files for either **-background** or **-showcase** are supplied,
372
-    the menu will be static.
373
+    Note that column 2 titles are justified to the left unless you add
374
+    **-edge-justify** to the command line. The menu will be static if no video
375
+    files are supplied with either **-background** or **-showcase** options.
376
 : **-quick-menu**
377
     If you are using ffmpeg 0.8 or newer you can use this option.  This will
378
     make a very quick  menu by using ffmpeg instead of imagemagick.
379
@@ -354,19 +447,19 @@
380
     text-menu style of menu, with no video thumbs, and a central showcase
381
     IMAGE(static) | VIDEO(animated).
382
     (i) see **-bg-color** if you are not using a **-background** and want to
383
-    change the default black )
384
-    (ii) Note: todisc will still work with vhooks if you have an old ffmpeg with
385
-    vhooks compiled in.
386
+    change the default.  (default is dark blue for -quick-menu arrangements). )
387
+    (ii) Note: todisc will still work with 'vhooks' if you have an old ffmpeg
388
+    with vhooks compiled in.
389
 
390
     Specifying the IMAGE|VIDEO argument to **-showcase** is mandatory for this
391
     style of menu, unless used in conjunction with **-switched-menus**
392
     in which case the videos passed with **-files** automatically become the
393
-    showcase videos.  If this is used in combination with **-switched-menus**
394
-    it can really speed up an otherwise time consuming process.
395
+    showcase videos.  If **-quick-menu** is used in combination with
396
+    **-switched-menus** it really speeds up an otherwise time consuming process.
397
 
398
     Example:
399
 ```
400
-    -quick-menu -showcase /home/robert/showcase.mpg
401
+    -quick-menu -showcase /home/grepper/showcase.mpg
402
 ```
403
     See **-switched-menus** for example of making switched menus with
404
     **-quick-menu**
405
@@ -375,7 +468,8 @@
406
     The color to use for the menu background. (default: ntsc-safe black)
407
     Note: use a color a great deal darker than you want, as it appears quite
408
     a bit lighter in the video version.  You can use hexadecimal ('#ffac5f')
409
-    or named colors notation.
410
+    notation or named colors ('Lime').  convert -list color will show them.
411
+    See [colors http://www.imagemagick.org/script/color.php] for more details.
412
 : **-submenu-bg-color**, **-submenu-bg-colour**
413
     The color to use as background for the  submenu(s).
414
     (default: ntsc-safe black)  See **-bg-color**
415
@@ -385,7 +479,7 @@
416
     a 'moving' menu, in spite of the static buttons.  This option also does
417
     double duty for the **-switched-menus** option, and will create static
418
     "switched" images.
419
-    See also **-switched-menu**
420
+    See also **-switched-menus**
421
 : **-background** IMAGE|VIDEO
422
     Menu background.  This can be a image file or an video file.  If it is a
423
     video file the background will be animated.  Pick a file of correct aspect
424
@@ -398,21 +492,21 @@
425
 : **-menu-title**
426
     Title for the root menu - may be longer than thumbnail labels
427
     Also if you use \n in the title, you can use multi line titles, but you
428
-    would need to adjust **-menu-fontsize** to something smaller than default
429
+    would need to adjust **-title-fontsize** to something smaller than default
430
     for example:
431
 
432
 ```
433
-    $ tovid disc ... -menu-title "A\nMultilined\nTitle" -menu-fontsize 24
434
+    $ tovid disc ... -menu-title "A\nMultilined\nTitle" -title-fontsize 24
435
 ```
436
-: **-menu-font** FONT
437
+: **-title-font**, **-menu-font** FONT
438
     Font to use for titles, either by ImageMagick font name (ex., "Arial") or
439
     explicit pathname (ex., "/full/path/to/arial.ttf"). To see a complete
440
     list of acceptable ImageMagick font names, run **convert -list type**, and
441
     refer to the leftmost column
442
-: **-menu-fontsize**
443
+: **-title-fontsize**, **-menu-fontsize**
444
     Font size for main menu - best to -preview if you use this
445
 : **-submenu-font**
446
-    Font to use for the sub-menu main titles.  See **-menu-font**
447
+    Font to use for the sub-menu main titles.  See **-title-font**
448
 : **-submenu-fontsize**
449
     Font size for the sub-menu main titles
450
 : **-menu-fade** ['BACKGROUND DURATION']
451
@@ -461,7 +555,7 @@
452
   using **-quick-nav** as you would not have a way to get to other titlesets.
453
 : **-skip-vmgm**
454
   Start DVD from the first titleset instead of the VMGM ( root ) menu.
455
-: **-switched-menus**
456
+: **-switched-menus**, **-switched-menu**
457
     This will make a "switched menu": there will be a central image where the
458
     showcase image would go, and text menu titles along the menu edge where
459
     textmenu titles go.  As you select a video title with the down or up arrow
460
@@ -485,6 +579,10 @@
461
 
462
 ==Thumbnail style==
463
 
464
+: **-titles-font** FONT
465
+    Display thumbnail or textmenu titles in the given font
466
+: **-titles-fontsize** POINTS
467
+    Font size to use for thumbnail or textmenu titles
468
 : **-thumb-shape**
469
     normal|oval|vignette|plectrum|arch|spiral|blob|star|flare
470
     Apply a shaped transparency mask to thumbnail videos.
471
@@ -506,10 +604,6 @@
472
 : **-3d-thumbs**, **-3dthumbs**
473
     This will give an illusion of 3D to the thumbnails: dynamic lighting on
474
     rounded thumbs, and a raised effect on rectangular thumbs.  Try it !
475
-: **-titles-font** FONT
476
-    Display thumbnail or textmenu titles in the given font
477
-: **-titles-fontsize** POINTS
478
-    Font size to use for thumbnail or textmenu titles
479
 
480
 
481
 ==Slideshows==
482
@@ -603,7 +697,7 @@
483
     be static.  If you used with a mixed menu of videos and slideshows, then
484
     the video thumbs WILL be animated, so you may wish to use -static or
485
     -textmenu with the option in that case.  If you want to use the
486
-    **-switched-menus option with a mixed menu leave this option out. 
487
+    **-switched-menus option with a mixed menu leave this option out.
488
 
489
 : **-background-slideshow**, **-bg-slideshow**
490
     If doing multiple slideshows or mixed videos and slideshow(s), then use
491
@@ -616,6 +710,7 @@
492
     and backup your images, as you would with any beta software.  Todisc
493
     will prompt you to backup your files normally.  If you have already backed
494
     up your images, use this option to disable the prompt.
495
+    See **General Options**
496
 
497
 : **-use-dvd-slideshow** [CONFIG FILE]
498
     If you pass this option without an argument, tovid will use the
499
@@ -639,7 +734,7 @@
500
     The speed to use for burning the disc.
501
 
502
 
503
-==ADVANCED USAGE==
504
+==Advanced usage==
505
 
506
 ===Options===
507
 
508
@@ -650,11 +745,11 @@
509
     audio for static submenus.  (Assuming that -submenu-audio was passed in).
510
     The default is to use 10 seconds of audio for static menus.
511
 : **-submenu-stroke** COLOR
512
-    The color for the sub-menu font outline (stroke)
513
+    The color for the sub-menu font shadow
514
 : **-submenu-title-color**, **-submenu-title-colour**
515
     The fill color used for sub-menu title fonts
516
 : **-submenu-titles**
517
-    You can supple a list of titles here for sub-menus without the length
518
+    You can supply a list of titles here for sub-menus without the length
519
     restrictions found in thumb titles.  Must equal number of videos
520
 : **-chapters** [ NUM | CHAPTER POINTS in HH:MM:SS ]
521
     The number of chapters for each video (default: 6) OR
522
@@ -725,7 +820,7 @@
523
 : **-chapter-color** COLOR
524
     The color for the chapters font.
525
 : **-chapter-stroke** COLOR
526
-    The color for the chapters font outline (stroke)
527
+    The color for the chapters font shadow
528
 
529
 : **-seek** NUM | "NUM1 NUM2 NUM3 . . ."
530
     Seek to NUM seconds before generating thumbnails (default: 2.0 seconds)
531
@@ -772,21 +867,6 @@
532
     title and/or thumbnail for bar.mpg will appear in the menu.  You can use
533
     **-group** more than once for multiple groups.  Be  sure to quote video
534
     filenames if they contain  spaces.
535
-: **-jobs**
536
-    By default, **tovid disc** starts a parallel job for each processor
537
-    detected.  With this option you can manually set the number of jobs.  For
538
-    example if you have a computer with 2 CPUs you can set "-jobs 1" to keep
539
-    one processor free for other things.  At present this applies to the time
540
-    consuming imagemagick loops: you will notice a substantial speedup now if
541
-    you have a multi-cpu system.
542
-: **-no-ask**, **-noask**
543
-    Skip all interactive questions.  No preview, automatic re-encoding with
544
-    tovid if needed, no interactive option to use background video for bgaudio.
545
-: **-no-warn**, **-nowarn**
546
-    Don't pause after outputting warning or info messages
547
-: **-grid**
548
-    Show a second preview image with a grid and numbers that will help in finding
549
-    coordinates for options that might use them, like **-text-start**
550
 
551
 
552
 ==Menu Style==
553
@@ -799,22 +879,35 @@
554
     Move menu title by this offset from its N|S|E|W|Center position.  You
555
     may need to use -align as well if you don't want your title covering other
556
     parts of your menu.  See **-align**
557
-: **-button-style** rect|text|line|text-rect
558
+: **-button-style** line|rect|text|text-rect [line]
559
     The style of button that you will see when you play the DVD.
560
-    "rect" draws a rectangle around the thumb when you select it
561
-    in the DVD player.  "text" highlights the video title text, "line"
562
-    underlines the title, and "text-rect" draws a rectangle around the title
563
+    "line" style underlines the title, "rect" draws a rectangle around the
564
+    thumb when you select it in the DVD player, "text" highlights the video
565
+    title text, and "text-rect" draws a rectangle around the title
566
     text.
567
 : **-title-color**, **-title-colour** COLOR
568
     Color to use for the main menu title.  For list of supported colors do:
569
     **convert -list** color.  HTML notation may be used: "#ff0000". See:
570
     http://www.imagemagick.org/script/color.php
571
 : **-title-stroke** COLOR
572
-    Outline color for the main menu's title font. Use "none" for transparent
573
-    outline  (see title-color)
574
+    Shadow color for the main menu's title font. Use "none" for transparent
575
+    outline  (see title-color).  Note: this is not a -stroke in the sense that
576
+    imagemagick uses the term, but a shadow (the font is drawn twice).  To get
577
+    a true imagemagick stroke see **-title-font-deco**
578
+: **-title-font-deco**, **-title-fontdeco** "IMAGEMAGICK STRING"
579
+    Sets the font decoration method to FONTDECORATION. It is used by the 'convert'
580
+    ImageMagick command to draw the menu text. You can add colored text
581
+    outlines, gradient fills, and many others. See **Usage notes**
582
 : **-titles-stroke** COLOR
583
-    Outline color for the thumb or textmenu video titles font. Use "none" for
584
-    transparent outline  (see **-titles-color**).
585
+    Shadow color for the thumb or textmenu video titles font. Use "none" for
586
+    transparent outline  (see **-titles-color**).  Note: this is not a -stroke
587
+    in the sense that imagemagick uses the term, but a shadow
588
+    (the font is drawn twice).  To get a true imagemagick stroke,
589
+    see **-titles-font-deco**
590
+: **-titles-font-deco**, **-titles-fontdeco** "IMAGEMAGICK STRING"
591
+    Sets the font decoration method to FONTDECORATION. It is used by the 'convert'
592
+    ImageMagick command to draw the menu text. You can add colored text
593
+    outlines, gradient fills, and others. See **Usage notes** for more info.
594
 : **-highlight-color**, **-highlight-colour**
595
     Color to use for the menu buttons that your DVD remote uses to navigate.
596
 : **-select-color**, **-select-colour**
597
@@ -846,7 +939,7 @@
598
     Only 4:3 aspect is supported: 16:9 will give unexpected results.
599
 
600
 
601
-===Menu Style options specific to showcase and textmenu arrangements===
602
+===Style options specific to showcase/textmenu arrangements===
603
 : **-text-start** N
604
     This option is for **-textmenu** menus.  The titles will start at the Nth
605
     pixel from the top of the menu ( Y axis ).
606
@@ -858,7 +951,8 @@
607
     (default: if used without options, the rotate will be 5 degrees).  Note:
608
     this will not turn a portait image into a landscape image!
609
 : **-showcase-geo** GEOMETRY
610
-    The position of the showcase image.  ( XxY position )
611
+    The position of the showcase image.  ( +X+Y  position )
612
+    For example: **-showcase-geo** +300+200
613
 : **-wave** default|GEOMETRY
614
     Wave effect for showcase image|video.  Alters thumbs along a sine wave using
615
     GEOMETRY. (default: no wave)
616
@@ -894,11 +988,12 @@
617
 
618
 
619
 ==Thumbnail Style==
620
-: **-user-thumbs** IMAGE
621
+: **-user-thumbs** IMAGE(S)
622
     Supply your own images for menu buttons, rather than relying on todisc to
623
     generate them from the video.  They must be the same aspect ratio as the
624
     videos in the titleset (4:3 or 16:9), as todisc will resize them without
625
-    checking and cropping.
626
+    checking and cropping.  There must be on image for each thumb that will be
627
+    displayed on the menu (ie. one thumb for each video in a titleset).
628
 : **-opacity** [0-100] (default 100)
629
     Opacity of thumbnail videos as a percentage (no percent sign).
630
     Anything less than 100(%) is semi-transparent. Not recommended with dark
631
@@ -912,10 +1007,22 @@
632
     The amount of 'feather' blur to apply to the showcase image/video.  Choose
633
     values between 0.1 and 2.0.  This option has no effect on **-3d-showcase**.
634
     See **-thumb-blur** for more info.
635
-: **-align** north|south
636
-    This will align  thumbs/titles north or south.
637
+: **-align** DIRECTION
638
+    This will align  thumbs/titles in DIRECTION, which is a compass direction
639
+    as used by imagemagick: ie. north|south|east|west|northeast|northwest etc.
640
     If **-align** south then menu title will align north, unless you manually
641
     set one or both of **-menu-title-geo** or **-menu-title-offset**.
642
+    Only **-align** north|south|center has any effect on showcase with thumb,
643
+    or with the default montage arrangement of central thumbs. The most
644
+    apparent changes with be with textmenu, though with 2 column arrangements
645
+    only the north* and south* changes will show an effect.
646
+
647
+    Diagram:
648
+:    . northwest   north   northeast .
649
+:    .                               .
650
+:    . west        center       east .
651
+:    .                               .
652
+:    . southwest   south    souteast .
653
 : **-thumb-mist** [COLOR]
654
     Use a mist behind thumbnails.  The optional argument is the color of the
655
     mist.  This option helps with contrast.  Be sure to set the font color
656
@@ -973,7 +1080,7 @@
657
     the **-vmgm** ... **-end-vmgm** options to allow playing ALL titlesets.
658
     (If you want also to have a playall button in each titleset you could use
659
     this option between each **-titleset** ... **-end-titleset** option or put
660
-    it outside of the vmgm and titlset options as a general option.
661
+    it outside of the vmgm and titlset options as a global option.
662
 : **-videos-are-chapters**
663
     A button will be made on the main menu for each video, which you can use as
664
     a chapter button.  Selecting any video will play them all in order
665
@@ -1037,6 +1144,33 @@
666
     equal the number of grouped videos.
667
 
668
 
669
+
670
+==Usage notes==
671
+
672
+The argument given to various *-font options that set the font to use must be
673
+one of the fonts listed by the command 'convert -list type'. Please note that
674
+many of your installed fonts may not be available; if you want to maximize the
675
+number of fonts available to todisc, download and run
676
+[Anthony Thyssen's http://www.cit.gu.edu.au/~anthony/anthony.html]
677
+[imagick_type_gen http://www.imagemagick.org/Usage/scripts/imagick_type_gen]
678
+script and run it like this:
679
+imagick_type_gen > ~/.magick/type.xml.
680
+If that doesn't work, try imagick_type_gen > ~/.magick/type.mgk.
681
+
682
+Or you can specify a ttf font file directly to the *-font options if you don't
683
+want to install fonts to ImageMagick.
684
+
685
+The *-stroke options in todisc are not a stroke in the sense that ImageMagick
686
+uses the term, but rather a font shadow (the text is drawn twice)  To get a
687
+truer Imagemagick -stroke try something like:
688
+-title-font-deco "-stroke black" (or -titles-font-deco "-stroke black").  The
689
+**-fontdeco** option is quite flexible and takes a lot of ImageMagick's
690
+//convert// options. Please refer to the tovid
691
+[wiki http://tovid.wikia.com/wiki/Making_a_DVD_with_text_menus] and Anthony
692
+Thyssen's guide [http://www.imagemagick.org/Usage] for further explanation and examples.
693
+
694
+
695
+
696
 =Command:mpg=
697
 
698
 **tovid mpg** converts arbitrary video files into (S)VCD/DVD-compliant
699
@@ -1044,6 +1178,7 @@
700
 standalone DVD player.
701
 
702
 
703
+
704
 ==Usage==
705
 
706
 **tovid mpg** [//OPTIONS//] **-in** //INFILE// **-out** //OUTPREFIX//
707
@@ -1339,7 +1474,7 @@
708
     regularly the progress-meter is updated. The default is once every five
709
     seconds.
710
 
711
-: **-mplayeropts** **"**//OPTIONS//**"**
712
+: **-mplayeropts** //OPTIONS//
713
     Append //OPTIONS// to the mplayer command run during video encoding.  Use
714
     this if you want to add specific video filters (documented in the mplayer
715
     manual page). Overriding some options will cause encoding to fail, so use
716
@@ -1409,6 +1544,9 @@
717
     Display output in a table format for easier comparison. Most useful
718
     when identifying multiple video files.
719
 
720
+: **-keepfiles**
721
+    Keep temporary directory for debugging.
722
+
723
 : **-isformat** [//pal-dvd//|//ntsc-dvd//] (same syntax for vcd and svcd)
724
     Check //VIDEO_FILE// for compliance with the given disc format.
725
     If //VIDEO_FILE// matches the given format, then **tovid id** reports "true"
726
@@ -1427,365 +1565,35 @@
727
     Check to see if homevideo.mpg is compliant with the DVD standard.
728
 
729
 
730
-=Command:menu=
731
-
732
-**tovid menu** generates textual (S)VCD- or DVD-compliant MPEG videos for use
733
-as navigational menus, given a list of text strings to use for title names. You
734
-can customize the menu by providing an optional background image or audio clip,
735
-or by using custom font and font color.
736
-
737
-
738
-==Usage==
739
-
740
-**tovid menu** [//OPTIONS//] //TITLES// **-out** //OUT_PREFIX//
741
-
742
-For example:
743
-
744
-: ``tovid menu "Season One" "Season Two" "Featurettes" -out MainMenu``
745
-
746
-
747
-==Options==
748
-
749
-: **-ntsc** (default)
750
-    Generate an NTSC-format menu
751
-: **-ntscfilm**
752
-    Generate an NTSC-format menu (24000/1001fps)
753
-: **-pal**
754
-    Generate a PAL-format menu
755
-: **-dvd** (default)
756
-    Generate a DVD-format menu, with highlighted text included
757
-    as a multiplexed subtitle stream.
758
-: **-vcd**
759
-: **-svcd**
760
-    Generate a VCD/SVCD menu; each menu option will have a
761
-    number associated with it. You can have up to nine menu
762
-    options per menu.
763
-
764
-
765
-Menu background/audio options:
766
-
767
-: **-background** //IMAGE//
768
-    Use //IMAGE// (in most any graphic format) as a background. If image is not
769
-    the correct aspect ratio (4:3), it will be scaled and/or cropped,
770
-    depending on the **-crop** and **-scale** options. If no background is
771
-    supplied, a default background will be created.
772
-
773
-: **-crop** (default)
774
-    If provided background image is not 4:3 aspect ratio, crop edges
775
-    to make it so. Image will be scaled up if it is too small. Cropping
776
-    keeps the center area of image. If you want to do cropping/scaling
777
-    yourself in another program, provide an image of 768x576 pixels.
778
-
779
-: **-scale**
780
-    If provided background image is not 4:3 aspect ratio, scale/stretch
781
-    it to make it fit. May cause visible distortion!
782
-
783
-: **-audio** //AUDIOFILE//
784
-    Use //AUDIOFILE// (in most any audio format) for background music. The
785
-    menu will play for long enough to hear the whole audio clip. If
786
-    one is not provided, 4 seconds of silence will be used.
787
-
788
-: **-length** //NUM//
789
-    Make the menu //NUM// seconds long. Useful for menus with **-audio**:
790
-    if you don't want the entire //AUDIOFILE// in the menu, then you can trim
791
-    the length of the menu with **-length**.
792
-
793
-
794
-Menu text options:
795
-
796
-: **-menu-title** **"**//MENU TITLE TEXT//**"**
797
-    Add //MENU TITLE TEXT// as a title/header to the menu.
798
-
799
-: **-font** //FONTNAME// (default Helvetica)
800
-    Use //FONTNAME// for the menu text. Run 'convert -list type' to see a
801
-    list of the fonts that you can use; choose a font name from the
802
-    leftmost column that is displayed. Or you can specify a ttf font file instead.
803
-    E.g., '-font /path/to/myfont.ttf'.
804
-
805
-: **-fontsize** //NUM// (default 24)
806
-    Sets the size for the font to //NUM// pixels.
807
-
808
-: **-menu-title-fontsize** //NUM// (default **-fontsize** + 8)
809
-    Sets the size of the menu title.
810
-
811
-: **-fontdeco** **'**//FONTDECORATION//**'**
812
-    Sets the font decoration method to //FONTDECORATION//. It is used by the
813
-    'convert' ImageMagick command to draw the menu text. You can add colored
814
-    text outlines, gradient fills, and many others. See **Usage notes**.
815
-
816
-: **-align** {**left**|**center**|**middle**|**right**}
817
-    Align the text at the top left, top center, very middle, or top right
818
-    side of the screen. You may also substitute any "gravity" keyword
819
-    allowed by ImageMagick (north|south|east|west|northeast|southwest|...).
820
-
821
-: **-textcolor** {**#**//RRGGBB//|**#**//RGB//|//COLORNAME//}
822
-    Use specified color for menu text. #//RRGGBB// and #//RGB// are
823
-    hexadecimal triplets (e.g., #FF8035). //COLORNAME// may be any of
824
-    several hundred named colors; run 'convert -list color' to see them.
825
-    White (#FFF) is the default color.
826
-
827
-
828
-DVD-only options:
829
-
830
-: **-button** //BUTTON// (default '>')
831
-    Specify the button used for menu selection. Specify either a _single_
832
-    character or one of the shortcuts:
833
-    - **play** -- Use a button shaped like 'Play' on many A/V electronics:
834
-        a triangle pointing to the right. (uses the font Webdings)
835
-    - **movie** -- Use a button shaped like an old movie projector.
836
-        (uses the font Webdings)
837
-    - **utf8** -- Use your own non-keyboard character as a button. Provide
838
-        only the four hex digits: eg '-button utf8 00b7'. Beware that
839
-        ImageMagick's utf8 characters aren't the same as those drawn in
840
-        character browsers like gucharmap.
841
-
842
-
843
-: **-highlightcolor** {**#**//RRGGBB//|**#**//RGB//|//COLORNAME//}
844
-    Use the specified color for button highlighting. Yellow (#FF0) is the
845
-    default color.
846
-
847
-: **-selectcolor** {**#**//RRGGBB//|**#**//RGB//|//COLORNAME//}
848
-    Use the specified color for button selections (when a menu item is played
849
-    or activated). Red (#F00) is the default color.
850
-
851
-: **-button-outline** {**#**//RRGGBB//|**#**//RGB//|//COLORNAME//}
852
-    Outline buttons with the specified color. 'none' is the default.
853
-
854
-: **-button-font** //FONTNAME//
855
-    Specify a differnt font to use for the buttons. By default, the button
856
-    font will be inherited from the title font (see **-font**). Use this
857
-    option to use a different font for the buttons. The button font size is
858
-    inherited from **-fontsize** and cannot be changed.
859
-
860
-
861
-Other options:
862
-
863
-: **-debug**
864
-    Print extra debugging information to the log file. Useful in
865
-    diagnosing problems if they occur. This option also leaves
866
-    the log file (with a .log extension) in the directory after
867
-    encoding finishes as well as all the temporary files created.
868
-
869
-: **-nosafearea**
870
-    Do not attempt to put text inside a TV-safe viewing area. Most
871
-    television sets cut off about 10% of the image border, so the script
872
-    automatically leaves a substantial margin. This option turns that
873
-    behavior off, leaving only a tiny margin. Use at your own risk.
874
-
875
-: **-overwrite**
876
-    Overwrite any existing output menu.
877
-
878
-: **-noask**
879
-    Don't ask interactive questions, and assume answers that will
880
-    continue making the menu until completion.
881
-
882
-: **-quiet**
883
-    Limit output to essential messages.
884
-
885
-
886
-If the word "**back**" is given as an episode title, a "back" button for
887
-returning to a higher-level menu will be added at the end of the list
888
-of titles. "**Back**" //must be the last title listed//.
889
-
890
-
891
-==Examples==
892
-
893
-Make an NTSC VCD menu with white Helvetica text containing three centered
894
-selections: Episode 1, Episode 2, and Episode 3. The finished menu will be
895
-called Season-1.mpg:
896
-
897
-```
898
-tovid menu -ntsc -vcd \
899
-    -align center -textcolor white -font "Helvetica" \
900
-    "Episode 1" "Episode 2" "Episode 3" \
901
-    -out "Season-1"
902
-```
903
-
904
-Make an NTSC DVD menu with white Kirsty text containing three lower-left
905
-aligned selections: Episode 1, Episode 2, and Episode 3. Items under the cursor
906
-will be highlighted a pale blue, and selected items will be a pale orange
907
-(before going to the selected title). The finished menu will be called
908
-Main-menu.mpg:
909
-
910
-```
911
-tovid menu -ntsc -dvd \
912
-    -align southwest \
913
-    -textcolor white \
914
-    -highlightcolor "#5f65ff" \
915
-    -selectcolor "#ffac5f" \
916
-    -font "Kirsty" \
917
-    "Episode 1" "Episode 2" "Episode 3" \
918
-    -out "Main_menu"
919
-```
920
-
921
-
922
-
923
-==Usage notes==
924
-
925
-The argument given to **-font** must be one of the fonts listed
926
-by the command 'convert -list type'. Please note that many of
927
-your installed fonts may not be available; if you want to maximize the
928
-number of fonts available, download and run
929
-[Anthony Thyssen's http://www.cit.gu.edu.au/~anthony/anthony.html]
930
-[imagick_type_gen.pl http://www.cit.gu.edu.au/~anthony/software/imagick_type_gen.pl]
931
-script and run it like this:
932
-imagick_type_gen.pl > ~/.magick/type.xml.
933
-If that doesn't work, try
934
-imagick_type_gen.pl > ~/.magick/type.mgk.
935
-
936
-Or you can specify a ttf font file directly to the **-font** options if you
937
-don't want to install fonts to ImageMagick.
938
-
939
-The **-fontdeco** option is quite flexible and takes a lot of ImageMagick's
940
-//convert// options. Please refer to the tovid
941
-[wiki http://tovid.wikia.com/wiki/Making_a_DVD_with_text_menus]
942
-and Anthony Thyssen's guide for further explanation and examples.
943
-
944
-
945
-=Command:xml=
946
-
947
-**tovid xml** generates XML output describing an (S)VCD
948
-or DVD file structure and navigation hierarchy in the format expected by
949
-[dvdauthor http://dvdauthor.sourceforge.net/] or
950
-[vcdxbuild http://www.vcdimager.org/].
951
-
952
-
953
-==Usage==
954
-
955
-**tovid xml** [//OPTIONS//] //VIDEOS// -out //OUTFILE//
956
-
957
-For example:
958
-
959
-```
960
-$ tovid xml -menu MainMenu.mpg \
961
-    Season1.mpg Season2.mpg Featurettes.mpg \
962
-    -out MyDisc
963
-```
964
-
965
-
966
-==Options==
967
-
968
-: **-dvd** (default)
969
-    Generate the XML for a DVD disc, to be used with dvdauthor or **tovid dvd**.
970
-: **-vcd**
971
-    Generate the XML for a VCD disc, to be used with vcdxbuild or **tovid vcd**.
972
-: **-svcd**
973
-    Generate the XML for an SVCD disc, to be used with vcdxbuild or **tovid vcd**.
974
-: **-overwrite**
975
-    Overwrite any existing output files.
976
-: **-quiet**
977
-    Limit output to essential messages.
978
-
979
-
980
-//VIDEOS// may be any of the following:
981
-
982
-: //<file list>//
983
-    List of one or more video files to include, separated by spaces. At
984
-    minimum, a DVD must have one video file. You can use shell wildcards
985
-    (i.e., "*.mpg") to include multiple files easily. Put filenames in
986
-    quotes if they have spaces in them.
987
-
988
-: **-menu** //VIDEO// //<file list>//
989
-    Use video file //VIDEO// as a menu from which you can jump to each of
990
-    the listed video files. If you have multiple menus, include a
991
-    top menu so they are reachable.
992
-
993
-: **-slides** //<file list>//
994
-    Create a slide-show of still images
995
-
996
-
997
-DVD-only options
998
-
999
-: **-group** //<file list>// **-endgroup**
1000
-    (DVD only) List of video files to include as one single title. This is useful
1001
-    if you have split a movie into several video files.
1002
-
1003
-: **-topmenu** //VIDEO// [**-menu** //VIDEO// //<file list>//] [**-menu** //VIDEO// //<file list>//]...
1004
-    (DVD only) Use video file //VIDEO// for the top-level (VMGM) menu. The
1005
-    top menu will jump to each of the subsequent [-menu...] videos listed.
1006
-    Use this only if you have multiple sub-menus to jump to. You can only
1007
-    have one top menu.
1008
-
1009
-: **-titlesets**
1010
-    (DVD only) Forces the creation of a separate titleset per title. This
1011
-    is useful if the titles of a DVD have different video formats,
1012
-    e.g. PAL + NTSC or 4:3 + 16:9. If used with menus, there must be a
1013
-    **-topmenu** option that specifies a menu file with an entry for each of the
1014
-    titlesets.
1015
-
1016
-: **-chapters** //INTERVAL//
1017
-    (DVD only) Creates a chapter every //INTERVAL// minutes (default 5 minutes:
1018
-    without **-chapters**, each movie will be divided into 5-minute chapters).
1019
-    This option can be put at any position in a //<file list>// and is valid
1020
-    for all subsequent titles until a new **-chapters** option is encountered.
1021
-    Using this option may take some time, since the duration of the video is
1022
-    calculated.
1023
-
1024
-: **-nochapters**
1025
-    (DVD only) Don't create chapters for the videos.
1026
-
1027
-
1028
-//OUT_PREFIX// is the file that will receive the resulting XML.
1029
-
1030
-
1031
-==Usage notes==
1032
-
1033
-The 'xml' command checks to make sure the video filenames you
1034
-give it exist, but it does not check whether they are valid for the
1035
-chosen disc format. MPEG videos of menus should have the specified
1036
-number of buttons for reaching each of the videos, and, if you're
1037
-using DVD, should be multiplexed with their corresponding subtitles
1038
-using spumux of the dvdauthor 0.6.0 package prior to
1039
-authoring using dvdauthor. If you use the 'tovid menu'
1040
-component to generate the menu, this should all be handled for you.
1041
-
1042
-
1043
-==Examples==
1044
-
1045
-: ``tovid xml -dvd title-1.mpg title-2.mpg title-3.mpg -out My_DVD``
1046
-    Make a DVD without a menu. Title 1, 2, and 3 will play in sequence.
1047
-
1048
-: ``tovid xml -dvd -group chapter-1.mpg chapter-2.mpg chapter-3.mpg -endgroup -out My_DVD``
1049
-    Group the file chapter-1|2|3.mpg into one title and make a DVD without a menu.
1050
-
1051
-: ``tovid xml -dvd -menu main_menu.mpg -chapters 3 movie-1.mpg -chapters 10 movie-2.mpg -out My_DVD``
1052
-    Make a DVD with a main menu that points to two movies, with movie-1.mpg
1053
-divided into 3-minute chapters, and movie-2.mpg into 10-minute chapters.
1054
-
1055
-
1056
 
1057
 =Command:dvd=
1058
 
1059
-**tovid dvd** takes a dvdauthor XML file (as generated by the **tovid xml**
1060
-command) and authors a DVD filesytem. This command can also burn a DVD disc
1061
-from either the XML file or from an existing DVD file-system.
1062
+**tovid dvd** takes a DVD directory as generated by tovid with 'tovid disc' or
1063
+one of the GUI frontends like 'tovid gui' or 'tovid titlesets' and burns
1064
+it to appropriate media.  This will also work if the DVD directory is
1065
+generated by the dvdauthor backend that tovid also uses.
1066
 
1067
-To ensure that this script successfully executes, please run it from a
1068
-directory with plenty of free space. "Plenty" would be 10 GB for single-layer
1069
-discs, and 20 GB for dual-layer discs.  Running this program may slow down your
1070
-other applications, due to intense disk activity.
1071
+Running this program may slow down your other applications, due to intense
1072
+disk activity.
1073
 
1074
 
1075
 ==Usage==
1076
 
1077
-**tovid dvd** [//OPTIONS//] //FILE.xml//
1078
 
1079
 **tovid dvd** [//OPTIONS//] //DVD_DIR//
1080
 
1081
 For example:
1082
 
1083
-: ``tovid dvd -burn MyDisc.xml``
1084
-: ``tovid dvd -burn /path/to/DVD/directory``
1085
+: ``tovid dvd /path/to/DVD/directory``
1086
 
1087
 
1088
 ==Options==
1089
 
1090
-: **-author**
1091
-    Author the DVD described by //FILE.xml//. Overwrites an existing
1092
-    directory containing the dvdauthor output if already present.
1093
-
1094
 : **-burn**
1095
     Burn a DVD file-system in //DVD_DIR// (must contain a VIDEO_TS folder).
1096
+    This option is currently not necessary as the makedvd script ONLY burns
1097
+    now that legacy scripts like makexml have been removed.  Left for
1098
+    compatibility only.
1099
 
1100
 : **-eject**
1101
     Eject the DVD tray after burning is complete. By default, the DVD is not
1102
@@ -1813,133 +1621,29 @@
1103
     execution.
1104
 
1105
 
1106
-==Examples==
1107
-
1108
-: ``tovid dvd -burn -device /dev/dvdrw foo.xml``
1109
-    Author the dvd file-system and burn to /dev/dvdrw. This will
1110
-    automatically call dvdauthor to make the file-system. **-author**
1111
-    is not explicitly needed. If there's an existing file-system, it
1112
-    will be burned.
1113
-
1114
-: ``tovid dvd -author foo.xml``
1115
-    Author the DVD file-system and exit without burning. If the output
1116
-    directory given in foo.xml already exists, then the contents are
1117
-    removed before authoring. At this point, the DVD can be previewed
1118
-    by calling //**xine** dvd:/path/to/output/directory//.
1119
-
1120
-
1121
-=Command:vcd=
1122
-
1123
-**tovid vcd** takes an XML file (which may be generated by **tovid xml**) and
1124
-creates a cue/bin (S)VCD image. It can also burn (S)VCD discs.
1125
-
1126
-To ensure that this script successfully executes, please run it from a directory
1127
-with plenty of free space. "Plenty" would be about 1 GB. Running this program
1128
-may slow down your other applications, due to intense disk activity.
1129
-
1130
-
1131
-==Usage==
1132
-
1133
-**tovid vcd** [//OPTIONS//] //VCDIMAGER.xml//
1134
-
1135
-For example:
1136
-
1137
-: ``tovid vcd -burn MyDisc.xml``
1138
-
1139
-
1140
-==Options==
1141
-
1142
-: **-overwrite** (default off -- nothing is overwritten)
1143
-    Overwrite any existing cue/bin files matching //VCDIMAGER.xml//. Useful
1144
-    if you modified the xml file and wish to re-image or burn the new (S)VCD.
1145
-
1146
-: **-burn** (default off -- no images are burned)
1147
-    Burn the (S)VCD described by //VCDIMAGER.xml//.
1148
-
1149
-: **-device** //DEVICE// (default /dev/cdrw)
1150
-    Burn the disc image to //DEVICE//, the Linux device file-system
1151
-    name of your CD-recorder. Common examples might be /dev/cdrw,
1152
-    /dev/scd1, and /dev/hdc.
1153
-
1154
-: **-speed** //NUM// (default 12)
1155
-    Burn the disc at speed //NUM//.
1156
-
1157
-: **-quiet**
1158
-    Limit output to essential messages.
1159
-
1160
-
1161
-==Examples==
1162
-
1163
-: ``tovid vcd -burn -device /dev/cdrw foo.xml``
1164
-    Create the (S)VCD image and burn it to /dev/cdrw. This will
1165
-    automatically call vcdxbuild to make the image. If there is an existing
1166
-    image, it will be burned.
1167
-
1168
-: ``tovid vcd -overwrite foo.xml``
1169
-    Create the (S)VCD image and exit without burning. If the image
1170
-    already exists, then it is removed before re-imaging.
1171
-
1172
-
1173
-
1174
-=Command:postproc=
1175
-
1176
-**tovid postproc** is designed to do simple post-processing on MPEG video files, such
1177
-as those generated by tovid. It can adjust audio/video sync, and re-quantize
1178
-(shrink) without re-encoding.
1179
+    After burning, the DVD can be previewed by calling:
1180
+    //**xine** dvd:/path/to/output/directory//
1181
+    or:
1182
+    //**vlc** /path/to/output/directory//
1183
 
1184
 
1185
-==Usage==
1186
-
1187
-**tovid postproc** [//OPTIONS//] //IN_FILE// //OUT_FILE//
1188
-
1189
-
1190
-==Options==
1191
-
1192
-: **-audiodelay** //NUM//
1193
-    Delay the audio stream by //NUM// milliseconds. Use this if
1194
-    your final output has audio that is not synced with the
1195
-    video. For example, if the audio comes 2 seconds sooner than
1196
-    the video, use "-audiodelay 2000". Use a negative number for
1197
-    audio that comes later than the video.
1198
-
1199
-: **-normalize**
1200
-    Analyze the audio stream and then normalize the volume of the audio.
1201
-    This is useful if the audio is too quiet or too loud, or you want to
1202
-    make volume consistent for a bunch of videos. Similar to running
1203
-    normalize without any parameters. The default is -12dB average level
1204
-    with 0dB gain.
1205
-
1206
-: **-amplitude** //NUM//[dB]
1207
-    In addition to analyzing and normalizing, apply the gain to the audio
1208
-    such that the 'average' (RMS) sound level is //NUM//. Valid values
1209
-    range 0.0 - 1.0, with 0.0 being silent and 1.0 being full scale. Use
1210
-    //NUM//dB for a decibel gain below full scale (the default without
1211
-    -amplitude is -12dB).
1212
-
1213
-: **-shrink** //NUM//
1214
-    Shrink the video stream by a factor of //NUM//. May be a decimal
1215
-    value. A value of 1.0 means the video will be the same size;
1216
-    larger values cause more reduction in size. Beyond 2.0, the
1217
-    returns are diminishing.
1218
-
1219
-: **-parallel**
1220
-    Run all processes in parallel and pipe into multiplexer, should
1221
-    increase speed significantly.
1222
-
1223
-: **-debug**
1224
-    Save output in a temporary file, for later viewing if
1225
-    something goes wrong.
1226
-
1227
 
1228
 =Command:chapters=
1229
 
1230
 **tovid chapters** will start a GUI using mplayer to set chapter points in a
1231
-video.  Its only (mandatory) option is the path to a video file.
1232
+video.  If the video plays through and you want to add more chapters you can
1233
+press the play button again, but remember that new chapter points will be
1234
+appended (in correct sequential order).  It will display the resulting chapter
1235
+points, and also output to a terminal (useful for scripts).  As well it will
1236
+give the option of saving the chapters string to a text file.
1237
+
1238
+Note that the 'tovid gui' now features a similar widget when you press the
1239
+chapters button on the opening page.
1240
 
1241
 ==Examples==
1242
 : ``tovid chapters foo.avi``
1243
 
1244
-: ``tovid chapters /home/grepper/videos/foo.avi``
1245
+: ``chapters=$(tovid chapters /home/grepper/videos/foo.avi)``
1246
 
1247
 
1248
 =CONTACT=
1249
tovid-0.34.tar.bz2/libtovid/__init__.py -> tovid-0.35.tar.gz/libtovid/__init__.py Changed
49
 
1
@@ -3,29 +3,16 @@
2
 
3
 __all__ = [
4
     # Subdirectories
5
-    'backend',
6
-    'gui',
7
     'guis',
8
     'metagui',
9
-    'render',
10
-    'template',
11
-    'test',
12
-    'util',
13
     # .py files
14
-    'author',
15
     'cli',
16
-    'deps',
17
-    'encode',
18
     'odict',
19
-    'opts',
20
-    'rip',
21
-    'standard',
22
-    'stats',
23
     'utils',
24
-    'xml',
25
 ]
26
 
27
 import os
28
+from sys import version_info
29
 
30
 # Python < 3.x
31
 try:
32
@@ -34,6 +21,16 @@
33
 except ImportError:
34
     from configparser import ConfigParser
35
 
36
+# Python 3.x compatibility assignments
37
+if version_info[0] < 3: # python 3.x
38
+    unicode = unicode
39
+    basestring = basestring
40
+    xrange = xrange
41
+else: # Python 3.x
42
+    unicode = str
43
+    basestring = str
44
+    xrange = range
45
+
46
 # Configuration file reader/writer
47
 class Config (ConfigParser):
48
     """Interface for reading/writing tovid configuration files. Just a wrapper
49
tovid-0.34.tar.bz2/libtovid/cli.py -> tovid-0.35.tar.gz/libtovid/cli.py Changed
16
 
1
@@ -80,12 +80,9 @@
2
 import subprocess
3
 import signal
4
 import os
5
-
6
 # Small workaround for Python 3.x
7
-try:
8
-    _temp = unicode
9
-except NameError:
10
-    unicode = str
11
+from libtovid import unicode, basestring
12
+
13
 
14
 class ProgramNotFound (ValueError):
15
     """Raised when the program given to a command is not available.
16
tovid-0.34.tar.bz2/libtovid/guis/helpers.py -> tovid-0.35.tar.gz/libtovid/guis/helpers.py Changed
994
 
1
@@ -1,21 +1,29 @@
2
-import Tkinter as tk
3
 import time
4
 import shlex
5
-import commands
6
 import re
7
 import os
8
 import fnmatch
9
 from libtovid.metagui import *
10
 from libtovid.metagui.control import _SubList
11
 from libtovid.util import filetypes
12
-from subprocess import Popen, PIPE, STDOUT
13
-from tempfile import mkdtemp
14
+from subprocess import Popen, PIPE
15
+from tempfile import mkdtemp, mkstemp
16
+from sys import stdout
17
+
18
+try:
19
+    from commands import getstatusoutput, getoutput
20
+    import Tkinter as tk
21
+except ImportError:
22
+    # python 3
23
+    from subprocess import getstatusoutput, getoutput
24
+    import tkinter as tk
25
 
26
 __all__ = [ 'VideoGui', 'SetChapters', 'Chapters', 'strip_all', 'to_title',
27
 'find_masks', 'nodupes', 'video_filetypes', 'image_filetypes',
28
 'visual_filetypes', 'dvd_video_files', 'av_filetypes', 'sys_dir',
29
 'thumb_masks', 'home_dir', 'tovid_prefix', 'tovid_icon', 'os_path',
30
-'heading_text', '_files_and_titles', '_out' ]
31
+'heading_text', '_files_and_titles', '_out', 'CopyableInfo' ]
32
+
33
 
34
 class VideoGui(tk.Frame):
35
     """A basic GUI to play video files.  It runs mplayer in slave mode
36
@@ -24,7 +32,7 @@
37
     Without subclassing it only contains a 'play/pause button
38
     and an 'exit' button.
39
     """
40
-    def __init__(self, master, args='', title='', callback=None, style='popup'):
41
+    def __init__(self, master, args='', title='', callback=None):
42
         """Initialize GUI
43
 
44
            master
45
@@ -36,8 +44,6 @@
46
                the wm title given to the master widget.
47
            callback
48
                a function run at program exit, before cleanup of temp files
49
-           style
50
-               may be one of 'popup' (default), 'standalone', or 'embedded'(TBA)
51
         """
52
         tk.Frame.__init__(self, master)
53
 
54
@@ -50,98 +56,143 @@
55
             try:
56
                 self.master.title(title)
57
             except AttributeError:
58
-                print "Error: " + \
59
-                  "VideoGui master must be a root window for 'title' option"
60
+                print("Error: " + \
61
+                  "VideoGui master must be a root window for 'title' option")
62
         self.callback = callback
63
-        self.style = style
64
-                
65
+        self.v_width = 540
66
+        self.v_height = 405
67
         self.is_running = tk.BooleanVar()
68
         self.is_running.set(False)
69
         self.pauseplay = tk.StringVar()
70
-        self.pauseplay.set('play')
71
+        self.pauseplay.set('Play')
72
         # temporary directory for fifo and other mplayer files
73
+        self.make_tmps()
74
+        self.draw()
75
+
76
+    def make_tmps(self):
77
+        """Make temporary directory containing fifo for mplayer commmands,
78
+        editlist, and log
79
+        """
80
         self.tempdir = mkdtemp(prefix='tovid-')
81
         self.cmd_pipe = os.path.join(self.tempdir, 'slave.fifo')
82
         self.editlist = os.path.join(self.tempdir, 'editlist')
83
         os.mkfifo(self.cmd_pipe)
84
         self.log = os.path.join(self.tempdir, 'mplayer.log')
85
-        self.draw()
86
-
87
+        
88
     def draw(self):
89
         """Draw the GUI in self.master and get X11 identifier for container"""
90
         self.root_frame = tk.Frame(self)
91
         self.root_frame.pack(side='top', fill='both', expand=1, pady=20)
92
         self.container = tk.Frame(self.root_frame, bg='black', container=1, colormap='new')
93
+        self.container.configure(width=self.v_width, height=self.v_height, bg='black')
94
         self.container.pack()
95
         # X11 identifier for the container frame
96
         self.xid = self.tk.call('winfo', 'id', self.container)
97
-        # bindings for exit
98
-        if self.style == 'standalone':
99
-            self._root().protocol("WM_DELETE_WINDOW", self.confirm_exit)
100
-            self._root().bind('<Control-q>', self.confirm_exit)
101
         self.add_widgets()
102
 
103
     def add_widgets(self):
104
-        """
105
-        Add buttons to the VideoGui.  Override this to customize buttons.
106
+        """Add buttons to the VideoGui.  Override this to customize buttons.
107
         root_frame has 'grab_set()' applied to it so make sure widgets go
108
         into this frame or they will not be functional!
109
         This function is called in draw()
110
         """
111
         button_frame = tk.Frame(self.root_frame)
112
         button_frame.pack(side='bottom', fill='x', expand=1)
113
-        control_frame = tk.Frame(button_frame, borderwidth=1, relief='groove')
114
-        control_frame.pack()
115
-        exit_button = tk.Button(control_frame, command=self.exit_mplayer, text='exit')
116
-        pause_button = tk.Button(control_frame, command=self.pause,
117
+        self.control_frame = tk.Frame(button_frame, borderwidth=1, relief='groove')
118
+        self.control_frame.pack()
119
+        self.load_button = tk.Button(self.control_frame,
120
+            command=self.load, text='load video')
121
+        self.load_button.pack(side='left')
122
+        exit_button = tk.Button(self.control_frame, command=self.exit_mplayer, text='exit')
123
+        self.pause_button = tk.Button(self.control_frame, command=self.pause,
124
                           width=12, textvariable=self.pauseplay)
125
-        exit_button.pack(side='left')
126
-        pause_button.pack(side='left')
127
+        self.pause_button.pack(side='left')
128
+        exit_button.pack(side='left', padx=5)
129
+        self.mp_ctrls = [self.pause_button]
130
+        self.toggle_controls('disabled', self.mp_ctrls)
131
 
132
 
133
     def identify(self, video):
134
-        """
135
-        Get information about video from mplayer -identify.
136
+        """Get information about video from mplayer -identify.
137
         Called by set_container()
138
         """
139
         
140
-        output = commands.getoutput('mplayer -vo null -ao null -frames 5 \
141
-          -channels 6 -identify %s' %video)
142
-        return output
143
+        cmd = 'mplayer -vo null -ao null -frames 5 -channels 6 -identify'
144
+        cmd = shlex.split(cmd) + [video]
145
+        output = Popen(cmd, stdout=PIPE, stderr=PIPE)
146
+        return output.communicate()[0]
147
 
148
-    def set_container(self, video):
149
+    def load(self, event=None):
150
+        """Load a file to play in the GUI"""
151
+        try:
152
+            from tkFileDialog import askopenfilename
153
+        except ImportError:
154
+            # python 3
155
+            from tkinter.filedialog import askopenfilename
156
+        vid_name = askopenfilename()
157
+        if vid_name:
158
+            self.toggle_controls('normal', self.mp_ctrls)
159
+            if self.pauseplay.get() == 'Pause':
160
+                self.pauseplay.set('Play')
161
+            self.run(vid_name)
162
+
163
+    def set_container(self, video=None):
164
         """Get aspect ratio and set dimensions of video container.
165
            Called by run().
166
         """
167
-        if self.style == 'standalone':
168
-            v_width = 600
169
-        else:
170
-            v_width = 540
171
         media_info = self.identify(video)
172
-        asr = re.findall('ID_VIDEO_ASPECT=.*', media_info)
173
+        asr = re.findall('ID_VIDEO_ASPECT=.*', str(media_info))
174
         # get last occurence as the first is 0.0 with mplayer
175
         if asr:
176
             asr = sorted(asr, reverse=True)[0].split('=')[1]
177
-        try:
178
-            asr = float(asr)
179
-        except ValueError:
180
-            asr = 0.0
181
+            try:
182
+                asr = float(asr)
183
+            except ValueError:
184
+                asr = 0.0
185
         # get largest value as mplayer prints it out before playing file
186
         if asr and asr > 0.0:
187
-            v_height = int(v_width/asr)
188
+            v_height = int(self.v_width/asr)
189
         else:
190
             # default to 4:3 if identify fails
191
-            v_height = int(v_width/1.333)
192
-        self.container.configure(width=v_width, height=v_height)
193
+            v_height = int(self.v_width/1.333)
194
+        self.container.configure(width=self.v_width, height=v_height)
195
 
196
     def run(self, video):
197
         """Play video in this GUI using mplayer."""
198
+        if video == None:
199
+            self.toggle_controls('disabled', self.mp_ctrls)
200
+            return
201
+        elif not os.path.exists(video):
202
+            try:
203
+                from tkMessageBox import showerror
204
+            except ImportError:
205
+                from tkinter.messagebox import showerror
206
+            showerror('Oops', video + ' does not exist')
207
+            self.toggle_controls('disabled', self.mp_ctrls)
208
+            self.master.master.withdraw()
209
+        else:
210
+            self.toggle_controls('enabled', self.mp_ctrls)
211
+        # a new video has been loaded if no temp files, so make them
212
+        if not os.path.exists(self.tempdir):
213
+            self.make_tmps()
214
+        # set the container size, then run the video
215
         self.set_container(video)
216
         command =  'mplayer -wid %s -nomouseinput -slave \
217
           -input nodefault-bindings:conf=/dev/null:file=%s \
218
-          -edlout %s %s %s' \
219
-          %(self.xid, self.cmd_pipe, self.editlist, self.args, video)
220
-        self.command = shlex.split(command)
221
+          -edlout %s %s' \
222
+          %(self.xid, self.cmd_pipe, self.editlist, self.args)
223
+        self.command = shlex.split(command) + [video]
224
+
225
+    def toggle_controls(self, state, widgets):
226
+        """
227
+        Enable/disable mplayer control widgets
228
+        state is either 'normal' or 'disabled', widgets is an instance list
229
+        """
230
+        for widget in widgets:
231
+            try:
232
+                widget.configure(state=state)
233
+            except tk.TclError:
234
+                pass
235
 
236
     def poll(self):
237
         """
238
@@ -153,20 +204,24 @@
239
         """
240
         if not self.is_running.get():
241
             return
242
-        tail = 'tail -n 1 %s' %self.log
243
-        log_output = commands.getoutput(tail)
244
-        # restart mplayer with same commands if it exits without being sent
245
-        # an explict 'quit'.
246
-        if '(End of file)' in log_output:
247
-            self.on_eof()
248
-            # check for is_running again as on_oef() might set it to false
249
-            if self.is_running.get():
250
-                cmd = Popen(self.command, stderr=open(os.devnull, 'w'), \
251
-                  stdout=open(self.log, "w"))
252
-                if self.show_osd:
253
-                    self.send('osd 3\n')
254
-                self.pause()
255
-        self.master.after(200, self.poll)
256
+        f = open(self.log, 'r')
257
+        # seek to 50 bytes from end of file
258
+        try:
259
+            f.seek(-50, 2)
260
+            if '(End of file)' in f.read():
261
+                self.on_eof()
262
+                # check for is_running again as on_oef() might set it to false
263
+                if self.is_running.get():
264
+                    cmd = Popen(self.command, stderr=open(os.devnull, 'w'), \
265
+                      stdout=open(self.log, "w"))
266
+                    if self.show_osd:
267
+                        self.send('osd 3')
268
+                    self.pause()
269
+        # if file does not contain 50 bytes, do nothing
270
+        except IOError:
271
+            pass
272
+        self.master.after(100, self.poll)
273
+
274
 
275
     def on_eof(self):
276
         """
277
@@ -177,20 +232,20 @@
278
         pass
279
 
280
     def send(self, text):
281
-        """send command to mplayer's slave fifo"""
282
+        """Send command to mplayer's slave fifo"""
283
         if self.is_running.get():
284
-            commands.getstatusoutput('echo -e "%s"  > %s' %(text, self.cmd_pipe))
285
+            getstatusoutput('echo "%s"  > %s' %(text, self.cmd_pipe))
286
 
287
     def pause(self):
288
-        """send pause to mplayer via slave and set button var to opposite value"""
289
+        """Send pause to mplayer via slave and set button var to opposite value"""
290
         # mplayer's 'pause' pauses if playing and plays if paused
291
-        # pauseplay ==play in pause mode, and ==pause in play mode (button text)
292
+        # pauseplay ==Play in pause mode, and ==Pause in play mode (button text)
293
         if self.is_running.get():
294
-            if self.pauseplay.get() == 'pause':
295
-                self.pauseplay.set('play')
296
+            if self.pauseplay.get() == 'Pause':
297
+                self.pauseplay.set('Play')
298
             else:
299
-                self.pauseplay.set('pause')
300
-            self.send('pause\n')
301
+                self.pauseplay.set('Pause')
302
+            self.send('pause')
303
         else:
304
             # start the video for the 1st time
305
             cmd = Popen(self.command, stderr=open(os.devnull, 'w'), stdout=open(self.log, "w"))
306
@@ -198,32 +253,35 @@
307
             self.poll()
308
             # show osd time and remaining time
309
             if self.show_osd:
310
-                self.send('osd 3\n')
311
-            self.pauseplay.set('pause')
312
+                self.send('osd 3')
313
+            self.pauseplay.set('Pause')
314
 
315
-    def exit_mplayer(self):
316
+    def exit_mplayer(self): # called by [done] button
317
         """
318
         Close mplayer if it is running, then exit, running callback if it exists
319
         """
320
         # unpause so mplayer doesn't hang
321
         if self.is_running.get():
322
-            if self.pauseplay.get() == 'play':
323
-                self.send('mute 1\n')
324
-                self.send('pause\n')
325
-            self.send('quit\n')
326
+            if self.pauseplay.get() == 'Play':
327
+                self.send('mute 1')
328
+                self.send('pause')
329
+            self.send('quit')
330
             self.is_running.set(False)
331
         time.sleep(0.3)
332
         self.confirm_exit()
333
 
334
+    def confirm_msg(self):
335
+        mess = "osd_show_text 'please exit mplayer first' 4000 3"
336
+        if not self.show_osd:
337
+            self.send('osd 3\n%s' %mess)
338
+            self.after(2500, lambda:self.send('osd 0'))
339
+        else:
340
+            self.send(mess)
341
+
342
     def confirm_exit(self, event=None):
343
-        """on exit, make sure that mplayer is not running before quit"""
344
+        """On exit, make sure that mplayer is not running before quit"""
345
         if self.is_running.get():
346
-            mess = "osd_show_text 'please exit mplayer first' 4000 3\n"
347
-            if not self.show_osd:
348
-                self.send('osd 3\n%s' %mess)
349
-                self.after(2500, lambda:self.send('osd 0\n'))
350
-            else:
351
-                self.send(mess)
352
+            self.confirm_msg()
353
         else:
354
             # run any custom commands on exit
355
             if callable(self.callback):
356
@@ -234,15 +292,16 @@
357
                     os.remove(f)
358
             if os.path.exists(self.tempdir):
359
                 os.rmdir(self.tempdir)
360
-            if self.style == 'standalone':
361
-                self.quit()
362
-            else:
363
-                self.destroy()
364
+            self.quit()
365
+
366
+    def quit(self):
367
+        """Quit the application.  This detroys the root window, exiting Tkinter"""
368
+        self.destroy()
369
 
370
 
371
 class SetChapters(VideoGui):
372
-    """A GUI to set video chapter points using mplayer"""
373
-    def __init__(self, master, args='', title='', callback=None, style='popup'):
374
+    """Elements for a GUI to set video chapter points using Mplayer"""
375
+    def __init__(self, master, args='', title='', callback=None):
376
         """
377
         master
378
             Pack into this widget
379
@@ -252,75 +311,96 @@
380
             Window manager titlebar title (master must be root window for this)
381
         callback
382
             Function to run on application exit, run before temp file cleanup
383
-        style
384
-            Can one of: 'popup' (default), 'standalone', or 'embedded'(TBA)
385
         """
386
-        VideoGui.__init__(self, master, args, title, callback, style)
387
-
388
+        VideoGui.__init__(self, master, args, title, callback)
389
         self.chapter_var = tk.StringVar()
390
 
391
     def add_widgets(self):
392
+        """
393
+        Add buttons to the Gui. root_frame has 'grab_set()' applied to it so
394
+        make sure widgets go into this frame or they will not be functional!
395
+        This function is called in draw()
396
+        """
397
         # button frame and buttons
398
         button_frame = tk.Frame(self.root_frame)
399
         button_frame.pack(side='bottom', fill='x', expand=1)
400
-        control_frame = tk.Frame(button_frame, borderwidth=1, relief='groove')
401
-        control_frame.pack()
402
-        exit_button = tk.Button(control_frame, command=self.exit_mplayer, text='done !')
403
-        mark_button = tk.Button(control_frame, command=self.set_chapter,text='set chapter')
404
-        pause_button = tk.Button(control_frame, command=self.pause,
405
+        self.control_frame = tk.Frame(button_frame, borderwidth=1, relief='groove')
406
+        self.control_frame.pack()
407
+        exit_button = tk.Button(self.control_frame, command=self.exit_mplayer, text='done !')
408
+        mark_button = tk.Button(self.control_frame, command=self.set_chapter,text='set chapter')
409
+        pause_button = tk.Button(self.control_frame, command=self.pause,
410
                           width=12, textvariable=self.pauseplay)
411
-        framestep_button = tk.Button(control_frame, text='step >', command=self.framestep)
412
-        forward_button = tk.Button(control_frame, text='seek >', command=self.forward)
413
-        back_button = tk.Button(control_frame, text='< seek', command=self.back)
414
-        # seek frame and scale widget
415
-        seek_frame = tk.Frame(self.root_frame)
416
-        seek_frame.pack(side='left', fill='x', expand=1, padx=30)
417
-        self.seek_scale = tk.Scale(seek_frame, from_=0, to=100, tickinterval=10,
418
-        orient='horizontal', label='Use slider to seek to point in file (%)')
419
-        self.seek_scale.bind('<ButtonRelease-1>', self.seek)
420
+        framestep_button = tk.Button(self.control_frame, text='step>',
421
+                                                command=self.framestep)
422
+        forward_button = tk.Button(self.control_frame, text='>>',
423
+                                                command=self.forward)
424
+        fast_forward_button = tk.Button(self.control_frame, text='>>>',
425
+                                                command=self.fastforward)
426
+        back_button = tk.Button(self.control_frame, text='<<', command=self.back)
427
+        fast_back_button = tk.Button(self.control_frame, text='<<<', command=self.fast_back)
428
+#        self.seek_scale = tk.Scale(seek_frame, from_=0, to=100, tickinterval=10,
429
+#        orient='horizontal', label='Use slider to seek to point in file (%)')
430
+#        self.seek_scale.bind('<ButtonRelease-1>', self.seek)
431
         # pack the buttons and scale in their frames
432
         mark_button.pack(side='bottom', fill='both', expand=1)
433
-        self.seek_scale.pack(side='left', fill='x', expand=1)
434
+        #self.seek_scale.pack(side='left', fill='x', expand=1)
435
         exit_button.pack(side='left')
436
+        fast_back_button.pack(side='left')
437
         back_button.pack(side='left')
438
-        pause_button.pack(side='left')
439
+        pause_button.pack(side='left', expand=1)
440
         framestep_button.pack(side='left')
441
         forward_button.pack(side='left')
442
+        fast_forward_button.pack(side='left')
443
+        self.mp_ctrls = self.control_frame.winfo_children()
444
 
445
-    def seek(self, event=None):
446
-        """seek in video according to value set by slider"""
447
-        self.send('seek %s 3\n' %self.seek_scale.get())
448
+#    def seek(self, event=None):
449
+#        """Seek in video according to value set by slider"""
450
+#        self.send('seek %s 3\n' %self.seek_scale.get())
451
+#        self.after(500, lambda:self.seek_scale.set(0))
452
 
453
     def forward(self):
454
-        """seek forward 10 seconds and make sure button var is set to 'pause'"""
455
-        self.send('seek 10\n')
456
-        self.pauseplay.set('pause')
457
+        """Seek forward 10 seconds and make sure button var is set to 'Pause'"""
458
+        self.send('seek 10')
459
+        self.pauseplay.set('Pause')
460
+
461
+    def fastforward(self):
462
+        """Seek forward 5 minutes and make sure button var is set to 'Pause'"""
463
+        self.send('seek 300')
464
+        self.pauseplay.set('Pause')
465
 
466
     def back(self):
467
-        """seek backward 10 seconds and make sure button var is set to 'pause'"""
468
-        self.send('seek -10\n')
469
-        self.pauseplay.set('pause')
470
+        """Seek backward 10 seconds and make sure button var is set to 'Pause'"""
471
+        self.send('seek -10')
472
+        self.pauseplay.set('Pause')
473
+
474
+    def fast_back(self):
475
+        """Seek backward 10 seconds and make sure button var is set to 'Pause'"""
476
+        self.send('seek -300')
477
+        self.pauseplay.set('Pause')
478
 
479
     def framestep(self):
480
-        """step frame by frame forward and set button var to 'play'"""
481
-        self.send('pausing frame_step\n')
482
-        self.pauseplay.set('play')
483
+        """Step frame by frame forward and set button var to 'Play'"""
484
+        self.send('pausing frame_step')
485
+        self.pauseplay.set('Play')
486
 
487
     def set_chapter(self):
488
-        """send chapter mark (via slave) twice so mplayer writes the data.
489
+        """Send chapter mark (via slave) twice so mplayer writes the data.
490
            we only take the 1st mark on each line
491
         """
492
         for i in range(2):
493
-            self.send('edl_mark\n')
494
-        mess = "osd_show_text 'chapter point saved' 2000 3\n"
495
+            self.send('edl_mark')
496
+        mess = "osd_show_text 'chapter point saved' 2000 3"
497
         if not self.show_osd:
498
-            self.send('osd 3\n%s' %mess)
499
-            self.after(2500, lambda:self.send('osd 0\n'))
500
+            self.send('osd 3%s' %mess)
501
+            self.after(2500, lambda:self.send('osd 0'))
502
         else:
503
             self.send(mess)
504
 
505
 
506
     def get_chapters(self):
507
+        """Read mplayer's editlist to get chapter points and return
508
+        HH:MM:SS.xxx format string, comma separated
509
+        """
510
         # need a sleep to make sure mplayer gives up its data
511
         if not os.path.exists(self.editlist):
512
             return
513
@@ -328,8 +408,8 @@
514
         f = open(self.editlist)
515
         c = f.readlines()
516
         f.close()
517
-        # if chapter_var has value, editlist has been reset.  Append value, if any.
518
-        # only 1st value on each line is taken (2nd is to make mplayer write out)
519
+        # if chapter_var has value, editlist has been reset.  Append value.
520
+        # only 1st value on each line is taken (the 2nd makes mplayer write out)
521
         s = [ i.split()[0]  for i  in self.chapter_var.get().splitlines() if i]
522
         c.extend(s)
523
         times = [ float(shlex.split(i)[0]) for i in c ]
524
@@ -339,13 +419,127 @@
525
             chapters.append(time.strftime('%H:%M:%S', time.gmtime(t)) + fraction)
526
         if c:
527
             return '%s' %','.join(chapters)
528
+    
529
+    def on_eof(self):
530
+        """
531
+        Run when 'End of file' discovered in mplayer output by poll().
532
+        """
533
+        f = open(self.editlist)
534
+        self.chapter_var.set(f.read())
535
+        f.close()
536
+
537
+class SetChaptersGui(SetChapters):
538
+    """A standalone GUI to set video chapter points using SetChapters class"""
539
+    def __init__(self, master, args='', title='', callback=None):
540
+        """
541
+        master
542
+            Pack into this widget
543
+        args
544
+            Additional args to pass to mplayer
545
+        title
546
+            Window manager titlebar title (master must be root window for this)
547
+        callback
548
+            Function to run on application exit, run before temp file cleanup
549
+        """
550
+        SetChapters.__init__(self, master, args, title, callback)
551
+        self.callback = self.print_chapters
552
+        # bindings for exit
553
+        self._root().protocol("WM_DELETE_WINDOW", self.exit)
554
+        self._root().bind('<Control-q>', self.exit)
555
+
556
+
557
+    def add_widgets(self):
558
+        """Override add_widgets() from SetChapters, calling it first
559
+        then adding widgets to it
560
+        """
561
+        SetChapters.add_widgets(self)
562
+        self.result_frame = tk.Frame(self)
563
+        self.text_frame = tk.Frame(self.result_frame)
564
+        self.result_frame.pack(side='bottom', fill='x', expand=1)
565
+        self.text_frame.pack(side='bottom', fill='x', expand=1)
566
+        self.load_button = tk.Button(self.text_frame,
567
+            command=self.load, text='Load Video')
568
+        self.load_button.pack(side='left', padx=5)
569
+        self.entry = tk.Entry(self.text_frame)
570
+        self.entry.insert(0, "00:00:00.0")
571
+        self.entry.pack(side='left', fill='x', expand=1)
572
+        self.exit_button = tk.Button(self.text_frame,
573
+            command=self.exit, text='Exit')
574
+        self.exit_button.pack(side='left')
575
+        # keep a list of mplayer controls so we can disable/enable them later
576
+        self.mp_ctrls = self.control_frame.winfo_children()
577
+
578
+    def load(self, event=None):
579
+        """Load a file to play in the GUI"""
580
+        try:
581
+            from tkFileDialog import askopenfilename
582
+        except ImportError:
583
+            # python 3
584
+            from tkinter.filedialog import askopenfilename
585
+        vid_name = askopenfilename()
586
+        if vid_name:
587
+            self.toggle_controls('normal', self.mp_ctrls)
588
+            # reset entry to 0 and chapter_var if we have a new video loaded
589
+            self.entry.delete(0, tk.END)
590
+            self.entry.insert(0, "00:00:00.0")
591
+            if self.pauseplay.get() == 'Pause':
592
+                self.pauseplay.set('Play')
593
+            self.run(vid_name)
594
+
595
+    def print_chapters(self):
596
+        """
597
+        Run get_chapters(), output result to stdout, entry box, and write
598
+        to tempory file.  Disable mplayer controls.
599
+        This functions as the callback on mplayer exit.
600
+        """
601
+        if self.get_chapters():
602
+            try:
603
+                from tkMessageBox import askyesno, showinfo
604
+            except ImportError:
605
+                # python 3
606
+                from tkinter.messagebox import askyesno, showinfo
607
+            output = self.get_chapters()
608
+            stdout.write(output + '\n')
609
+            self.entry.delete(0, tk.END)
610
+            self.entry.insert(0, output)
611
+            self.toggle_controls('disabled', self.mp_ctrls)
612
+            string1 = "Chapter string will be saved to: "
613
+            string2 = '\nDo you wish to save it ?'
614
+            #string2 += '  Choose "Yes" to save it.'
615
+            # get basename of video, remove extension, add a '_'
616
+            vid = os.path.basename(self.command[-1]) + '_'
617
+            tmpfile = mkstemp(prefix=vid)
618
+            if askyesno(title="Save chapter string",
619
+              message= '%s%s%s' %(string1, tmpfile[1], string2)):
620
+                save_msg = "%s%s\n" %('Saved ', tmpfile[1])
621
+                showinfo(title='Chapters saved', message=save_msg)
622
+                if os.path.exists(tmpfile[1]):
623
+                    f = open(tmpfile[1], 'w')
624
+                    f.write(output)
625
+                    f.close()
626
+            else:
627
+                    os.remove(tmpfile[1])
628
+
629
+    def quit(self):
630
+        """Override quit() from base class, as standalone uses exit()"""
631
+        # disable controls, because tempdir has been deleted
632
+        self.toggle_controls('disabled', self.mp_ctrls)
633
+        if self.chapter_var.get():
634
+            self.chapter_var.set('')
635
+
636
+    def exit(self, event=None):
637
+        """Exit the GUI after confirming that mplayer is not running."""
638
+        if self.is_running.get():
639
+            self.confirm_msg()
640
+        else:
641
+            self.master.destroy()
642
 
643
 
644
 # class for control that allow setting chapter points
645
 class Chapters(ListToOne):
646
     """A popup version of the ListToOne Control, that also
647
-       allows setting chapter points with a mplayer GUI
648
-       (SetChapters).  This Control is specific to the tovid GUI.
649
+    allows setting chapter points with a mplayer GUI
650
+    (SetChapters).  This Control is specific to the tovid GUI.
651
     """
652
     def __init__(self,
653
                  parent,
654
@@ -359,9 +553,9 @@
655
                  text='',
656
                  **kwargs):
657
         """initialize Chapters
658
-           text
659
-               The text for the button that calls mplayer
660
-           For other options see help(control.ListToOne) 
661
+        text
662
+           The text for the button that calls mplayer
663
+        For other options see help(control.ListToOne) 
664
         """
665
         ListToOne.__init__(self, parent, label, option, default, help,
666
                           control, filter, side, **kwargs)
667
@@ -371,7 +565,7 @@
668
         self.top_height = 540
669
 
670
     def draw(self, master):
671
-        """initialize Toplevel popup, video/chapters lists, and mplayer GUI.
672
+        """Initialize Toplevel popup, video/chapters lists, and mplayer GUI.
673
         Only pack the video/chapter lists (_SubList).  Withdraw until called.
674
         """
675
         chapters_button = tk.Button(master, text='edit', command=self.popup)
676
@@ -387,7 +581,7 @@
677
         '   2. Or, use a different auto chapter value for each video.\n' + \
678
         'HH:MM:SS format:\n' + \
679
         '   1. Enter timecode for each video, eg. 00:00:00,00:05:00 ...\n' + \
680
-        '   2. Or use the "set with mplayer" button to use a GUI'
681
+        '   2. Or use the "set with mplayer" button to use a GUI.'
682
         self.top.label = tk.Label(self.top, text=txt, justify=tk.LEFT)
683
         self.top.label.pack(side=tk.TOP)
684
         self.top_button = tk.Button(self.top, text='Okay', command=self.top.withdraw)
685
@@ -413,14 +607,14 @@
686
 
687
     def get_geo(self, widget):
688
         """Get geometry of a widget.
689
-           Returns List (integers): width, height, Xpos, Ypos
690
+        Returns List (integers): width, height, Xpos, Ypos
691
         """
692
         geo = widget.winfo_geometry()
693
         return  [ int(x) for x in geo.replace('x', '+').split('+') ]
694
 
695
     def center_popup(self, master, width, height):
696
         """Get centered screen location of popup, relative to master.
697
-           Returns geometry string in form of 'WxH+Xpos+Ypos'
698
+        Returns geometry string in form of 'WxH+Xpos+Ypos'
699
         """
700
         root_width, root_height, rootx, rooty = self.get_geo(master)
701
         xoffset = (root_width - width) / 2
702
@@ -429,7 +623,7 @@
703
         return '%dx%d+%d+%d' %(width, height, rootx + xoffset, rooty + yoffset)
704
         
705
     def popup(self):
706
-            """popup the list of chapters, with button to run mplayer GUI"""
707
+            """Popup the list of chapters, with button to run mplayer GUI"""
708
             videolist = self.parent_listbox
709
             self.top.transient(self.parent._root())
710
             w = self.top_width
711
@@ -440,7 +634,7 @@
712
                 self.parent_listbox.select_index(0)
713
     
714
     def run_mplayer(self, event=None):
715
-        """run the mplayer GUI to set chapters"""
716
+        """Run the mplayer GUI to set chapters"""
717
         selected = self.parent_listbox.selected.get()
718
         if selected:
719
             # initialize mplayer GUI
720
@@ -460,9 +654,9 @@
721
             self.top.bind('<Escape>', self.mpl.confirm_exit)
722
 
723
     def on_exit(self):
724
-        """callback run when mplayer GUI exits. This sets the chapters list
725
-           to the timecodes set by the mplayer gui, repacks the label and the
726
-           list frame, sets/resets bindings, and releases the grab_set().
727
+        """Callback run when mplayer GUI exits. This sets the chapters list
728
+        to the timecodes set by the mplayer gui, repacks the label and the
729
+        list frame, sets/resets bindings, and releases the grab_set().
730
         """
731
         if self.mpl.get_chapters():
732
             self.control.variable.set(self.mpl.get_chapters())
733
@@ -477,11 +671,12 @@
734
         self.top.bind('<Escape>', self.withdraw_popup)
735
 
736
     def withdraw_popup(self, event=None):
737
+        """Withdraw the chapters popup window"""
738
         self.top.withdraw()
739
 
740
     def select(self, index, value):
741
         """Select an item in the list and enable editing.
742
-           List select method overriden in order to clear entry selection.
743
+        List select method overriden in order to clear entry selection.
744
         """
745
         List.select(self, index, value)
746
         # don't make it easy to erase a chapters string with a keypress
747
@@ -512,6 +707,185 @@
748
     [noDupes.append(i) for i in seq if not noDupes.count(i)]
749
     return noDupes
750
 
751
+def get_loadable_opts(opts):
752
+    good_opts = []
753
+    bad_opts = []
754
+    add_opt = False
755
+    for index, opt in enumerate(opts):
756
+        if opt.startswith('-'):
757
+            if opt in no_load_opts:
758
+                add_opt = False
759
+            else:
760
+                add_opt = True
761
+                # -colour is not loadable, but is a valid todisc option
762
+                if '-colour' in opt:
763
+                    opt = opt.replace('-colour','-color')
764
+        if add_opt:
765
+            good_opts.append(opt)
766
+        else:
767
+            bad_opts.append(opt)
768
+
769
+    return [good_opts, bad_opts]
770
+
771
+# this is part of the HACK in working around broken load_args
772
+# load_script was lifted from gui.py in metagui, with mods
773
+def load_script(filename):
774
+    #"""Load current script options and arguments from a text file.
775
+    #"""
776
+    # Read lines from the file and reassemble the command
777
+    command = ''
778
+    for line in open(filename, 'r'):
779
+        line = line.strip()
780
+        # Discard comment lines and PATH assignment
781
+        if line and not (line.startswith('#') or line.startswith('PATH=')):
782
+            command += line.rstrip('\\')
783
+    # Split the full command into arguments, according to shell syntax
784
+    args = shlex.split(command)
785
+
786
+    # Ensure the expected program is being run
787
+    program = args.pop(0)
788
+    if program != 'todisc':
789
+        raise ValueError("This script runs '%s', expected '%s'" %
790
+              (program, 'todisc'))
791
+    return args
792
+
793
+
794
+def filter_args(master=None, args=None):
795
+    # HACK
796
+    # we need to sanitize the GUI args as load_args in metagui is broken
797
+    # this function and imports of it can be removed when it is fixed
798
+    a = get_loadable_opts(args)
799
+    args = a[0]
800
+    if a[1]:
801
+        #import Tkinter as tk
802
+        from textwrap import dedent
803
+        heading = '''
804
+        The tovid GUI did not load some of your options.
805
+        This is normal as loading options externally
806
+        is experimental. Sorry for the inconvenience.
807
+
808
+        You can copy this for reference as you will need
809
+        to set the following options yourself in the GUI:
810
+
811
+        '''
812
+
813
+        #u = unloadable_opts[:]
814
+        #data = ['\n' + x + '\n' if x.startswith('-') else x for x in u]
815
+        nonloadable = []
816
+        for i in a[1]:
817
+            if i.startswith('-'):
818
+                nonloadable.append('\n' + i)
819
+            elif ' ' in i:
820
+                nonloadable.append("'" + i + "'")
821
+            else:
822
+                nonloadable.append(i)
823
+        #data = ' '.join(nonloadable)
824
+        master.title('Important!')
825
+        info_msg = CopyableInfo(master, 'Important', dedent(heading),
826
+                                     ' '.join(nonloadable), tovid_icon)
827
+        info_msg.mainloop()
828
+    return args
829
+
830
+
831
+from libtovid.metagui.support import show_icons
832
+from libtovid.metagui import Style
833
+class CopyableInfo(tk.Frame):
834
+    def __init__(self, master, title='', heading='', data='', icon=None):
835
+        tk.Frame.__init__(self, master)
836
+        self.pack()
837
+        master.minsize(300, 300)
838
+        text_frame = tk.Frame(self)
839
+        text_frame.pack(side='top')
840
+        style = Style()
841
+        inifile = os.path.expanduser('~/.metagui/config')
842
+        if os.path.exists(inifile):
843
+            style.load(inifile)
844
+            font = style.font or None
845
+        else:
846
+            font = None
847
+        text_widget = tk.Text(text_frame, width=50, height=20, wrap='word')
848
+        text_widget["bg"] = self.cget('background')
849
+        text_widget["relief"] = 'flat'
850
+        master["relief"] = 'flat'
851
+        if font:
852
+            text_widget["font"] = font
853
+        text_widget.pack(side='top', fill='both', expand=1)
854
+        text_widget.insert('1.0',heading)
855
+        #text_widget.bind("<1>", self.set_focus(self, text_widget))
856
+        text_widget.insert('end',data)
857
+        text_widget['state'] = 'disabled'
858
+        lines = int(text_widget.index('end-1c').split('.')[0]) 
859
+        text_widget['height'] = lines + 3
860
+        rclick = RightClickMenu(text_widget)
861
+        text_widget.bind("<3>", rclick)
862
+        exit_button = tk.Button(self, text='Close',
863
+                       command=lambda:self._quit())
864
+        #exit_button.focus_set()
865
+        exit_button.pack(side='bottom')
866
+        master.bind('<Control-q>', lambda event=None: self._quit())
867
+        master.bind('<Escape>', lambda event=None: self._quit())
868
+        if icon:
869
+            show_icons(self.master, icon)
870
+        master.update_idletasks() # update geometry
871
+        # center the popup
872
+        m = master
873
+        x = int((m.winfo_screenwidth() / 2) - (m.winfo_width() /2))
874
+        y = int((m.winfo_screenheight() / 2) - int((m.winfo_height() /2)))
875
+        master.geometry('+%s+%s' %(x, y))
876
+
877
+
878
+
879
+    def _quit(self, event=None):
880
+        self.master.destroy()
881
+        #self.master.destroy()
882
+
883
+
884
+class RightClickMenu(object):
885
+    # thanks to 'paperrobot' at:
886
+    #  http://paperrobot.wordpress.com for this gem
887
+    """
888
+    Simple widget to add basic right click menus to entry widgets.
889
+
890
+    usage:
891
+
892
+    rclickmenu = RightClickMenu(some_entry_widget)
893
+    some_entry_widget.bind("<3>", rclickmenu)
894
+
895
+    Replace all Tix references with Tkinter and this will still work fine.
896
+    """
897
+    def __init__(self, parent):
898
+        self.parent = parent
899
+        # bind Control-A to select_all() to the widget.  Others work ok without
900
+        self.parent.bind("<Control-a>", lambda e: self.select_all(), add='+')
901
+        self.parent.bind("<Control-A>", lambda e: self.select_all(), add='+')
902
+    def __call__(self, event):
903
+        # grab focus of the entry widget.  this way you can see
904
+        # the cursor and any marking selections
905
+        self.parent.focus_force()
906
+        self.build_menu(event)
907
+    def build_menu(self, event):
908
+        self.menu = tk.Menu(self.parent, tearoff=0)
909
+        #self.parent.bind("<Button-1>", self.close_menu)
910
+        #self.parent.bind("<Escape>", self.close_menu)
911
+        if self.parent.tag_ranges("sel"):
912
+            self.menu.add_command(
913
+                label="Copy",
914
+                command=lambda: self.parent.event_generate("<<Copy>>"))
915
+        else:
916
+            self.menu.add_command(label="Copy", state=tk.DISABLED)
917
+        self.menu.add_command(label="Cut", state=tk.DISABLED)
918
+        self.menu.add_command(label="Paste", state=tk.DISABLED)
919
+        # make things pretty with a horizontal separator
920
+        self.menu.add_separator()
921
+        self.menu.add_command(label="Select All", command=self.select_all)
922
+        self.menu.tk_popup(event.x_root, event.y_root)
923
+    def select_all(self):
924
+        self.parent.tag_add(tk.SEL, 1.0, tk.END)
925
+        # return 'break' because doesn't work otherwise.
926
+        return 'break'
927
+
928
+
929
+
930
 # List of file-type selections for Filename controls
931
 image_filetypes = [filetypes.image_files]
932
 image_filetypes.append(filetypes.all_files)
933
@@ -519,7 +893,7 @@
934
 # video file-types from filetypes needs some additions
935
 v_filetypes = 'm2v vob ts '
936
 v_filetypes += filetypes.get_extensions('video').replace('*.', '')
937
-v_filetypes += ' mp4 mpeg4 mp4v divx mkv ogv ogm ram rm rmvb wmv'
938
+v_filetypes += ' mp4 mpeg4 mp4v divx mkv ogv ogm ram rm rmvb wmv webm'
939
 vid_filetypes = filetypes.new_filetype('Video files', v_filetypes)
940
 video_filetypes = [vid_filetypes]
941
 video_filetypes += [filetypes.all_files]
942
@@ -537,6 +911,12 @@
943
 # Users can use their own thumb masks.  Add to thumb mask control drop-down
944
 masks = [ 'none', 'normal', 'oval', 'vignette', 'plectrum', 'arch', 'spiral', \
945
 'blob', 'star', 'flare' ]
946
+
947
+# some options can not be loaded by the gui:
948
+# options with multiple choices for args, for example: none, single, multiple
949
+# this is a list of 'unloadable' options for the GUI
950
+no_load_opts = ['-chapter-titles', '-menu-fade', '-loop', '-video-pause', '-group-video-pause', '-slide-blur', '-slide-border', '-slide-frame', '-chain-videos', '-showcase', '-titles-font-deco', '-chapters', '-subtitle-lang', '-audio-channel', '-audio-lang', '-seek', '-showcase-seek', '-bg-video-seek', '-bgvideo-seek', '-bg-audio-seek', '-bgaudio-seek', '-submenu-audio-seek', '-rotate-thumbs', '-tile3x1', '-tile-3x1', '-tile4x1', '-tile-4x1']
951
+
952
 # $PREFIX/lib/tovid is already added to end of PATH
953
 os_path = os.environ['PATH'].rsplit(':')
954
 sys_dir = os_path[-1] + '/masks'
955
@@ -544,11 +924,16 @@
956
 for dir in sys_dir, home_dir:
957
     masks.extend(find_masks(dir, '*.png'))
958
 thumb_masks =  '|'.join(nodupes(masks))
959
-tovid_prefix = commands.getoutput('tovid -prefix')
960
+tovid_prefix = getoutput('tovid -prefix')
961
 tovid_icon = os.path.join(tovid_prefix, 'lib', 'tovid', 'tovid.png')
962
 
963
+# default heading text for tovid GUI (opening pane)
964
+heading_text = 'You can author (and burn) a DVD with a simple menu '
965
+heading_text += 'using ONLY this "Basic" pane\n'
966
+heading_text += 'Required: video files (and/or slideshows) and "Output name"'
967
+
968
 ### configuration for titleset wizard ( 'tovid titlesets' )
969
-wizard = os.getenv('METAGUI_WIZARD')
970
+wizard = os.getenv('METAGUI_WIZARD') or '0'
971
 if wizard == '1':
972
     # General options
973
     heading_text = 'General options applying to all titlesets.\n'
974
@@ -562,10 +947,6 @@
975
     # titleset options
976
     heading_text = 'Options for titleset %s\n' %(int(wizard) - 2)
977
     heading_text += 'Required: 1 or more videos and/or slideshows'
978
-else:
979
-    heading_text = 'You can author (and burn) a DVD with a simple menu '
980
-    heading_text += 'using ONLY this "Basic" pane\n'
981
-    heading_text += 'Required: video files (and/or slideshows) and "Output name"'
982
 
983
 if wizard == '2':
984
     # Root menu options
985
@@ -586,7 +967,7 @@
986
         Text(),
987
         filter=to_title)
988
 
989
-if wizard and wizard != '1':
990
+if int(wizard) and wizard != '1':
991
     # 'Output name' only for General Options ( '1' )
992
     _out = Label(' ')
993
 else:
994
tovid-0.34.tar.bz2/libtovid/guis/todisc.py -> tovid-0.35.tar.gz/libtovid/guis/todisc.py Changed
238
 
1
@@ -3,7 +3,11 @@
2
 """A GUI for the todisc command-line program.
3
 """
4
 
5
-import Tkinter as tk
6
+try:
7
+    import Tkinter as tk
8
+except ImportError:
9
+    # python 3
10
+    import tkinter as tk
11
 
12
 # Get supporting classes from libtovid.metagui
13
 from libtovid.metagui import *
14
@@ -75,11 +79,10 @@
15
     Number('Columns', '', 13, '', 0, 13))
16
 
17
 _quick_menu = Flag('Quick menu (may need a menu video)',
18
-    '-quick-menu', False, 'Note: may not be available in your ffmpeg '
19
-    'as the needed "vhooks" have been deprecated. Ten times faster than '
20
-    'normal showcase animation.  A showcase or background video is required '
21
-    'unless doing switched menus.  Menu links are text only.  Not compatible '
22
-    'with wave or rotate options.')
23
+    '-quick-menu', False, 'Note: you need a recent ffmpeg with the "movie" '
24
+    'filter enabled. Ten times faster than normal showcase animation.  A '
25
+    'showcase or background video is required unless doing switched menus.  '
26
+    'Menu links are text only.  Not compatible with wave or rotate options.')
27
 
28
 _switched_menus = Flag('Switched menus (try with "Quick menu" !)',
29
     '-switched-menus', False,
30
@@ -377,8 +380,9 @@
31
 _thumb_shape = Choice('Thumb shape', '-thumb-shape', 'none',
32
     'Apply a shaped transparency mask to thumbnail videos or images.  These '
33
     '"feathered" shapes look best against a plain background or used with '
34
-    '**-thumb-mist** [COLOR].  To use a "mist" background behind each thumb, '
35
+    '-thumb-mist [COLOR].  To use a "mist" background behind each thumb, '
36
     'see "Thumb mist" section.  No frame will be used for this option.  '
37
+    'See "man tovid" (-thumb-shape) for info on how to add your own masks.'
38
     'Leave at "none" to not use a feathered shape.',
39
     thumb_masks, 'dropdown')
40
 
41
@@ -449,8 +453,11 @@
42
     '(4 videos only).  Not a showcase option.')
43
 
44
 _align = Choice('Align', '-align', 'north',
45
-    'Controls positioning of the thumbnails and their titles.  '
46
-    'With some arrangements this will have limited effects however.',
47
+    'Controls positioning of the thumbnails (if any) and video titles.  '
48
+    'With some arrangements this will have limited effects however.'
49
+    'For example only north|south|center can be used with the default montage '
50
+    'of thumbs arrangement, or with showcase with thumb arrangement. '
51
+    'It will be most effective with single column showcase and textmenu styles',
52
     'north|south|east|west|center', 'dropdown')
53
 
54
 _seek = SpacedText('Thumbnail seek(s)', '-seek', '',
55
@@ -458,16 +465,19 @@
56
     'A single value or space separated list, 1 value per video.  '
57
     'Also used for seeking in switched menus.')
58
 
59
+_user_thumbs = List('Image(s)', '-user-thumbs', None,
60
+    'Images for thumbnails.  This option requires one image for each title.',
61
+    Filename('', filetypes=image_filetypes))
62
 
63
 ### --------------------------------------------------------------------
64
 ### Fonts and font colors
65
 ### --------------------------------------------------------------------
66
 
67
 # Menu title font
68
-_menu_font = Font('', '-menu-font', 'Helvetica',
69
+_menu_font = Font('', '-title-font', 'Helvetica',
70
     'The font to use for the menu title')
71
 
72
-_menu_fontsize = Number('Size', '-menu-fontsize', 24,
73
+_menu_fontsize = Number('Size', '-title-fontsize', 24,
74
     'The font size to use for the menu title',
75
     0, 80, 'pixels', toggles=True)
76
 
77
@@ -492,6 +502,9 @@
78
 # Video title font
79
 _titles_font = Font('', '-titles-font', 'Helvetica',
80
     'The font to use for the video titles')
81
+# unused FIXME
82
+_titles_font_deco = SpacedText('Custom font decoration', '', '',
83
+         'Space-separated list of custom options to imagemagick.'),
84
 
85
 _titles_fontsize = Number('Size', '-titles-fontsize', 12,
86
     'The font size to use for the video titles.  '
87
@@ -779,10 +792,11 @@
88
             ),
89
             VPanel('Backgrounds',
90
                 VPanel('Image or video options',
91
-                    _bgvideo_seek,
92
-                    _bg_color),
93
+                    HPanel('', _bgvideo_seek,
94
+                    _bg_color)),
95
                 VPanel('Audio options',
96
                     HPanel('',  _bgaudio_seek, _menu_audio_fade)),
97
+                HPanel('Menu alignment', _align),
98
             ),
99
         ),
100
     ),
101
@@ -872,7 +886,7 @@
102
         HPanel('',
103
             Number('Number of slides shown on menu', '-menu-slide-total', 0,
104
                 'Use this many slides for making the slideshow menu. '
105
-                'The default is to use all the slides given.',
106
+                'Leave at 0 for default: use all slides given.',
107
                 0, 100),
108
             _submenu_slide_total,
109
         ),
110
@@ -906,10 +920,16 @@
111
 slideshows = Tabs('Slideshows', *tab_list)
112
 
113
 
114
-thumbnails = VPanel("Thumbnails",
115
+thumbnails = Tabs("Thumbnails",
116
+    VPanel('Menu link thumbnails',
117
+    VPanel('',
118
     HPanel('',
119
-        VPanel('Menu link thumbnails',
120
-            HPanel('Seeking', _seek),
121
+        VPanel('',
122
+            HPanel('',
123
+            VPanel('Aspect ratio', Label('Automatic: force video ratio on "Playback" tab')),
124
+            VPanel('Seeking', _seek),
125
+            ),
126
+            HPanel('',
127
             VPanel("Effects",
128
                 HPanel('',_opacity, Label('(Also affects showcase thumb)')),
129
                 HPanel('', _blur, _3dthumbs),
130
@@ -920,11 +940,21 @@
131
                 _thumb_framesize,
132
                 _thumb_frame_color,
133
                 _thumb_columns,
134
-                _align,
135
+            ),
136
                 ),
137
         ),
138
+    ),
139
+    VPanel('User supplied thumbs',
140
+    VPanel('',
141
+    Label("Use this only if you want to substitute your own thumbs for default thumbnails.", 'center'),
142
+    _user_thumbs,
143
+    ),
144
+    ),
145
+    ),
146
+    ),
147
         VPanel("Showcase thumbnail",
148
             HPanel('Seeking', _showcase_seek),
149
+            HPanel('',
150
             VPanel('Effects',
151
                 _wave,
152
                 HPanel('', _showcase_blur, _3dshowcase),
153
@@ -936,9 +966,7 @@
154
                 _showcase_frame_color,
155
                 _showcase_geo),
156
         ),
157
-    ),
158
-    HPanel('Aspect ratio', Label('Note: the aspect ratio of menu link '
159
-        'thumbnails is automatic: (force video ratio on "Playback" tab)')),
160
+        ),
161
 )
162
 
163
 from libtovid.guis import tovid
164
@@ -975,23 +1003,68 @@
165
 
166
 encoding = VPanel('Encoding',
167
     Label("\nVideo re-encoding options - you may leave these at defaults.", 'center'),
168
-    Tabs('tovid options',
169
+    Tabs('',
170
         tovid.BASIC_OPTS,
171
         tovid.VIDEO,
172
         tovid.AUDIO,
173
         tovid.BEHAVIOR,
174
     ),
175
-    SpacedText('Custom makempg options', '', '',
176
+    Flag('Encode only', '-encode-only', False,
177
+    'Use this GUI for encoding only.  On the Main tab, load files and '
178
+    'select an out filename'),
179
+    SpacedText('Custom makempg ("tovid mpg") options', '', '',
180
          'Space-separated list of custom options to pass to makempg.'),
181
+    
182
 )
183
 
184
 ### --------------------------------------------------------------------
185
 
186
-def run(args=None):
187
+def run(args=None, position='', project=''):
188
+    from libtovid.guis.helpers import get_loadable_opts, load_script
189
+    import os
190
+    # if the first arg is a text file, treat it as a script and try to load
191
+    # the options from it as a list into args
192
+    # load_script from helpers overrides load_script from gui.py as the latter
193
+    # suffers from the load_args bug mentioned in that file.
194
+    if args:
195
+        script = args[0]
196
+        if not script.startswith('-'):
197
+            try:
198
+                from commands import getoutput 
199
+            except ImportError:
200
+            # python 3
201
+                from subprocess import getoutput 
202
+            if os.path.exists(script) \
203
+              and 'text' in getoutput('file %s' %script):
204
+                script = args.pop(0)
205
+                args.extend(load_script(script))
206
+    # now check if we have unloadable options, this first call does only that
207
+    # this will return 2 lists, [0] is loadable and [1] is unloadable
208
+    # probably don't want to do this anyway, as filter_args will just return
209
+    # the args it is sent if none are unloadable
210
+    a = get_loadable_opts(args)
211
+    if a[1]:
212
+        from libtovid.guis.helpers import filter_args
213
+        r = tk.Tk()
214
+        args = filter_args(r, args)
215
+    # workaround for netbooks (could use xrandr perhaps, but this works fine)
216
+    gui_width, gui_height = 800, 660
217
+    root = tk.Tk()
218
+    root.withdraw()
219
+    root.update_idletasks()
220
+    screen_height = root.winfo_screenheight()
221
+    # insure screen is not 800x600 or somesuch which doesn't work for gui anyway
222
+    # need float like 1.3333333 that we multiply * 100 and convert back to int
223
+    screen_width = float(root.winfo_screenwidth())
224
+    if int(screen_height) < 660 and not int(screen_width / screen_height * 100) == 133:
225
+        gui_height = 600
226
+    root.destroy()
227
+
228
+    # finally, run it
229
     app = Application('todisc',
230
         main, main_menu, submenus, thumbnails, slideshows, playback, behavior, encoding)
231
-    gui = GUI("tovid gui", 800, 660, app, icon=tovid_icon)
232
-    gui.run(args)
233
+    gui = GUI("tovid gui", gui_width, gui_height, app, icon=tovid_icon, position=position)
234
+    gui.run(args, script=project)
235
 
236
 if __name__ == '__main__':
237
 
238
tovid-0.34.tar.bz2/libtovid/guis/tovid.py -> tovid-0.35.tar.gz/libtovid/guis/tovid.py Changed
10
 
1
@@ -78,7 +78,7 @@
2
     0, 4400, units='MiB')
3
 
4
 # Encoder options
5
-_mplayeropts = SpacedText('mplayer options', '-mplayeropts', '', 'TODO: Tooltip')
6
+_mplayeropts = Text('mplayer options', '-mplayeropts', '', 'TODO: Tooltip')
7
 _filters = Choice('mplayer filters', '-filters', 'none', 'TODO: Tooltip',
8
     'none|denoise|deblock|contrast|all', side='top')
9
 _ffmpeg = Flag('Encode using ffmpeg', '-ffmpeg', False)
10
tovid-0.34.tar.bz2/libtovid/metagui/control.py -> tovid-0.35.tar.gz/libtovid/metagui/control.py Changed
48
 
1
@@ -28,9 +28,11 @@
2
     def any(iterable):
3
         """Return True if bool(x) is True for any x in iterable."""
4
         for item in iterable:
5
-            if not item:
6
-                return False
7
-        return True
8
+            if item:
9
+                return True
10
+        return False
11
+
12
+             
13
 
14
 # Python < 3.x
15
 try:
16
@@ -45,6 +47,9 @@
17
         (asksaveasfilename, askopenfilename, askopenfilenames)
18
     from tkinter.colorchooser import askcolor
19
 
20
+# Python 3.x
21
+from libtovid import basestring
22
+
23
 from libtovid.metagui.widget import Widget
24
 from libtovid.metagui.variable import VAR_TYPES, ListVar
25
 from libtovid.metagui.support import \
26
@@ -472,7 +477,10 @@
27
         """Event handler to update the color preview.
28
         """
29
         color = self.variable.get().strip()
30
-        self.set(color)
31
+        try:
32
+            self.set(color)
33
+        except (ValueError):
34
+            pass
35
 
36
 
37
     def pick_color(self):
38
@@ -1000,7 +1008,8 @@
39
     def next_item(self, event):
40
         """Select the next item in the parent listbox.
41
         """
42
-        self.parent_list.listbox.next_item(event)
43
+        if self.parent_list is not None:
44
+            self.parent_list.listbox.next_item(event)
45
 
46
 
47
 class SpacedText (Text):
48
tovid-0.34.tar.bz2/libtovid/metagui/gui.py -> tovid-0.35.tar.gz/libtovid/metagui/gui.py Changed
281
 
1
@@ -11,32 +11,35 @@
2
 import tempfile
3
 import shlex
4
 import subprocess
5
-from sys import exit
6
+from sys import exit, argv
7
 
8
 # Python < 3.x
9
 try:
10
+    import Tix
11
     import Tkinter as tk
12
     from ScrolledText import ScrolledText
13
-    from tkFileDialog import \
14
-        (asksaveasfilename, askopenfilename)
15
     from tkMessageBox import showinfo, showerror
16
-    import Tix
17
+    from tkFileDialog import (
18
+      asksaveasfilename, askopenfilename
19
+      )
20
 
21
 # Python 3.x
22
 except ImportError:
23
     import tkinter as tk
24
+    import tkinter.tix as Tix
25
     from tkinter.scrolledtext import ScrolledText
26
-    from tkinter.filedialog import \
27
-        (asksaveasfilename, askopenfilename)
28
     from tkinter.messagebox import showinfo, showerror
29
-    import tkinter.tix as Tix
30
+    from tkinter.filedialog import (
31
+      asksaveasfilename, askopenfilename
32
+      )
33
 
34
 from libtovid import cli
35
 from libtovid.metagui.widget import Widget
36
 from libtovid.metagui.panel import Panel, Tabs
37
-from libtovid.metagui.support import \
38
-    (ConfigWindow, Style, ensure_type, askyesno, get_photo_image, show_icons)
39
 from libtovid.metagui.control import Control, NoSuchControl
40
+from libtovid.metagui.support import (
41
+  ConfigWindow, Style, ensure_type, askyesno, get_photo_image, show_icons
42
+  )
43
 
44
 
45
 DEFAULT_CONFIG = os.path.expanduser('~/.metagui/config')
46
@@ -210,6 +213,7 @@
47
             self.notify("Output saved to '%s'" % filename)
48
 
49
 
50
+from textwrap import dedent
51
 class Application (Widget):
52
     """Graphical frontend for a command-line program
53
     """
54
@@ -246,10 +250,14 @@
55
         """Draw the Application in the given master.
56
         """
57
         Widget.draw(self, master)
58
+        self.master = master
59
         # Draw all panels as tabs
60
         self.tabs = Tabs('', *self.panels)
61
         self.tabs.draw(self)
62
         self.tabs.pack(anchor='n', fill='both', expand=True)
63
+        # need to wait until draw is called before setting this variable
64
+        self.script = tk.StringVar()
65
+        self.script.set('')
66
 
67
 
68
     def draw_toolbar(self, config_function, exit_function):
69
@@ -328,6 +336,13 @@
70
             self.executor.notify("Cancelled.")
71
             self.toolbar.enable()
72
 
73
+    def set_scriptname(self, name):
74
+        """Set script filename.  Called externally, this sets the variable
75
+        that used used for save_exit() as well as the 'initial file' for
76
+        prompt_save_script().
77
+        """
78
+        self.script.set(name)
79
+
80
 
81
     def prompt_save_script(self):
82
         """Prompt for a script filename, then save the current
83
@@ -336,7 +351,8 @@
84
         # TODO: Make initialfile same as last saved script, if it exists
85
         filename = asksaveasfilename(parent=self,
86
             title="Select a filename for the script",
87
-            initialfile='%s_commands.bash' % self.program)
88
+            #initialfile='%s_commands.bash' % self.program)
89
+            initialfile=self.script.get() or '%s_commands.bash' % self.program)
90
 
91
         if not filename:
92
             return
93
@@ -347,20 +363,34 @@
94
             showerror(title="Error", message="Failed to save '%s'" % filename)
95
             raise
96
         else:
97
+            saved_script = os.path.split(filename)[1]
98
             showinfo(title="Script saved", message="Saved '%s'" % filename)
99
 
100
 
101
     def save_exit(self):
102
-        filename = os.getcwd() + os.path.sep + '%s_commands.bash' % self.program
103
+        """Save current command to script and exit, without prompt
104
+        """
105
+        # hack for titleset wizard to get gui's screen position
106
+        from sys import stderr
107
+        stderr.write("%s %+d%+d" 
108
+          %('gui position', self._root().winfo_x(), self._root().winfo_y()))
109
+
110
+        default = os.getcwd() + os.path.sep + '%s_commands.bash' % self.program
111
+        filename = self.script.get() or default
112
         self.save_script(filename)
113
-        # exit code borrowed from apache so wizard knows it has a file to read
114
-        exit(200)
115
+        exit()
116
 
117
 
118
     def prompt_load_script(self):
119
-        """Prompt for a script filename, then load current Control settings
120
-        from that file.
121
+        """Prompt for script filename; reload gui with current Control settings
122
         """
123
+        #"""Prompt for a script filename, then load current Control settings
124
+        #from that file.
125
+        #"""
126
+        # Hack: This is broken (commented section), presumably because of
127
+        # load_args limitations. This hack fixes it for libtovid, but does not
128
+        # belong in metagui.  So refactor this when load_args is fixed.
129
+        # see http://code.google.com/p/tovid/issues/detail?id=121
130
         filename = askopenfilename(parent=self,
131
             title="Select a shell script or text file to load",
132
             filetypes=[('Shell scripts', '*.sh *.bash'),
133
@@ -368,15 +398,23 @@
134
 
135
         if not filename:
136
             return
137
-
138
+        # begin Hack
139
+        geometry = self._root().winfo_x(), self._root().winfo_y()
140
+        command = argv[0]
141
         try:
142
-            self.reset()
143
-            self.load_script(filename)
144
+            cmd = command, '--position', '+%s+%s' %geometry, filename
145
+            os.execlp(cmd[0], *cmd)
146
         except:
147
-            showerror(title="Error", message="Failed to load '%s'" % filename)
148
+            showerror(title="Error", message="Failed load '%s'" %filename)
149
             raise
150
-        else:
151
-            showinfo(title="Script loaded", message="Loaded '%s'" % filename)
152
+        #try:
153
+        #    self.reset()
154
+        #    self.load_script(filename)
155
+        #except:
156
+        #    showerror(title="Error", message="Failed to load '%s')
157
+        #    raise
158
+        #else:
159
+        #    showinfo(title="Script loaded", message="Loaded '%s'" % filename)
160
 
161
 
162
     def save_script(self, filename):
163
@@ -398,26 +436,29 @@
164
 
165
 
166
     def load_script(self, filename):
167
-        """Load current Control settings from a text file.
168
-        """
169
+        # this is now disabled and its functionality passed to guis.helpers.py
170
+        # see http://code.google.com/p/tovid/issues/detail?id=121
171
+        pass
172
+        #"""Load current Control settings from a text file.
173
+        #"""
174
         # Read lines from the file and reassemble the command
175
-        command = ''
176
-        for line in open(filename, 'r'):
177
-            line = line.strip()
178
+        #command = ''
179
+        #for line in open(filename, 'r'):
180
+        #    line = line.strip()
181
             # Discard comment lines and PATH assignment
182
-            if line and not (line.startswith('#') or line.startswith('PATH=')):
183
-                command += line.rstrip('\\')
184
+        #    if line and not (line.startswith('#') or line.startswith('PATH=')):
185
+        #        command += line.rstrip('\\')
186
         # Split the full command into arguments, according to shell syntax
187
-        args = shlex.split(command)
188
+        #args = shlex.split(command)
189
 
190
         # Ensure the expected program is being run
191
-        program = args.pop(0)
192
-        if program != self.program:
193
-            raise ValueError("This script runs '%s', expected '%s'" %
194
-                  (program, self.program))
195
+        #program = args.pop(0)
196
+        #if program != self.program:
197
+        #    raise ValueError("This script runs '%s', expected '%s'" %
198
+        #          (program, self.program))
199
         # Load the rest of the arguments
200
-        self.load_args(args)
201
-        print("Done reading '%s'" % filename)
202
+        #self.load_args(args)
203
+        #print("Done reading '%s'" % filename)
204
 
205
 
206
     # TODO: Relocate all this stuff into Control and its subclasses
207
@@ -484,6 +525,8 @@
208
                 Name of an .ini-formatted file with GUI configuration
209
             icon
210
                 Full path to an image to use as the titlebar icon
211
+            position
212
+                position on screen: '+X+Y'
213
         """
214
         Tix.Tk.__init__(self)
215
 
216
@@ -491,19 +534,20 @@
217
         ensure_type("GUI needs Application", Application, application)
218
         self.application = application
219
 
220
+        # Get keyword arguments
221
+        self.inifile = kwargs.get('inifile', DEFAULT_CONFIG)
222
+        self.icon_file = kwargs.get('icon', None)
223
+        self.position = kwargs.get('position', '')
224
+
225
         # Set main window attributes
226
-        self.geometry("%dx%d" % (width, height))
227
+        self.geometry("%dx%d%s" % (width, height, self.position))
228
         self.title(title)
229
         self.width = width
230
         self.height = height
231
 
232
-        # Get keyword arguments
233
-        self.inifile = kwargs.get('inifile', DEFAULT_CONFIG)
234
-        self.icon_file = kwargs.get('icon', None)
235
-
236
         self.style = Style()
237
         if os.path.exists(self.inifile):
238
-            print("Loading style from config file: '%s'" % self.inifile)
239
+            print("Loading style from the config file: '%s'" % self.inifile)
240
             self.style.load(self.inifile)
241
         else:
242
             print("Creating config file: '%s'" % self.inifile)
243
@@ -519,11 +563,14 @@
244
         self.bind('<Control-q>', self.confirm_exit)
245
 
246
 
247
-    def run(self, args=None):
248
+    def run(self, args=None, script=''):
249
         """Run the GUI and enter the main event handler.
250
         This function does not return until the GUI is closed.
251
+        args: arguments to the programe being run
252
+        script: a filename to save the GUI command output to
253
         """
254
         self.draw()
255
+        
256
         if args:
257
             # If first argument looks like a filename, load
258
             # a script from that file
259
@@ -541,6 +588,9 @@
260
             # If more args remain, load those too
261
             if args:
262
                 self.application.load_args(args)
263
+            # if a script/project name was provided, set it in 'application'
264
+        if script:
265
+            self.application.set_scriptname(script)
266
 
267
         # Enter the main event handler
268
         self.mainloop()
269
@@ -581,6 +631,11 @@
270
     def confirm_exit(self, event=None):
271
         """Exit the GUI, with confirmation prompt.
272
         """
273
+        # Hack to sync titleset wizard's position with exiting GUI's position
274
+        if os.getenv('METAGUI_WIZARD'):
275
+            from sys import stderr
276
+            stderr.write("%s %+d%+d" 
277
+            %('gui position', self._root().winfo_x(), self._root().winfo_y()))
278
         if askyesno(message="Exit?"):
279
             self.quit()
280
 
281
tovid-0.34.tar.bz2/libtovid/metagui/panel.py -> tovid-0.35.tar.gz/libtovid/metagui/panel.py Changed
20
 
1
@@ -19,14 +19,15 @@
2
 except ImportError:
3
     import tkinter as tk
4
 
5
+from base64 import b64encode
6
 from libtovid import cli
7
 from libtovid.odict import Odict
8
 from libtovid.metagui.widget import Widget
9
 from libtovid.metagui.control import Control, Flag
10
-from libtovid.metagui.support import \
11
-    (ComboBox, ensure_type, divide_list, get_photo_image)
12
 from libtovid.metagui.variable import ListVar
13
-from base64 import b64encode
14
+from libtovid.metagui.support import (
15
+  ComboBox, ensure_type, divide_list, get_photo_image
16
+  )
17
 
18
 
19
 class Label (Widget):
20
tovid-0.34.tar.bz2/libtovid/metagui/support.py -> tovid-0.35.tar.gz/libtovid/metagui/support.py Changed
18
 
1
@@ -43,6 +43,16 @@
2
     import tkinter.tix as Tix
3
     import tkinter.font as tkFont
4
 
5
+# Python 2.4
6
+try:
7
+    all
8
+except NameError:
9
+    def all(iterable):
10
+        for element in iterable:
11
+            if not element:
12
+                return False
13
+        return True
14
+
15
 from libtovid import cli
16
 from libtovid.util import imagemagick_fonts
17
 from libtovid.metagui.variable import ListVar
18
tovid-0.34.tar.bz2/libtovid/metagui/widget.py -> tovid-0.35.tar.gz/libtovid/metagui/widget.py Changed
11
 
1
@@ -12,6 +12,9 @@
2
 except ImportError:
3
     import tkinter as tk
4
 
5
+# Python 3 compatibility
6
+from libtovid import basestring
7
+
8
 class Widget (tk.Frame):
9
     """Generic metagui widget, suitable for Controls, Panels, etc.
10
     """
11
tovid-0.34.tar.bz2/libtovid/util/__init__.py -> tovid-0.35.tar.gz/libtovid/util/__init__.py Changed
43
 
1
@@ -24,6 +24,8 @@
2
 import doctest
3
 import mimetypes
4
 import tempfile
5
+# Python 3 compatibility
6
+from libtovid import basestring, unicode
7
 
8
 # Special characters that may need escaping
9
 special_chars = '\\ #*:;&?!<>[]()"\''
10
@@ -89,14 +91,21 @@
11
     # Split text into lines, converting tabs to spaces
12
     lines = text.expandtabs().splitlines()
13
     # Determine minimum indentation (except first line)
14
-    indent = sys.maxint
15
+    try:
16
+        MAXINT = sys.maxint
17
+    # python 3 compatibility
18
+    except AttributeError:
19
+        MAXINT = sys.maxsize
20
+
21
+    indent = MAXINT
22
+
23
     for line in lines[1:]:
24
         stripped = line.lstrip()
25
         if stripped:
26
             indent = min(indent, len(line) - len(stripped))
27
     # Remove indentation (first line is special)
28
     trimmed = [lines[0].strip()]
29
-    if indent < sys.maxint:
30
+    if indent < MAXINT:
31
         for line in lines[1:]:
32
             # Append line, minus indentation
33
             trimmed.append(line[indent:].rstrip())
34
@@ -250,7 +259,7 @@
35
     """Print a message and pause for the given number of seconds.
36
     """
37
     print("Resuming in %s seconds..." % seconds)
38
-    os.system('sleep %ss' % seconds)
39
+    os.system('sleep %s' % seconds)
40
 
41
 
42
 def imagemagick_version():
43
tovid-0.34.tar.bz2/setup.py -> tovid-0.35.tar.gz/setup.py Changed
60
 
1
@@ -20,7 +20,12 @@
2
     as a string like 'svn-r1234'. If svn is not installed, or if something goes
3
     wrong, return 'svn-unknown'
4
     """
5
-    from commands import getoutput
6
+    try:
7
+        from commands import getoutput
8
+    except ImportError:
9
+        # python 3
10
+        from subprocess import getoutput
11
+
12
     rev_line = getoutput('svn info 2>/dev/null | grep ^Revision')
13
     # If rev_line is found, get the revision number
14
     if rev_line:
15
@@ -39,7 +44,7 @@
16
 # Current SVN version number
17
 #_tovid_version = svn_version()
18
 # Official release number
19
-_tovid_version = '0.34'
20
+_tovid_version = '0.35'
21
 
22
 
23
 import os
24
@@ -181,7 +186,7 @@
25
 
26
 # Build tovid-init with regular 'build' command
27
 build.sub_commands.append(('build_tovid_init', None))
28
-#build.sub_commands.append(('build_docs', None))
29
+build.sub_commands.append(('build_docs', None))
30
 
31
 # The actual setup
32
 setup(
33
@@ -205,8 +210,6 @@
34
         'libtovid.guis',
35
         'libtovid.util',
36
         'libtovid.metagui',
37
-        'libtovid.render',
38
-        'libtovid.backend',
39
     ],
40
 
41
     # Executable files go into /$PREFIX/bin/
42
@@ -222,17 +225,10 @@
43
             # Bash scripts
44
             'src/idvid',
45
             'src/makedvd',
46
-            'src/makemenu',
47
-            'src/makevcd',
48
-            'src/makexml',
49
-            'src/postproc',
50
             'src/todisc',
51
             'src/todisc-fade-routine',
52
             'src/makempg',
53
-            'src/tovid-batch',
54
             'src/tovid-init',
55
-            'src/tovid-interactive',
56
-            'src/make_titlesets',
57
 
58
             # Python scripts
59
             'src/todiscgui',
60
tovid-0.34.tar.bz2/src/idvid -> tovid-0.35.tar.gz/src/idvid Changed
565
 
1
@@ -1,5 +1,4 @@
2
 #!/usr/bin/env bash
3
-#set -u
4
 
5
 ME="[idvid]:"
6
 . tovid-init 2>/dev/null ||
7
@@ -8,7 +7,6 @@
8
 echo -e "Or are you trying to run the script directly?"
9
 echo -e "Please run idvid as:\ntovid id OPTIONS"
10
 exit 1 ; }
11
-
12
 # idvid
13
 # Part of the tovid suite
14
 # =======================
15
@@ -17,7 +15,7 @@
16
 #
17
 # Project homepage: http://tovid.wikia.com
18
 #
19
-# Copyright (C) 2005-2010
20
+# Copyright (C) 2005-2015
21
 #
22
 # This program is free software; you can redistribute it and/or
23
 # modify it under the terms of the GNU General Public License
24
@@ -53,6 +51,7 @@
25
     -terse      Suitable for parsing
26
     -verbose    Also use ffmpeg and tcprobe
27
     -accurate   Do accurate duration estimation
28
+    -keepfiles  Keep temporary directory for debugging
29
     -isformat [ntsc-vcd|pal-vcd|ntsc-svcd|pal-svcd|ntsc-dvd|pal-dvd]
30
         Tell whether the first file is compliant with the given
31
         format; prints "true" or "false" (returns shell 0 or 1)
32
@@ -89,8 +88,9 @@
33
 MATCH_FORMAT=""
34
 MATCH_TVSYS=""
35
 TABULAR=false
36
-USE_MENCODER=:
37
+GET_FFMPEG_LEN=:
38
 USE_NAVLOG=false
39
+KEEPFILES=false
40
 ID_FILES=""
41
 
42
 mkdir -p "$STAT_DIR"
43
@@ -140,18 +140,36 @@
44
             echo "Identifying video with ffmpeg..."
45
             echo $SEPARATOR
46
             # ffmpeg puts its output on standard error
47
-            ffmpeg -i "$INFILE" 2>&1 | tee -a "$SCRATCH_FILE"
48
+            $FFmpeg -i "$INFILE" 2>&1 | tee -a "$SCRATCH_FILE"
49
         else
50
-            ffmpeg -i "$INFILE" >> "$SCRATCH_FILE" 2>&1
51
+            $FFmpeg -i "$INFILE" >> "$SCRATCH_FILE" 2>&1
52
         fi
53
     fi
54
+    # avconv messed with formatting, so we need to move to ffprobe/avprobe
55
+    # ffprobe and avprobe show slightly different formatting, but this should do
56
+    # adds a new line after [/STREAM] (ffmpeg). avconv already has it.
57
+    if test -n $FFprobe; then
58
+        i=0
59
+        while IFS= read -r  line; do
60
+            [[ $line ]] || { ((++i)); continue; }
61
+            probe_info[i]+=$line$'\n'
62
+        done < <($FFprobe   -show_streams "$INFILE" 2>/dev/null | \
63
+         sed '/\[\/STREAM\]/{G;s/$//;};/DISPOSITION/d')
64
+    fi
65
+    # avprobe begins with a # comment\n so delete that index and flatten array
66
+    for i in ${!probe_info[@]}; do
67
+        grep -q '^#' <<<  ${probe_info[i]} && unset probe_info[i]
68
+    done
69
+    # if index 0 is unset flatten array
70
+    [[ ${probe_info[0]+unset} ]] || probe_info=( "${probe_info[@]}" )
71
+        
72
     # Identify video using tcprobe
73
     if test -n "$TCPROBE"; then
74
         if $VERBOSE ; then
75
             echo $SEPARATOR
76
             echo "Identifying video with tcprobe..."
77
             echo $SEPARATOR
78
-            tcprobe -i "$INFILE" 2>&1 | tee -a "$SCRATCH_FILE"
79
+            tcprobe -i "$INFILE" 2>&1 | tee -a "$SCRATCH_FILE" 2>/dev/null
80
         else
81
             tcprobe -i "$INFILE" >> "$SCRATCH_FILE" 2>/dev/null
82
         fi
83
@@ -169,6 +187,10 @@
84
         fi
85
         exit 1
86
     fi
87
+    # remove ffmpeg metadata from scratch file
88
+    # make portable for bsd sed etc
89
+    #sed  '/Metadata/,/Duration/{//!d}' "$SCRATCH_FILE" > "${SCRATCH_FILE}2"
90
+    #mv "${SCRATCH_FILE}2" "$SCRATCH_FILE"
91
 
92
     # Defaults. Many of these values may be overridden by
93
     # vars from mplayer's output to be sourced later.
94
@@ -190,14 +212,15 @@
95
     V_DURATION=""
96
     ID_LENGTH="0"
97
 
98
-    # bash appears to have no way of initializing empty arrays; we append to these later,
99
-    # so unsetting them clears out their previous contents
100
-    unset A_SAMPRATES
101
-    unset A_BITRATES
102
-    unset A_CODECS
103
-    unset A_HEX_TRACKS
104
-    unset A_TRACKS
105
-    unset wavs
106
+    # arrays
107
+    A_SAMPRATES=()
108
+    A_BITRATES=()
109
+    A_CODECS=()
110
+    A_HEX_TRACKS=()
111
+    A_TRACKS=()
112
+    MPL_AIDS=()
113
+    wavs=()
114
+    probe_audio_info=()
115
 
116
     # send formated mplayer's output to a vars file to be sourced to set relevant variables.
117
     # (ID_V(ideo), ID_A(udio), and ID_L(ength))
118
@@ -212,25 +235,33 @@
119
     # get array of mplayer audio ids, used if no hextracks from ffmpeg
120
     while read; do MPL_AIDS+=(${REPLY##*=}); done < <(grep ID_AUDIO_ID "$SCRATCH_FILE")
121
 
122
-    ID_VIDEO_FRAMES=$(grep 'length:' "$SCRATCH_FILE" | \
123
-        awk -F ' ' '{print $2}')
124
-    test -z $ID_VIDEO_FRAMES && ID_VIDEO_FRAMES="0"
125
-
126
-    # ffmpeg has a better concept of the actual bitrate than mplayer
127
-    TOTAL_AV_BITRATE=$(awk -F: '{gsub("kb/s", "")};  /bitrate:/ {print $6*1000}' "$SCRATCH_FILE")
128
-    ## take the lower of the two
129
-    if test $ID_VIDEO_BITRATE -eq 0 || test $TOTAL_AV_BITRATE -lt $ID_VIDEO_BITRATE; then
130
-        # make sure we have a value from ffmpeg
131
-        if test_is_number $TOTAL_AV_BITRATE; then
132
-            ID_VIDEO_BITRATE=$TOTAL_AV_BITRATE
133
+    # try tcprobe to determine length (# of frames)
134
+    # assuming it is installed, otherwise this should 'fail' silently
135
+    ID_VIDEO_FRAMES=$(awk '/length:/ {print $2}' "$SCRATCH_FILE")
136
+    ((ID_VIDEO_FRAMES)) || ID_VIDEO_FRAMES="0"
137
+
138
+    FF_V_BITRATE=$(sed -n 's/.*Stream.*Video:.*\(\ [0-9][0-9][0-9]*\) kb\/s.*/\1/p' "$SCRATCH_FILE" |uniq)
139
+    FF_V_BITRATE=${FF_V_BITRATE// /} # trim spaces
140
+    # make sure we have a value from ffmpeg (a number and non zero)
141
+    if test_is_number "$FF_V_BITRATE" && (( FF_V_BITRATE )); then
142
+        # kilobits to bits
143
+        ID_VIDEO_BITRATE=${FF_V_BITRATE}000
144
+    elif [[ -z $ID_VIDEO_BITRATE || $ID_VIDEO_BITRATE = 0 ]]; then
145
+        mplayer_stats_br=$(sed '/VIDEO:/!d;s/.*(//; s/).*=\ /:/;s/[kK][bB].*//g' "$SCRATCH_FILE")
146
+        # make an integer
147
+        mplayer_stats_br=${mplayer_stats_br%.*}
148
+        # make sure it is a number
149
+        if test_is_number $mplayer_stats_br && (( mplayer_stats_br )); then
150
+            ID_VIDEO_BITRATE=$(( mplayer_stats_br * 8 * 1000 ))
151
         fi
152
-    else
153
-        ID_VIDEO_BITRATE=$ID_VIDEO_BITRATE
154
     fi
155
+    # if mplayer decides there is no video, unset ID_VIDEO_BITRATE
156
+    # else it will still show a value from TOTAL_AV_BITRATE
157
+    grep -qi "no video" "$SCRATCH_FILE" && unset ID_VIDEO_BITRATE
158
     # if we still don't have a value for ID_VIDEO_WIDTH and ID_VIDEO_HEIGHT
159
     MP_FRAMESIZE=$(awk '/=>/ {print $3}' "$SCRATCH_FILE")
160
     if test $ID_VIDEO_WIDTH -eq 0; then
161
-        test_is_number ${MP_FRAMESIZE%x*} &&  ID_VIDEO_WIDTH=${MP_FRAMESIZE%x*}
162
+        test_is_number ${MP_FRAMESIZE%x*} && ID_VIDEO_WIDTH=${MP_FRAMESIZE%x*}
163
     fi
164
     if test $ID_VIDEO_HEIGHT -eq 0; then
165
         test_is_number ${MP_FRAMESIZE#*x} && ID_VIDEO_HEIGHT=${MP_FRAMESIZE#*x}
166
@@ -238,18 +269,25 @@
167
 
168
     # Find out which channel is the video channel ( 1st )
169
     # TODO Do we want to worry about videos with multiple channels of video ?
170
-    VIDEO_INFO=$(grep "Video:" "$SCRATCH_FILE")
171
-    ID_VIDEO_TRACKS=( $(sed -r 's/.*Stream #([0-9]\.[0-9]+).*/\1/' <<< "$VIDEO_INFO") )
172
-    ID_VIDEO_TRACK="${ID_VIDEO_TRACKS[0]}"
173
+    VIDEO_INFO=$(grep "Video:" "$SCRATCH_FILE" 2>&1| uniq)
174
+    ID_VIDEO_TRACKS=( $(sed -r 's/.*Stream #([0-9][:.][0-9]+).*/\1/' <<< "$VIDEO_INFO") )
175
+    #ID_VIDEO_TRACKS=( $(awk '/Stream.*Video/ { gsub("#|: ", " ") ; print $2}' <<< "$VIDEO_INFO") )
176
+    test_is_number "${ID_VIDEO_TRACKS[0]/:/}" && ID_VIDEO_TRACK="${ID_VIDEO_TRACKS[0]}"
177
     # Find out what audio channels are available
178
+    for p in ${!probe_info[@]}; do
179
+        if grep -q codec_type=audio <<< "${probe_info[p]}"; then
180
+            probe_audio_info+=( "${probe_info[p]}" )
181
+        fi
182
+    done
183
     if test -n "$ID_AUDIO_ID"; then
184
-        AUDIO_INFO=$(grep -w "Audio:" "$SCRATCH_FILE")
185
+        # grep for Steam.*Audio instead of just "Audio:" fixes some wmv issues
186
+        AUDIO_INFO=$(grep "Stream.*Audio:" "$SCRATCH_FILE")
187
         # ID_AUDIO_ID needs "TRACKS" var to remain in columns
188
-        TRACKS=$(sed -r 's/.*Stream #([0-9]\.[0-9]+).*/\1/' <<< "$AUDIO_INFO")
189
+        TRACKS=$(sed -r 's/.*Stream #([0-9][:.][0-9]+).*/\1/' <<< "$AUDIO_INFO")
190
         A_TRACKS=(${TRACKS//$'\n'/ })
191
         # Get hexadecimal track IDs, if present
192
         if grep -q "\[0x[0-9a-fA-F]*]" <<< $AUDIO_INFO; then
193
-            HEX_TRACKS=$(awk -F [][] '{gsub("0x", ""); print $2}' <<< "$AUDIO_INFO")
194
+            HEX_TRACKS=$(awk -F '[][]' '{gsub("0x", ""); print $2}' <<< "$AUDIO_INFO")
195
             HEX_TRACKS=(${HEX_TRACKS//$'\n'/ })
196
             USE_HEX_TRACKS=:
197
         else
198
@@ -258,15 +296,30 @@
199
         # Loop through available tracks and get specs on each
200
         for ((i=0; i<${#A_TRACKS[@]}; i++)); do
201
             CUR_CHAN=$(grep "Stream #${A_TRACKS[i]}" <<< "$AUDIO_INFO")
202
-            A_SAMPRATES=("${A_SAMPRATES[@]}" "$(echo $CUR_CHAN | \
203
-                sed -r 's/.* ([0-9]+) Hz.*/\1/')")
204
-            ! test_is_number ${A_SAMPRATES[i]} && A_SAMPRATES[i]=?
205
-            A_BITRATES=("${A_BITRATES[@]}" "$(echo $CUR_CHAN | \
206
-                sed -r 's/.* ([0-9]+) kb\/s.*/\1/')")
207
-            # make sure the above is a number, else set  A_BITRATE to 0
208
-            ! test_is_number ${A_BITRATES[i]} && A_BITRATES[i]=0
209
-            A_CODECS=("${A_CODECS[@]}" "$(echo $CUR_CHAN | \
210
-                sed -r 's/.*Audio: ([^,]+),.*/\1/')")
211
+            A_SAMPRATES[i]=$(sed -r 's/.* ([0-9]+) Hz.*/\1/' <<< "$CUR_CHAN")
212
+            if ! test_is_number ${A_SAMPRATES[i]}; then
213
+                # probe_audio_info should have same indexes as A_TRACKS
214
+                aud_samplerate=$(awk -F= '/^sample_rate=/ {print $2}' <<< "${probe_audio_info[i]}")
215
+                if test_is_number $aud_samplerate; then
216
+                    A_SAMPRATES[i]=${aud_samplerate%.*}
217
+                else
218
+                    A_SAMPRATES[i]=0
219
+                fi
220
+            fi
221
+            A_BITRATES[i]=$(sed -r 's/.* ([0-9]+) kb\/s.*/\1/' <<< "$CUR_CHAN")
222
+            # test for a number, add 3 zeros (bits), else set  A_BITRATE to 0
223
+            if test_is_number ${A_BITRATES[i]} && (( ${A_BITRATES[i]} )); then
224
+                A_BITRATES[i]=${A_BITRATES[i]}000
225
+            else
226
+                # probe_audio_info should have same indexes as A_TRACKS
227
+                aud_bitrate=$(awk -F= '/^bit_rate=/ {print $2}' <<< "${probe_audio_info[i]}")
228
+                if test_is_number $aud_bitrate; then
229
+                    A_BITRATES[i]=${aud_bitrate%.*}
230
+                else
231
+                    A_BITRATES[i]=0
232
+                fi
233
+            fi
234
+            A_CODECS[i]=$(sed -nr 's/.*Audio: (\w+).*/\1/p' <<< "$CUR_CHAN")
235
             if $USE_HEX_TRACKS; then
236
                 MP_TRACKNUM=$((16#${HEX_TRACKS[i]}))
237
             else
238
@@ -275,21 +328,24 @@
239
             fi
240
             ID_AUDIO_IDS="$ID_AUDIO_IDS ${MP_TRACKNUM//$'\n'/ }"
241
 
242
-            # last ditch efforts to get audio bitrate if we still don't have it
243
-            if test ${A_BITRATES[i]} -eq 0; then
244
-                MP_ABITRATE=$(mplayer -nomsgcolor -vo null -ao null -frames 30 \
245
-                -channels 6 -identify -aid $MP_TRACKNUM -noconsolecontrols \
246
-                "$INFILE" 2>&1 | grep ID_AUDIO_BITRATE|awk -F=  'END{print $2}')
247
-                if test_is_number $MP_ABITRATE; then
248
-                    MP_ABITRATE=${MP_ABITRATE%.*}
249
-                    A_BITRATES[i]=${MP_ABITRATE/000*}
250
-                else # final attempt
251
-                    MENC_ABITRATE=$(mencoder "$INFILE" -aid $MP_TRACKNUM  -oac pcm -ovc copy \
252
-                    -frames 30 -o /dev/null 2>&1 | awk '/AUDIO/ {print $7}')
253
-                    test_is_number $MENC_ABITRATE && A_BITRATES[i]=${MENC_ABITRATE%.*}
254
+            # last ditch efforts to get audio {bit,sample}rate if 0
255
+            if (( ${A_BITRATES[i]} == 0 )) || (( ${A_SAMPRATES[i]} == 0 )); then
256
+                MP_CHAN_INFO=$(mplayer -nomsgcolor -vo null -ao null -frames 30 \
257
+                -channels 6 -identify -aid ${MPL_AIDS[i]} -noconsolecontrols \
258
+                "$INFILE" 2>&1)
259
+                # we want the last match: AFTER mplayer plays it a bit
260
+                MP_ABITRATE=$(awk -F= '/^ID_AUDIO_BITRATE=/ {b=$2} END{print b}' <<< "$MP_CHAN_INFO")
261
+                MP_SAMPRATE=$(awk -F= '/^ID_AUDIO_RATE=/  {b=$2} END{print b}' <<< "$MP_CHAN_INFO")
262
+                MP_ABITRATE=${MP_ABITRATE%.*}
263
+                MP_SAMPRATE=${MP_SAMPRATE%.*}
264
+                if test_is_number $MP_ABITRATE && (( MP_ABITRATE )); then
265
+                    [[ ${A_BITRATES[i]} = 0 ]] && A_BITRATES[i]=$MP_ABITRATE
266
+                fi
267
+                if test_is_number $MP_SAMPRATE && (( MP_SAMPRATE )); then
268
+                    [[ ${A_SAMPRATES[i]} = 0 ]] && A_SAMPRATES[i]=$MP_SAMPRATE
269
                 fi
270
             fi
271
-            A_HEX_TRACKS=("${A_HEX_TRACKS[@]}" "$MP_TRACKNUM")
272
+            A_HEX_TRACKS[i]=$MP_TRACKNUM
273
         done
274
         # use comma separator and remove possible leading comma
275
         ID_AUDIO_IDS=${ID_AUDIO_IDS// /,}
276
@@ -315,16 +371,16 @@
277
         tracks=( ${TRACKS[@]} )
278
         if (( ${#tracks[@]} > 0 )); then
279
             for i in ${!tracks[@]}; do
280
-                map_cmd[i]="-map ${tracks[i]}"
281
-                wavs=( "${wavs[@]}" "$TMP_DIR/$i.wav" )
282
+                # for -map seperator needs to be ':' not '.'
283
+                map_cmd[i]="-map ${tracks[i]/./:}"
284
+                wavs[i]="$TMP_DIR/$i.wav"
285
             done
286
             for r in ${!tracks[@]}; do
287
-                test_tracks[r]="$(ffmpeg -i "$INFILE" -ss 2 -t 1 ${map_cmd[r]} -y ${wavs[r]} 2>&1)"
288
+                test_tracks[r]="$($FFmpeg -i "$INFILE" -ss 2 -t 1 ${map_cmd[r]} -y ${wavs[r]} 2>&1)"
289
                 if grep -q Unsupported <<< "${test_tracks[r]}"; then
290
                     tracks[r]="Unsupported"
291
                 fi
292
             done
293
-            #test_tracks=( "$(ffmpeg -i "$INFILE" -ss 2 -t 1 ${map_cmd[@]} -y ${wavs[@]} 2>&1)" )
294
             echo "${test_tracks[@]}" >> "$SCRATCH_FILE"
295
             rm -f "${wavs[@]}"
296
         fi
297
@@ -334,30 +390,25 @@
298
         ID_AUDIO_TRACKS=${TRACKS// /,}
299
     fi # if test -n "$ID_AUDIO_ID"
300
 
301
-    # If tcprobe reports an aspect ratio, use that
302
-    if grep -q "aspect ratio" "$SCRATCH_FILE"; then
303
-        RATIO=$(awk '/aspect ratio/ {print $3}'  "$SCRATCH_FILE")
304
-        V_ASPECT_WIDTH=$(expr ${RATIO%:*} \* 100 \/ ${RATIO#*:})
305
-    # Otherwise, infer from mplayer
306
-    else
307
-        # Infer aspect ratio from width/height of mplayer playback
308
-        MPLAYER_RES=$(grep '^VO:' "$SCRATCH_FILE" | \
309
-            sed -e "s/..*=> *//g" -e "s/ .*$//g")
310
-        #PLAY_WIDTH=$(echo $MPLAYER_RES | awk -F 'x' '{print $1}')
311
-        #PLAY_HEIGHT=$(echo $MPLAYER_RES | awk -F 'x' '{print $2}')
312
-        # patch from ML:
313
-        PLAY_WIDTH=$(echo "$MPLAYER_RES" | awk -F '[x ]' 'BEGIN {wid = 0}; {if ($1 > wid) wid = $1}; END {print wid}')
314
-        PLAY_HEIGHT=$(echo "$MPLAYER_RES" | awk -F '[x ]' 'BEGIN {hgt = 0}; {if ($2 > hgt) hgt = $2}; END {print hgt}')
315
-        # Fix nulls
316
-        if test -z "$PLAY_WIDTH" || test -z "$PLAY_HEIGHT"; then
317
-            PLAY_WIDTH="100"
318
-            PLAY_HEIGHT="100"
319
-        fi
320
-        V_ASPECT_WIDTH=$(expr $PLAY_WIDTH \* 100 \/ $PLAY_HEIGHT)
321
+    # Infer aspect ratio from width/height of mplayer playback
322
+    MPLAYER_RES=$(grep '^VO:' "$SCRATCH_FILE" | \
323
+     sed -e "s/..*=> *//g" -e "s/ .*$//g")
324
+    # patch from ML:
325
+    PLAY_WIDTH=$(awk -F '[x ]' 'BEGIN {wid = 0}; {if ($1 > wid) wid = $1}; END {print wid}'<<< "$MPLAYER_RES")
326
+    PLAY_HEIGHT=$(awk -F '[x ]' 'BEGIN {hgt = 0}; {if ($2 > hgt) hgt = $2}; END {print hgt}' <<< "$MPLAYER_RES")
327
+    # fix nulls and division by 0 errors as well (( xxx ))
328
+    if ! (( PLAY_WIDTH )) || ! (( PLAY_HEIGHT )); then
329
+        PLAY_WIDTH="100"
330
+        PLAY_HEIGHT="100"
331
     fi
332
+    V_ASPECT_WIDTH=$(expr $PLAY_WIDTH \* 100 \/ $PLAY_HEIGHT)
333
     # Normalized aspect ratio
334
-    V_ASPECT_RATIO=$(echo $V_ASPECT_WIDTH | \
335
-    sed -r -e 's/([0-9]*)([0-9][0-9])/\1.\2:1/g')
336
+    if test_is_number "$V_ASPECT_WIDTH"; then
337
+        V_ASPECT_RATIO=$(sed -r -e 's/([0-9]*)([0-9][0-9])/\1.\2:1/g' \
338
+        <<< "$V_ASPECT_WIDTH")
339
+    fi
340
+    # if mplayer decides there is no video, unset V_ASPECT_WIDTH
341
+    grep -qi "no video" "$SCRATCH_FILE" && unset V_ASPECT_WIDTH
342
 
343
     NAV_LOG="${INFILE}.nav_log"
344
     USE_NAVLOG=false
345
@@ -369,41 +420,41 @@
346
     # if a nav_log file exists and we have a value for FPS, use the log
347
     if  [[ -s "$NAV_LOG"  &&  ${ID_VIDEO_FPS%%.*} -ne 0 ]]; then
348
         ! $TERSE && echo "Using $NAV_LOG"
349
-        USE_MENCODER=false
350
+        GET_FFMPEG_LEN=false
351
         USE_NAVLOG=:
352
     else # no nav_log or ID_VIDEO_FPS missing
353
         # If doing -fast identification, skip "accurate" length determination
354
         if $FAST; then # skip this long process
355
-            USE_MENCODER=false  # USE_NAV_LOG already set to false
356
+            GET_FFMPEG_LEN=false  # USE_NAV_LOG already set to false
357
         else
358
-            # check if tcdemux present, and if mpg extension (vob uses mencoder)
359
-            if grep -qi mpg <<< "${INFILE##*.}" && hash tcdemux 2>/dev/null && \
360
+            # check if tcdemux present, and if mpg extension (vob uses ffmpeg)
361
+            if egrep -qi 'mpg$|mpeg$|vob$' <<< "${INFILE##*.}" && hash tcdemux 2>/dev/null && \
362
               [[ ${ID_VIDEO_FPS%%.*} -ne 0 ]]; then
363
                 NAVSEEK_CMD=(nice tcdemux  -f $ID_VIDEO_FPS -W -i "$INFILE")
364
             # or check if aviindex installed, and if extension is avi
365
             elif grep -qi avi <<< "${INFILE##*.}" && hash aviindex 2>/dev/null && \
366
               [[ ${ID_VIDEO_FPS%%.*} -ne 0 ]]; then
367
                 NAVSEEK_CMD=(nice aviindex -x -i "$INFILE" -o "$NAV_LOG")
368
-            else # not $FAST and indexing not possible, so use mencoder
369
-                USE_MENCODER=:
370
+            else # not $FAST, no indexing: so use ffmpeg for length/frames
371
+                GET_FFMPEG_LEN=:
372
             fi
373
         fi
374
         if [[ "${NAVSEEK_CMD[@]}" ]]; then
375
             "${NAVSEEK_CMD[@]}"  >  "$NAV_LOG" 2>/dev/null
376
             if [[ -s  "$NAV_LOG" ]]; then # if non empty lets use it
377
-                USE_MENCODER=false
378
+                GET_FFMPEG_LEN=false
379
                 USE_NAVLOG=:
380
             else
381
-                # remove empty log and we will use mencoder in next code block
382
+                # remove empty log and we will use ffmpeg in next code block
383
                 [[ -e "$NAV_LOG" ]] && rm -f "$NAV_LOG"
384
-                USE_MENCODER=:
385
+                GET_FFMPEG_LEN=:
386
             fi
387
         fi
388
     fi
389
     # set variables from NAV_LOG results
390
     if $USE_NAVLOG; then
391
-        if grep -qi mpg <<< "${INFILE##*.}"; then
392
-            ID_VIDEO_FRAMES=$(cat "$NAV_LOG" | awk 'END{print NR}')
393
+        if egrep -qi 'mpeg$|mpg$|vob$' <<< "${INFILE##*.}"; then
394
+            ID_VIDEO_FRAMES=$(awk 'END{print NR}' "$NAV_LOG" )
395
             V_DUR=$(bc <<< "$ID_VIDEO_FRAMES / $ID_VIDEO_FPS")
396
             V_DURATION=${V_DUR%%.*} # final value is integer ( seconds )
397
         else
398
@@ -413,32 +464,93 @@
399
             # final value is in seconds
400
             V_DURATION=${V_DURATION%%.*} # integer
401
         fi
402
-        # if no usable value, use mencoder
403
-        { ! test_is_number $V_DURATION || ((V_DURATION == 0)) ; } && USE_MENCODER=:
404
+        # if no usable value, use ffmpegs
405
+        { ! test_is_number $V_DURATION || ((V_DURATION == 0)) ; } && GET_FFMPEG_LEN=:
406
     fi
407
-    # find duration by playing the video with mencoder into /dev/null
408
+    # find duration by playing the video with ffmpeg into /dev/null
409
     # any of: no/empty log file, ! $FAST, no tcdemux/aviindex, or not an mpg/avi
410
-    if $USE_MENCODER; then
411
-        MENCODER_STATS=$(LC_ALL=C mencoder -ovc copy -nosound -noskiplimit \
412
-        "$INFILE" -o /dev/null 2>/dev/null)
413
-        V_DURATION=$(awk 'END{print $(NF-3)}' <<< "$MENCODER_STATS")
414
-        V_DURATION=${V_DURATION%%.*}  # integer in seconds
415
+    if $GET_FFMPEG_LEN; then
416
+        ff_opts="-an -vcodec copy -f null -y /dev/null"
417
+        ffmpeg_cmd=($FFmpeg -i "$INFILE"  $ff_opts)
418
+        ffmpeg_full_output=$( "${ffmpeg_cmd[@]}" 2>&1 )
419
+        sed_var_time='x;$s/^.*time= *\([^ ]*\).*/\1/p'
420
+        sed_var_frames='{s/^.*frame= *\([^ ]*\).*/\1/p}'
421
+        V_DURATION=$(sed -n "$sed_var_time" <<< "$ffmpeg_full_output")
422
+        test_is_number ${V_DURATION//:} && V_DURATION=$(unformat_time $V_DURATION int) || \
423
+          V_DURATION=0
424
         # overwrite ID_VIDEO_FRAMES since we have a more accurate count now
425
-        ID_VIDEO_FRAMES=$(awk 'END{print $(NF-1)}' <<< "$MENCODER_STATS")
426
-        # if we failed to get a video bitrate earlier, use mencoder stats
427
-        if test $ID_VIDEO_BITRATE -eq 0; then
428
-            MENCODER_STATS_BR=$(awk -F: 'END{print $2}' <<< "$MENCODER_STATS" | awk '{print $1}')
429
-            # make sure it is a number
430
-            if test_is_number $MENCODER_STATS_BR; then
431
-                ID_VIDEO_BITRATE=${MENCODER_STATS_BR%.*}000
432
-            fi
433
+        ID_V_FRAMES=$(sed -n "$sed_var_frames" <<< "$ffmpeg_full_output")
434
+        test_is_number "$ID_V_FRAMES" && ID_VIDEO_FRAMES=$ID_V_FRAMES
435
+        if $VERBOSE; then
436
+            echo "getting video length with ffmpeg"
437
+            echo "$ffmpeg_full_output"
438
         fi
439
-        $VERBOSE && echo "$MENCODER_STATS"
440
-    fi
441
 
442
-    # Use mplayer-reported length as a last resort (truncate floating-point)
443
-    test -z $V_DURATION && V_DURATION=$(echo $ID_LENGTH | sed 's/\.[0-9]*//')
444
+        # old stuff
445
+    fi
446
 
447
+    # try ffmpeg's estimate of duration first, then tcprobe's, then mplayers
448
+    if ! (( ${V_DURATION//:} )); then
449
+        # below from go|dfish on #sed, quits after 1st match (we have 2 matches)
450
+        V_DURATION=$(sed -n '/.*Duration: /{ s///; s/\..*//; p; q; }' "$SCRATCH_FILE")
451
+        if egrep -q  '([0-9]+:[0-9][0-9]:[0-9][0-9])' <<< "$V_DURATION"; then
452
+            V_DURATION=$(unformat_time $V_DURATION int)
453
+        else
454
+            V_DURATION=0
455
+        fi
456
+        if ! (( ${V_DURATION//:} )); then
457
+            V_DUR=$(sed -n '/.*duration=/{ s///; s/\..*//; p; q; }' "$SCRATCH_FILE")
458
+            # try ffprobe's (avprobe) output first
459
+            if (( ${vid_duration%.*} )); then
460
+                V_DURATION=${vid_duration%.*}
461
+            # try tcprobe if above fails, if installed, 'failing' silently otherwise
462
+            elif (( ${V_DUR%.*} )); then
463
+                egrep -q '([0-9]+:[0-9][0-9]:[0-9][0-9])' <<< "$V_DURATION" && \
464
+                 V_DURATION=$(unformat_time $V_DURATION int)
465
+            else
466
+                V_DURATION=0
467
+            fi
468
+        fi
469
+        # Lastly try mplayer-reported length (secs) (truncate floating-point)
470
+        if ! (( ${V_DURATION} )); then
471
+            V_DURATION=$(sed 's/\.[0-9]*//' <<< "$ID_LENGTH")
472
+            (( V_DURATION )) || V_DURATION=0
473
+        fi
474
+    fi
475
+    # now we have (hopefully) duration and audio bitrate, we can try other ways
476
+    # to get video bitrate if we don't have it yet, from the total bitate
477
+    # or from the file size.
478
+    # make sure of numerical values for audio and video bitrate, then subtract
479
+    if ! test_is_number $ID_VIDEO_BITRATE || ! (( ID_VIDEO_BITRATE )); then
480
+        TOTAL_AV_BITRATE=$(awk -F: '{gsub("kb/s", "")};  /Duration:.*bitrate:/ {print $6*1000;exit}' "$SCRATCH_FILE")
481
+        if test_is_number $TOTAL_AV_BITRATE && (( TOTAL_AV_BITRATE )); then
482
+            (( ID_AUDIO_BITRATE )) && test_is_number $ID_AUDIO_BITRATE && \
483
+            ID_VIDEO_BITRATE=$(( TOTAL_AV_BITRATE - ID_AUDIO_BITRATE ))
484
+            #echo -e "Probed video bitrate not available, infering from total bitrate and audio bitrate\n"
485
+        else
486
+            # infer bitrate from file size and duration
487
+            v_size=$(( $(du -m "$INFILE" | awk '{ print $1 }') * 8192 ))
488
+            if (( ${V_DURATION%.*} )); then
489
+                ID_VIDEO_BITRATE=$(bc -l <<< "$v_size / $V_DURATION")
490
+                ID_VIDEO_BITRATE=$(( v_size / V_DURATION ))000
491
+                #echo -e "Probed video bitrate not available, infering from file size and duration\n"
492
+            fi
493
+        fi
494
+    fi
495
+    # use 0 for unknown video bitrate, same as unknown audio bitrate
496
+    [[ $ID_VIDEO_BITRATE = 0 ]] && ID_VIDEO_BITRATE=0
497
+
498
+    # use {ff,av}probe info to infer frames count, from duration and fps
499
+    # if we already have ID_VIDEO_FRAMES from mplayer, this block does nothing
500
+    if test_is_number $vid_frames && ((vid_frames)); then
501
+        (( $ID_VIDEO_FRAMES == 0 )) && ID_VIDEO_FRAMES=$vid_frames
502
+    elif  (( ${V_DURATION%.*} )) &&  (( ${ID_VIDEO_FPS/./} )); then
503
+        VIDEO_FRAMES=$(bc -l <<< "$V_DURATION * $ID_VIDEO_FPS")
504
+        if (( $ID_VIDEO_FRAMES == 0 )); then
505
+            ID_VIDEO_FRAMES=${VIDEO_FRAMES%.*}
506
+            #echo -e "Probed frame count not available, infering from duration and framerate\n"
507
+        fi
508
+   fi 
509
     # TODO: WARN if video is less than one second!
510
 
511
     # Mplayer reports ac3 and mp2 incorrectly, so refer to numeric codes
512
@@ -534,7 +646,7 @@
513
             echo "---------------------------"
514
             echo "              Codec: ${A_CODECS[j]}"
515
             if [[ ${tracks[j]} != Unsupported ]]; then
516
-                echo "            Bitrate: ${A_BITRATES[j]}000 bits per second"
517
+                echo "            Bitrate: ${A_BITRATES[j]} bits per second"
518
                 echo "      Sampling rate: ${A_SAMPRATES[j]} Hz"
519
             fi
520
         done
521
@@ -568,8 +680,8 @@
522
 
523
     # VCD/SVCD must be 44.1khz mp2
524
     elif test "$ID_AUDIO_RATE" = "44100" && test "$ID_AUDIO_CODEC" = "mp2"; then
525
-        # SVCD can be 32-384 bps, 1-4 channels
526
-        if test "$ID_AUDIO_NCH" -le "4" && \
527
+        # SVCD can be 32-384 bps, 1-4 channels - check 1st audio stream only
528
+        if test "${ID_AUDIO_NCH%%,*}" -le "4" && \
529
           test "$ID_AUDIO_BITRATE" -ge "32000" && \
530
           test "$ID_AUDIO_BITRATE" -le "384000"; then
531
             A_SVCD="$ID_AUDIO_NCH-channel $ID_AUDIO_BITRATE bps SVCD"
532
@@ -630,6 +742,8 @@
533
     esac
534
 
535
     # Find matching video profile(s)
536
+    # some mplayer versions report MPG2 instead of MPEG2 or hex
537
+    test "$ID_VIDEO_FORMAT" = "MPG2" && ID_VIDEO_FORMAT=MPEG2
538
     # Test for VCD/DVD-VCD MPEG1 compliance
539
     if test "$ID_VIDEO_FORMAT" = "MPEG1" && test "$ID_VIDEO_BITRATE" -le "1856000"; then
540
         # VCD compliance
541
@@ -858,7 +972,7 @@
542
 
543
 # See what programs are available for doing identification
544
 MPLAYER=$(type -p mplayer)
545
-FFMPEG=$(type -p ffmpeg)
546
+FFMPEG=$(type -p $FFmpeg)
547
 TCPROBE=$(type -p tcprobe)
548
 
549
 
550
@@ -874,6 +988,7 @@
551
         "-fast" ) FAST=: ;;
552
         "-accurate" ) FAST=false ;;
553
         "-tabular" ) TABULAR=: ;;
554
+        "-keepfiles" ) KEEPFILES=: ;;
555
         "-isformat" )
556
             shift
557
             MATCH_FORMAT="$1"
558
@@ -904,5 +1019,5 @@
559
     column -s "||" -t "$TABLE"
560
 fi
561
 
562
-rm -rf "$TMP_DIR"
563
+$KEEPFILES || rm -rf "$TMP_DIR"
564
 exit 0
565
tovid-0.34.tar.bz2/src/makedvd -> tovid-0.35.tar.gz/src/makedvd Changed
55
 
1
@@ -15,7 +15,7 @@
2
 #
3
 # Project homepage: http://tovid.wikia.com
4
 #
5
-# Copyright (C) 2005-2010
6
+# Copyright (C) 2005-2015
7
 #
8
 # This program is free software; you can redistribute it and/or
9
 # modify it under the terms of the GNU General Public License
10
@@ -44,15 +44,12 @@
11
 EOF`
12
 
13
 USAGE=`cat << EOF
14
-Usage: tovid dvd [OPTIONS] FILE.xml
15
-   or: tovid dvd [OPTIONS] DVD_DIR
16
+Usage: tovid dvd [OPTIONS] DVD_DIR
17
 
18
-With FILE.xml, containing dvdauthor XML as generated by 'makexml',
19
-or DVD_DIR, a directory containing a DVD filesystem (VIDEO_TS, namely).
20
+DVD_DIR: a directory containing a DVD filesystem (VIDEO_TS, namely).
21
 
22
 OPTIONS may be any of the following:
23
 
24
-  -author              Create DVD filesystem from FILE.xml
25
   -burn                Burn DVD filesystem from DVD_DIR
26
   -eject               Eject the DVD tray after burning
27
   -device DEVFS_NAME   DVD recorder device name (Default: /dev/dvdrw)
28
@@ -228,6 +225,8 @@
29
 
30
 # See what kind of file we're working with, and do the right thing
31
 # Author an XML file
32
+# This first if block is no longer really needed as makexml has
33
+# been removed from tovid but I will leave it here for now.
34
 if echo "$DISC_NAME" | grep -q -i '\.xml$'; then
35
     DVDAUTHOR_XML="$DISC_NAME"
36
     DO_AUTHOR=:
37
@@ -339,7 +338,7 @@
38
         export VIDEO_FORMAT=ntsc
39
         echo -e '\n***'
40
         echo "No default video format defined!!!"
41
-        echo "Was this xml created by a recent version of tovid/makexml?"
42
+        echo "Was this xml created by a recent version of tovid/todisc?"
43
         echo "Using default video format of 'ntsc'."
44
         echo "Run 'export VIDEO_FORMAT=\"pal\"' if this is wrong for your disc."
45
         echo -e '\n***'
46
@@ -416,7 +415,7 @@
47
         echo "Found $DISC_STATUS $DISC_TYPE. Please insert a usable DVD into $DVDRW_DEVICE."
48
         for COUNTER in {10..1}; do
49
           printf "Trying again in %2s seconds...\r" $((COUNTER * TIME_SCALE))
50
-          sleep ${TIME_SCALE}s
51
+          sleep $TIME_SCALE
52
         done
53
         ((COUNT++))
54
         echo
55
tovid-0.34.tar.bz2/src/makempg -> tovid-0.35.tar.gz/src/makempg Changed
440
 
1
@@ -1,5 +1,5 @@
2
 #!/usr/bin/env bash
3
-ME="[tovid]:"
4
+ME="[makempg]:"
5
 . tovid-init 2>/dev/null ||
6
 { echo -e "===============================================================\n"
7
 echo -e "'tovid-init' not found.  Was tovid improperly installed?"
8
@@ -16,7 +16,7 @@
9
 #
10
 # Project homepage: http://tovid.wikia.com
11
 #
12
-# Copyright (C) 2005-2010
13
+# Copyright (C) 2005-2015
14
 #
15
 # This program is free software; you can redistribute it and/or
16
 # modify it under the terms of the GNU General Public License
17
@@ -145,6 +145,7 @@
18
 # Audio bitrate (for ac3 or mp2)
19
 AUD_BITRATE="224"
20
 # Don't generate an empty audio stream
21
+NEWAUDIO_OPT=false
22
 GENERATE_AUDIO=false
23
 # Amplitude used when adjusting audio (-amplitude)
24
 AUDIO_AMPLITUDE=""
25
@@ -297,7 +298,7 @@
26
         yecho
27
         return
28
     else
29
-        eval "$@" 2>&1 | strings >> "$LOG_FILE" &
30
+        eval "$@" 2>&1 | $std_buf strings >> "$LOG_FILE" &
31
         PIDS="$PIDS $!"
32
     fi
33
 }
34
@@ -319,8 +320,10 @@
35
 # ******************************************************************************
36
 function check_disk_space()
37
 {
38
+    # this function is very inaccurate, needs attention
39
     # Determine space available in current directory (in MB)
40
-    AVAIL_SPACE=$(df -mP . | awk 'NR != 1 {print $4;}')
41
+    # os compatibility patch from 'virtualestates' as per issue #152
42
+    AVAIL_SPACE=$(df -P . | awk 'NR==1 {sub("-blocks", "", $2); blocksize=$2} NR!=1 {print int($4/1024*blocksize/1024)}')
43
     # Rough estimates of KB/sec for different formats
44
     K_PER_SEC=200
45
     test "$TGT_RES" = "VCD" && K_PER_SEC=172
46
@@ -333,15 +336,15 @@
47
     # based on original file size
48
     $SLICE && VIDEO_DURATION=$CLIP_LENGTH || VIDEO_DURATION=$V_DURATION
49
     if test "$VIDEO_DURATION" = "0"; then
50
-        CUR_SIZE=$(du -Dck \"$IN_FILE\" | awk 'END{print $1}')
51
+        CUR_SIZE=$(du -Dck "$IN_FILE" | awk 'END{print $1}')
52
         NEED_SPACE=$(expr $CUR_SIZE \* 2)
53
-        yecho  "The encoding process will require about"
54
     # Estimate space based as kbps * duration
55
     else
56
         NEED_SPACE=$(expr $VIDEO_DURATION \* $K_PER_SEC \/ 500)
57
-        yecho "The encoding process is estimated to require $NEED_SPACE MB of disk space."
58
     fi
59
-
60
+    # ffmpeg can do a+v 'at once' so half as much space needed
61
+    $USE_FFMPEG && ! $DO_NORM && ! [[ $ASYNC ]] && NEED_SPACE=$((NEED_SPACE/2))
62
+    yecho "The encoding process is estimated to require $NEED_SPACE MB of disk space."
63
     yecho "You currently have $AVAIL_SPACE MB available in this directory."
64
 }
65
 
66
@@ -560,7 +563,7 @@
67
             "-downmix" )
68
                 DOWNMIX=:
69
                 ;;
70
-            "-ffmpeg" )
71
+            "-ffmpeg" | "-avconv" )
72
                 USE_FFMPEG=:
73
                 ;;
74
             "-nofifo" )
75
@@ -740,7 +743,7 @@
76
     PEAK_BITRATE=$(grep 'Peak bit-rate' "$LOG_FILE" | awk '{print $6}')
77
     if $USE_FFMPEG && ! $DO_NORM && ! $VIDEO_OK; then
78
         # get lines with frame= , and print last field with kbit/s removed
79
-        bitrates=$(awk -F= '/^frame=/ {gsub("kbits/s", ""); print $NF}' "$LOG_FILE")
80
+        bitrates=$(sed -n 's/kbits\/s//g;s/^.*bitrate= *\([^ ]*\).*/\1/p' "$LOG_FILE")
81
         # get highest value, and remove spaces with sed
82
         bitrates=$(sort -un <<< "$bitrates" | sed 's/^[ \t]*//;s/[ \t]*$//')
83
         # average the values.  Add 000, so it is in bits.
84
@@ -756,7 +759,7 @@
85
     KB_PER_MIN=$(expr $FINAL_SIZE \* 60 \/ $V_DURATION \+ 1)
86
     ENC_TIME_RATIO=$(echo "scale = 2; $SCRIPT_TOT_TIME / $V_DURATION" | bc)
87
     if $USE_FFMPEG; then
88
-        BACKEND="ffmpeg"
89
+        BACKEND="$FFmpeg"
90
     else
91
         BACKEND="mpeg2enc"
92
     fi
93
@@ -800,11 +803,11 @@
94
     if ! $QUIET; then
95
         yecho "Your encoded video should be in the file(s) $OUT_FILENAME."
96
         echo
97
-        echo "You can author a disc with this video on it by running:"
98
-        echo "    tovid xml $OUT_FILENAME -out MyDisc"
99
-        echo "    tovid dvd MyDisc.xml"
100
-        echo "You can also use todisc or makemenu to create menus for your disc."
101
-        echo "See the tovid manual page ('man tovid') for more information."
102
+        echo "You can author a simple disc with this video on it by running:"
103
+        echo "    tovid disc -no-menu \"$OUT_FILENAME\" -out MyDisc"
104
+        echo "Add -burn for a prompt to burn (-device and -speed optional)"
105
+        echo "Or use todisc (tovid disc) to create text-only or animated menus."
106
+        echo "See the manual ('man tovid') for more information and options."
107
         echo
108
         echo "Please report bugs to:"
109
         echo "   http://code.google.com/p/tovid/issues/list"
110
@@ -880,10 +883,26 @@
111
 fi
112
 
113
 if ((USE_FILTERS)) && $USE_FFMPEG; then
114
-    usage_error "Sorry, you are using ffmpeg to encode
115
+    usage_error "Sorry, you are using $FFmpeg to encode
116
     video, either by choice or another option requires it.
117
     You can not use -filters with -ffmpeg"
118
 fi
119
+
120
+# see if ffmpeg is new enough to support -b:v etc
121
+# remove this when 0.9x ffmpeg is the oldest tovid will support
122
+# note ffmpeg is used for audio so this must run even when using mpeg2enc
123
+if $FFmpeg -f rawvideo  -pix_fmt yuv420p -s cif \
124
+    -i /dev/zero -t 1 -r 30 -f rawvideo \
125
+      -b:v 500k -y /dev/null > /dev/null 2>&1; then
126
+    VB=-b:v
127
+    AB=-b:a
128
+    CA=-c:a
129
+else
130
+    VB=-b
131
+    AB=-ab
132
+    CA=-acodec
133
+fi
134
+
135
 # make sure we are not running from the gui and set some options
136
 ! $FROM_GUI && NOCONSOLE_CONTROLS="-noconsolecontrols"
137
 
138
@@ -915,6 +934,16 @@
139
     usage_error "Please provide an output name with the -out option."
140
 fi
141
 
142
+# check that outfile does not contain a comma because of a mpeg2enc limitation
143
+if ! $USE_FFMPEG && [[ "$OUT_PREFIX" = *,* || "$IN_FILE" = *,* ]]; then
144
+    exit_with_error "Comma illegal in -out and -in NAME (mpeg2enc limitation)"
145
+fi
146
+# check that outfile or infile don't use $$ or $[0-9] because of mpeg2 'bug'
147
+if ! $USE_FFMPEG && [[ "$OUT_PREFIX" = *\$\$* || "$IN_FILE" = *\$\$* ]]; then
148
+    exit_with_error '"$$" illegal in -out and -in NAME (mpeg2enc limitation)'
149
+elif ! $USE_FFMPEG && [[ "$OUT_PREFIX" = *\$[0-9]* || "$IN_FILE" = *\$[0-9]* ]]; then
150
+    exit_with_error '"$" followed by a digit illegal in -out and -in NAME (mpeg2enc limitation)'
151
+fi
152
 # check that outfile is not a directory
153
 if test -d "$OUT_PREFIX"; then
154
     exit_with_error "Error: The specified output file is a directory.  A filename must be specified."
155
@@ -1066,7 +1095,7 @@
156
 
157
 # If multiple CPUs are available, do multithreading in mpeg2enc
158
 if $MULTIPLE_CPUS; then
159
-    yecho "Multiple CPUs detected; mpeg2enc and ffmpeg will use multithreading."
160
+    yecho "Multiple CPUs detected; mpeg2enc and $FFmpeg will use multithreading."
161
     MTHREAD="--multi-thread 2"
162
     FF_THREAD="-threads 4"
163
 else
164
@@ -1127,11 +1156,11 @@
165
 
166
     # Check for available space and prompt if it's not enough
167
     # not needed if using ffmpeg to encode video and audio "at once"
168
-    if ($USE_FFMPEG && (! $DO_NORM || ! [[ $ASYNC ]])) || $PARALLEL; then
169
+    if $PARALLEL; then
170
         :
171
     else
172
         check_disk_space
173
-        if test "$AVAIL_SPACE" -lt "$NEED_SPACE" && ! test $FROM_GUI -o $NOASK ; then
174
+        if ((AVAIL_SPACE < NEED_SPACE)) && ! $FROM_GUI && ! $NOASK; then
175
             yecho "Available: $AVAIL_SPACE, needed: $NEED_SPACE"
176
             echo "It doesn't look like you have enough space to encode this video."
177
             echo "Of course, I could be wrong. Do you want to proceed anyway? (y/n)"
178
@@ -1519,7 +1548,7 @@
179
         yecho "I can't find any deinterlacing options to use. No deinterlacing"
180
         yecho "will be done on this video (but encoding will continue)."
181
         yecho "Encoding will resume in 5 seconds..."
182
-        sleep 5s
183
+        sleep 5
184
     fi
185
     # Deinterlacing for ffmpeg
186
     FF_ILACE="-deinterlace"
187
@@ -1609,9 +1638,9 @@
188
 fi
189
 
190
 # ffmpeg's -vf aspect is more dependable than -aspect, if ffmpeg is new enough
191
-FF_FILTERS=$(ffmpeg -filters 2>&1)
192
+FF_FILTERS=$($FFmpeg -filters 2>&1)
193
 # newer ffmpeg's use setdar= and setsar=
194
-if grep -qw ^setdar <<< "$FF_FILTERS"; then
195
+if grep -qw setdar <<< "$FF_FILTERS"; then
196
     FF_ASPECT="setdar="
197
 # somewhat older rev's used aspect=
198
 elif grep -qw ^aspect <<< "$FF_FILTERS"; then
199
@@ -1620,14 +1649,24 @@
200
     FF_ASPECT='-aspect '
201
 fi
202
 # newer ffmpegs using filters use "-vf"
203
-FF_HELP=$(ffmpeg -h 2>&1)
204
+FF_HELP=$($FFmpeg -h full 2>&1)
205
 if grep -qw -- -vf <<< "$FF_HELP"; then
206
     VF="-vf"
207
 # somewhat older is "-vfilters"
208
 elif grep -qw -- -vfilters <<< "$FF_HELP"; then
209
     VF="-vfilters"
210
 else
211
-    VF=""
212
+    runtime_error "Your $FFmpeg is too old to support video filters"   
213
+fi
214
+# newaudio was removed in ffmpeg 0.9 as it was redundant because of -map opt
215
+grep -qw -- -newaudio <<< "$FF_HELP" && NEWAUDIO_OPT=true
216
+
217
+# we can't really parse which syntax to use for all filters, so here is a test
218
+errors=$( $FFmpeg -i "$IN_FILE" -t 1  \
219
+-vf scale=w=720:h=352,pad=width=720:height=480:x=0:y=64,setdar=16/9 \
220
+-f null  -y /dev/null 2>&1)
221
+if grep -qE "Error.*\(width\|height\|setdar\|w=\|h=\)" <<< "$errors"; then
222
+    ff_legacy=1
223
 fi
224
 
225
 # Anamorphic widescreen (16:9 output)
226
@@ -1635,14 +1674,16 @@
227
 # wasted on letterbox bars (or if the user requested -widetv output).
228
 if $ANAMORPH && { ((V_ASPECT_WIDTH >= 153)) || $WIDE_TV ; }; then
229
     TGT_ASPECT_WIDTH=177
230
-    FF_ASPECT="${FF_ASPECT}16:9"
231
+    ((ff_legacy)) && asp=16:9 || asp=16/9
232
+    FF_ASPECT="${FF_ASPECT}${asp}"
233
     ASPECT_FMT="--aspect 3"
234
 # For all others, use "non-anamorphic" (4:3 output)
235
 # Aspects from 133:100 to 153:100 have minimum pixel wastage
236
 # when letterboxed in 4:3
237
 else
238
     TGT_ASPECT_WIDTH=133
239
-    FF_ASPECT="${FF_ASPECT}4:3"
240
+    ((ff_legacy)) && asp=4:3 || asp=4/3
241
+    FF_ASPECT="${FF_ASPECT}${asp}"
242
     ASPECT_FMT="--aspect 2"
243
 fi
244
 
245
@@ -1703,10 +1744,6 @@
246
     FORCE_FPSRATIO=$TGT_FPSRATIO
247
     yecho "Found 1000fps (wmv) source, setting input to $TGT_FPS fps."
248
     yecho "Use -fps to force a different input fps (see 'man tovid')"
249
-    # TODO: Instead, use a two-pass encoding (since mencoder can
250
-    # do -ofps)
251
-    # mencoder -ovc copy -oac copy -ofps $TGT_FPSRATIO $INFILE -o twopass
252
-    # then do normal encoding on twopass
253
 fi
254
 
255
 # If forced FPS was used, apply it
256
@@ -1800,8 +1837,8 @@
257
     done
258
     testfile="/tmp/$(date +%s).mpg"
259
     track_key=${AUDIO_TRACK[max_key]}
260
-    ffm_cmd=( ffmpeg -i "$IN_FILE" $FF_THREAD -ss 2 -ab 224k -ac 2 \
261
-     -target ntsc-dvd -b 6000k -vframes 1 $VIDEO_MAP \
262
+    ffm_cmd=( $FFmpeg -i "$IN_FILE" $FF_THREAD -ss 2 $AB 224k -ac 2 \
263
+     -target ntsc-dvd $VB 6000k -vframes 1 $VIDEO_MAP \
264
      -map ${AIDS[track_key-1]//./:} "$testfile")
265
     yecho "Running ${ffm_cmd[@]}"
266
     if ! "${ffm_cmd[@]}" >/dev/null 2>&1; then
267
@@ -1836,14 +1873,16 @@
268
         AUDIO_WAV_MAP=( "${AUDIO_WAV_MAP[@]}" -map $i:0 )
269
         AUDIO_STREAM=( "${AUDIO_STREAM[@]}" "${TMP_DIR}/audio${i}.$AUD_SUF" )
270
         STREAM_CHANS=( "${STREAM_CHANS[@]}" ${AUDIO_CHAN[track-1]} "${AUDIO_STREAM[i]}" )
271
-        NEW_AUDIO[i]="-acodec ac3 -ab 224k ${AUDIO_CHAN[track-1]} -newaudio"
272
+        # -newaudio for ffmpeg versions prior to 0.9
273
+        $NEWAUDIO_OPT && \
274
+          NEW_AUDIO[i]="$CA ac3 $AB 224k ${AUDIO_CHAN[track-1]} -newaudio"
275
         AUDIO_WAV[i]="$TMP_DIR/audio${i}.wav"
276
         AUDIO_WAV_CHANS=( "${AUDIO_WAV_CHANS[@]}" ${AUDIO_CHAN[track-1]} "${AUDIO_WAV[i]}" )
277
     done
278
 
279
     FF_CHANNEL_MAP="$VIDEO_MAP $AUDIO_MAP"
280
     # we don't need the 1st track for -newaudio
281
-    unset NEW_AUDIO[0]
282
+    $NEWAUDIO_OPT && unset NEW_AUDIO[0]
283
     ((${#AUDIO_TRACK[@]} > 1)) && OUTPUT_FILES="each file" && s=s
284
 fi
285
 
286
@@ -1855,16 +1894,20 @@
287
 # ******************************************************************************
288
 
289
 if $USE_FFMPEG; then
290
-    FF_BITRATE="-b ${VID_BITRATE}k"
291
-    FF_SIZE="-s ${INNER_WIDTH}x${INNER_HEIGHT}"
292
+    FF_BITRATE="$VB ${VID_BITRATE}k"
293
+    if ((ff_legacy)); then
294
+        FF_SIZE="scale=${INNER_WIDTH}:${INNER_HEIGHT}"
295
+    else
296
+        FF_SIZE="scale=w=${INNER_WIDTH}:h=${INNER_HEIGHT}"
297
+    fi
298
     FF_CODEC="-f mpeg1video"
299
     FF_FPS="-r $TGT_FPS"
300
     FF_SAMPRATE="-ar $SAMPRATE"
301
     # try to get -quality 9 between quality 8 and 10
302
     if ((VID_QUALITY == 9)); then
303
         FF_ADD_ARGS="-trellis 1"
304
-        ! ffmpeg -h 2>&1 | grep -q trellis && usage_error \
305
-        "Your ffmpeg is too old to have the '-trellis' switch.  Use a -quality setting other than '9'."
306
+        ! grep -q trellis <<< "$FF_HELP" && usage_error \
307
+        "Your $FFmpeg is too old to have the '-trellis' switch.  Use a -quality setting other than '9'."
308
     fi
309
     [[ $TARGET = "DVD-VCD" ]] && FF_ADD_ARGS="$FF_ADD_ARGS -g 12" # experiment FIXME
310
 
311
@@ -1877,22 +1920,24 @@
312
     (( FF_VPIX )) || (( FF_HPIX )) && PAD=1
313
     # changed options: -pad{side} to -vf(ilters) pad= .
314
     if ((PAD)); then
315
-        if [[ $VF ]]; then
316
+        if ((ff_legacy)); then
317
             FF_PAD="pad=${TGT_WIDTH}:${TGT_HEIGHT}:${FF_HPIX}:${FF_VPIX}"
318
         else
319
-            ((FF_HPIX)) && FF_HPAD="-padleft $FF_HPIX -padright $FF_HPIX"
320
-            ((FF_VPIX)) && FF_VPAD="-padtop $FF_VPIX -padbottom $FF_VPIX"
321
-            FF_PAD="$FF_HPAD $FF_VPAD"
322
-        fi 
323
+            FF_PAD="pad=width=${TGT_WIDTH}:height=${TGT_HEIGHT}:x=${FF_HPIX}:y=${FF_VPIX}"
324
+        fi
325
     fi
326
 
327
     # use single variable for current, or legacy ffmpeg: VF_FILTERS and OLD_OPTS
328
     if [[ $VF ]]; then # libavfilter is being used, FF_ASPECT always passed
329
-        VF_FILTERS="${FF_PAD},${FF_ASPECT}"
330
+        VF_FILTERS="${FF_SIZE},${FF_PAD},${FF_ASPECT}"
331
         VF_FILTERS="$VF ${VF_FILTERS#,}" # add -vf*, axe possible leading comma
332
     else # legacy ffmpeg
333
         OLD_OPTS="$FF_PAD $FF_ASPECT"
334
     fi
335
+    # Remove extraneous commas from filter command
336
+    if test -n "$VF_FILTERS"; then
337
+        VF_FILTERS=$(sed 's/,,/,/g;s/,$//' <<< "$VF_FILTERS")
338
+    fi
339
 
340
     # Target TV system
341
     test "$TVSYS" = "PAL" && FF_TARGET="-target pal"
342
@@ -1915,12 +1960,12 @@
343
 if $USE_FFMPEG && ! $DO_NORM && [[ -z "$AUDIO_SYNC" ]] && ! $GENERATE_AUDIO; then
344
     chan1=${AUDIO_TRACK[0]}
345
     yecho
346
-    yecho "Using ffmpeg to encode audio and video."
347
+    yecho "Using $FFmpeg to encode audio and video."
348
 
349
-    FF_BITRATE="-b ${VID_BITRATE}k -ab ${AUD_BITRATE}k ${AUDIO_CHAN[chan1-1]} "
350
-    FF_ENC_CMD="$PRIORITY ffmpeg -i \"$IN_FILE\" $FF_THREAD $CLIP_SEEK $FF_LENGTH $ASYNC $ASYNC1 \
351
-        $FF_TARGET $FF_QUANT $FF_BITRATE $FF_ADD_ARGS $FF_FPS $FF_ILACE \
352
-        $FF_SIZE $VF_FILTERS $OLD_OPTS $FF_CHANNEL_MAP"
353
+    FF_BITRATE="$VB ${VID_BITRATE}k $AB ${AUD_BITRATE}k ${AUDIO_CHAN[chan1-1]} "
354
+    FF_ENC_CMD="$PRIORITY $FFmpeg -i \"$IN_FILE\" $FF_THREAD $CLIP_SEEK $FF_LENGTH $ASYNC $ASYNC1 \
355
+        $FF_TARGET $FF_QUANT $FF_ADD_ARGS $FF_ILACE \
356
+        $VF_FILTERS $OLD_OPTS $FF_BITRATE $FF_CHANNEL_MAP"
357
     $OVERWRITE && FF_ENC_CMD="$FF_ENC_CMD -y "
358
     FF_ENC_CMD="$FF_ENC_CMD \"$OUT_FILENAME\" ${NEW_AUDIO[@]}"
359
     yecho "Encoding video and audio with the following command:"
360
@@ -1931,7 +1976,7 @@
361
     if $FAKE; then
362
         :
363
     else
364
-        file_output_progress "$OUT_FILENAME" "Encoding with ffmpeg"
365
+        file_output_progress "$OUT_FILENAME" "Encoding with $FFmpeg"
366
         wait
367
     fi
368
     yecho
369
@@ -1962,14 +2007,12 @@
370
     yecho "Found compliant audio and dumping the stream."
371
     precho "This sometimes causes errors when multiplexing; add '-force' to the tovid command line to re-encode if multiplexing fails."
372
     yecho "Copying the existing audio stream with the following command:"
373
-    AUDIO_CMD=($PRIORITY ffmpeg $FF_THREAD $CLIP_SEEK $FF_LENGTH -i "$IN_FILE" -vn -acodec copy $AUDIO_MAP "${STREAM_CHANS[@]}")
374
+    AUDIO_CMD=($PRIORITY $FFmpeg $FF_THREAD $CLIP_SEEK $FF_LENGTH -i "$IN_FILE" -vn $CA copy $AUDIO_MAP "${STREAM_CHANS[@]}")
375
     yecho "${AUDIO_CMD[@]}"
376
     #AUDIO_CMD="$PRIORITY mplayer $MPLAYER_OPTS \"$IN_FILE\" -dumpaudio -dumpfile \"$AUDIO_STREAM\""
377
     run_audio_cmd()
378
     {
379
         "${AUDIO_CMD[@]}" >> "$LOG_FILE" 2>&1 &
380
-        #$PRIORITY ffmpeg $CLIP_SEEK $FF_LENGTH -i "$IN_FILE" -vn -acodec copy \
381
-        #$AUDIO_MAP "${AUDIO_STREAM[@]}" >> "$LOG_FILE" 2>&1
382
     }
383
     run_audio_cmd &
384
     PIDS="$PIDS $!"
385
@@ -1994,7 +2037,7 @@
386
         AUDIO_IN_FILE[1]="${AUDIO_WAV[0]}"
387
 
388
         #AUDIO_CMD="$PRIORITY mplayer $MPLAYER_OPTS -quiet -vc null -vo null $MP_AUDIOTRACK_CMD -ao pcm:waveheader:file=\"$AUDIO_WAV\" \"$IN_FILE\""
389
-        AUDIO_CMD=( $PRIORITY ffmpeg -y $FF_THREAD $CLIP_SEEK $FF_LENGTH -i "$IN_FILE" $ASYNC1 $AUDIO_MAP -ar $SAMPRATE -acodec pcm_s16le "${AUDIO_WAV_CHANS[@]}" )
390
+        AUDIO_CMD=( $PRIORITY $FFmpeg -y $FF_THREAD $CLIP_SEEK $FF_LENGTH -i "$IN_FILE" $ASYNC1 $AUDIO_MAP -ar $SAMPRATE $CA pcm_s16le "${AUDIO_WAV_CHANS[@]}" )
391
 
392
         # Generate or dump audio
393
         yecho "Normalizing the audio stream${s}."
394
@@ -2017,20 +2060,20 @@
395
         yecho
396
     fi
397
 
398
-    AUDIO_ENC=( $PRIORITY ffmpeg )
399
+    AUDIO_ENC=( $PRIORITY $FFmpeg )
400
 
401
     if $GENERATE_AUDIO; then
402
         # Read input from /dev/zero to generate a silent audio file
403
-        AUDIO_ENC=( "${AUDIO_ENC[@]}" -f s16le -i /dev/zero -t $V_DURATION )
404
+        AUDIO_ENC=( "${AUDIO_ENC[@]}" -f s16le -ar 48000 -i /dev/zero -t $V_DURATION )
405
         yecho "Generating a silent audio stream with the following command:"
406
     else
407
         # Encode audio stream directly from the input file
408
         AUDIO_ENC=( "${AUDIO_ENC[@]}" -i "${AUDIO_IN_FILE[@]}" )
409
         yecho "Encoding audio stream to $AUD_SUF with the following command:"
410
     fi
411
-    AUDIO_ENC=( "${AUDIO_ENC[@]}" -vn -ab ${AUD_BITRATE}k -ar $SAMPRATE )
412
+    AUDIO_ENC=( "${AUDIO_ENC[@]}" -vn $AB ${AUD_BITRATE}k -ar $SAMPRATE )
413
     ! $DO_NORM && AUDIO_ENC=( "${AUDIO_ENC[@]}" $CLIP_SEEK $FF_LENGTH $AUDIO_MAP )
414
-    AUDIO_ENC=( "${AUDIO_ENC[@]}" -acodec $AUD_SUF)
415
+    AUDIO_ENC=( "${AUDIO_ENC[@]}" $CA $AUD_SUF)
416
     $DO_NORM && AUDIO_ENC=( "${AUDIO_ENC[@]}" "${AUDIO_WAV_MAP[@]}" )
417
     AUDIO_ENC=( "${AUDIO_ENC[@]}" -y "${STREAM_CHANS[@]}" )
418
     "${AUDIO_ENC[@]}" >> "$LOG_FILE" 2>&1 &
419
@@ -2073,7 +2116,7 @@
420
 
421
 # If existing video is OK, skip video encoding and just copy the stream
422
 if ! $FORCE_ENCODING && $VIDEO_OK; then
423
-    VID_COPY_CMD="mencoder -of rawvideo -nosound -ovc copy \"$IN_FILE\" -o \"$VIDEO_STREAM\""
424
+    VID_COPY_CMD="$FFmpeg -i \"$IN_FILE\" -an -sn -vcodec copy -f rawvideo -o \"$VIDEO_STREAM\""
425
     yecho "Copying existing video stream with the following command:"
426
     yecho "$VID_COPY_CMD"
427
 
428
@@ -2093,9 +2136,9 @@
429
     if $USE_FIFO; then
430
         mkfifo "$YUV_STREAM" || runtime_error "Cannot create fifo $YUV_STREAM"
431
     fi
432
-    VID_PLAY_CMD="$PRIORITY $MPLAYER $NOCONSOLE_CONTROLS -benchmark -nosound -noframedrop $SUBTITLES -vo yuv4mpeg:file=\"$YUV_STREAM\"${YUV4MPEG_ILACE} $VID_FILTER $MPLAYER_OPTS \"$IN_FILE\" $CLIP_SEEK $MP_FRAMES"
433
+    VID_PLAY_CMD="$PRIORITY $MPLAYER -nomsgcolor $NOCONSOLE_CONTROLS -benchmark -nosound -noframedrop $SUBTITLES -vo yuv4mpeg:file=\"$YUV_STREAM\"${YUV4MPEG_ILACE} $VID_FILTER $MPLAYER_OPTS \"$IN_FILE\" $CLIP_SEEK $MP_FRAMES"
434
     if $USE_FFMPEG ; then
435
-        VID_ENC_CMD="ffmpeg -i \"$IN_FILE\" $FF_THREAD $CLIP_SEEK $FF_LENGTH -an $FF_TARGET $FF_CODEC $FF_QUANT $FF_BITRATE $FF_ADD_ARGS $FF_ILACE $FF_SIZE $VF_FILTERS $OLD_OPTS -y \"$VIDEO_STREAM\""
436
+        VID_ENC_CMD="$FFmpeg -i \"$IN_FILE\" $FF_THREAD $CLIP_SEEK $FF_LENGTH -an $FF_TARGET $FF_CODEC $FF_QUANT $FF_ADD_ARGS $FF_ILACE $VF_FILTERS $OLD_OPTS $FF_BITRATE -y \"$VIDEO_STREAM\""
437
     else
438
         VID_ENC_CMD="cat \"$YUV_STREAM\" | $YUVDENOISE $ADJUST_FPS $PRIORITY mpeg2enc --sequence-length $DISC_SIZE --nonvideo-bitrate $NONVIDEO_BITRATE $MTHREAD $ASPECT_FMT $MPEG2_FMT $VID_FPS $VERBOSE $VID_NORM $MPEG2_QUALITY -o \"$VIDEO_STREAM\""
439
     fi
440
tovid-0.34.tar.bz2/src/set_chapters -> tovid-0.35.tar.gz/src/set_chapters Changed
37
 
1
@@ -2,26 +2,21 @@
2
 
3
 import sys
4
 import Tkinter as tk
5
-from libtovid.guis.helpers import SetChapters
6
+from libtovid.guis.helpers import SetChaptersGui
7
 from os import path
8
 
9
 if len(sys.argv) < 2:
10
-    print("Usage: set_chapters.py video")
11
-    exit()
12
-
13
-video = sys.argv[1]
14
-if not path.exists(video):
15
-    print('Error: %s does not exist' %video)
16
-    exit()
17
-
18
-def print_chapters():
19
-    if app.get_chapters():
20
-        sys.stdout.write(app.get_chapters() + '\n')
21
+    video = None
22
+else:
23
+    video = sys.argv[1]
24
+    if not path.exists(video):
25
+        print('Error: the video file "%s" does not exist' %video)
26
+        exit()
27
 
28
 root = tk.Tk()
29
-app = SetChapters(root, '-menu', 'Mplayer', print_chapters, style='standalone')
30
+app = SetChaptersGui(root, '-osdlevel 3', 'Set chapter points with Mplayer')
31
 app.run(video)
32
 app.pack()
33
 
34
-root.mainloop()
35
+app.mainloop()
36
 
37
tovid-0.34.tar.bz2/src/titleset-wizard -> tovid-0.35.tar.gz/src/titleset-wizard Changed
1164
 
1
@@ -2,101 +2,182 @@
2
 
3
 import os.path
4
 import shlex
5
-import commands
6
-import tkFont
7
 import re
8
-from Tkinter import *
9
-from tkMessageBox import *
10
-from tkSimpleDialog import askstring
11
-from tkFileDialog import asksaveasfilename
12
-from subprocess import Popen, PIPE
13
-from libtovid.metagui import Style
14
-from libtovid.metagui.support import PrettyLabel, show_icons, get_photo_image
15
-from libtovid.cli import _enc_arg, Command
16
-from libtovid.util import trim
17
 from time import sleep
18
 from tempfile import mktemp
19
 from sys import argv, exit
20
 from base64 import b64encode
21
 from copy import deepcopy
22
-
23
-class Wizard(Frame):
24
-    """A frame to hold the wizard pages.  It will also hold the commands
25
-       that will  be processed and written out as a script.  Its base frame
26
-       holds a frame common to all pages that displays an icon, title, and
27
-       status panel.  It also has a bottom frame that contains the [Next] and
28
-       [Exit] buttons.  It will hold a list of all of the wizard pages.
29
+from subprocess import Popen, PIPE
30
+from libtovid import xrange
31
+from libtovid.cli import _enc_arg, Command
32
+from libtovid.util import trim
33
+from libtovid.metagui import Style
34
+from libtovid.metagui.support import (
35
+  PrettyLabel, show_icons, get_photo_image
36
+)
37
+
38
+# Python 3 compatibility
39
+try:
40
+    import Tkinter as tk
41
+    import tkFont
42
+    from tkSimpleDialog import askstring
43
+    from tkFileDialog import asksaveasfilename
44
+    from commands import getoutput, getstatusoutput
45
+    from tkMessageBox import (
46
+      askyesno, showwarning, showinfo, showerror, askokcancel
47
+      )
48
+except ImportError:
49
+    import tkinter as tk
50
+    import tkinter.font as tkFont
51
+    from tkinter.simpledialog import askstring
52
+    from tkinter.filedialog import asksaveasfilename
53
+    from subprocess import getoutput, getstatusoutput
54
+    from tkinter.messagebox import (
55
+      askyesno, showwarning, showinfo, showerror, askokcancel
56
+      )
57
+
58
+def get_screen_info(icon):
59
+    """Get window manager's title bar height and screen height.
60
+    This function  masquerades as a progress bar.
61
+    winfo_? includes the top panel if it exists, xwininfo just the titlebar.
62
+    Returns tuple: screen h, deco w, deco h.
63
+    """
64
+    try:
65
+        import Tix
66
+    # Python 3
67
+    except ImportError:
68
+        import tkinter.tix as Tix
69
+    import time
70
+    r = Tix.Tk()
71
+    r.withdraw()
72
+    top = Tix.Toplevel(r)
73
+    top.title('Loading ...')
74
+    top.geometry('+0+0')
75
+    show_icons(top, icon)
76
+    top.update_idletasks()
77
+    p = Tix.Meter(top, value=0.0)
78
+    p.pack()
79
+    for i in range(100):
80
+         time.sleep(0.01)
81
+         p.configure(value=(i/100.0))
82
+         p.update_idletasks()
83
+    xid = top.wm_frame()
84
+    # xwininfo returns a geometry string like '+2+23':  split it on '+'
85
+    # it tends to give just window decoration h, w rather than including a panel
86
+    Xwininfo = \
87
+      getoutput("xwininfo -frame -id %s |awk '/Corners:/ {print $2}'" %xid)
88
+    X_x = Xwininfo.split('+')[1]
89
+    X_y = Xwininfo.split('+')[2]
90
+    # winfo_x() winfo_y() tend to give panel AND window decoration
91
+    TK_x = top.winfo_x()
92
+    TK_y = top.winfo_y()
93
+    # so subtract the xwininfo x dimension from winfo_x; same for the y dimensions
94
+    # if xwininfo gives a lesser value, assume it just window deco, and subtract it
95
+    # else default to the greater (or equal) value of winfo_x (same for y dimension)
96
+    if TK_x > int(X_x):
97
+        frame_width = TK_x - int(X_x)
98
+    else:
99
+        frame_width = TK_x
100
+    if TK_y > int(X_y):
101
+        frame_height = TK_y - int(X_y)
102
+    else:
103
+        frame_height = TK_y
104
+    screeninfo = top.winfo_screenheight(), frame_width, frame_height
105
+    r.destroy()
106
+    return screeninfo
107
+
108
+
109
+
110
+class Wizard(tk.Frame):
111
+    """A frame to hold the wizard pages.
112
+       It will also hold the commands that will  be processed and written out
113
+       as a script.  Its base frame holds a frame common to all pages that
114
+       displays an icon, title, and status panel.  It also has a bottom frame
115
+       that contains the [Next] and [Exit] buttons.
116
+       It will hold a list of all of the wizard pages.
117
 
118
        master: the Tk() instance called by __main__
119
-       icon: Path to an image file (gif) to display on the left frame
120
        text: The text for the wizard title above and/or below the icon
121
              Use \n to break title into above\nbelow.
122
+       icon: Path to an image file (gif) to display on the left frame
123
+       infile: an infile provided as a saved project, that will be loaded
124
        
125
     """
126
-    def __init__(self, master, text, icon):
127
-        Frame.__init__(self, master)
128
+    def __init__(self, master, text, icon, infile=''):
129
+        tk.Frame.__init__(self, master)
130
         self.pages = []
131
-        self.index = IntVar()
132
+        self.index = tk.IntVar()
133
         self.text = text
134
         self.icon = icon
135
         self.master = master
136
         self.root = self._root()
137
         self.commands = []
138
+        self.screen_info = []
139
         # for cancelling run_gui if exit is called
140
-        self.is_running = BooleanVar()
141
+        self.is_running = tk.BooleanVar()
142
         self.is_running.set(True)
143
         # for waiting on [Next>>>] being pushed to continue titleset loop
144
-        self.waitVar = BooleanVar()
145
+        self.waitVar = tk.BooleanVar()
146
         self.waitVar.set(False)
147
-        # pid for xterm, to allow clean exit
148
-        # need this to make sure we don't have zombie processes
149
-        self.xterm_is_running = BooleanVar()
150
-        self.check = ''
151
-        self.xterm_is_running.set(False)
152
+        # variable for name of final script
153
+        self.project = ''
154
+        # variable for possible pre-loaded script -
155
+        self.is_infile = False
156
         # bindings for exit
157
         self.root.protocol("WM_DELETE_WINDOW", self.confirm_exit)
158
         self.root.bind('<Control-q>', self.confirm_exit)
159
         self.root.title('Tovid titleset wizard')
160
 
161
         # button frame
162
-        self.button_frame = Frame(master)
163
+        self.button_frame = tk.Frame(master)
164
         self.button_frame.pack(side='bottom', fill='x', expand=1,  anchor='se')
165
-        self.exit_button = Button(self.button_frame, text='Exit',
166
+        self.exit_button = tk.Button(self.button_frame, text='Exit',
167
                                        command=self.confirm_exit)
168
         self.exit_button.pack(side='left', anchor='sw')
169
-        self.next_button = Button(self.button_frame, text='Next >>',
170
+        self.next_button = tk.Button(self.button_frame, text='Next >>',
171
                                                   command=self.next)
172
         self.next_button.pack(side='right', anchor='se')
173
-        self.prev_button = Button(self.button_frame, text='<< Back',
174
+        self.prev_button = tk.Button(self.button_frame, text='<< Back',
175
                                                     command=self.previous)
176
         # frame for icon and status display
177
-        self.frame1 = Frame(master)
178
+        self.frame1 = tk.Frame(master)
179
         self.frame1.pack(side='left', anchor='nw', padx=10, pady=80)
180
         inifile = os.path.expanduser('~/.metagui/config')
181
         style = Style()
182
-        style.load(inifile)
183
+        # make sure ~/.metagui and the config file exist
184
+        if os.path.exists(inifile):
185
+            style.load(inifile)
186
+            print("Loading style from config file: '%s'" % inifile)
187
+        else:
188
+            print("Creating config file: '%s'" % inifile)
189
+            style.save(inifile)
190
         self.font = style.font
191
         self.draw()
192
 
193
+        # if a script is being loaded (infile), then assign to self.project
194
+        if infile:
195
+            self.is_infile = True
196
+            self.project = infile
197
+
198
     def draw(self):
199
         # get fonts
200
         font = self.font
201
         self.lrg_font = self.get_font(font, size=font[1]+4, _style='bold')
202
         self.medium_font = self.get_font(font, size=font[1]+2)
203
         self.heading_font = self.get_font(font, size=font[1]+8, _style='bold')
204
-        fixed =  '-misc-fixed-medium-r-normal--13-100-100-100-c-70-iso8859-1'
205
-        self.fixed_font = tkFont.Font(font=fixed)
206
+        #fixed =  '-misc-fixed-medium-r-normal--13-100-100-100-c-70-iso8859-1'
207
         self.background = self.root.cget('background')
208
         if self.text:
209
             txt = self.text.split('\n')
210
-            app_label1 = Label(self.frame1, text=txt[0], font=self.heading_font)
211
+            app_label1 = tk.Label(self.frame1, text=txt[0], font=self.heading_font)
212
             app_label1.pack(side='top', fill='both', expand=1, anchor='nw')
213
         # icons and image
214
         if os.path.isfile(self.icon):
215
             img = get_photo_image(self.icon, 0, 0, self.background)
216
             self.img = img
217
             # Display the image in a label on all pages
218
-            img_label = Label(self.frame1, image=self.img)
219
+            img_label = tk.Label(self.frame1, image=self.img)
220
             img_label.pack(side='top', fill='both', expand=1,
221
                                         anchor='nw', pady=20)
222
             # If Tcl supports it, generate an icon for the window manager
223
@@ -106,11 +187,12 @@
224
             print('%s does not exist' % img_file)
225
         # if 2 lines of text for image, split top and bottom
226
         if self.text and len(txt) > 1:
227
-            app_label2 = Label(self.frame1, text=txt[1], font=self.lrg_font)
228
+            app_label2 = tk.Label(self.frame1, text=txt[1], font=self.lrg_font)
229
             app_label2.pack(side='top', fill='both', expand=1, anchor='nw')
230
 
231
     def next(self):
232
-        """Move to the next wizard page"""
233
+        """Move to the next wizard page.
234
+        """
235
         index = self.index.get()
236
         try:
237
             self.pages[index].hide_page()
238
@@ -124,11 +206,15 @@
239
         self.pages[index].previous()
240
 
241
     def set_pages(self, page):
242
-        """Accept incoming list of wizard page instances"""
243
+        """Accept incoming list of wizard page instances.
244
+        """
245
         self.pages.append(page)
246
 
247
+    def set_screen_info(self, iterable):
248
+        self.screen_info = iterable
249
+
250
     def get_font(self, font_descriptor, name='', size='', _style=''):
251
-        """Get metagui font configuration
252
+        """Get metagui font configuration.
253
         """
254
         font = [name, size, _style]
255
         for i in range(len(font_descriptor)):
256
@@ -137,75 +223,67 @@
257
         return tuple(font)
258
 
259
     def show_status(self, status):
260
-        """Show status label on all pages, with timeout
261
+        """Show status label on all pages, with timeout.
262
         """
263
         if status == 0:
264
             text='\nOptions saved!\n'
265
         else:
266
             text='\nCancelled!\n'
267
         font = self.medium_font
268
-        status_frame = Frame(self.frame1, borderwidth=1, relief=RAISED)
269
+        status_frame = tk.Frame(self.frame1, borderwidth=1, relief=tk.RAISED)
270
         status_frame.pack(pady=40)
271
-        label1 = Label(status_frame, text=text, font=font, fg='blue')
272
+        label1 = tk.Label(status_frame, text=text, font=font, fg='blue')
273
         label1.pack(side='top')
274
-        label2 = Label(status_frame, text='ok', borderwidth=2, relief=GROOVE)
275
+        label2 = tk.Label(status_frame, text='ok', borderwidth=2, relief=tk.GROOVE)
276
         label2.pack(side='top')
277
-        self.root.after(1000, lambda: label2.configure(relief=SUNKEN))
278
+        self.root.after(1000, lambda: label2.configure(relief=tk.SUNKEN))
279
         self.root.after(2000, lambda: status_frame.pack_forget())
280
 
281
     def confirm_exit(self, event=None):
282
         """Exit the GUI, with confirmation prompt.
283
         """
284
-        mess = 'Xterm is still open: is todisc still running?  ' + \
285
-          'If so, please ctrl-c in the terminal if you wish to quit.  ' + \
286
-          'In any case, you will need to close the terminal ' + \
287
-          'by pressing <ENTER> in it.'
288
-        if self.xterm_is_running.get() == True:
289
-            showwarning(message=mess)
290
-            return
291
         if askyesno(message="Exit?"):
292
             # set is_running to false so the gui doesn't get run
293
             self.is_running.set(False)
294
+            # remove project file if we quit early and it exists and is empty
295
+            if os.path.exists(self.project):
296
+                if os.stat(self.project).st_size == 0:
297
+                    print('removing empty file: %s' %self.project)
298
+                    os.remove(self.project)
299
             # waitVar may cause things to hang, spring it
300
             self.set_waitvar()
301
             self.root.quit()
302
 
303
     # unused
304
     def kill_pid(self, pid):
305
-        """Test and kill xterm pid in case of premature exit"""
306
+        """Test and kill xterm pid in case of premature exit.
307
+        """
308
         if not pid:
309
             return
310
-        test_pid = commands.getstatusoutput('kill -0 %s' %pid)
311
+        test_pid = getstatusoutput('kill -0 %s' %pid)
312
         if test_pid[0] == 0:
313
             cmd = ['kill', '%s' %pid]
314
             Popen(cmd, stderr=PIPE)
315
 
316
     def set_waitvar(self):
317
-        """Set a BooleanVar() so tk.wait_var can exit
318
+        """Set a BooleanVar() so tk.wait_var can exit.
319
         """
320
         self.waitVar.set(True)
321
 
322
 
323
-class WizardPage(Frame):
324
-    """Base class for the wizard pages.  As such it contains everythig
325
-       common to all wizard pages.
326
+class WizardPage(tk.Frame):
327
+    """Base class for the wizard pages.
328
+       As such it contains everythig common to all wizard pages.
329
     """
330
     def __init__(self, master):
331
-        Frame.__init__(self, master)
332
-        Frame.pack(master)
333
+        tk.Frame.__init__(self, master)
334
+        tk.Frame.pack(master)
335
         self.master = master
336
         self.root = self._root()
337
-        # a temp file name for the final script name if it exists already
338
-        curdir = os.path.abspath('')
339
-        self.newname = mktemp(suffix='.bash', prefix='todisc_commands.',
340
-                                                             dir=curdir)
341
         # get tovid prefix
342
-        tovid_prefix = commands.getoutput('tovid -prefix')
343
+        tovid_prefix = getoutput('tovid -prefix')
344
         self.tovid_prefix = os.path.join(tovid_prefix, 'lib', 'tovid')
345
         os.environ['PATH'] = self.tovid_prefix + os.pathsep + os.environ['PATH']
346
-        # the script we will be using for options
347
-        cur_dir = os.path.abspath('')
348
-        self.script_file = cur_dir + '/todisc_commands.bash'
349
         # get script header
350
         shebang = '#!/usr/bin/env bash'
351
         _path = 'PATH=' + self.tovid_prefix + ':$PATH'
352
@@ -214,9 +292,10 @@
353
         identifier = '# tovid project script\n# tovid version %s' % _version
354
         self.header = '%s\n\n%s\n\n%s\n\n' % (shebang, identifier, _path )
355
         # ititialize a frame, but don't pack yet
356
-        self.frame = Frame(self.master)
357
+        self.frame = tk.Frame(self.master)
358
         # initialize widgets, but don't show yet
359
         self.master.set_pages(self)
360
+        self.titlebar_width, self.titlebar_height = self.master.screen_info[1:]
361
 
362
     def show_page(self):
363
         wizard = self.master
364
@@ -228,47 +307,79 @@
365
     def hide_page(self):
366
         self.frame.pack_forget()
367
 
368
-    def run_gui(self, args=[], index='', script=''):
369
-        """Run the tovid GUI, collecting options, and saving to wizard
370
+    def get_screen_position(self):
371
+        """get real screen position, taking into account window decorations.
372
+        """
373
+        r = self.root
374
+        r.update_idletasks() # make sure geometry is updated before we 'get' it
375
+        geo_x = r.winfo_rootx() - self.titlebar_width
376
+        geo_y = r.winfo_rooty() - self.titlebar_height
377
+        return '+%s+%s' %(geo_x, geo_y)
378
+
379
+    def check_int(self, List):
380
+        """return list of ints from list of strings, checking 1st if castable.
381
+        """
382
+        for index, item in enumerate(List):
383
+            try:
384
+                List[index] = int(item)
385
+            except ValueError:
386
+                return []
387
+        return List
388
+
389
+    def run_gui(self, args=[], index='', project=''):
390
+        """Run the tovid GUI, collecting options, and saving to wizard.
391
         """
392
         title = 'load saved script'
393
-        script = 'todisc_commands.bash'
394
-        set_env = []
395
         if index:
396
             os.environ['METAGUI_WIZARD'] = '%s' %index
397
-        cmd = ['todiscgui'] + args
398
-        todiscgui_cmd = Popen(cmd, stdout=PIPE)
399
+        self.root.update_idletasks() # update geometry before it is 'deiconified'
400
+        self.screen_pos = self.get_screen_position()
401
+        # these 2 are just convenience vars for shorter line length
402
+        script = self.master.project
403
+        position = self.screen_pos
404
+        # get modification time of the script, so we can see if it changes
405
+        mtime = os.path.getmtime(script)
406
+        #cmd = ['todiscgui'] + ['--position', self.screen_pos] + ['--project', self.master.project.get()] + args
407
+        cmd = ['todiscgui', '--position', position, '--project', script] + args
408
+        todiscgui_cmd = Popen(cmd, stdout=PIPE, stderr=PIPE)
409
         # sleep to avoid the 'void' of time before the GUI loads
410
         sleep(0.5)
411
         if self.root.state() is not 'withdrawn':
412
             self.root.withdraw()
413
-        status = todiscgui_cmd.wait()
414
-        if status == 200:
415
-        # if script doesn't exist prompt for load.
416
-            if os.path.exists(self.script_file):
417
-                script = self.script_file
418
-            else:
419
-                err = 'A problem has occured with saving your options.  ' + \
420
-                  'The saved script file was not found.  ' + \
421
-                  'Please submit a bug report'
422
-                showerror(message=err)
423
-                return
424
+        todiscgui_cmd.wait()
425
+        # hack to deiconify wizard at same position as the exiting tovid gui
426
+        for line in todiscgui_cmd.stderr.readlines():
427
+            L = line.split(b'+') # python 3 compatibility (b'')
428
+            if b'gui position ' in L and len(L) == 3:
429
+                result = self.check_int(L[-2:])
430
+                if result:
431
+                    x = result[0]-self.master.screen_info[1]
432
+                    y = result[1]-self.master.screen_info[2]
433
+                    self.screen_pos = '+%d+%d' %(x, y)
434
+                    break
435
+            
436
+        # if modification time changed, then the script was saved from the gui
437
+        if os.path.getmtime(script) > mtime:
438
             # Read lines from the file and reassemble the command
439
             todisc_opts = self.script_to_list(script)
440
-            os.remove(script)
441
+            # blank file: don't remove as we need it to get mtime in run_gui()
442
+            open(script, 'w').close()
443
         else:
444
             todisc_opts  = []
445
+        # set wizard screen position again, then update
446
+        self.root.geometry(self.screen_pos)
447
+        self.root.update_idletasks()
448
         return todisc_opts
449
 
450
     def page_controller(self):
451
         self.master.next()
452
 
453
-    def script_to_list(self, infile):
454
-        """File contents to a list, trimming '-from-gui' and header
455
+    def script_to_list(self, script):
456
+        """File contents to a list, trimming '-from-gui' and header.
457
         """
458
         add_line = False
459
         command = ''
460
-        for line in open(infile, 'r'):
461
+        for line in open(script, 'r'):
462
             if line.startswith('-'):
463
                 add_line = True
464
             if add_line and not line.startswith('-from-gui'):
465
@@ -277,12 +388,13 @@
466
         return shlex.split(command)
467
 
468
     def write_script(self):
469
-        """Write out the final script to todisc_commands.bash
470
+        """Write out the final script to project filename.
471
         """
472
         commands = self.master.commands
473
         header = self.header
474
-        cmdout = open(self.script_file, 'w')
475
-        os.chmod(self.script_file, 0775)
476
+        cmdout = open(self.master.project, 'w')
477
+        # mode compatibility for 2.4 to 3.x python
478
+        os.chmod(self.master.project, int('755', 8))
479
         # add the shebang, PATH, and 'todisc \' lines
480
         cmdout.writelines(header)
481
         # flatten the list
482
@@ -299,7 +411,7 @@
483
         cmdout.close()
484
 
485
     def trim_list_header(self, cmds):
486
-            """Trim header (items before 1st '-' type option) from a list
487
+            """Trim header (items before 1st '-' type option) from a list.
488
             """
489
             # remove shebang, identifier and PATH
490
             try:
491
@@ -329,7 +441,7 @@
492
         return chunk
493
 
494
     def get_list_args(self, items, option):
495
-        """Get option arguments from a list (to next item starting with '-')
496
+        """Get option arguments from a list (to next item starting with '-').
497
         """
498
         try:
499
             index = items.index(option)
500
@@ -347,7 +459,7 @@
501
         return chunk
502
 
503
     def see_me(self, widget):
504
-        """Bring attention to widget by changing text colour
505
+        """Bring attention to widget by changing text colour.
506
         """
507
         # 3000 and 4000 ms because show_status uses up 3000 already
508
         self.root.after(3000, lambda: widget.configure(foreground='blue'))
509
@@ -356,7 +468,7 @@
510
 
511
 
512
     def refill_listbox(self, listbox, opts):
513
-        """Repopulate the rerun listbox with option list titles
514
+        """Repopulate the rerun listbox with option list titles.
515
         """
516
         if '-titles' in opts:
517
             new_titles = self.get_list_args(opts, '-titles')
518
@@ -370,10 +482,11 @@
519
         for i in xrange(numtitles):
520
             listbox.insert('end', new_titles[i])
521
 
522
-    def rename_script(self):
523
+    # unused (note self.script_file also unused now)
524
+    def rename_script(self, path):
525
         # if todisc_commands.bash exists in current dir, prompt for rename
526
         rename_msg = 'The option file we will use:\n' + \
527
-          '"todisc_commands.bash"\n' + \
528
+          self.master.script.get() + '\n' + \
529
           'exists in the current directory.\n' + \
530
           'It will be renamed to:\n' + \
531
           '"%s"' + \
532
@@ -387,14 +500,15 @@
533
 
534
 
535
 class Page1(WizardPage):
536
-    """Wizard intro page"""
537
+    """Wizard intro page.
538
+    """
539
     def __init__(self, master):
540
         WizardPage.__init__(self, master)
541
         # draw the page by default unless script file arg passed
542
-        if len(argv) < 2:
543
+        if not self.master.is_infile:
544
             self.draw()
545
-        index = self.master.pages.index(self)
546
-        self.master.index.set(index)
547
+            index = self.master.pages.index(self)
548
+            self.master.index.set(index)
549
 
550
     def draw(self):
551
         self.frame.pack(side='right', fill='both', expand=1, anchor='nw')
552
@@ -430,7 +544,8 @@
553
 
554
 
555
 class Page2(WizardPage):
556
-    """Wizard general options page"""
557
+    """Wizard general options page.
558
+    """
559
     def __init__(self, master):
560
         WizardPage.__init__(self, master)
561
 
562
@@ -438,6 +553,11 @@
563
         self.frame.pack(side='right', fill='both', expand=1, anchor='nw')
564
         text = '''GENERAL OPTIONS
565
 
566
+        Please set a name for your 'project' in the box at the bottom of the page,
567
+        by pressing the "Browse" button, and browsing to the directory you want
568
+        to save it.  This will be a bash script that can be run standalone, or
569
+        reloaded into the titleset-wizard for further editing.
570
+
571
         When you press the  "Next >>>"  button at the bottom of the wizard, we
572
         will start the GUI and begin with general options applying to all
573
         titlesets.  For example you may wish to have all menus share a common
574
@@ -448,17 +568,31 @@
575
         bottom of the GUI's main tab.  Options you enter will be overridden if
576
         you use the same option again later for titlesets.
577
 
578
-        After making your selections, press [ Save to wizard ] in the GUI
579
+        In the GUI, after making your selections, press [ Save to wizard ].
580
 
581
-        Press  "Next >>>"  to begin ...
582
+        Enter a project name, then press  "Next >>>"
583
         '''
584
         text = trim(text)
585
         self.label = PrettyLabel(self.frame, text, self.master.font)
586
         self.label.pack(fill='both', expand=1, anchor='nw')
587
+        # setting project name
588
+        self.project_label = tk.Label(self.frame, text='Project name', font=self.master.font,
589
+                                       justify='left', padx=10, pady=10)
590
+        self.project_label.pack(fill='both', expand=1, anchor='sw')
591
+        self.project_frame = tk.Frame(self.frame)
592
+        self.project_entry = tk.Entry(self.project_frame, width=50)
593
+        self.project_entry.insert(0, 'Press Browse Button')
594
+        self.project_entry.bind("<KeyPress>", lambda e: "break")
595
+        self.browse_button = tk.Button(self.project_frame, text="Browse...",
596
+                                                        command=self.browse)
597
+        self.project_frame.pack(fill='both', expand=1, anchor='sw')
598
+        self.project_entry.pack(side='left')
599
+        self.browse_button.pack(side='right')
600
 
601
     def page_controller(self):
602
-        if os.path.exists(self.script_file):
603
-            self.rename_script()
604
+        if not self.master.project:
605
+            # here we need a popup telling user to enter a project name #FIXME
606
+            return 
607
         wizard = self.master
608
         index = wizard.index.get()
609
         move = True
610
@@ -469,16 +603,25 @@
611
             move = False
612
         else:
613
             status = 0
614
-            cmds = [l for l in cmds if l]
615
+            cmds = [L for L in cmds if L]
616
             wizard.commands.append(cmds)
617
         wizard.show_status(status)
618
         self.root.deiconify()
619
         if move:
620
             wizard.next()
621
 
622
+    def browse(self, e=None):
623
+        title = 'Type a filename'
624
+        filename = asksaveasfilename(parent=self, title=title, initialfile='my_project.tovid')
625
+        if filename:
626
+            self.project_entry.delete(0, 'end')
627
+            self.project_entry.insert(0, filename)
628
+            self.master.project = filename
629
+            open(filename, 'w').close()
630
 
631
 class Page3(WizardPage):
632
-    """Wizard root menu page"""
633
+    """Wizard root menu page.
634
+    """
635
     def __init__(self, master):
636
         WizardPage.__init__(self, master)
637
 
638
@@ -509,16 +652,16 @@
639
         self.titlebox = TitleBox(self.frame, text="Root 'menu link' titles")
640
 
641
     def save_list(self):
642
-        """Save the current listbox contents
643
+        """Save the current listbox contents.
644
         """
645
         # get a list of listbox lines
646
         temp_list = list(self.titlebox.get(0, 'end'))
647
-        return [ l for l in temp_list if l]
648
+        return [ L for L in temp_list if L]
649
 
650
     def page_controller(self):
651
         wizard = self.master
652
         run_cmds = list(self.titlebox.get(0, 'end'))
653
-        run_cmds = [l for l in run_cmds if l]
654
+        run_cmds = [L for L in run_cmds if L]
655
         if len(run_cmds) < 2:
656
             showerror(message=\
657
               'At least two titlesets (titles) must be defined')
658
@@ -546,7 +689,8 @@
659
 
660
 
661
 class Page4(WizardPage):
662
-    """Wizard titleset menu page"""
663
+    """Wizard titleset menu page.
664
+    """
665
     def __init__(self, master):
666
         WizardPage.__init__(self, master)
667
 
668
@@ -569,8 +713,8 @@
669
         text1 = trim(text1)
670
         self.label1 = PrettyLabel(self.frame, text1, self.master.font)
671
         self.label1.pack(fill='both', expand=True, side='top', anchor='nw')
672
-        self.frame2 = Frame(self.frame, borderwidth=2, relief=GROOVE)
673
-        self.label2 = Label(self.frame2, text='', font=self.master.font,
674
+        self.frame2 = tk.Frame(self.frame, borderwidth=2, relief=tk.GROOVE)
675
+        self.label2 = tk.Label(self.frame2, text='', font=self.master.font,
676
                                        justify='left', padx=10, pady=10)
677
         self.label2.pack(fill='both', expand=True, side='top', anchor='nw')
678
 
679
@@ -622,16 +766,17 @@
680
 
681
 
682
 class Page5(WizardPage):
683
-    """Final wizard page.  Here you can rerun options that have been saved
684
-       from the tovid GUI, and add or remove titlesets.  You can also
685
-       choose to run the final project
686
+    """Final wizard page.
687
+       Here you can rerun options that have been saved from the tovid GUI, and
688
+       add or remove titlesets.  You can also choose to run the final project.
689
     """
690
     def __init__(self, master):
691
         WizardPage.__init__(self, master)
692
         self.curindex = 0
693
         self.lastindex = 0
694
-        # set commands and draw this page if script file arg passed
695
-        if len(argv) > 1:
696
+        # set commands and draw by default if script (infile) arg passed
697
+        # self.master.project.get() would be set to that file
698
+        if self.master.is_infile:
699
             self.set_project_commands()
700
             self.draw()
701
             index = self.master.pages.index(self)
702
@@ -646,8 +791,8 @@
703
         Edit or reorder your selections using the listbox below.  (Note
704
         that menu link titles as shown in listbox are saved as titles
705
         in the "Root menu" options.)  If you are happy with your saved
706
-        options, run the script now , or exit and run it later.
707
-        You can run it later with:
708
+        options, run the script now in an xterm, or exit and run it later.
709
+        You can run it with:
710
 
711
         bash %s
712
 
713
@@ -662,32 +807,33 @@
714
         tovid titlesets %s
715
 
716
         Edit your selections, or press [Run script now] or [Exit].
717
-        ''' % (self.script_file, self.script_file)
718
+        ''' % (self.master.project, self.master.project)
719
+
720
         text = trim(text)
721
-        self.heading_label = Label(self.frame, text='Finished!',
722
-                                      font=wizard.lrg_font)
723
-        self.label = PrettyLabel(self.frame, text,
724
-                      wizard.font, height=18)
725
+        self.heading_label = tk.Label(self.frame,
726
+                    text='Your script is ready to run!', font=wizard.lrg_font)
727
+        self.label = tk.Label(self.frame, text=text,
728
+                      font=wizard.font, justify='left')
729
         self.heading_label.pack(fill='both', expand=1, anchor='nw', pady=5)
730
         self.label.pack(fill='both', expand=1, anchor='nw')
731
-        # create the listbox (note that size is in characters)
732
+
733
         frame_text = "Edit items, or add, remove or drag/drop titlesets"
734
-        frame2 = LabelFrame(self.frame, text=frame_text)
735
-        button_frame = Frame(frame2)
736
-        button_frame.pack(side='bottom', fill=X, expand=1, anchor='sw')
737
-        button2 = Button(button_frame, text='Add titleset',
738
+        frame2 = tk.LabelFrame(self.frame, text=frame_text)
739
+        button_frame = tk.Frame(frame2)
740
+        button_frame.pack(side='bottom', fill=tk.X, expand=1, anchor='sw')
741
+        button2 = tk.Button(button_frame, text='Add titleset',
742
                                  command=self.add_titleset)
743
         button2.pack(side='left', anchor='w')
744
-        button1 = Button(button_frame, text='Edit', command=self.rerun_options)
745
+        button1 = tk.Button(button_frame, text='Edit', command=self.rerun_options)
746
         button1.pack(side='left', fill='x', expand=1)
747
-        button3 = Button(button_frame, text='Remove titleset',
748
+        button3 = tk.Button(button_frame, text='Remove titleset',
749
                                  command=self.remove_titleset)
750
         button3.pack(side='right', anchor='e')
751
-        self.listbox = Listbox(frame2, width=50, exportselection=0)
752
+        self.listbox = tk.Listbox(frame2, width=50, exportselection=0)
753
         self.listbox.pack(side='left', fill='both', expand=1)
754
         self.listbox.bind('<Double-Button-1>', self.rerun_options)
755
         # create a vertical scrollbar to the right of the listbox
756
-        yscroll = Scrollbar(frame2, command=self.listbox.yview,
757
+        yscroll = tk.Scrollbar(frame2, command=self.listbox.yview,
758
                                              orient='vertical')
759
         yscroll.pack(side='right', fill='y', anchor='ne')
760
         self.listbox.configure(yscrollcommand=yscroll.set)
761
@@ -743,7 +889,7 @@
762
             temp_list[index_b] = item_a
763
         except IndexError:
764
             # should not happen
765
-            print 'index out of range!'
766
+            print('index out of range!')
767
         # Set the updated list
768
         self.listbox.delete(0, 'end')
769
         self.listbox.insert(0, *temp_list)
770
@@ -764,8 +910,9 @@
771
             self.write_script()
772
 
773
     def set_index(self, Event=None):
774
-        """Called when item in listbox selected.  Set curindex and change
775
-           cursor to double-arrow.  lastindex==curindex if no drag occurs.
776
+        """Called when item in listbox selected.
777
+           Set curindex and change cursor to double-arrow.
778
+           lastindex==curindex if no drag occurs.
779
         """
780
         self.curindex = self.listbox.nearest(Event.y)
781
         self.lastindex = self.curindex
782
@@ -783,7 +930,7 @@
783
 
784
     # used to repopulate titleset titles after adding new one
785
     def get_option(self, items, option):
786
-        """Get option and arguments from a list (to next item starting with '-')
787
+        """Get option and args from a list (to next item starting with '-').
788
         The list is modified in place.
789
         """
790
         try:
791
@@ -868,10 +1015,11 @@
792
         self.write_script()
793
 
794
     def mod_sublist(self, item='', *index):
795
-        """Modify commands sublist.  If 2 indexes, just swap items.  If one
796
-           index the default behavior is to delete the index from the sublist
797
-           and remove it from commands, but if item is passed, add it as a
798
-           new index instead.
799
+        """Modify commands sublist.
800
+           If 2 indexes, just swap items.
801
+           If one index the default behavior is to delete the index from the
802
+           sublist and remove it from commands, but if item is passed,
803
+           add it as a new index instead.
804
         """
805
         wizard = self.master
806
         vmgm_cmds = [w for w in wizard.commands[1]]
807
@@ -898,7 +1046,7 @@
808
         wizard.commands.insert(1, vmgm_cmds)
809
 
810
     def rerun_options(self, Event=None, index=None):
811
-        """Run the gui with the selected options
812
+        """Run the gui with the selected options.
813
         """
814
         # self.master is the WizardPage
815
         commands = self.master.commands
816
@@ -913,7 +1061,7 @@
817
         # the GUI doesn't understand the titleset type options
818
         remove = ['-vmgm', '-end-vmgm', '-titleset', '-end-titleset']
819
         options = [ i for i in commands[index] if not i in remove ]
820
-        rerun_opts = self.run_gui(options, '%s' %(index+1))
821
+        rerun_opts = self.run_gui(options, '%d' %(index+1))
822
         if rerun_opts:
823
             status = 0
824
             # trim header from todisc_cmds
825
@@ -943,16 +1091,17 @@
826
     def set_project_commands(self):
827
         in_contents = self.script_to_list(argv[1])
828
         in_cmds = in_contents[:]
829
-        all = [self.get_chunk(in_cmds, '-vmgm', '-end-vmgm')]
830
+        _all = [self.get_chunk(in_cmds, '-vmgm', '-end-vmgm')]
831
         while '-titleset' in in_cmds:
832
-            all.append( self.get_chunk(in_cmds, '-titleset', '-end-titleset') )
833
-        all.insert(0, in_cmds)
834
-        self.master.commands = all
835
+            _all.append( self.get_chunk(in_cmds, '-titleset', '-end-titleset') )
836
+        _all.insert(0, in_cmds)
837
+        self.master.commands = _all
838
 
839
     def load_project(self):
840
-        """Load a saved project script for editing with the wizard and GUI
841
+        """Load a saved project script for editing with the wizard and GUI.
842
         """
843
-        self.heading_label.configure(text='Editing a saved project')
844
+        script = os.path.abspath(self.master.project)
845
+        #self.heading_label.configure(text='Editing a saved project')
846
         error_msg = 'This is not a saved tovid project script.  ' + \
847
           'Do you want to try to load it anyway?'
848
         if not '# tovid project script\n' in open(argv[1], 'r'):
849
@@ -960,20 +1109,26 @@
850
                 quit()
851
         numtitles = len(self.master.commands[2:])
852
         menu_titles = []
853
-        l = self.master.commands[1]
854
-        menu_titles.extend(self.get_list_args(l, '-titles'))
855
+        L = self.master.commands[1]
856
+        menu_titles.extend(self.get_list_args(L, '-titles'))
857
         self.refill_listbox(self.listbox, menu_titles)
858
         self.listbox.selection_set('end')
859
-        # write out todisc_commands.bash in current dir
860
-        # if it exists in current dir, prompt for rename
861
-        if os.path.exists(self.script_file):
862
-            mess = '%s has been loaded for editing.  Your ' %self.script_file + \
863
-              'new edits will be saved to the same file.  Continue?'
864
+        # write out to project filename
865
+        if os.path.exists(script):
866
+            infile_prefix = os.path.basename(script)
867
+            backup = mktemp(prefix=infile_prefix + '.', dir='/tmp')
868
+            backup_prefix = os.path.basename(backup)
869
+            mess = '%s has been loaded for editing, ' %infile_prefix + \
870
+              'and will be used for new edits. A backup ' + \
871
+              'will be saved to /tmp .\n' + \
872
+              'Continue ?'
873
             if askokcancel\
874
               (message=mess):
875
                 pass
876
             else:
877
                 quit()
878
+        from shutil import copyfile
879
+        copyfile(script, backup)
880
         self.write_script()
881
 
882
 class Page6(WizardPage):
883
@@ -989,28 +1144,39 @@
884
         wizard.prev_button.pack(side='right', anchor='se')
885
 
886
         text1='Running saved project'
887
-        self.label = Label(self.frame, text=text1, font=wizard.lrg_font)
888
+        self.label = tk.Label(self.frame, text=text1, font=wizard.lrg_font)
889
         self.label.pack(side='top', fill='both', expand=1, anchor='nw', pady=5)
890
         cmd_labelfont = wizard.get_font(wizard.font, _style='bold')
891
-        self.cmd_title = Label(self.frame,
892
+        self.cmd_title = tk.Label(self.frame,
893
           font=cmd_labelfont, text='\n\n\nThe command that will run:')
894
         self.cmd_title.pack(fill='both', expand=1)
895
         self.cmd_str = ''
896
         index = wizard.index.get()
897
-        self.cmd_label = Label(self.frame, text=self.cmd_str, justify='left',
898
-        font=wizard.fixed_font, wraplength=560, fg='white', bg='black')
899
+        try:
900
+            self.fixed_font = tkFont.Font(font=('TkFixedFont'))
901
+            self.fixed_font.configure(size=9)
902
+            xterm_font = [ '-fa', self.fixed_font.actual()['family']]
903
+            fsize = ['-fs', str(self.fixed_font.actual()['size'])]
904
+            self.xterm_cmd = ['xterm'] + fsize + xterm_font
905
+        # tcl/tk < 8.5: no freetype support or 'Standard fonts' like tkFixedFont
906
+        except tk._tkinter.TclError:
907
+            self.fixed_font = tkFont.Font(font='7x14')
908
+            xterm_font = ['-fn', '7x14']
909
+            self.xterm_cmd = ['xterm'] + xterm_font
910
+        self.cmd_label = tk.Label(self.frame, text=self.cmd_str, justify='left',
911
+        font=self.fixed_font, wraplength=560, fg='white', bg='black')
912
         self.cmd_label.pack(fill='both', expand=1)
913
-        self.termtitle = Label(self.master, text='\nFocus mouse in terminal')
914
-        self.button_frame = Frame(self.frame, borderwidth=2, relief='groove')
915
+        self.termtitle = tk.Label(self.master, text='\nFocus mouse in terminal')
916
+        self.button_frame = tk.Frame(self.frame, borderwidth=2, relief='groove')
917
         self.button_frame.pack(side='bottom', fill='both', expand=1)
918
-        self.run_button = Button(self.button_frame, text='Run project now',
919
+        self.run_button = tk.Button(self.button_frame, text='Run project now',
920
                                             command=self.run_in_xterm)
921
         self.run_button.pack(side='left', fill='both', expand=1)
922
-        self.save_button = Button(self.button_frame, text='Save log',
923
+        self.save_button = tk.Button(self.button_frame, text='Save log',
924
                                             command=self.save_log)
925
         self.save_button.pack(side='left', fill='both', expand=1)
926
         # disable the save log button till xterm is run
927
-        self.save_button.configure(state='disabled')
928
+        #self.save_button.configure(state='disabled')
929
 
930
     def set_cmd_label(self):
931
         cmds = self.master.commands
932
@@ -1018,7 +1184,7 @@
933
         cmd = ''
934
         for line in all_lines:
935
             cmd += ' ' + line
936
-        prompt = commands.getoutput('printf "[${USER}@$(hostname -s) ] $ "')
937
+        prompt = getoutput('printf "[${USER}@$(hostname -s) ] $ "')
938
         # probably not necessary, but ...
939
         if 'not found' in prompt:
940
             prompt = '[me@mymachine ] $ '
941
@@ -1026,7 +1192,8 @@
942
         self.cmd_label.configure(text=self.cmd)
943
 
944
     def previous(self):
945
-        """Move to the previous wizard page"""
946
+        """Move to the previous wizard page.
947
+        """
948
         self.frame.pack_forget()
949
         wizard = self.master
950
         index = wizard.index.get()
951
@@ -1052,57 +1219,28 @@
952
         wizard.next_button.pack_forget()
953
 
954
     def run_in_xterm(self):
955
-        ''' run the final script in an xterm, completing the project '''
956
-        self.frame.pack_forget()
957
-        self.master.prev_button.configure(state='disabled')
958
-        self.termtitle.pack(side='top')
959
-        self.container = Frame(self.master, container=1, height=600, width=600)
960
-        self.container.pack(side='right', fill='both',
961
-              padx=20, expand=1, anchor='nw')
962
-        lines = '80x44+0+0'
963
-        cmd = 'xterm -sb -si -fn %s -rv -sb -rightbar -g %s -e sh -c' \
964
-          %(self.master.fixed_font, lines)
965
-        cmd = shlex.split(cmd)
966
-        try:
967
-            id = self.root.tk.call('winfo', 'id', self.container)
968
-            frame_id = '%s' %int(id, 16)
969
-            self.master.xterm_is_running.set(True)
970
-        except TclError, ValueError:
971
-            self.master.xterm_is_running.set(False)
972
-            frame_id = ''
973
-        help = commands.getoutput('xterm -help')
974
-        self.logfile = mktemp(suffix='.log', prefix='todisc_commands.',
975
-                                                             dir='/tmp')
976
-        if re.search('-into ', help) and frame_id:
977
-            cmd.insert(1, frame_id)
978
-            cmd.insert(1, '-into')
979
-        tovid_cmd = """
980
-        bash %s | tee -a %s
981
-        echo
982
-        echo "Press Enter to exit terminal"
983
-        read input
984
-        """ %(self.script_file, self.logfile)
985
-        cmd.append(tovid_cmd)
986
-        command = Popen(cmd, stderr=PIPE)
987
-        self.after(200, self.poll)
988
-
989
-    def poll(self):
990
-        # return if container is not created yet, or xterm is not running
991
-        if not self.container or not self.master.xterm_is_running.get():
992
+        """Run the final script in an xterm, completing the project.
993
+        """
994
+        if not askyesno(message="Run in xterm now?"):
995
+            self.master.show_status(1)
996
             return
997
-        try:
998
-            # bogus call to container to see if it has been destroyed
999
-            self.container.winfo_class()
1000
-        except TclError:
1001
-            self.termtitle.pack_forget()
1002
-            self.master.xterm_is_running.set(False)
1003
-            self.frame.pack(fill='both', expand=1, anchor='nw')
1004
-            self.master.prev_button.configure(state='normal')
1005
-            self.log_contents = commands.getoutput('tr "\r" "\n" < %s' \
1006
-              %self.logfile)
1007
-            os.remove(self.logfile)
1008
-            self.save_button.configure(state='normal')
1009
-        self.root.check = self.root.after(200, self.poll)
1010
+        self.screen_pos = self.get_screen_position()
1011
+        xterm_geo = '80x40' + self.screen_pos
1012
+        cmd = \
1013
+          ['-sb', '-title', 'todisc',
1014
+            '-g', xterm_geo, '-e', 'sh', '-c']
1015
+        self.xterm_cmd.extend(cmd)
1016
+        wait_cmd = ';echo ;echo "Press Enter to exit terminal"; read input'
1017
+        tovid_cmd = 'bash %s' % self.master.project
1018
+        self.xterm_cmd.append(tovid_cmd + wait_cmd)
1019
+        self.root.withdraw()
1020
+        command = Popen(self.xterm_cmd, stderr=PIPE)
1021
+        command.wait()
1022
+        # without the following the position of restored window can jump around
1023
+        self.root.geometry(self.screen_pos)
1024
+        self.root.update_idletasks() # update geometry before it is 'deiconified'
1025
+        self.root.deiconify()
1026
+
1027
 
1028
     def save_log(self, event=None):
1029
         logfile = asksaveasfilename(initialfile='todisc_output.log')
1030
@@ -1111,25 +1249,24 @@
1031
             log.writelines(self.log_contents)
1032
 
1033
 # unfinished and unused
1034
-class Messagebox(Frame):
1035
+class Messagebox(tk.Frame):
1036
     def __init__(self, master, use=None, text='', boolean_var=None):
1037
-        Frame.__init__(self, master)
1038
+        tk.Frame.__init__(self, master)
1039
         self.master = master
1040
         self.use = use
1041
-        self.var = boolean_var
1042
+        self.var = tk.boolean_var
1043
         #self.overrideredirect(1)
1044
-        self.top = Toplevel(self.master, use=use)
1045
+        self.top = tk.Toplevel(self.master, use=use)
1046
         text = text
1047
-        label = Label(self.top, text=text, wraplength=400)
1048
+        label = tk.Label(self.top, text=text, wraplength=400)
1049
         label.pack()
1050
-        button1 = Button(self.top, text='Yes', command=self.yes)
1051
-        button2 = Button(self.top, text='No', command=self.no)
1052
+        button1 = tk.Button(self.top, text='Yes', command=self.yes)
1053
+        button2 = tk.Button(self.top, text='No', command=self.no)
1054
         button1.pack(side='left')
1055
         button2.pack(side='left')
1056
 
1057
     def yes(self, event=None):
1058
         #self.var.set(True)
1059
-        print 'from yes() return_code is: ', self.master.return_code.get()
1060
         self.quit()
1061
         return True
1062
 
1063
@@ -1138,29 +1275,29 @@
1064
         self.quit()
1065
         return False
1066
 
1067
-class TitleBox(Frame):
1068
-    """A Listbox in a LabelFrame with Entry associated with it
1069
+class TitleBox(tk.Frame):
1070
+    """A Listbox in a LabelFrame with Entry associated with it.
1071
        text: the label for the frame
1072
     """
1073
     def __init__(self, master=None, text=''):
1074
-        Frame.__init__(self, master)
1075
+        tk.Frame.__init__(self, master)
1076
         self.master = master
1077
         self.text = text
1078
         self.draw()
1079
 
1080
     def draw(self):
1081
         # create the listbox (note that size is in characters)
1082
-        frame1 = LabelFrame(self.master, text=self.text)
1083
+        frame1 = tk.LabelFrame(self.master, text=self.text)
1084
         frame1.pack(side='left', fill='y', expand=False)
1085
         # use entry widget to display/edit selection
1086
-        self.enter1 = Entry(frame1, width=50)
1087
+        self.enter1 = tk.Entry(frame1, width=50)
1088
         self.enter1.pack(side='bottom', fill='both', expand=False)
1089
-        self.listbox = Listbox(frame1, width=50, height=12)
1090
+        self.listbox = tk.Listbox(frame1, width=50, height=12)
1091
         self.listbox.pack(side='left', fill='y', expand=False, anchor='nw')
1092
         self.get = self.listbox.get
1093
 
1094
         # create a vertical scrollbar to the right of the listbox
1095
-        yscroll = Scrollbar(frame1, command=self.listbox.yview,
1096
+        yscroll = tk.Scrollbar(frame1, command=self.listbox.yview,
1097
                                              orient='vertical')
1098
         yscroll.pack(side='right', fill='y', anchor='ne')
1099
         self.listbox.configure(yscrollcommand=yscroll.set)
1100
@@ -1172,7 +1309,7 @@
1101
         self.listbox.bind('<ButtonRelease-1>', self.get_list)
1102
 
1103
     def set_list(self, event):
1104
-        """Insert an edited line from the entry widget back into the listbox
1105
+        """Insert an edited line from the entry widget back into the listbox.
1106
         """
1107
         try:
1108
             index = self.listbox.curselection()[0]
1109
@@ -1193,7 +1330,7 @@
1110
         self.listbox.selection_set('end')
1111
 
1112
     def get_list(self, event):
1113
-        """Read the listbox selection and put the result in an entry widget
1114
+        """Read the listbox selection and put the result in an entry widget.
1115
         """
1116
         try:
1117
             # get selected line index and text
1118
@@ -1210,15 +1347,33 @@
1119
 
1120
 # Execution
1121
 if __name__ == '__main__':
1122
+    args = argv[1:]
1123
+    infile = ''
1124
+    while args:
1125
+        arg = args.pop(0)
1126
+        # check for script to load: if its a file assume it is one (in)
1127
+        if os.path.exists(arg):
1128
+            infile = arg
1129
     # get tovid prefix so we can find the app image file
1130
-    tovid_prefix = commands.getoutput('tovid -prefix')
1131
+    tovid_prefix = getoutput('tovid -prefix')
1132
     tovid_prefix = os.path.join(tovid_prefix, 'lib', 'tovid')
1133
     os.environ['PATH'] = tovid_prefix + os.pathsep + os.environ['PATH']
1134
     img_file = os.path.join(tovid_prefix, 'titleset-wizard.png')
1135
+    root_height = 660
1136
+    # run a 'progress bar' to get info (tuple):
1137
+    # screen height, title bar height, title bar width
1138
+    screen_info = get_screen_info(img_file)
1139
     # instantiate Tk and Wizard
1140
-    root = Tk()
1141
-    root.minsize(width=800, height=660)
1142
-    app = Wizard(root, 'Tovid\nTitleset Wizard', img_file)
1143
+    root = tk.Tk()
1144
+    root.withdraw()
1145
+    # shave height if we are dealing with a netbook resolution
1146
+    if screen_info[0] < 660:
1147
+        root_height = 600
1148
+    root.minsize(width=800, height=root_height)
1149
+    app = Wizard(root, 'Tovid\nTitleset Wizard', img_file, infile=infile)
1150
+    app.set_screen_info(screen_info)
1151
+    root.update_idletasks()
1152
+    root.deiconify()
1153
     # instantiate pages
1154
     page1 = Page1(app)
1155
     page2 = Page2(app)
1156
@@ -1228,6 +1383,6 @@
1157
     page6 = Page6(app)
1158
     # run it
1159
     try:
1160
-        mainloop()
1161
+        root.mainloop()
1162
     except KeyboardInterrupt:
1163
         exit(1)
1164
tovid-0.34.tar.bz2/src/todisc -> tovid-0.35.tar.gz/src/todisc Changed
5698
 
1
@@ -15,7 +15,7 @@
2
 #
3
 # Project homepage: http://tovid.wikia.com
4
 #
5
-# Copyright (C) 2005-2010
6
+# Copyright (C) 2005-2015
7
 #
8
 # This program is free software; you can redistribute it and/or
9
 # modify it under the terms of the GNU General Public License
10
@@ -39,37 +39,50 @@
11
 #     grepper on irc.freenode.net
12
 
13
 SCRIPT_NAME=`cat << EOF
14
+
15
 --------------------------------
16
 tovid disc
17
-Generate a DVD filesystem with animated thumbnail menus
18
+Generate a DVD file-system with optional menus, from a list of multimedia files.
19
+Menus can be moving or static thumbnails, or text.  Encoding done automatically.
20
+
21
 Version $TOVID_VERSION
22
 $TOVID_HOME_PAGE
23
 --------------------------------
24
+
25
 EOF`
26
 
27
 USAGE=`cat << EOF
28
 Usage:
29
-
30
-    todisc [OPTIONS] \\\\
31
-      -files File1.mpg File2.mpg ... \\\\
32
+    tovid disc [OPTIONS] \\\\
33
+      -files File1.mpg File2.avi ... \\\\
34
       -titles "Title 1" "Title 2" ... \\\\
35
-      -out OUT_PREFIX
36
+      -menu-title "Tovid Demo" \\\\
37
+      -out OUT_DIRECTORY
38
 
39
 You can also do slideshows using -slides IMAGES rather than -files VIDEOS
40
+General Options:
41
+    -no-ask, -no-warn, -keep-files, -jobs, -grid, -no-confirm-backup
42
+Other quick examples:
43
+Create 'text menu' DVD filesystem:
44
+    tovid disc -text-menu -files ... -titles .. -out OUT_DIRECTORY
45
+Create DVD filesystem with no menu, encoding with ffmpeg and prompt for burn:
46
+    tovid disc -files *.mp4 -ffmpeg -no-menu -burn -out OUT_DIRECTORY
47
+Create DVD compatible mpeg2 files using makempg (and ffmpeg) and then quit:
48
+    tovid disc -encode-only -ffmpeg -quality 8 -files *.avi (no -out required)
49
 See the tovid manual page ('man tovid') for additional documentation.
50
 
51
 EOF`
52
 # check that needed todisc deps are installed
53
 assert_dep "$todisc_deps"
54
 assert_dep strings "'strings' is part of binutils.  In most distros the package
55
-is called  by the same name. http://www.gnu.org/software/binutils/ ."
56
+is called binutils. http://www.gnu.org/software/binutils/ ."
57
 SCRIPT_START_TIME=`date +%s`
58
 
59
 # check if symlink in /tmp exists and use time stamped link if so
60
 WORK_DIR="/tmp/todisc-work"
61
 
62
 LOG_FILE=$(readlink -f todisc.log)
63
-OUT_PREFIX=""
64
+OUT_DIRECTORY=""
65
 TV_STANDARD=ntsc
66
 PIXEL_AR="10:11"
67
 MENU_LEN=( 20 )
68
@@ -78,8 +91,10 @@
69
 SUBMENU_LEN=(10)
70
 MAX_MENU_LEN=""
71
 TARGET=dvd
72
-FRAME_RATE=29.970
73
+FRAME_RATE=29.970 # for bc. mjpegtools and transcode convert this to 30000/1001
74
+ff_frame_rate="30000/1001" # ffmpeg needs to be explicitly told exact framerate
75
 VIDSIZE=720x480
76
+VF_SCALE=${VIDSIZE%x*}:${VIDSIZE#*x}
77
 MENU_TITLE="My Video Collection"
78
 STATIC=false
79
 SUB_MENU=false
80
@@ -88,10 +103,10 @@
81
 SM_TITLE_CLR="#EAEAEA"
82
 THUMB_BG_CLR=white
83
 TITLES_CLR=""
84
-BUTTON_STYLE="rect"
85
+BUTTON_STYLE="line"
86
 MIST_COLOUR=white
87
 MIST_OPACITY=60
88
-TITLE_STROKE=""
89
+M_TITLE_STROKE=""
90
 SUBMENU_STROKE="none"
91
 BG_AUDIO=""
92
 BG_PIC=""
93
@@ -147,24 +162,24 @@
94
 USER_SM_AUDIO_SEEK=false
95
 SC_THUMB=:
96
 TEXTMENU=false
97
-SC_TITLE_ALIGN=center
98
-THUMB_TITLE_ALIGN=center
99
+SC_TITLE_ALIGN="center"
100
+EDGE_JUSTIFY=false
101
 ALIGN_OVERRIDE=false
102
 MULTILINE_TITLE=false
103
 SAFE_AREA=50 # undocumented: you can set this from CLI with -showcase-safe-area
104
-SAFE_OFFSET=36
105
+SAFE_OFFSET=0 # we only add this offset if center title align, to keep onscreen
106
 ASPECT_RATIO=4:3
107
 AR=1.333
108
 ASPECT_ARG=all
109
 WIDE_SCREEN=false
110
 WIDESCREEN="nopanscan"
111
+GROUP_ARR=""
112
 GROUPING=false
113
 TEXT_YSTART=$SAFE_AREA
114
 BUTTON_GRAVITY=north
115
 XGEO=0
116
 YGEO=45
117
 USER_GRAVITY=false
118
-USER_GEO=false
119
 USER_SPLIT=false
120
 TITLE_GRAVITY=south
121
 SPACER=15
122
@@ -209,6 +224,7 @@
123
 USER_AUDIOLENGTH=false
124
 BURN=false
125
 EJECT=''
126
+BURN_PROG="makedvd"
127
 BURN_DEVICE="/dev/dvdrw"
128
 QUICK_MENU=false
129
 BG_CLR='#101010'
130
@@ -249,27 +265,43 @@
131
 JUSTIFY="center"
132
 CONTRAST_CLR='gray'
133
 NOMENU=false
134
+ENCODE_ONLY=false
135
 SC_AR=133
136
 THUMB_COLUMNS=""
137
 FAST_SEEK=false # ffmpeg: default:decode during seek (more accurate but slower)
138
 USER_THUMBS=false # is user providing images for the menu link thumbs ?
139
-FRAME_SAFE=false # (-static) if true take the best of 9 frames. default: 1 frame
140
-PIPE_FORMAT="-pix_fmt yuv420p -f yuv4mpegpipe"
141
+FRAME_SAFE=false # (-static) if true take the best of 9 frames. default 1 frame
142
+USE_V_TITLES_DECO=false
143
+USE_M_TITLE_DECO=false
144
+PIPE_FORMAT=""
145
 IMG_DEPTH="-depth 8" # when converting to png: ppmtoy4m needs 8 bit
146
+AUDIO_EXT="ac3"
147
+SAMPLERATE="48000"
148
+AUDIO_OPTS="-ab 224k -ar $SAMPLERATE -acodec $AUDIO_EXT"
149
+MPLEX_FORMAT="8"
150
+FROM_GUI=false # needed to disable tput (colour output) in GUI
151
 TOVID_PREFIX=$(tovid -prefix)
152
+use_transcode=:
153
+yuv_correct="yuvcorrect -T NO_HEADER"
154
 
155
 ##############################################################################
156
 #                                 Functions                                  #
157
 ##############################################################################
158
 
159
-# Y-echo: echo to two places at once (stdout and logfile)
160
+# Y-echo: print to two places at once (stdout and logfile)
161
 # Output is preceded by the script name that produced it
162
 # Args: $@ == any text string
163
-# If no args are given, echo a separator bar
164
+# If no args are given, print a separator bar
165
+# If empty string is the arg, print a newline
166
 # Use yecho if you want output to go to the logfile
167
 yecho()
168
 {
169
-    if test $# -eq 0; then
170
+    # arg supplied but empty (""): just print a newline
171
+    if [[  "${1+defined}" && -z $1 ]]; then
172
+        printf "\n"
173
+        [[ -e "$LOG_FILE" ]] && printf "\n" >> "$LOG_FILE"
174
+    # no arg supplied at all, just 'yecho': print \n[todisc]:\n
175
+    elif test $# -eq 0; then
176
         printf "\n%s\n\n" "$SEPARATOR"
177
         # If logfile exists, copy output to it (with pretty formatting)
178
         test -e "$LOG_FILE" && \
179
@@ -281,14 +313,6 @@
180
             fold -bs >> "$LOG_FILE"
181
     fi
182
 }
183
-# ******************************************************************************
184
-# Execute the given command-line string, with appropriate stream redirection
185
-# Args: $@ == text string containing complete command-line
186
-# Returns: Exit status of the subprocess
187
-# To filter/prettify the subprocess output before writing it to the log file,
188
-# set the LOG_FILTER variable before calling this function, to e.g.
189
-#    LOG_FILTER="sed 's/\r/\r\n/g'"    # Replace LF with CR/LF
190
-# ******************************************************************************
191
 
192
 # Print script name, usage notes, and optional error message, then exit.
193
 # Args: $@ == text string(s) containing error message and help
194
@@ -304,27 +328,109 @@
195
     fi
196
     exit 1
197
 }
198
-warning_message()
199
+
200
+# Usage: continue_in [SECONDS]
201
+continue_in()
202
 {
203
-    local MESSAGE=( "$@" )
204
-    yecho $SEPARATOR
205
-    for ((i=0; i<$#; i++)) ; do printf "%s" "${MESSAGE[i]}"; done |
206
-    format_output | tee -a "$LOG_FILE"
207
-    echo | tee -a "$LOG_FILE"
208
-    yecho "$SEPARATOR"
209
+    yecho ""
210
+    (($1)) && LAST=$1 || LAST=5
211
+    for ((i=LAST; i>=0; i--)); do
212
+        ((i==0)) && count='' || count="continuing in $i seconds ..."
213
+        spin $count
214
+        ((i>0)) && sleep 1
215
+    done
216
+}
217
+
218
+info_message()
219
+{
220
+    local MESSAGE=$(sed "s/    */ /g;s/^ *//" <<< "$@" | fold -w 60 -bs)
221
+    printgreen "*** Note: ***"
222
+    print2log "$MESSAGE"
223
+    while read -r line; do
224
+        printf "%s\n" "$line"
225
+    done <<< "$MESSAGE"
226
+    printgreen "*************"
227
+}
228
+
229
+# print to log, formated with leading/trailing spaces removed
230
+# and prefixed with the script name. [todisc]:
231
+# with no args it just prints [todisc]:, with "" as arg it prints newline
232
+print2log()
233
+{
234
+    local MESSAGE=$(sed "s/    */ /g;s/^ *//" <<< "$@" | fold -w 60 -bs)
235
+    # if "" passed in as arg (ie. defined but empty, print a blank line
236
+    if [[  "${1+defined}" && -z $1 ]]; then
237
+        printf "\n" >> "$LOG_FILE"
238
+    # otherwise print  [todisc]: $line for each line of input
239
+    else
240
+        while read -r line; do
241
+            printf "%s %s\n" "$ME" "$line" >> "$LOG_FILE"
242
+        done <<< "$MESSAGE"
243
+        printf "\n" >> "$LOG_FILE"
244
+    fi
245
+}
246
+
247
+# pipe stdout to log prefixed by "[name]:", and ending in newline. 2 opt args
248
+# arg 1:  [name to prefix each line of output]
249
+# arg 2: [fold] fold lines appropriately. Usually you don't fold program stdout.
250
+# uses stdbuf (coreutils) if present so stdin is line buffered
251
+pipe2log()
252
+{
253
+    if [[ $1 ]]; then
254
+        name="[$1]: "
255
+    else
256
+        name="[${0##*/}]: "
257
+    fi
258
+    if [[ $2 && $2 = format ]]; then
259
+        cols=$(( 79 - $(wc -c <<< $name) ))
260
+        ((cols)) || cols=60
261
+        format="fold -w $cols -bs"
262
+    else
263
+        format="cat"
264
+    fi
265
+    $std_buf tr "\015" "\012" < /dev/stdin | $std_buf tr -d "\033" | $format | \
266
+    while read line; do
267
+        printf "%s %s\n" "$name" "$line"
268
+    done >> "$LOG_FILE"
269
+    printf "\n" >> "$LOG_FILE"
270
+}
271
+
272
+printgreen()
273
+{
274
+    $FROM_GUI || tput setaf 2
275
+    printf "%s\n" "$@" | sed "s/    */ /g;s/^ *//"
276
+    print2log "$@"
277
+    $FROM_GUI || tput sgr0
278
+    printf ""
279
+}
280
+
281
+printred()
282
+{
283
+    $FROM_GUI || tput setaf 1
284
+    printf "%s\n" "$@" | sed "s/    */ /g;s/^ *//"
285
+    print2log "$@"
286
+    $FROM_GUI || tput sgr0
287
+    printf ""
288
 }
289
 
290
 titlesafe_error()
291
 {
292
-    echo "***** WARNING *****"
293
-    yecho "thumb title is $1 pixels from screen edge"
294
+    (($1 > SAFE_AREA)) && preposition='off the' || preposition='from'
295
+    yecho ""
296
+    printred "***** WARNING *****"
297
+    yecho "video title is $1 pixels $preposition screen edge"
298
     yecho "Part of the title may not be visible on your tv screen"
299
     yecho "Perhaps use a smaller -titles-fontsize, or shorten \"${TITLES[i]}\""
300
-    $SHOWCASE && [[ -z $SHOWCASE_FILE ]] && \
301
-    yecho "You may also use '-showcase-titles-align east' since you are not
302
-    using a -showcase FILE."
303
-    echo "****************************"
304
-    $WARN && sleep 5
305
+    # no need to test $SHOWCASE: default montage will never be offscreen
306
+    if [[ -z $SHOWCASE_FILE && ! $SC_TITLE_ALIGN = east ]]; then
307
+        yecho \
308
+        "You may also use '-showcase-titles-align east' since you are not
309
+        using a -showcase FILE."
310
+    elif ((NUM_FILES >= SPLIT)); then # two columns
311
+        : # insert message here for east offscreen stuff #fixme
312
+    fi
313
+    yecho "****************************"
314
+    $WARN && continue_in 5
315
 }
316
 
317
 format_output()
318
@@ -344,25 +450,38 @@
319
     # TODO: Check for font availability?
320
 }
321
 
322
-vid_length()
323
-{
324
-    check_frames=""
325
-    [[ -n $2 ]] && check_frames=$2 && check_frames="-frames $check_frames"
326
-    echo "Using mencoder to get length of $1" >> "$LOG_FILE"
327
-    L=$(mencoder -nosound -mc 0 -oac pcm -ovc copy $check_frames \
328
-    -o /dev/null "$1" 2> /dev/null)
329
-    awk 'END{print $(NF-3)}' <<< "$L"
330
-    # awk '{for (i=0; i<NF; i++) { if ($i=="secs") {print $(i-1); break} } }' \
331
-    # <<< "$L"
332
-}
333
-audio_length()
334
-{
335
-    # optional 2nd arg is maximum length checked in file (seconds)
336
-    end=""
337
-    [[ -n $2 ]] && end="-endpos $2"
338
-    mplayer -nomsgcolor -noconsolecontrols -vo null -ao pcm:fast:file=/dev/null $end "$1" \
339
-    2>&1 | tr '\r' '\n' | grep ^A: | tail -1 | sed s/^.*A:// | awk '{print $1}'
340
+# get the length of a stream
341
+# usage: stream_length STREAM [type, duration]
342
+# type is either video or audio, duration is the max length to test
343
+# last 2 args are optional: defaults 'video' and the whole stream.
344
+stream_length()
345
+{
346
+    local end=""
347
+    local stream_type=video
348
+    local ff_opts="-an -vcodec copy"
349
+    [[ -n $2 ]] && stream_type=$2
350
+    [[ -n $3 ]] && end="-t $3"
351
+    sed_var="{s/^.*time= *\([^ ]*\).*/\1/p}"
352
+    stream_name=$stream_type
353
+    if [[ $stream_type = 'audio' ]]; then
354
+        ff_opts="-vn -acodec copy"
355
+    # workaround for avconv which is broken atm wrt getting m2v framerate right
356
+    # overload stream_type to have another meaning, 
357
+    elif [[ $stream_type = 'm2v' ]]; then
358
+        sed_var="{s/^.*frame= *\([^ ]*\).*/\1/p}"
359
+        stream_name=video
360
+    fi
361
+    print2log "Using $FFmpeg to get accurate $stream_name length of $1"
362
+    local len=$($FFmpeg -i "$1" $end $ff_opts -f null -y /dev/null 2>&1 |
363
+    sed -n "$sed_var" | tail -n 1)
364
+    # sed -n 's/^.*time= *\([^ ]*\).*/\1/p' | tail -n 1)
365
+    if [[ $stream_type = 'm2v' ]]; then
366
+        bc_math "$len / $FRAME_RATE"
367
+    else
368
+        unformat_time $len # no need for echo, prints to stdout
369
+    fi
370
 }
371
+
372
 cleanup()
373
 {
374
     #TODO make a kill_pid function to avoid repetition below
375
@@ -439,9 +558,12 @@
376
     yecho "todisc encountered an error:"
377
     yecho "    $@"
378
     echo
379
-    echo "The error should be shown above, also check the contents of 
380
+    echo "See above message, and also you can check the contents of 
381
     $LOG_FILE to see what went wrong." |format_output
382
-    echo "See the tovid website ($TOVID_HOME_PAGE) for possible further info."
383
+    echo "See the tovid website ($TOVID_HOME_PAGE) for further help options."
384
+    echo "Latest fixes for ffmpeg api changes go in svn tovid."
385
+    echo "So you should try that if you get ${FFmpeg##*/} errors in the log."
386
+    echo "See subversion section: http://tovid.wikia.com/wiki/Installing_tovid"
387
     echo "Sorry for the inconvenience!"
388
     echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
389
     cleanup
390
@@ -476,18 +598,21 @@
391
 # usage: bc_math "expression" [int]
392
 bc_math()
393
 {
394
+    OLC_ALL=$LC_ALL
395
+    LC_ALL=C
396
     bc_out=$(bc <<< "scale=3;$1" 2>/dev/null)
397
     if [[ -n $2 && $2 = "int" ]]; then
398
         echo ${bc_out%.*}
399
     else
400
         printf  "%.03f" $bc_out
401
     fi
402
+    LC_ALL=$OLC_ALL
403
 }
404
 
405
 confirm_preview()
406
 {
407
     confirm_msg="type 'yes' to continue, or press <ENTER> to exit: "
408
-    yecho
409
+    yecho ""
410
     if $SWITCHED || $TITLESET_MODE || $VMGM_ONLY; then
411
         echo "If doing titlesets or switched menus and you wish to exit "
412
         echo "without seeing more previews, then type: 'exit', else you will "
413
@@ -496,12 +621,12 @@
414
         confirm_msg="Type yes to continue, press <ENTER> to abort but see "
415
         confirm_msg="$confirm_msg other previews, or type 'exit' to quit."
416
     fi
417
-    echo "If you are happy with the preview, $confirm_msg"
418
+    echo -e "If you are happy with the preview, \n$confirm_msg"
419
     read input
420
     echo
421
     if [ ! -z "$input" -a "$input" = "yes" ]; then
422
         yecho "Preview OK, continuing."
423
-        yecho
424
+        yecho ""
425
     else
426
         yecho "Preview not OK, exiting."
427
         #echo -n "Deleting symlink in /tmp . . . "
428
@@ -513,7 +638,7 @@
429
             #echo -n "Deleting "$REAL_WORK_DIR" . . . "
430
             rm -fr "$REAL_WORK_DIR"
431
         fi
432
-        yecho
433
+        yecho ""
434
         echo
435
         echo "Some configuration options to try, if things look bad:"
436
         echo "Color:"
437
@@ -541,12 +666,10 @@
438
 {
439
     SPIN_CHARS=".oOo"
440
     SPINNER="${SPIN_CHARS:SP++%${#SPIN_CHARS}:1}"
441
-    # Print spaces to overwrite previous line
442
-    echo -ne "\r                                                            "
443
+    echo -ne "\r$(printf %60s)" # print spaces to overwrite previous line
444
     echo -ne "\r$@ "
445
 }
446
 
447
-#EXPAND="expand=-6:-6,"
448
 get_framed_pics()
449
 {
450
 mplayer -ss $MPLAYER_SEEK_VAL -vo $VOUT -noconsolecontrols \
451
@@ -567,69 +690,82 @@
452
 {
453
 awk 'END{print NR}' "$LOG_FILE"
454
 }
455
+ 
456
+# unused
457
+get_ffmpeg_version()
458
+{
459
+local test_version=$1
460
+ff_ver=$($FFmpeg -version 2>&1 | awk '{ gsub(",", ""); if(NR == 1) print $3 }')
461
+(( ${ff_ver:2:1} == test_version )) 2>/dev/null
462
+} 
463
+
464
+is_video()
465
+{
466
+file -biL "$1" |grep -qw video || return 1
467
+}
468
 
469
 check_filetype()
470
 {
471
     fstats=$(file -L "$1" | awk '{ $1 = ""; print }')
472
     if [[ $fstats =~ "image" || $fstats =~ "bitmap" ]]; then
473
-        TYPE="image"
474
+        file_type="image"
475
         CONVRT=:
476
-        if [[ $fstats = *JPEG* || $fstats = *PNG || $fstas = *PPM* ]]; then
477
+        if [[ $fstats = *JPEG* || $fstats = *PNG || $fstats = *PPM* ]]; then
478
             CONVRT=false
479
         fi
480
-    elif mencoder \
481
-    -endpos 2 -oac pcm -ovc copy "$1" -o /dev/null >/dev/null 2>&1; then
482
-        TYPE=video
483
+    elif is_video "$1"; then
484
+        file_type=video
485
     else
486
-        TYPE=unknown
487
+        file_type=unknown
488
     fi
489
 }
490
 
491
 get_stats()
492
 {
493
-unset IN_STATS FILES_IN
494
-this_set=$1
495
-if [[ $this_set = "group" ]]; then
496
-    unset TOT IN_STATS FILES_IN
497
-    TOT=${#grouping[@]} # || TOT=${#IN_FILES[@]}
498
-    IN_STATS=( "${group_idvid_stats[@]}" )
499
-    FILES_IN=( "${grouping[@]}" )
500
-else
501
-    TOT=${#IN_FILES[@]}
502
-    IN_STATS=( "${idvid_stats[@]}" )
503
-    FILES_IN=( "${IN_FILES[@]}" )
504
-fi
505
-for ((i=0; i<TOT; i++)); do
506
-    VCODEC="$(awk -F= '/ID_VIDEO_FORMAT/ {print $2}'    <<< "${IN_STATS[i]}")"
507
-    V_BR="$(awk -F= '/ID_VIDEO_BITRATE/ {print $2}'    <<< "${IN_STATS[i]}")"
508
-    ACODEC="$(awk -F= '/ID_AUDIO_CODEC/ {print $2}'    <<< "${IN_STATS[i]}")"
509
-    A_BR="$(awk -F= '/ID_AUDIO_BITRATE/ {print $2}'    <<< "${IN_STATS[i]}")"
510
-    if [ -z "$A_BR" ]; then
511
-        A_BR="No audio found"
512
-    fi
513
-    V_LENGTH=${VID_LEN[i]}
514
-    [[ $this_set = "group" ]] && V_LENGTH=${GROUP_VID_LEN[i]}
515
-    FPS="$(awk -F= '/ID_VIDEO_FPS/ {print $2}'    <<< "${IN_STATS[i]}")"
516
-    yecho
517
-    if [[ $this_set = "group" ]] && ((i == 0)); then
518
-        echo; echo ". . . Grouped file stats . . ."; echo
519
-    yecho
520
-    fi
521
-    [[ $this_set = "group" ]] && echo -e "Stats for" \
522
-    $(readlink -f "${FILES_IN[i]}") "\n" || \
523
-    echo -e "Stats for" "${FILES_IN[i]}" "\n"
524
-    echo -e  \
525
-    " video codec:   " \
526
-    "$VCODEC" "\n" \
527
-    "video bitrate: " "$V_BR" "bits per second" "\n" \
528
-    "framerate:     " "$FPS" "fps" "\n" \
529
-    "audio codec:   " \
530
-    "$ACODEC" "\n" \
531
-    "audio bitrate: " \
532
-    "$A_BR" "bits per second" "\n" \
533
-    "video length:  " \
534
-    "$V_LENGTH" "seconds" |tee -a "$LOG_FILE"
535
-done
536
+    unset IN_STATS FILES_IN
537
+    this_set=$1
538
+    if [[ $this_set = "group" ]]; then
539
+        unset TOT IN_STATS FILES_IN
540
+        TOT=${#grouping[@]} # || TOT=${#IN_FILES[@]}
541
+        IN_STATS=( "${group_idvid_stats[@]}" )
542
+        FILES_IN=( "${grouping[@]}" )
543
+    else
544
+        TOT=${#IN_FILES[@]}
545
+        IN_STATS=( "${idvid_stats[@]}" )
546
+        FILES_IN=( "${IN_FILES[@]}" )
547
+    fi
548
+    for ((i=0; i<TOT; i++)); do
549
+        VCODEC="$(awk -F= '/ID_VIDEO_FORMAT/ {print $2}' <<< "${IN_STATS[i]}")"
550
+        V_BR="$(awk -F= '/ID_VIDEO_BITRATE/ {print $2}'  <<< "${IN_STATS[i]}")"
551
+        ACODEC="$(awk -F= '/ID_AUDIO_CODEC/ {print $2}'  <<< "${IN_STATS[i]}")"
552
+        A_BR="$(awk -F= '/ID_AUDIO_BITRATE/ {print $2}'  <<< "${IN_STATS[i]}")"
553
+        if [ -z "$A_BR" ]; then
554
+            A_BR="No audio found"
555
+        fi
556
+        V_LENGTH=${VID_LEN[i]}
557
+        [[ $this_set = "group" ]] && V_LENGTH=${GROUP_VID_LEN[i]}
558
+        FPS="$(awk -F= '/ID_VIDEO_FPS/ {print $2}' <<< "${IN_STATS[i]}")"
559
+        yecho ""
560
+        if [[ $this_set = "group" ]] && ((i == 0)); then
561
+            print2log ""; print2log ". . . Grouped file stats . . ."
562
+        yecho ""
563
+        fi
564
+        [[ $this_set = "group" ]] && print2log "Stats for \
565
+        $(readlink -f "${FILES_IN[i]}")" || \
566
+        print2log "Stats for" "${FILES_IN[i]}"
567
+        echo -e  \
568
+        " video codec:   " \
569
+        "$VCODEC" "\n" \
570
+        "video bitrate: " "$V_BR" "bits per second" "\n" \
571
+        "framerate:     " "$FPS" "fps" "\n" \
572
+        "audio codec:   " \
573
+        "$ACODEC" "\n" \
574
+        "audio bitrate: " \
575
+        "$A_BR" "bits per second" "\n" \
576
+        "video length:  " \
577
+        "$V_LENGTH" "seconds" |pipe2log
578
+    done
579
+    
580
 }
581
 test_compliance()
582
 {
583
@@ -647,8 +783,14 @@
584
     # slide mpg's go in $WORK_DIR, and are moved to BASEDIR later if recursing
585
     # for video files: files are named $IN_FILE.enc.mpg
586
     unset FILES_TO_ENCODE ENC_IN_FILES CHECK_IN_FILES
587
+    # get user's config options for makempg from the tovid.ini file
588
+    makempg_ini_opts=$(tovid mpg | awk '/Read options/{getline;print}')
589
     group_set=false
590
-    if [[ $1 = "group" ]]; then
591
+    if $ENCODE_ONLY; then
592
+        # encoding all files as -encode-only was used
593
+        CHECK_IN_FILES=()
594
+        FILES_TO_ENCODE=( "${IN_FILES[@]}" )
595
+    elif [[ $1 = "group" ]]; then
596
         group_set=:
597
         unset x a
598
         CHECK_IN_FILES=( "${grouping[@]}" )
599
@@ -670,7 +812,7 @@
600
             OUTFILE="$WORK_DIR/${TSET_NUM}-$((i+1)).mpg"
601
         fi
602
 
603
-        spin "Checking compliance of file $((i+1))"
604
+        print2log "Checking compliance of file $((i+1))"
605
         # if file tested as an image when we were verifying input files
606
         if [[ $is_image = "yes" ]]; then
607
             $group_set && grp_use_image2mpeg2[i]="yes" ||
608
@@ -691,48 +833,51 @@
609
             ENC_IN_FILES=("${ENC_IN_FILES[@]}" "${IN_FILE}.enc.mpg")
610
         fi
611
     done
612
+    echo
613
     $DEBUG && etime=$(date +%s) && get_elapsed "compliance check"
614
     if test "${#FILES_TO_ENCODE[@]}" -gt 0; then
615
         TGT_CAPS=$(tr a-z A-Z <<< "$TARGET")
616
         TV_STND_CAPS=$(tr a-z A-Z <<< "$TV_STANDARD")
617
-        echo
618
-        yecho "Encode input files"
619
+        print2log "Encode input files"
620
         if ! $SINGLE_SLIDESHOW; then
621
-            echo
622
-            yecho "Some of the -files you provided are not \
623
-            $TV_STND_CAPS $TGT_CAPS-compliant:"
624
-            echo " "
625
+            if $ENCODE_ONLY; then
626
+                yecho "Encoding the following files to \
627
+                $TV_STND_CAPS $TGT_CAPS format:"
628
+            else
629
+                yecho "Some of the -files you provided are not \
630
+                $TV_STND_CAPS $TGT_CAPS-compliant:"
631
+            fi
632
+            print2log ""
633
         fi
634
         if test ${#FILES_TO_ENCODE[@]} -lt 12 && ! $SINGLE_SLIDESHOW; then
635
+            printgreen '-------------'
636
             for i in "${FILES_TO_ENCODE[@]}"; do
637
                 this_file=$(readlink -f "$i")
638
                 test -n "$this_file" && yecho " $this_file"
639
             done
640
+            printgreen '-------------'
641
         fi
642
         # this ugly list of OR's are cases we want automatic encoding
643
         # all switched runs except the 1st, if -no-ask, if single slideshow
644
         # or if all input files are images
645
         if { $SWITCHED && [[ $MENU_NUM -ne 2 ]] ; } \
646
-         || $NOASK || [[ ${TOVID_OPTS[@]} = *-noask* ]] || \
647
+         || $NOASK || [[ ${TOVID_OPTS[@]} = *-noask* ]] || $ENCODE_ONLY || \
648
          [[ ${#NO_PROMPT_FILES[@]} = ${#FILES_TO_ENCODE[@]} ]]; then
649
-            yecho " "
650
             echo "Encoding files to $TV_STND_CAPS $TGT_CAPS-compliant format."
651
-            echo "(This may take a long time)"
652
             ENCODE="yes"
653
         else
654
-            yecho " "
655
+            yecho ""
656
             yecho "I can encode them for you, but it may take a long time."
657
             yecho "Encoding will ensure that your disc is fully compliant;"
658
             yecho "you may skip this, but your disc may not be playable."
659
             yecho "Please type 'yes' if you want the files to be encoded:"
660
             read ENCODE
661
-        fi
662
-        if test -n "$ENCODE" && test "$ENCODE" = 'yes'; then
663
-            if ! $SINGLE_SLIDESHOW; then
664
-                yecho
665
-                yecho "Converting files to $TGT_CAPS format"
666
-                yecho
667
+            if [[ $ENCODE = "yes" ]]; then
668
+                ! $SINGLE_SLIDESHOW && yecho \
669
+                "Converting files to $TGT_CAPS format"
670
             fi
671
+        fi
672
+        if [[ $ENCODE = 'yes' ]]; then
673
             for i in "${!FILES_TO_ENCODE[@]}"; do
674
                 IN=$(readlink -f "${FILES_TO_ENCODE[i]}")
675
                 if $group_set; then
676
@@ -762,12 +907,26 @@
677
                     fi
678
                     # AUDIO_FADE=false # do not fade silence FIXME ???
679
                 else # not an image file - outfile goes beside infile
680
-                    THIS_FILE=$(readlink -f "${FILES_TO_ENCODE[i]}")
681
-                    yecho "Converting $THIS_FILE"
682
+                    #THIS_FILE=$(readlink -f "${FILES_TO_ENCODE[i]}")
683
+                    if [[ -e "$IN.enc.mpg" ]]; then
684
+                        if ! grep -w -- -overwrite <<< \
685
+                          "$makempg_ini_opts ${script_args[@]}"; then
686
+                            : #FIXME echo to terminal what makempg would do ?
687
+                        fi
688
+                    fi
689
+                    yecho "Converting $IN"
690
                     echo
691
-                    countdown 3
692
+                    continue_in 3
693
                     TOVID_WORKING_DIR=$WORKING_DIR makempg $NO_ASK \
694
-                    -$TV_STANDARD -$TARGET -in "$IN" -out "${IN}.enc" "${TOVID_OPTS[@]}"
695
+                    -$TV_STANDARD -$TARGET -in "$IN" -out "${IN}.enc" \
696
+                    "${TOVID_OPTS[@]}"
697
+                    wait
698
+                    if [[ -e "${IN}.enc.mpg" ]]; then
699
+                        ! $ENCODE_ONLY && yecho "Using ${IN}.enc.mpg for this DVD"
700
+                    else
701
+                        runtime_error "There appears to be a problem creating \
702
+                        the DVD compatible mpeg.  See $LOG_FILE for details"
703
+                    fi
704
                     # for grouped files replace symlink in $WORK_DIR
705
                     $group_set && [[ -L "${FILES_TO_ENCODE[i]}" ]] && \
706
                     ln -sf "${IN}.enc.mpg" "${FILES_TO_ENCODE[i]}"
707
@@ -783,17 +942,19 @@
708
                     KEEP_FILES=:
709
                     runtime_error "Could not encode file: $IN"
710
                 fi
711
-                #yecho
712
+                #yecho ""
713
             done
714
 
715
             # Replace IN_FILES with ENC_IN_FILES (with .enc extension)
716
             # for grouped files the mpeg already replaced the group symlink
717
             ! $group_set && IN_FILES=("${ENC_IN_FILES[@]}")
718
         else
719
-            yecho
720
-            yecho "Not re-encoding. I will proceed with menu generation, but"
721
-            yecho "your authored disc will not be fully $TGT_CAPS-compliant."
722
-            yecho
723
+            if $ENCODE_ONLY; then
724
+                info_message "Not re-encoding."
725
+            else
726
+                info_message "Not re-encoding. I will proceed with menu generation, but
727
+                your authored disc will not be fully $TGT_CAPS-compliant."
728
+            fi
729
         fi
730
     fi
731
 }
732
@@ -804,7 +965,7 @@
733
     VIDEO_IN="$1"
734
     VIDEO_IN_SEEK="$2"
735
     video_type=$3
736
-    yecho
737
+    yecho ""
738
     yecho "$VIDEO_IN is not compliant - re-encoding \
739
       $(bc <<< "$VIDEO_IN_SEEK + ${MENU_LEN[MENU_NUM-1]}" 2>/dev/null)
740
         second slice to DVD compliant file"
741
@@ -819,9 +980,9 @@
742
             return
743
         fi
744
     fi
745
-    yecho
746
+    yecho ""
747
     yecho "Converting files to $TGT_CAPS format with 'makempg'"
748
-    countdown
749
+    continue_in 5
750
     makempg $NO_ASK -in "$VIDEO_IN" \
751
     -slice 0-$(bc <<< "$VIDEO_IN_SEEK + ${MENU_LEN[MENU_NUM-1]}" 2>/dev/null) \
752
     -${TV_STANDARD} -${TARGET} -in "$VIDEO_IN" \
753
@@ -834,7 +995,7 @@
754
         [[ $video_type = background ]] && BG_VIDEO="${VIDEO_IN}.enc.mpg"
755
     fi
756
     SUPPORT_VIDEOS=( "${SUPPORT_VIDEOS[@]}" "${VIDEO_IN}.enc.mpg" )
757
-    yecho
758
+    yecho ""
759
 }
760
 
761
 mk_workdir()
762
@@ -982,13 +1143,18 @@
763
 {
764
     IN_IMAGE="$1"
765
     OUT_MPEG="$2"
766
+    # need to set VIDSIZE here as pal VIDSIZE assignment is later in script
767
+    [ $TV_STANDARD = "pal" ] && VIDSIZE=720x576
768
+    VF_SCALE=${VIDSIZE%x*}:${VIDSIZE#*x}
769
     # remove symlinks, as otherwise we overwrite symlink target
770
-    IMAGE_ENC_CMD=(ffmpeg -f image2 $LOOP -vframes $vlength \
771
-    -i "$IN_IMAGE" -s $VIDSIZE -f s16le -ar 48000 -i /dev/zero -t $alength \
772
+    IMAGE_ENC_CMD=($FFmpeg -f image2 $LOOP \
773
+    -i "$IN_IMAGE" -f s16le -ar 48000 -i /dev/zero -t $alength \
774
     -ar $SAMPLERATE -ac 2 -ab 224k -target ${TV_STANDARD}-${TARGET} \
775
-    -aspect $ASPECT_RATIO -y "$OUT_MPEG")
776
-    echo "Running ${IMAGE_ENC_CMD[@]}" | format_output >> "$LOG_FILE"
777
-    "${IMAGE_ENC_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"
778
+    $VF scale=${VF_SCALE},${ASPECT} -y -vframes $vlength  "$OUT_MPEG")
779
+    print2log ""
780
+    print2log "Running ${IMAGE_ENC_CMD[@]}"
781
+    print2log ""
782
+    "${IMAGE_ENC_CMD[@]}" 2>&1 | pipe2log fmpeg
783
 }
784
 
785
 switched_menu_mode()
786
@@ -1003,6 +1169,7 @@
787
         -basedir "$BASEDIR" -menu_num $((i+1)) -showcase "${FILES[i]}""
788
         todisc "$@" -switched-mode $IS_TITLESET -basedir "$WORK_DIR" \
789
         -menu_num $((i+1)) -todisc_pids "$TODISC_PIDS" -showcase "${FILES[i]}"
790
+        yecho
791
     done
792
         yecho
793
         yecho "Working on switched menu 1"
794
@@ -1034,9 +1201,9 @@
795
         fi
796
         MC_CMD=(todisc -slides "${IN_SLIDES[@]}" $mix_range \
797
         $NO_CONFIRM_BACKUP ${encopt[@]} $sld_tranition $background_carousel \
798
-        $showcase_carousel -out "$OUT_PREFIX" -carousel_menu_mode -basedir \
799
+        $showcase_carousel -out "$OUT_DIRECTORY" -carousel_menu_mode -basedir \
800
         "$WORK_DIR" $menulen -carousel_num $((c+1)) -todisc_pids "$TODISC_PIDS")
801
-        yecho
802
+        yecho ""
803
         yecho "Running ${MC_CMD[@]}"
804
         "${MC_CMD[@]}"
805
     }
806
@@ -1205,7 +1372,8 @@
807
     DVDAUTHOR_XML="$BASEDIR/dvdauthor.xml"
808
     VMGM_PRE="        if ( g5 eq 0 ) g5=1;"
809
     VMGM_PRE="$VMGM_PRE\n        if ( g6 eq 0 ) g6=1; button = g6 * 1024;"
810
-    egrep -qw -- "-switched-menu[s]" <<< "${args[@]}" && \
811
+    # switch is now singular (-switched-menu) OR plural (-switched-menus)
812
+    egrep -q -- "-switched-menu" <<< "${args[@]}" && \
813
     VMGM_PRE="$VMGM_PRE\n        if (g1 eq 0) g1=1;"
814
     $DO_INTRO && INTRO_PRE="        if (g2==1) jump cell 2; "
815
     $SKIP_VMGM_MENU && VMGM_PRE="$VMGM_PRE\n        if ( g3 eq 0 )  g3=1 ;"
816
@@ -1324,7 +1492,7 @@
817
     ################### end titleset options testing #########################
818
 
819
     if [[ -z ${VMGM_OPTS[@]} ]]; then
820
-        yecho
821
+        #yecho
822
         yecho "You have not supplied -vmgm OPTIONS -end-vmgm"
823
         yecho "At a minumum you should have: \
824
         '-vmgm -titles "Title one" "Title two" -end-vmgm'"
825
@@ -1344,8 +1512,8 @@
826
         fi
827
         yecho "Making a generic vmgm menu for you - \
828
         you may wish to cancell out and change this."
829
-        yecho
830
-        $VMGM_MENU && $WARN && sleep 15
831
+        yecho ""
832
+        $VMGM_MENU && $WARN && continue_in 15
833
     else
834
         unset vmgmtitles
835
         get_menu_titles "${VMGM_OPTS[@]}"
836
@@ -1356,12 +1524,11 @@
837
     fi
838
     ################### end titleset options testing #########################
839
     # VMGM menu
840
-    yecho
841
-    yecho "Making a VMGM menu with the following command:"
842
+    print2log "Making a VMGM menu"
843
     vmgm_menu_cmd=(todisc "${GEN_OPTS[@]}" -basedir "$WORK_DIR" -vmgm_only \
844
     -textmenu -todisc_pids "$TODISC_PIDS" $NO_CONFIRM_BACKUP \
845
     -title_count "$num_titles" $vmgm_playall  "${VMGM_OPTS[@]}")
846
-    yecho "Running: ${vmgm_menu_cmd[@]}"
847
+    print2log "Running: ${vmgm_menu_cmd[@]}"
848
     INITIALDIR="$BASEDIR"
849
     if ! "${vmgm_menu_cmd[@]}" ; then cleanup && exit 1; fi
850
     # TITLESET menus
851
@@ -1385,8 +1552,8 @@
852
                 yecho
853
                 yecho "Working on the menu for titleset number $tset"
854
                 yecho
855
-                $WARN && sleep 5
856
-                yecho "Running: ${titleset_cmd[@]}"
857
+                $WARN && continue_in 5
858
+                print2log "Running: ${titleset_cmd[@]}"
859
                 if ! "${titleset_cmd[@]}"; then cleanup && exit 1; fi
860
                 yecho
861
                 ;;
862
@@ -1395,7 +1562,7 @@
863
     done
864
     echo -e "</dvdauthor>" >> "$DVDAUTHOR_XML"
865
     yecho "Running dvdauthor to create final DVD structure"
866
-    dvdauthor -x "$DVDAUTHOR_XML" 2>&1 | tee -a "$LOG_FILE"
867
+    dvdauthor -x "$DVDAUTHOR_XML" 2>&1 | pipe2log dvdauthor
868
     if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
869
         dvdauthor_error
870
     fi
871
@@ -1420,7 +1587,9 @@
872
 
873
 burn_disc()
874
 {
875
-    BURN_CMD=(tovid dvd -burn -device $EJECT "$BURN_DEVICE" \
876
+    BURN_TGT="$OUT_DIR"
877
+    BURN_TGT_STR="DVD directory"
878
+    BURN_CMD=(tovid dvd -burn -device "$BURN_DEVICE" $EJECT  \
879
     $BURN_SPEED \"$BURN_TGT\")
880
     yecho
881
     echo "You have indicated you want to burn the $BURN_TGT_STR"
882
@@ -1431,9 +1600,12 @@
883
     if [ ! -z "$input" -a "$input" = "yes" ]; then
884
         echo "Proceeding to burn, continuing."
885
         echo
886
-        $BURN_PROG -burn -device "$BURN_DEVICE" \
887
-        $BURN_SPEED "$BURN_TGT" | tee -a "$LOG_FILE" 2>&1
888
-        if ((${PIPESTATUS[0]}==0)); then
889
+        # probably could do redirection using exec and such, but this is simple
890
+        $BURN_PROG -device "$BURN_DEVICE" \
891
+        $BURN_SPEED "$BURN_TGT" | tee  "$WORK_DIR/makedvd.log"
892
+        pipe_status=${PIPESTATUS[0]}
893
+        pipe2log makedvd < "$WORK_DIR/makedvd.log"
894
+        if ((pipe_status==0)); then
895
             echo "Your ${BURN_TGT_STR/ *} should be ready"
896
         else
897
             echo "There was a problem burning the ${BURN_TGT_STR/ *}"
898
@@ -1449,80 +1621,88 @@
899
 
900
 thanks_goodbye()
901
 {
902
-    echo
903
-    echo $SEPARATOR
904
     SCRIPT_TIME=$(format_seconds $SECONDS)
905
-    echo "todisc took $SCRIPT_TIME to finish on $CPU_MODEL $CPU_SPEED mhz"
906
-    echo $SEPARATOR
907
-    echo "Your new DVD should be in $OUT_DIR"
908
-    echo "You can preview them in gxine with this command:"
909
-    echo "    gxine \"dvd:/$OUT_DIR\""
910
-    echo "If you are satisfied with the results, you can burn a disc with:"
911
-    echo "    tovid dvd -burn \"$OUT_DIR\""
912
+    goodbye=`cat << EOF
913
+
914
+    $SEPARATOR
915
+    todisc took $SCRIPT_TIME to finish on
916
+    $CPU_MODEL $CPU_SPEED mhz
917
+    $SEPARATOR
918
+
919
+    Your new DVD should be in $OUT_DIR
920
+    You can preview them in gxine with this command:
921
+        $(printf "%s\t" "gxine \"dvd:/$OUT_DIR\"")
922
+    Or in vlc with this command:
923
+        $(printf "%s\t" "vlc \"$OUT_DIR\"")
924
+    If you are satisfied with the results, you can burn a disc with:
925
+        $(printf "%s\t" "tovid dvd -burn \"$OUT_DIR\"")
926
+    
927
+    Thanks for using tovid!
928
+EOF`
929
     echo
930
-    echo "Thanks for using todisc."
931
+    sed 's/^    //g' <<< "$goodbye" | tee -a "$LOG_FILE"
932
 }
933
 
934
-# usage mk_return_button (mk_play_button) COLOUR1 COLOUR2 OUTBUTTON
935
+# usage mk_return_button (mk_play_button) COLOUR1 COLOUR2 outbutton
936
 # ex. for menu button ( not spumux ):
937
 # mk_return_button "#C6C6C6" black "$WORK_DIR/Main.png"
938
 mk_return_button()
939
 {
940
 
941
-    COLR1="$1"
942
-    COLR2="$2"
943
-    TYPE=$3
944
-    OUTBUTTON="$4"
945
-    if [[ $TYPE = "spu" ]]; then
946
-        CLR1="none"
947
-    elif [[ $TYPE = "default" ]]; then
948
-        CLR1="$COLR1"
949
+    colr1="$1"
950
+    colr2="$2"
951
+    local auth_type=$3
952
+    outbutton="$4"
953
+    if [[ $auth_type = "spu" ]]; then
954
+        clr1="none"
955
+    elif [[ $auth_type = "default" ]]; then
956
+        clr1="$colr1"
957
     fi
958
 
959
-    MK_RTN_CMD=(convert -size 100x80 xc:none \
960
-    -strokewidth 1 -stroke "$COLR2" -fill "$CLR1" \
961
+    mk_rtn_cmd=(convert -size 100x80 xc:none \
962
+    -strokewidth 1 -stroke "$colr2" -fill "$clr1" \
963
     -draw 'rectangle 0,0 70,62' \
964
-    -fill "$COLR2" -stroke none \
965
+    -fill "$colr2" -stroke none \
966
     -draw "polyline 40,10 40,50 10,30 40,10" \
967
     -draw "polyline 60,10 60,50 30,30 60,10" \
968
-    -fill "$COLR2" -draw "rectangle 6,10 10,50" \
969
-    -resize 30% -trim +repage +antialias "$OUTBUTTON")
970
-    echo -e "\nRunning ${MK_RTN_CMD[@]}\n" |format_output
971
-    "${MK_RTN_CMD[@]}"
972
-    mogrify -channel A -threshold 50% "$OUTBUTTON"
973
-    RTN_BTN_DIM=$(get_image_dim "$OUTBUTTON")
974
-    rtn_btn_width=$(awk -Fx '{print $1}' <<< $RTN_BTN_DIM )
975
-    rtn_btn_height=$(awk -Fx '{print $2}' <<< $RTN_BTN_DIM )
976
+    -fill "$colr2" -draw "rectangle 6,10 10,50" \
977
+    -resize 30% -trim +repage +antialias "$outbutton")
978
+    print2log "Running ${mk_rtn_cmd[@]}"
979
+    "${mk_rtn_cmd[@]}"
980
+    mogrify -channel A -threshold 50% "$outbutton"
981
+    rtn_btn_dim=$(get_image_dim "$outbutton")
982
+    rtn_btn_width=$(awk -Fx '{print $1}' <<< $rtn_btn_dim )
983
+    rtn_btn_height=$(awk -Fx '{print $2}' <<< $rtn_btn_dim )
984
 }
985
 mk_play_button()
986
 {
987
-    COLR1="$1"
988
-    COLR2="$2"
989
-    TYPE=$3
990
-    OUTBUTTON="$4"
991
-    if [[ $TYPE = "spu" ]]; then
992
-        CLR1="none"
993
-    elif [[ $TYPE = "default" ]]; then
994
-        CLR1="$COLR1"
995
-    fi
996
-    #-fill "$COLR2" -draw "line 40,10 40,50"  \
997
-    # -fill "$COLR2" -draw "rectangle 36,10 40,50" \
998
-    MK_PLAY_CMD=(convert +antialias -size 100x80 xc:none  \
999
-    -strokewidth 2 -stroke "$COLR2" -fill "$CLR1" \
1000
+    colr1="$1"
1001
+    colr2="$2"
1002
+    local auth_type=$3
1003
+    outbutton="$4"
1004
+    if [[ $auth_type = "spu" ]]; then
1005
+        clr1="none"
1006
+    elif [[ $auth_type = "default" ]]; then
1007
+        clr1="$colr1"
1008
+    fi
1009
+    #-fill "$colr2" -draw "line 40,10 40,50"  \
1010
+    # -fill "$colr2" -draw "rectangle 36,10 40,50" \
1011
+    mk_play_cmd=(convert +antialias -size 100x80 xc:none  \
1012
+    -strokewidth 2 -stroke "$colr2" -fill "$clr1" \
1013
     -draw 'rectangle 22,0 92,62' \
1014
-    -fill "$COLR2" -stroke none \
1015
+    -fill "$colr2" -stroke none \
1016
     -draw "polyline 40,10 40,50 80,30 40,10" \
1017
-    -resize 30% -trim +repage "$OUTBUTTON")
1018
-    echo -e "\nRunning ${MK_PLAY_CMD[@]}\n" |format_output >> "$LOG_FILE"
1019
-    "${MK_PLAY_CMD[@]}"
1020
-    PLAY_BTN_DIM=$(get_image_dim "$OUTBUTTON")
1021
-    play_btn_width=$(awk -Fx '{print $1}' <<< $PLAY_BTN_DIM )
1022
-    play_btn_height=$(awk -Fx '{print $2}' <<< $PLAY_BTN_DIM )
1023
+    -resize 30% -trim +repage "$outbutton")
1024
+     print2log "Running ${mk_play_cmd[@]}"
1025
+    "${mk_play_cmd[@]}"
1026
+    play_btn_dim=$(get_image_dim "$outbutton")
1027
+    play_btn_width=$(awk -Fx '{print $1}' <<< $play_btn_dim )
1028
+    play_btn_height=$(awk -Fx '{print $2}' <<< $play_btn_dim )
1029
 }
1030
 
1031
 check_menufile()
1032
 {
1033
-    yecho
1034
+    yecho ""
1035
     if test -f "$MENU_FILE"; then
1036
         echo "Menu file $MENU_FILE created"
1037
         echo
1038
@@ -1535,54 +1715,38 @@
1039
 quick_menu()
1040
 {
1041
     funct_arg=$1
1042
-    unset LEFTPAD TOPPAD RIGHTPAD BOTTOMPAD
1043
     # is it a preview or main run of menu creation
1044
     if [[ -n $funct_arg && $funct_arg = "preview" ]]; then
1045
         QM_MENU_TIME=2 && QM_PREVIEW=:
1046
     else
1047
         QM_MENU_TIME=${MENU_LEN[MENU_NUM-1]} && QM_PREVIEW=false
1048
     fi
1049
-    # test for filters and vhook
1050
-    filters=$(ffmpeg -filters 2>/dev/null)
1051
-    if grep -q -w '^movie' <<< "$filters" && \
1052
-      grep -q -w '^crop' <<< "$filters"; then
1053
-        echo "libavfilter overlay and crop filters are present"
1054
-        use_overlay_filter=:
1055
-        $use_overlay_filter && echo "Using libavfilter for -quick-menu"
1056
-    elif grep -q ^-vhook <<< "$(ffmpeg -h 2>&1)"; then
1057
-        # find out where vhook lives for ffmpeg
1058
-        local config=$(ffmpeg -version 2>&1 | grep -- --prefix=)
1059
-        config=${ffmpeg_prefix//*--prefix=}
1060
-        ffmpeg_prefix=${config// *}
1061
-        # empty var means no --prefix passed, use default prefix of /usr/local
1062
-        ffmpeg_prefix=${ffmpeg_prefix:-/usr/local}
1063
-        imlib2_vhook="${ffmpeg_prefix}/lib/vhook/imlib2.so"
1064
-        if [[ -s "$imlib2_vhook" ]]; then
1065
-            use_vhooks=:
1066
-        else
1067
-            yecho "!!!!! $imlib2_vhook not found, can not continue !!!!!"
1068
+    # test for filters presense in ffmpeg
1069
+    # ffmpeg has really poor support for scripts so we can't do something
1070
+    # sane like grep for ^movie or ^crop.
1071
+    # using these ugly repeated grep calls because they are easier to
1072
+    # understand/maintain than an awk command.
1073
+    if ! ((filter_test_completed)); then
1074
+        filters=$($FFmpeg -filters 2>/dev/null)
1075
+        if grep  -w 'movie'  <<< "$filters" | grep -q -v 'amovie' &&
1076
+          grep -w 'crop' <<< "$filters" | grep -q -v 'cropdetect'; then
1077
+            print2log "libavfilter movie filter present, using for -quick-menu"
1078
+            use_overlay_filter=:
1079
+        else
1080
+            # exit if missing a needed video filter
1081
+            runtime_error \
1082
+              "Missing ${FFmpeg##*/} filters
1083
+              (movie or crop) -quick-menu impossible."
1084
         fi
1085
     fi
1086
 
1087
-    # FIXME this will not be needed when the overlay filter is in SVN proper
1088
-    if ! $use_vhooks && ! $use_overlay_filter; then
1089
-        runtime_error "You are not able to use -quick-menu:
1090
-        you must use the experimental ffmpeg with libavfilter 
1091
-        or an older (0.52 for example) version of ffmpeg with vhooks.
1092
-        See this post for details on installing ffmpeg with filters: 
1093
-        http://ubuntuforums.org/showthread.php?p=9021636"
1094
-    fi
1095
+    # ensure the filter test is only run once
1096
+    filter_test_completed=1
1097
     if $QUICKMENU_IS_SHOWCASE; then
1098
-        yecho
1099
-        yecho "resizing and padding showcase file: $SHOWCASE_VIDEO"
1100
-        LEFTPAD=$SC_X
1101
-        TOPPAD=$SC_Y
1102
-        RIGHTPAD="-padright \
1103
-        $(( ${VIDSIZE%%x*} - $LEFTPAD - ${SHOWCASE_SIZE%%x*} ))"
1104
-        BOTTOMPAD="-padbottom \
1105
-        $(( ${VIDSIZE##*x} - $TOPPAD - ${SHOWCASE_SIZE##*x} ))"
1106
-        LEFTPAD="-padleft $SC_X"
1107
-        TOPPAD="-padtop $SC_Y"
1108
+        if ! $NOASK; then
1109
+            yecho ""
1110
+            yecho "resizing and padding showcase file: $SHOWCASE_VIDEO"
1111
+        fi
1112
         local VF_PADX=$SC_X
1113
         local VF_PADY=$SC_Y
1114
         QM_FRAMESIZE=$SHOWCASE_SIZE
1115
@@ -1603,24 +1767,22 @@
1116
         qm_post_seek=$qm_seek && unset qm_pre_seek
1117
     fi
1118
 
1119
-    $QM_PREVIEW && yecho "Creating a quick-menu preview image"
1120
-    # pad/resize if needed, use overlay filter (or vhook) to add menu graphics
1121
+    $QM_PREVIEW && ! $NOASK && yecho "Creating a quick-menu preview image"
1122
+    # pad/resize if needed, use overlay filter to add menu graphics
1123
     # framing (if showcase) by ntsc-safe black bg
1124
-    ! $QM_PREVIEW && yecho
1125
     if ! $QM_PREVIEW; then
1126
-        yecho "Using ffmpeg to add titles and background"
1127
+        yecho ""
1128
+        yecho "Using $FFmpeg to add titles and background"
1129
     fi
1130
     if $use_overlay_filter; then
1131
+        local qw=${QM_FRAMESIZE%x*}
1132
+        local qh=${QM_FRAMESIZE#*x}
1133
+        # vhook uses the next var for scaling, but overlay does not
1134
+        unset QM_FRAMESIZE
1135
         local overlay="$WORK_DIR/quick_menu_bg.png"
1136
-        local PADDING="$VF pad=720:480:$VF_PADX:$VF_PADY"
1137
-        local aspect=""
1138
-        overlay_filter="movie=$overlay [wm];[in][wm] overlay=0:0:1 [wm2]"
1139
+        local PADDING="$VF scale=${qw}:${qh},pad=$VF_SCALE:${VF_PADX}:${VF_PADY}"
1140
+        overlay_filter="movie=$overlay [wm];[in][wm] overlay=0:0 [wm2]"
1141
         ffmpeg_filter=($VF "$overlay_filter; [wm2] setdar=4:3 [out]")
1142
-    elif $use_vhooks; then
1143
-        local PADDING="$TOPPAD $BOTTOMPAD $LEFTPAD $RIGHTPAD"
1144
-        local aspect="-aspect 4:3"
1145
-        local PAD_CLR="-padcolor $BG_CLR"
1146
-        ffmpeg_filter=(-vhook "$imlib2_vhook -x 0 -y 0 -i $WORK_DIR/quick_menu_bg.png")
1147
     fi
1148
     # no padding needed for background video, just resizing
1149
     $QUICKMENU_IS_BACKGROUND && PADDING=""
1150
@@ -1628,59 +1790,62 @@
1151
     yuvout="$WORK_DIR/out.yuv"
1152
     rm -f  "$yuvout"  && mkfifo "$yuvout"
1153
     # run the commands to make the final menu m2v video
1154
-    PAD_CMD=(ffmpeg -r $FRAME_RATE -async 1 $qm_pre_seek \
1155
-    -t "$QM_MENU_TIME" -i "$QUICK_MENU_FILE" $qm_post_seek \
1156
-    -s $QM_FRAMESIZE -an $PADDING -r $FRAME_RATE \
1157
+    PAD_CMD=($FFmpeg -async 1 $qm_pre_seek \
1158
+    -i "$QUICK_MENU_FILE" $qm_post_seek -t "$QM_MENU_TIME" \
1159
+    -an $PADDING -r $ff_frame_rate \
1160
     $PAD_CLR -f yuv4mpegpipe -vcodec rawvideo -y "$yuvout")
1161
-    QUICKMENU_CMD=(ffmpeg -s $VIDSIZE -f yuv4mpegpipe \
1162
-    -i "$yuvout" -an -f mpeg2video -r $FRAME_RATE \
1163
-    -tvstd $TV_STANDARD -b 7000k -maxrate 8000k -bufsize 224KiB \
1164
-    $aspect "${ffmpeg_filter[@]}" -y "$WORK_DIR/intro.m2v")
1165
-    $QM_PREVIEW && yecho
1166
-    yecho "Running ${PAD_CMD[@]}"|fold -bs
1167
-    echo "${QUICKMENU_CMD[@]}" | fold -bs | tee -a "$LOG_FILE"
1168
-    "${PAD_CMD[@]}" < /dev/null  > "${LOG_FILE}-1.tmp" 2>&1 &
1169
-    "${QUICKMENU_CMD[@]}" < /dev/null  > "${LOG_FILE}-2.tmp" 2>&1 &
1170
+    # removed-s $VIDSIZE from following cmd, don't think it needs it
1171
+    # check if I need to add a scale filter, perhaps comma sep at end.
1172
+    # http://forum.videohelp.com/threads/338494-Multiple-filter-problem-with-ffmpeg-help-please
1173
+    QUICKMENU_CMD=($FFmpeg -f yuv4mpegpipe \
1174
+    -i "$yuvout" -an -f mpeg2video -r $ff_frame_rate \
1175
+    $VB 7000k -maxrate 8000k -bufsize 224KiB \
1176
+    "${ffmpeg_filter[@]}" -y "$WORK_DIR/intro.m2v")
1177
+    echo "Running ${PAD_CMD[@]}" > "${LOG_FILE}-1.tmp"
1178
+    "${PAD_CMD[@]}" < /dev/null  >> "${LOG_FILE}-1.tmp" 2>&1 &
1179
+    echo "Running ${QUICKMENU_CMD[@]}" > "${LOG_FILE}-2.tmp"
1180
+    "${QUICKMENU_CMD[@]}" < /dev/null  >> "${LOG_FILE}-2.tmp" 2>&1 &
1181
     ffmpeg_pid=$!
1182
-    yecho
1183
-    while ps -p $ffmpeg_pid >/dev/null; do
1184
-        sleep 1
1185
-        [[ -s "$WORK_DIR/intro.m2v" ]] && txt="Writing" || txt="Seeking"
1186
-        spin $txt $SPINNER
1187
-    done
1188
+    if ! $QM_PREVIEW; then
1189
+        while ps -p $ffmpeg_pid >/dev/null; do
1190
+            sleep 1
1191
+            [[ -s "$WORK_DIR/intro.m2v" ]] && txt="Writing" || txt="Seeking"
1192
+            spin $txt $SPINNER
1193
+        done
1194
+    fi
1195
     wait
1196
-    yecho
1197
+    ! $QM_PREVIEW && yecho ""
1198
     # remove control characters and seeking lines
1199
-    strings "${LOG_FILE}-1.tmp" |   sed '/time=10000000000.00/d' >> "$LOG_FILE"
1200
-    strings "${LOG_FILE}-2.tmp" | sed '/time=10000000000.00/d' >> "$LOG_FILE"
1201
+    [[ -e ${LOG_FILE}-1.tmp ]] && \
1202
+      cat "${LOG_FILE}-1.tmp" | sed '/time=10000000000.00/d' | pipe2log ${FFmpeg##*/}
1203
+    [[ -e ${LOG_FILE}-2.tmp ]] && \
1204
+      cat "${LOG_FILE}-2.tmp" | sed '/time=10000000000.00/d' | pipe2log ${FFmpeg##*/}
1205
     if [[ ! -s "$WORK_DIR/intro.m2v" ]]; then
1206
         runtime_error "There was a problem creating the menu video $funct_arg"
1207
     fi
1208
     rm -f "${LOG_FILE}*.tmp"
1209
-    ! $QM_PREVIEW && yecho
1210
+    ! $QM_PREVIEW && yecho ""
1211
     # create preview images if called for, taking largest of 10 images
1212
     if $QM_PREVIEW; then
1213
-        FFMPEG_CMD=(ffmpeg -i "$WORK_DIR/intro.m2v" -an -vframes 10 \
1214
+        FFMPEG_CMD=($FFmpeg -i "$WORK_DIR/intro.m2v" -an -vframes 10 \
1215
         -f image2 -y "$outdir"/%06d.$IMG_FMT)
1216
-        yecho "Running ${FFMPEG_CMD[@]}" | strings
1217
-        "${FFMPEG_CMD[@]}" 2>&1 | strings >> "$LOG_FILE"
1218
+        print2log "Running ${FFMPEG_CMD[@]}"
1219
+        "${FFMPEG_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
1220
         # take the largest image (best quality?) of a 10 frame sampling
1221
         largest_img=$(get_largest 6 10 "$outdir" )
1222
         mv "$largest_img" "$PREVIEW_IMG"
1223
-        yecho "Removing temporary preview files"
1224
+        print2log "Removing temporary preview files"
1225
         rm -f "$WORK_DIR/intro.m2v"
1226
         rm -f "$WORK_DIR"/showcase/*.$IMG_FMT "$WORK_DIR"/bg/*.$IMG_FMT
1227
     fi
1228
-    $QM_PREVIEW && yecho
1229
+    $QM_PREVIEW && yecho ""
1230
 }
1231
 
1232
 # 3x1 and 4x1 tile only for default arrangement
1233
 tile_warning()
1234
 {
1235
-    yecho
1236
-    echo "-tile-3x1 and -tile-4x1 are not showcase options.  Disabling"
1237
-    yecho
1238
-    $WARN && sleep 5
1239
+    info_message "-tile-3x1 and -tile-4x1 are not showcase options.  Disabling"
1240
+    $WARN && continue_in 5
1241
 }
1242
 dvdauthor_error()
1243
 {
1244
@@ -1721,30 +1886,34 @@
1245
 
1246
 make_dummy()
1247
 {
1248
-    yecho "Creating a blank mpeg for the vmgm menu"
1249
     convert  -resize $VIDSIZE! xc:"#101010" "$WORK_DIR/dummy.jpg"
1250
-    ENC_CMD1=(jpeg2yuv -v 1 -f $FRAME_RATE -I p -n 1 -l 30 \
1251
+    [[ $TV_STANDARD = "ntsc" ]] && local len=30 || local len=25
1252
+    ENC_CMD1=(jpeg2yuv -v 1 -f $FRAME_RATE -I p -n 1 -l $len \
1253
     -L 1 -b1 -j "$WORK_DIR/dummy.jpg")
1254
-    ENC_CMD2=(ffmpeg -f yuv4mpegpipe -i - -an -r $FRAME_RATE -s $VIDSIZE \
1255
-    -tvstd $TV_STANDARD $FFMPEG_OPTS -y "$WORK_DIR/dummy.m2v")
1256
-    echo "Running: ${ENC_CMD1[@]} | ${ENC_CMD2[@]}" |
1257
-    format_output | tee -a "$LOG_FILE"
1258
-    if ! ${ENC_CMD1[@]} 2>> "$LOG_FILE"  |
1259
-    ${ENC_CMD2[@]} 2>&1 |strings  >> "$LOG_FILE"; then
1260
-        runtime_error
1261
-    fi
1262
-    VMGM_TIME=$(vid_length "$WORK_DIR/dummy.m2v")
1263
-    yecho
1264
-    BGAUDIO_CMD=(ffmpeg -f s16le -ar 48000 -i /dev/zero -t $VMGM_TIME \
1265
+    ENC_CMD2=($FFmpeg -f yuv4mpegpipe -i - -an -r $ff_frame_rate \
1266
+    $FFMPEG_OPTS -vf scale=${VF_SCALE},${ASPECT} -y "$WORK_DIR/dummy.m2v")
1267
+    print2log "Running: ${ENC_CMD1[@]} | ${ENC_CMD2[@]}"
1268
+    ${ENC_CMD1[@]} 2>> "${LOG_FILE}.tmp"  |
1269
+    ${ENC_CMD2[@]} 2>&1 |pipe2log ${FFmpeg##*/}
1270
+    [[ -e ${LOG_FILE}.tmp ]] && cat "${LOG_FILE}.tmp" | pipe2log jpeg2yuv
1271
+    rm -f "${LOG_FILE}.tmp"
1272
+    ! [[ -s "$WORK_DIR/dummy.m2v" ]] && \
1273
+      runtime_error "There was a problem creating a dummy vmgm video"
1274
+    local VMGM_TIME=1 # use one second as dummy.m2v or either 30 or 25 frames
1275
+    BGAUDIO_CMD=($FFmpeg -f s16le -ar 48000 -i /dev/zero -t $VMGM_TIME \
1276
     $AUDIO_OPTS -y "$WORK_DIR/dummy.$AUDIO_EXT")
1277
-    yecho "${BGAUDIO_CMD[@]}"
1278
-    "${BGAUDIO_CMD[@]}" 2>&1 | strings >> "$LOG_FILE"
1279
-    ! [[ -s "$WORK_DIR/dummy.$AUDIO_EXT" ]] &&  runtime_error
1280
+    print2log "Creating silent audio stream."
1281
+    print2log "${BGAUDIO_CMD[@]}"
1282
+    "${BGAUDIO_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
1283
+    ! [[ -s "$WORK_DIR/dummy.$AUDIO_EXT" ]] &&  runtime_error \
1284
+    "There was a problem creating audio for the dummy vmgm menu"
1285
 
1286
     MPLEX_CMD=(mplex -V -f $MPLEX_FORMAT -o  "$BASEDIR/dummy.mpg" \
1287
      "$WORK_DIR/dummy.$AUDIO_EXT"  "$WORK_DIR/dummy.m2v")
1288
-    echo "Running: ${MPLEX_CMD[@]}" |fold -bs >> "$LOG_FILE"
1289
-    ! "${MPLEX_CMD[@]}" 2>&1 |strings >> "$LOG_FILE" && runtime_error
1290
+    print2log "Running: ${MPLEX_CMD[@]}"
1291
+    "${MPLEX_CMD[@]}" 2>&1 |pipe2log mplex
1292
+    ((${PIPESTATUS[0]} != 0)) && runtime_error \
1293
+    "There was a problem muxing the audio and video with mplex"
1294
 }
1295
 verify_infiles()
1296
 {
1297
@@ -1762,7 +1931,7 @@
1298
         IN_FILE="${in_files[i]}"
1299
         if test -s "$IN_FILE"; then
1300
             check_filetype "$IN_FILE"
1301
-            if [[ $TYPE = "image" ]]; then
1302
+            if [[ $file_type = "image" ]]; then
1303
                 IMG_STATS=( $(identify -ping -format "%z %w %h" "$IN_FILE") )
1304
                 DEPTH=${IMG_STATS[0]}
1305
                 IMG_WIDTH=${IMG_STATS[1]}
1306
@@ -1796,13 +1965,11 @@
1307
                 # also convert if not PNG or JPEG or wrong aspect ratio
1308
                 # test IN_FILES for preview - group files tested later
1309
                 if [[ $DEPTH = 16 || $PAD_IMG = "yes" ]] || $CONVRT ; then
1310
-                    echo "Converting $IN_FILE to proper image format" \
1311
-                      >> "$LOG_FILE"
1312
+                    print2log "Converting $IN_FILE to proper image format"
1313
                     IMG_CMD=(convert "$IN_FILE" -depth 8 "${CROP_CMD[@]}" \
1314
                     -quality 01 "$OUTPNG")
1315
-                    format_output <<< "${IMG_CMD[@]}" \
1316
-                        >> "LOG_FILE"
1317
-                    "${IMG_CMD[@]}" |format_output >> "$LOG_FILE" 2>&1
1318
+                    print2log "${IMG_CMD[@]}"
1319
+                    "${IMG_CMD[@]}" 2>&1| pipe2log imagemagick
1320
                     # replace IN_FILES[i] OR group symlink
1321
                     if [[ $verify_type = "infiles" ]]; then
1322
                         IN_FILES[i]=$OUTPNG
1323
@@ -1830,8 +1997,7 @@
1324
                     grp_file_is_image[i]="yes"
1325
                 fi
1326
                 spin checking "${IN_FILE##*/}"
1327
-            elif mencoder -quiet -oac pcm -ovc copy \
1328
-            -frames 0 -o /dev/null "$IN_FILE" &>/dev/null; then
1329
+            elif is_video "$IN_FILE"; then
1330
                 checkfile="${IN_FILE##*/}"
1331
                 spin checking "$checkfile"
1332
             else
1333
@@ -1841,6 +2007,7 @@
1334
             usage_error "Sorry, $IN_FILE does not exist or is empty"
1335
         fi
1336
     done
1337
+    echo
1338
 }
1339
 
1340
 # contrasting 'undercolor' for -background from given font colour
1341
@@ -1943,22 +2110,23 @@
1342
 
1343
 transition_slide()
1344
 {
1345
-    TYPE=$1
1346
+    local fade_type=$1
1347
+    local value
1348
     index=$2
1349
     outppm="$WORK_DIR/animenu/$(printf %06d%s $index .ppm)"
1350
-    if [[ $TYPE = "crossfade" ]]; then
1351
-        local VALUE=$(bc -l <<< "scale=2; ($fade_slide + 1) * $fade_incr") >&2
1352
-        fade_cmd=(composite -blend $VALUE -depth 8 "$overlay_ppm" \
1353
+    if [[ $fade_type = "crossfade" ]]; then
1354
+        value=$(bc -l <<< "scale=2; ($fade_slide + 1) * $fade_incr") >&2
1355
+        fade_cmd=(composite -blend $value -depth 8 "$overlay_ppm" \
1356
         "$base_ppm" "$outppm")
1357
-    elif [[ $TYPE = "fadein" ]]; then
1358
-        local VALUE=$(bc -l <<< "scale=2; $fade_slide * $fade_incr") >&2
1359
+    elif [[ $fade_type = "fadein" ]]; then
1360
+        value=$(bc -l <<< "scale=2; $fade_slide * $fade_incr") >&2
1361
         fade_cmd=(composite -depth 8 "$base_ppm" "$WORK_DIR/black.ppm" \
1362
-        -blend ${VALUE}% "$outppm")
1363
-    elif [[ $TYPE = "fadeout" ]]; then
1364
-        local VALUE=$(bc -l <<< "scale=2;100 - (($fade_slide + 1) * $fade_incr)") >&2
1365
-        (( $(bc <<< "$VALUE < 0") == 1 )) && local VALUE=0
1366
+        -blend ${value}% "$outppm")
1367
+    elif [[ $fade_type = "fadeout" ]]; then
1368
+        value=$(bc -l <<< "scale=2;100 - (($fade_slide + 1) * $fade_incr)") >&2
1369
+        (( $(bc <<< "$value < 0") == 1 )) && value=0
1370
         fade_cmd=(composite -depth 8 "$base_ppm" "$WORK_DIR/black.ppm" \
1371
-        -blend ${VALUE}% "$outppm")
1372
+        -blend ${value}% "$outppm")
1373
     fi
1374
      "${fade_cmd[@]}" >/dev/null
1375
 }
1376
@@ -1966,10 +2134,10 @@
1377
 # this function does a loop with transition_slide() ... combine them into 1 ?
1378
 do_transitions()
1379
 {
1380
-    TYPE=$1
1381
+    local fade_type=$1
1382
     fade_slide=0
1383
     for ((i=0; i<=fade_frames; i++)); do
1384
-        transition_slide $TYPE $i &
1385
+        transition_slide $fade_type $i &
1386
         transition_pids="$transition_pids $!"
1387
         ((num_procs++))
1388
         if ((num_procs == max_procs || i == fade_frames-1)); then
1389
@@ -1978,7 +2146,7 @@
1390
         fi
1391
         let fade_slide=fade_slide+1
1392
     done
1393
-    if [[ $TYPE = "fadeout" ]] && ((f == ${#MIX_IN[@]}-1)); then
1394
+    if [[ $fade_type = "fadeout" ]] && ((f == ${#MIX_IN[@]}-1)); then
1395
         for p in {0..12}; do
1396
             cp "$WORK_DIR/black.ppm" \
1397
             "$WORK_DIR/animenu/$(printf %06d%s $((p +i)) .ppm)" >&2
1398
@@ -2024,7 +2192,7 @@
1399
         -bordercolor grey60 -border 1 \
1400
         -rotate ${randir}${angle}  \
1401
         -background  black  \( +clone -shadow 60x4+4+4 \) +swap \
1402
-        -background  none   -flatten \
1403
+        +repage -background none -flatten \
1404
         "$WORK_DIR/tnail${i%.*}.png"
1405
         stack_files[i]=$WORK_DIR/tnail${i%.*}.png
1406
 
1407
@@ -2048,23 +2216,6 @@
1408
 {
1409
     echo -e "\nIt took $(format_seconds $((etime-stime)) ) for the $1\n"
1410
 }
1411
-# make sure  correct sample size option for sox  is used
1412
-# getting sox version is inconsistent, so just run test command
1413
-get_sox_arg()
1414
-{
1415
-if cat /dev/zero 2>/dev/null | nice -n 0 sox -t raw -c 2 -r 48000 -w -s - \
1416
-"$WORK_DIR/foo.wav" trim 0 1 &>/dev/null; then
1417
-    echo -w
1418
-elif cat /dev/zero 2>/dev/null | nice -n 0 sox -t raw -c 2 -r 48000 -2 -s - \
1419
-"$WORK_DIR/foo.wav" trim 0 1 &>/dev/null; then
1420
-    echo -2
1421
-else
1422
-    runtime_error "Your sox appears to be incompatible with this program.  " \
1423
-    "Attempted to create a wav file using the -w option, then the -2 option"
1424
-fi
1425
-rm -f "$WORK_DIR/foo.wav"
1426
-
1427
-}
1428
 
1429
 # Usage: check_maskshape SHAPE.  Returns 1 if SHAPE not found.
1430
 check_maskshape()
1431
@@ -2087,7 +2238,7 @@
1432
     if [[ $mask_type == "thumb" ]]; then
1433
         local BLUR_CMD=( "${THUMB_BLUR_CMD[@]}" )
1434
     else
1435
-        local BLUR_CMD=( "${SC_BLUR_CMD[@]]}" )
1436
+        local BLUR_CMD=( "${SC_BLUR_CMD[@]}" )
1437
     fi
1438
     MASK="$WORK_DIR/${shape}_${mask_type}_mask.png"
1439
 
1440
@@ -2173,14 +2324,6 @@
1441
         convert - -resize $THUMB_SIZE! $MASK
1442
         ;;
1443
       "blob")
1444
-        echo $SEPARATOR
1445
-        echo "Running convert -size 100x60 xc:none -fill white \
1446
-        -draw \"circle 41,39 44,57 circle 59,39 56,57 circle 50,21 50,3\" miff:- |
1447
-        convert - -trim +repage -bordercolor none -border 10x10 miff:- |
1448
-        ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} | ${BLUR_CMD[@]} |
1449
-        convert - -resize $THUMB_SIZE! $MASK" | format_output
1450
-        echo $SEPARATOR
1451
-
1452
         convert -size 100x60 xc:none -fill white \
1453
         -draw "circle 41,39 44,57 circle 59,39 56,57 circle 50,21 50,3" miff:- |
1454
         convert - -trim +repage -bordercolor none -border 10x10 miff:- |
1455
@@ -2206,15 +2349,31 @@
1456
     esac
1457
 }
1458
 
1459
+# wait for file to appear
1460
+# name and timeout are optional: defaults to basename of FILE and 12 secs 
1461
+# usage: wait_for file [name] [timeout]
1462
 wait_for()
1463
 {
1464
-    # wait for file to appear
1465
-    while true; do
1466
-        if test -e $1; then
1467
+    local check_file=$1
1468
+    local filename=${check_file##*/}
1469
+    # default timeout of 10 seconds
1470
+    local timeout=${3:-10}
1471
+    timeout=$((timeout * 10))
1472
+    local name=${2:-$filename}
1473
+    x=0
1474
+    while ((x<timeout)); do
1475
+        if test -e "$check_file"; then
1476
             return
1477
         fi
1478
+        # print a message after 2 seconds: will only run when there is a problem
1479
+        if ((x==20)); then
1480
+            echo Waiting $(( (timeout / 10) - 2)) seconds for $name to appear ...
1481
+        fi
1482
         sleep .1
1483
+        ((x++))
1484
     done
1485
+    unset x
1486
+    return 1
1487
 }
1488
 
1489
 # HACK: transcode produces some scary output when run from python
1490
@@ -2224,7 +2383,7 @@
1491
     transcode shown below if it shows transcode finishing the last image. \
1492
     These harmless 'broken pipe' messages from transcode appear to be a \
1493
     subtle bug in transcode when running it (or a script) from python. \
1494
-    \n****\n" | sed "s/    */ /g;s/^ *//" |fold -bs >> "$LOG_FILE"
1495
+    \n****\n" | sed "s/    */ /g;s/^ *//" | pipe2log todisc format
1496
 }
1497
 
1498
 # get the largest PNG (1st match sequentially if more than one are same size)
1499
@@ -2248,6 +2407,16 @@
1500
     echo $result
1501
 }
1502
 
1503
+# tip from Steven M. Schultz
1504
+# https://www.mail-archive.com/mjpeg-users@lists.sourceforge.net/msg03511.html
1505
+# an alternative to yuvcorrect -T NO_HEADER
1506
+remove_header()
1507
+{
1508
+read junk
1509
+cat
1510
+return 0
1511
+}
1512
+
1513
 ##############################################################################
1514
 #                               End of Functions                                #
1515
 ##############################################################################
1516
@@ -2268,7 +2437,7 @@
1517
 
1518
 egrep -q 'titleset-mode|switched-mode|menu-only|carousel_menu_mode' <<< "$@" \
1519
  && NONAME=:
1520
-! $NONAME && yecho $"$SCRIPT_NAME"
1521
+! $NONAME && echo $"$SCRIPT_NAME"
1522
 
1523
 while test $# -gt 0; do
1524
     DO_SHIFT=:
1525
@@ -2291,6 +2460,9 @@
1526
                 for f in  ${!ARGS_ARRAY[@]}; do
1527
                     FILENAMES[f]=${ARGS_ARRAY[f]}
1528
                     filenames[f]=$(readlink -f "${ARGS_ARRAY[f]}")
1529
+                    if [[ ! -e ${filenames[f]} ]]; then
1530
+                        usage_error "${filenames[f]} does not exist"
1531
+                    fi
1532
                 done
1533
                 if $incoming_slides; then
1534
                     SLIDESHOW=( ${SLIDESHOW[@]} : ) # is this a slideshow ?
1535
@@ -2306,6 +2478,9 @@
1536
                 unset group groupkey grp x
1537
                 for ((i=0; i<${#ARGS_ARRAY[@]}; i++)); do
1538
                     grp[x++]=$(readlink -f "${ARGS_ARRAY[i]}")
1539
+                    if [[ ! -e "${ARGS_ARRAY[i]}" ]]; then
1540
+                        usage_error "${ARGS_ARRAY[i]} does not exist"
1541
+                    fi
1542
                 done
1543
                 unset x
1544
                 [[ -z ${FILES[@]} ]] && ss_index=0 || ss_index=${#FILES[@]}
1545
@@ -2313,7 +2488,7 @@
1546
                 FILES[ss_index]=$(readlink -f "${ARGS_ARRAY[0]}")
1547
                 GROUP_IN_FILES=( "${GROUP_IN_FILES[@]}" "${grp[@]}" )
1548
                 groupkey=${#FILES[@]}
1549
-                GROUP[groupkey-1]=${#grp[@]}
1550
+                GROUP_ARR[groupkey-1]=${#grp[@]}
1551
                 ((groupkeys++))
1552
                 # create symlinks to ease substitution later
1553
                 for c in ${!grp[@]}; do
1554
@@ -2360,7 +2535,7 @@
1555
             ((${ARGS_ARRAY[0]})) 2>/dev/null || usage_error "Arguments to \
1556
             -group must be preceeded by a positive integer.  See 'man tovid'"
1557
             groupkey=$(( ${ARGS_ARRAY[0]} - 1))
1558
-            GROUP[groupkey]=${#grp[@]}
1559
+            GROUP_ARR[groupkey]=${#grp[@]}
1560
             # temporary till I finish submenu groups TODO
1561
             is_vidgroup[groupkey]=1
1562
             # create symlinks to ease substitution later
1563
@@ -2405,10 +2580,14 @@
1564
         "-nomenu" | "-no-menu" )
1565
             NOMENU=:
1566
             ;;
1567
+        "-encode-only" )
1568
+            ENCODE_ONLY=:
1569
+            NOMENU=:
1570
+            ;;
1571
         "-out" )
1572
             shift
1573
-            OUT_PREFIX="$1"
1574
-            OUT_PREFIX=${OUT_PREFIX%/}
1575
+            OUT_DIRECTORY="$1"
1576
+            OUT_DIRECTORY=${OUT_DIRECTORY%/}
1577
             ;;
1578
         "-no-ask" | "-noask" )
1579
             NOASK=:
1580
@@ -2456,17 +2635,17 @@
1581
             [[ -n $wsarg ]] &&  WIDESCREEN=$wsarg || WIDESCREEN="nopanscan"
1582
             WIDE_SCREEN=:
1583
             ;;
1584
-        "-showcase-safe-area" )
1585
+        "-safe-area" | "-showcase-safe-area" )
1586
             ADV_OPT=( "${ADV_OPT[@]}" "$1" )
1587
             shift
1588
             SAFE_AREA="$1"
1589
-            let SAFE_OFFSET="86-SAFE_AREA"
1590
             USER_SAFE_AREA=:
1591
             ;;
1592
         "-align" )
1593
             ADV_OPT=( "${ADV_OPT[@]}" "$1" )
1594
             shift
1595
             BUTTON_GRAVITY=$1
1596
+            BUTTON_GRAVITY=$(tr A-Z a-z <<< $BUTTON_GRAVITY) # West => west
1597
             [[ $BUTTON_GRAVITY = "centre" ]] && BUTTON_GRAVITY="center"
1598
             USER_GRAVITY=:
1599
             ;;
1600
@@ -2756,9 +2935,14 @@
1601
             shift
1602
             get_listargs "$@"
1603
             arg=${ARGS_ARRAY[0]}
1604
+            [[ -n $arg && $arg = 0 ]] && usage_error "Using '0' as an arg for -textmenu not allowed -
1605
+            use -align east (northeast, southeast) for 1 right-aligned column"
1606
             [[ -n $arg ]] && SPLIT=$arg && USER_SPLIT=:
1607
             TEXTMENU=:
1608
             ;;
1609
+        "-edge-justify")
1610
+            EDGE_JUSTIFY=:
1611
+            ;;
1612
         "-text-start" )
1613
             ADV_OPT=( "${ADV_OPT[@]}" "$1" )
1614
             shift
1615
@@ -2767,9 +2951,10 @@
1616
         "-showcase-titles-align" )
1617
             shift
1618
             SC_TITLE_ALIGN="$1"
1619
+            SC_TITLE_ALIGN=$(tr A-Z a-z <<< $SC_TITLE_ALIGN) # West => west
1620
             [[ SC_TITLE_ALIGN = "centre" ]] && SC_TITLE_ALIGN="center"
1621
             ;;
1622
-        "-title-gap" )
1623
+        "-titles-gap" | "-title-gap" )
1624
             ADV_OPT=( "${ADV_OPT[@]}" "$1" )
1625
             shift
1626
             SPACER=$1
1627
@@ -2872,6 +3057,7 @@
1628
             (( ${SC_BLUR%.*} >= 2 )) && SC_BLUR=2
1629
             SC_USER_BLUR=1
1630
             ;;
1631
+        "-menu-title-colour" | "-menu-title-color" | \
1632
         "-title-colour" | "-title-color" )
1633
             shift
1634
             TITLE_CLR="$1"
1635
@@ -2888,13 +3074,13 @@
1636
             shift
1637
             SM_TITLE_CLR="$1"
1638
             ;;
1639
-        "-title-stroke" )
1640
+        "-menu-title-stroke" | "-title-stroke" )
1641
             shift
1642
-            TITLE_STROKE="$1"
1643
+            M_TITLE_STROKE="$1"
1644
             ;;
1645
         "-titles-stroke" )
1646
             shift
1647
-            TITLES_STROKE="$1"
1648
+            V_TITLES_STROKE="$1"
1649
             ;;
1650
         "-submenu-stroke" )
1651
             shift
1652
@@ -2904,7 +3090,7 @@
1653
             shift
1654
             test_is_number $1 && TITLES_OPACITY="$1"
1655
             ;;
1656
-        "-title-opacity" )
1657
+        "-menu-title-opacity" | "-title-opacity" )
1658
             shift
1659
             test_is_number $1 && TITLE_OPACITY="$1"
1660
             ;;
1661
@@ -2936,12 +3122,24 @@
1662
             shift
1663
             SELECT_CLR="$1"
1664
             ;;
1665
+        "-menu-title-font-deco" | "-title-font-deco" | \
1666
+        "-menu-title-fontdeco" | "-title-fontdeco")
1667
+            shift
1668
+            USE_M_TITLE_DECO=:
1669
+            M_TITLE_FONT_DECO=($1)
1670
+            ;;
1671
+        "-titles-font-deco" | "-titles-fontdeco" )
1672
+            shift
1673
+            USE_V_TITLES_DECO=:
1674
+            V_TITLES_FONT_DECO=($1)
1675
+            ;;
1676
         -thumb-text-col* | "-thumb-font" | "-thumb-fontsize" ) # removed
1677
             usage_error \
1678
-            "The $1 option has been renamed.  Now use: -titles-${1##*-}"
1679
+            "The $1 option now renamed.  Try: -titles-${1##*-} or check manual"
1680
             ;;
1681
         *-stroke-col* ) # removed
1682
-            usage_error "The $1 option has been renamed.  Now use: ${1%-*}"
1683
+            usage_error \
1684
+            "The $1 option now renamed.  Try: ${1%-*} or check manual"
1685
             ;;
1686
         "-text-mist" )
1687
             MIST=:
1688
@@ -3068,11 +3266,11 @@
1689
             shift
1690
             MENU_TITLE="$1"
1691
             ;;
1692
-        "-menu-font" )
1693
+        "-menu-title-font" | "-title-font" | "-menu-font" )
1694
             shift
1695
             MENU_FONT=$(get_font "$1")
1696
             ;;
1697
-        "-menu-fontsize" )
1698
+        "-menu-title-fontsize" | "-title-fontsize" | "-menu-fontsize" )
1699
             shift
1700
             MENU_FONTSIZE="$1"
1701
             ;;
1702
@@ -3119,6 +3317,8 @@
1703
             shift
1704
             USER_SC_GEO=:
1705
             SHOWCASE_GEO=$1
1706
+            ! grep -q "+[0-9]*+[0-9]*" <<< $SHOWCASE_GEO && usage_error \
1707
+            "-showcase-geo argument must be the position geometry in form +X+Y"
1708
             ;;
1709
         "-submenu-audio-seek" ) # not implemented yet
1710
             shift
1711
@@ -3131,6 +3331,7 @@
1712
             USER_TITLE_GEO=:
1713
             shift
1714
             TITLE_GRAVITY=$1
1715
+            # centre => center ... no other direction has re in it :)
1716
             TITLE_GRAVITY=${TITLE_GRAVITY/re/er}
1717
             ;;
1718
         "-menu-title-offset" )
1719
@@ -3272,6 +3473,9 @@
1720
             done
1721
             USER_THUMBS=:
1722
             ;;
1723
+        "-from-gui" )
1724
+            FROM_GUI=:
1725
+            ;;
1726
         "-config" | "-ntscfilm" | "-dvd-vcd" | "-half-dvd" | "-kvcd" | \
1727
         "-kvcdx3" | "-kvcdx3a" | "-kdvd" | "-bdvd" | "-704" | "-normalize" | \
1728
         "-amplitude" | "-overwrite" | "-panavision" | "-force" | "-fps" | \
1729
@@ -3279,8 +3483,8 @@
1730
         "-abitrate" | "-priority" | "-deinterlace" | "-progressive" | \
1731
         "-interlaced" | "-interlaced_bf" | "-type" | "-fit" | "-discsize" | \
1732
         "-parallel" | "-mkvsub" | "-autosubs" | "-subtitles" | "-update" | \
1733
-        "-mplayeropts" | "-audiotrack" | "-downmix" | "-ffmpeg" | "-nofifo" | \
1734
-        "-from-gui" | "-noask" | "-slice" | "-async" | "-quiet" | \
1735
+        "-mplayeropts" | "-audiotrack" | "-downmix" | "-ffmpeg" | "-avconv" | \
1736
+        "-nofifo" | "-from-gui" | "-noask" | "-slice" | "-async" | "-quiet" | \
1737
         "-fake" | "-keepfiles" )
1738
             # remove this warning for tovid 0.33 TODO
1739
             if [[ $1 = "-subtitles" ]]; then
1740
@@ -3299,6 +3503,12 @@
1741
                 else
1742
                     TOVID_OPTS+=( "$1" "$(readlink -f "$2")" )
1743
                 fi
1744
+            elif [[ $1 == '-mplayeropts' ]]; then
1745
+                # -mplayeropts can start with a '-' so just get entire string.
1746
+                # TODO allow using -mplayeropts for each video, use "" for none
1747
+                # [[  "${2+defined}" && -z $2 ]] ... MPLAYER_OPTS+=("")
1748
+                TOVID_OPTS+=("$1" "$2")
1749
+                shift
1750
             else
1751
                 TOVID_OPTS+=( "$1" )
1752
                 shift
1753
@@ -3319,6 +3529,10 @@
1754
 
1755
 # get script pid so we can kill the parent if doing recursive todisc's
1756
 TODISC_PIDS="$TODISC_PIDS $$"
1757
+    ########################################################################
1758
+    ### Setup and error checks (Critical 1st, Warnings after log created ###
1759
+    ########################################################################
1760
+
1761
 # make sure dvd-slideshow is installed if user passed -use-dvd-slideshow
1762
 $USE_DVD_SLIDESHOW && assert_dep dvd-slideshow \
1763
 "The program dvd-slideshow was not found - you can get it from
1764
@@ -3377,27 +3591,6 @@
1765
 # for switched menus the 1st menu (MN) made is the 2nd, not the 1st
1766
 { $SWITCHED_MODE || $SWITCHED_MENUS ; } && MN=2 || MN=1
1767
 
1768
-if [[ ${#TITLES[@]} -eq 0 ]]; then
1769
-    if [[ $MENU_NUM = $MN ]] && ! $NOMENU \
1770
-     && ! $SINGLE_SLIDESHOW && ! $DO_TITLESETS && $MONTAGE_MENU; then
1771
-        yecho
1772
-        yecho "You did not provide any titles with -titles"
1773
-        yecho "Using the basename of each file provided (minus the extension)."
1774
-        yecho
1775
-        ((sshows < 1)) && $WARN && sleep 5
1776
-    fi
1777
-    for i in ${!FILES[@]}; do
1778
-        TITLE=${FILES[i]##*/}
1779
-        TITLES[i]=" ${TITLE%%.*} "
1780
-    done
1781
-fi
1782
-if ! $TITLESET_MODE && ! $DO_TITLESETS && $QUICK_NAV && ! $VMGM_ONLY; then
1783
-    QUICK_NAV=false
1784
-    yecho
1785
-    yecho "No -quick-nav unless doing titlesets ... disabling this option"
1786
-    $WARN && sleep 5
1787
-    yecho
1788
-fi
1789
 if $DO_TITLESETS && ! $VMGM_MENU && ! $QUICK_NAV; then
1790
     usage_error \
1791
     "You can not use -no-vmgm if doing titlesets unless using -quick-nav"
1792
@@ -3417,20 +3610,39 @@
1793
     SC_TITLE_ALIGN="west"
1794
     SHOWCASE=:
1795
 fi
1796
+# usage error on mispellings for *align* options
1797
+case $BUTTON_GRAVITY in
1798
+  north|south|east|west|northwest|northeast|southwest|southeast|center)
1799
+    :
1800
+    ;;
1801
+  *)
1802
+    usage_error "$BUTTON_GRAVITY is an incorrect argument for '-align'"
1803
+    ;;
1804
+esac
1805
+case $SC_TITLE_ALIGN in
1806
+  west|east|center)
1807
+    :
1808
+    ;;
1809
+  *)
1810
+    usage_error "$SC_TITLE_ALIGN is an incorrect argument for \
1811
+      '-showcase-titles-align'"
1812
+    ;;
1813
+esac
1814
 if $TEXTMENU; then
1815
     SHOWCASE=:
1816
     IMG_FMT="png"
1817
-    SC_TITLE_ALIGN="west"
1818
+    # default -align for textmenu is northwest, not north
1819
+    ! $USER_GRAVITY && BUTTON_GRAVITY="northwest"
1820
+elif $SHOWCASE; then
1821
+    ! $USER_GRAVITY && BUTTON_GRAVITY="northwest" # with thumbs, use defaults
1822
 fi
1823
 # incompatible slideshow options with -switched-menus
1824
 if { $CAROUSEL_IS_BG || $CAROUSEL_IS_SHOWCASE ; } && $SWITCHED_MENUS; then
1825
     $CAROUSEL_IS_BG && OPT="-background-slideshow" || OPT="-showcase-slideshow"
1826
-    yecho
1827
-    yecho "$OPT uses slides from ALL slideshows, so its use with
1828
+    info_message "$OPT uses slides from ALL slideshows, so its use with \
1829
      -switched-menus makes no sense.  Removing this option for you."
1830
-    yecho
1831
     CAROUSEL_IS_SHOWCASE=false; CAROUSEL_IS_BG=false
1832
-    $WARN && sleep 10
1833
+    $WARN && continue_in 5
1834
 fi
1835
 # slideshows are animated by default like rest of todisc
1836
 if ((sshows>=1)); then
1837
@@ -3443,6 +3655,15 @@
1838
         SLIDE_FADE=:
1839
     fi
1840
 fi
1841
+
1842
+# you can not use submenus with slideshows
1843
+if ((num_slideshows>0)) && $SUB_MENU; then
1844
+    usage_error "You can not use submenus with slideshows.  If you have
1845
+    a mixed menu of videos and slideshows, but want submenus for the videos,
1846
+    you will have to put the videos in a separate titleset instead."
1847
+fi
1848
+    
1849
+
1850
 #if $DO_CAROUSEL && $SHOWCASE && ! { $SWITCHED_MODE || $SWITCHED_MENUS ; } && \
1851
 # ! $CAROUSEL_IS_BG && ! $CAROUSEL_IS_SHOWCASE && ((sshows<=1)); then
1852
 #    yecho
1853
@@ -3461,10 +3682,10 @@
1854
 : ${BASEDIR:="$WORK_DIR"}
1855
 
1856
 # Make sure -out was provided and it is valid
1857
-if test -n "$OUT_PREFIX"; then
1858
-    OUT_DIR=$(readlink -f "$OUT_PREFIX")
1859
+if test -n "$OUT_DIRECTORY"; then
1860
+    OUT_DIR=$(readlink -f "$OUT_DIRECTORY")
1861
     if [[ ! -d ${OUT_DIR%/*} ]]; then
1862
-        OUT_PATH=$(readlink -m "$OUT_PREFIX")
1863
+        OUT_PATH=$(readlink -m "$OUT_DIRECTORY")
1864
         usage_error "The -out path ${OUT_PATH%/*}/ does not exist"
1865
     fi
1866
     if egrep -q '<|>|&' <<< "$OUT_DIR"; then
1867
@@ -3476,7 +3697,7 @@
1868
         Please change the directory you gave as an -out argument."
1869
     fi
1870
 else
1871
-    usage_error "Please provide an output name with -out"
1872
+    ! $ENCODE_ONLY && usage_error "Please provide an output name with -out"
1873
 fi
1874
 ### dvdauthor stuff
1875
 # for xml, if -intro was used
1876
@@ -3517,13 +3738,6 @@
1877
     [[ -z $NR_AMT ]] && NR_AMT=200
1878
     NR="$NR $NR_AMT"
1879
 fi
1880
-# check for -loop or -loop_input
1881
-ffmpeg_help=$(ffmpeg -h 2>&1)
1882
-if grep -q -- '^-loop ' <<< "$ffmpeg_help"; then
1883
-    LOOP="-loop 1"
1884
-else
1885
-    LOOP="-loop_input"
1886
-fi
1887
 
1888
 # assign values for slides
1889
 # blurs
1890
@@ -3553,139 +3767,267 @@
1891
 # allow -thumb-frame-size (otherwise unused for 3D thumbs) to set -raise
1892
 ((USER_THUMB_FRAME_SIZE)) && RAISE="-raise $THUMB_FRAME_SIZE"
1893
 
1894
+# centre aligned titles under showcase thumbs need extra safe room
1895
+if [[ $SC_TITLE_ALIGN = center ]]; then
1896
+    SAFE_OFFSET=36
1897
+    $USER_SAFE_AREA && SAFE_OFFSET=$((86-SAFE_AREA))
1898
+fi
1899
 
1900
 # honour -noask for functions and called scripts that use them
1901
 $NOASK && NO_ASK="-noask"
1902
-# Warn if thumb labels have more than 16 characters
1903
-if ! $SHOWCASE; then
1904
-    for ((i=0; i<${#TITLES[@]}; i++)); do
1905
-        val=${#TITLES[i]}
1906
-        [ -z "$MAX_CHARS" ] || ((val > MAX_CHARS)) && MAX_CHARS=$val && key=$i
1907
-    done
1908
-    if [[ ${#TITLES[@]} -gt 6 \
1909
-    && $MAX_CHARS -gt 16 ]] && ! $SINGLE_SLIDESHOW; then
1910
-        yecho
1911
-        yecho "WARNING! Some titles are longer than 16 characters; \
1912
-        they may be chopped off."
1913
-        yecho
1914
-        #echo "\"${TITLES[key]}\" is too long; please use a shorter title."
1915
-        #exit 1
1916
-    fi
1917
+
1918
+#####################################
1919
+#           backend checks          #
1920
+####################################
1921
+
1922
+# transcode is needed for making animated submenu, else we can use just ffmpeg
1923
+hash transcode 2>/dev/null || use_transcode=false
1924
+# todisc should run if mjpegtools not installed, assumes -ffmpeg for 'tovid mpg'
1925
+hash yuvcorrect 2>/dev/null || yuv_correct=remove_header
1926
+#$ANI_SUB_MENU && assert_dep transcode "transcode is required for making
1927
+#  animated submenus"
1928
+if $use_transcode; then
1929
+    # transcode version >= 1.1.0 mandated
1930
+    _transcode_version=$(transcode -v 2>&1| awk '{gsub("v", ""); print $2}')
1931
+    _baseline_version=1.1.0
1932
+    if ! test_version $_transcode_version $_baseline_version; then
1933
+        test -f "$LOG_FILE" && rm -f "$LOG_FILE"
1934
+        runtime_error \
1935
+        "transcode version 1.1.0 or newer required to run this script (todisc).
1936
+        If you must use version $_transcode_version use tovid 0.34 or older."
1937
+    fi
1938
+    # stock debian transcode and probably others missing export_yuv4mpeg module
1939
+    if !  ls -1 $( tcmodinfo -p )/export*.so |grep -q yuv4mpeg; then
1940
+        test -f "$LOG_FILE" && rm -f "$LOG_FILE"
1941
+        _url="http://tovid.wikia.com/wiki/Known_bugs#tovid_is_broken_on_Debian"
1942
+        runtime_error \
1943
+        "your transcode is missing the yuv4mpeg export module. See $_url"
1944
+    fi
1945
+fi
1946
+# ffmpeg - minimum version: 0.7, which has necessary filters
1947
+ffmpeg_help=$($FFmpeg -h full 2>&1)
1948
+ff_filters=$($FFmpeg -filters 2>/dev/null | awk 'f;/Filters:/{f=1}')
1949
+# if no filters present show a runtime error and exit
1950
+[[ "$ff_filters" ]] || \
1951
+  runtime_error "Your ${FFmpeg##*/} is too old ! No filter support."
1952
+# newer ffmpeg's use setdar= and setsar=
1953
+if grep -qw setdar <<< "$ff_filters"; then
1954
+    ASPECT="setdar=4:3"  # for menu.  Always 4:3 aspect
1955
+# somewhat older rev's used aspect=
1956
+elif grep -qw ^aspect <<< "$ff_filters"; then
1957
+    ASPECT="aspect=4:3"
1958
 fi
1959
-# backend checks
1960
-# transcode version >= 1.1.0 mandated
1961
-_transcode_version=$(transcode -v 2>&1| awk '{gsub("v", ""); print $2}')
1962
-_baseline_version=1.1.0
1963
-if ! test_version $_transcode_version $_baseline_version; then
1964
-    runtime_error \
1965
-    "transcode version 1.1.0 or newer is required to run this script (todisc).
1966
-    If you must use version $_transcode_version use tovid 0.34 or older."
1967
+# check for -loop or -loop_input (-loop from 0.9 onwards)
1968
+if grep -q -- '^-loop ' <<< "$ffmpeg_help"; then
1969
+    LOOP="-loop 1"
1970
+else
1971
+    LOOP="-loop_input"
1972
 fi
1973
-# ffmpeg has been buggy with setting AR with -aspect, use -vf aspect if present
1974
+# switch form video filters: -vf or -vfilters
1975
 # "-vf" was "-vfilters" briefly, check
1976
-FF_HELP=$(ffmpeg -h 2>&1)
1977
-if grep -qw -- -vf <<< "$FF_HELP"; then
1978
+if grep -qw -- -vf <<< "$ffmpeg_help"; then
1979
     VF="-vf"
1980
 # somewhat older is "-vfilters"
1981
-elif grep -qw -- -vfilters <<< "$FF_HELP"; then
1982
+elif grep -qw -- -vfilters <<< "$ffmpeg_help"; then
1983
     VF="-vfilters"
1984
+else # this should not run as we would have exited checking for -filters above
1985
+    runtime_error "Your ffmpeg is too old: missing video filters"
1986
 fi
1987
-# ffmpeg's -vf aspect is more dependable than -aspect, if ffmpeg is new enough
1988
-FF_FILTERS=$(ffmpeg -filters 2>&1)
1989
-# newer ffmpeg's use setdar= and setsar=
1990
-if grep -qw ^setdar <<< "$FF_FILTERS"; then
1991
-    ASPECT="$VF setdar=4:3"  # for menu.  Always 4:3 aspect
1992
-    SS_ASPECT="$VF setdar=4:3" # for slideshows.  Always 4:3 aspect
1993
-# somewhat older rev's used aspect=
1994
-elif grep -qw ^aspect <<< "$FF_FILTERS"; then
1995
-    ASPECT="$VF aspect=4:3"
1996
-    SS_ASPECT="$VF aspect=4:3"
1997
+
1998
+# ffmpeg will not allow setting -pix_fmt before the -i if  > 0.8.x
1999
+make_dummy
2000
+if $FFmpeg -pix_fmt yuv420p -t 0.13 -i "$WORK_DIR/dummy.mpg" \
2001
+                    -f null -y /dev/null >/dev/null 2>&1; then
2002
+    PIPE_FORMAT="-pix_fmt yuv420p -f yuv4mpegpipe"
2003
 else
2004
-    ASPECT="-aspect 4:3"
2005
-    SS_ASPECT="-aspect 4:3"
2006
+    PIPE_FORMAT="-f yuv4mpegpipe"
2007
 fi
2008
- 
2009
+# -acodec, -vcodec, -b and -ab now use per stream options (-b:v)
2010
+if $FFmpeg -i "$WORK_DIR/dummy.mpg" -t 0.13 \
2011
+  -b:v 500k -f null -y /dev/null >/dev/null 2>&1; then
2012
+    VB=-b:v
2013
+    AB=-b:a
2014
+    CA=-c:a
2015
+else
2016
+    VB=-b
2017
+    AB=-ab
2018
+    CA=-acodec
2019
+fi
2020
+rm -f "$WORK_DIR/dummy.mpg"
2021
+
2022
+#####################################
2023
+#         end backend checks        #
2024
+#####################################
2025
+
2026
 # set some vars for switched menus so we know where we are
2027
 $SWITCHED_MODE && SWITCHED_MENUS=false
2028
 { $SWITCHED_MODE || $SWITCHED_MENUS ; } && SWITCHED=:
2029
+# check if user passed a usable thumb or showcase shape
2030
+if [[ -n $THUMB_SHAPE ]]; then
2031
+    if ! check_maskshape $THUMB_SHAPE; then
2032
+        usage_error "Please supply a usable thumb shape with
2033
+        -thumb-shape option. You gave \"$THUMB_SHAPE\""
2034
+    fi
2035
+
2036
+fi
2037
+# -user-thumbs is only compatible with static thumbs (-static)
2038
+if $USER_THUMBS && ! $STATIC; then
2039
+    if $SWITCHED_MENUS; then
2040
+        usage_error "If doing switched menus -user-thumbs can only be used
2041
+                    with a static menu (-static)"
2042
+    else
2043
+        usage_error "-user-thumbs option is for static buttons only (-static)"
2044
+    fi
2045
+fi
2046
+
2047
+# check for legal -button-style option
2048
+case $BUTTON_STYLE in
2049
+  line|text|text-rect|rect)
2050
+    :
2051
+    ;;
2052
+  *)
2053
+    usage_error "\"$BUTTON_STYLE\" is not a -button-style arg"
2054
+    ;;
2055
+esac
2056
+# transparent border around text so rect spumux outline can fit
2057
+if [[ $BUTTON_STYLE = "text-rect" ]]; then
2058
+    TEXT_BORDER="-bordercolor Transparent -border 8x8"
2059
+fi
2060
+
2061
+# If output directory already exists, print a message and exit
2062
+if test -e "$OUT_DIR"; then
2063
+    echo "Cleaning up created dirs"
2064
+    yecho
2065
+    echo "A file or directory named \"$OUT_DIR\" already exists."
2066
+    echo "Please use a different -out name, "
2067
+    echo "or (re)move the existing file or directory."
2068
+    rm -rf "$REAL_WORK_DIR"
2069
+    rm -f "$WORK_DIR"
2070
+    exit 1
2071
+fi
2072
+# Remove any existing log file, and print headers, unless recursing
2073
+if ! $SWITCHED_MODE && ! $TITLESET_MODE && \
2074
+! $MK_CAROUSEL_MODE && ! $VMGM_ONLY; then
2075
+    test -f "$LOG_FILE" && rm -f "$LOG_FILE"
2076
+    echo
2077
+    # script details for the log file
2078
+    PATTERN=$(for ((i=1; i<=79; i++)); do echo -n \*; done)
2079
+    printf "%s\n%s\n%s\n\n\n" "$PATTERN" \
2080
+    "todisc from the tovid suite ($TOVID_VERSION) - log for `date`" \
2081
+    "$PATTERN" >> "$LOG_FILE"
2082
+    script_args=( ${0##*/} "${args[@]}" )
2083
+    #for i in "${script_args[@]}"; do printf "%s %s\n" "$ME" "$i"; done
2084
+    # do some locale debugging
2085
+    printf "\n%s%s\n" "$ME" "You are using the following locale settings:" >> "$LOG_FILE"
2086
+    locale_env=( $(locale) )
2087
+    for v in "${locale_env[@]}"; do printf "%s %s\n" "$ME" "$v"; done >> "$LOG_FILE"
2088
+    printf "\n\n" >> "$LOG_FILE"
2089
+fi
2090
+# put command line into log for debugging - changes with recursive todisc calls
2091
+_args=( todisc "${args[@]}" )
2092
+for i in "${_args[@]}"; do printf "%s %s\n" "$ME" "$i"; done >> "$LOG_FILE"
2093
+print2log ""
2094
+    ##########################################################################
2095
+    ########## More setup, and non-critical info + warning messages ##########     
2096
+    ##########################################################################
2097
+
2098
+# information about -titles option in case user doesn't know
2099
+if [[ ${#TITLES[@]} -eq 0 ]]; then
2100
+    if [[ $MENU_NUM = $MN ]] && ! $NOMENU \
2101
+     && ! $SINGLE_SLIDESHOW && ! $DO_TITLESETS && $MONTAGE_MENU; then
2102
+        info_message "You did not provide any titles with -titles. Using the \
2103
+          basename of each file provided (minus the extension)."
2104
+        ((sshows < 1)) && $WARN && continue_in 5
2105
+    fi
2106
+    for i in ${!FILES[@]}; do
2107
+        title=${FILES[i]##*/}
2108
+        TITLES[i]=" ${title%%.*} "
2109
+    done
2110
+    unset title
2111
+fi
2112
+if ! $SINGLE_SLIDESHOW; then
2113
+    for i in ${!FILES[@]}; do
2114
+        if [[ ! ${TITLES[i]} && $BUTTON_STYLE != "rect" ]]; then
2115
+            notitles=1
2116
+        fi
2117
+    done
2118
+    if ((notitles)); then
2119
+        $USER_BSTYLE && notit_mess="You can not use \"$BUTTON_STYLE\" button 
2120
+        style with no titles. " || notit_mess="You have no titles. "
2121
+        info_message "$notit_mess Setting button style to 'rect' style for you"
2122
+        BUTTON_STYLE=rect
2123
+        TITLES_CLR=none
2124
+        V_TITLES_STROKE=none
2125
+        $WARN && continue_in 5
2126
+    fi
2127
+fi
2128
+if ! $TITLESET_MODE && ! $DO_TITLESETS && $QUICK_NAV && ! $VMGM_ONLY; then
2129
+    QUICK_NAV=false
2130
+    info_message "No -quick-nav unless doing titlesets ... disabling this option"
2131
+    $WARN && continue_in 5
2132
+fi
2133
+# Warn if thumb labels have more than 16 characters
2134
+if ! $SHOWCASE && ! $ENCODE_ONLY && ! $NOMENU; then
2135
+    for ((i=0; i<${#TITLES[@]}; i++)); do
2136
+        val=${#TITLES[i]}
2137
+        [ -z "$MAX_CHARS" ] || ((val > MAX_CHARS)) && MAX_CHARS=$val && key=$i
2138
+    done
2139
+    if [[ ${#TITLES[@]} -gt 6 \
2140
+    && $MAX_CHARS -gt 16 ]] && ! $SINGLE_SLIDESHOW; then
2141
+        info_message "WARNING! Some titles are longer than 16 characters; \
2142
+        they may be chopped off."
2143
+        $WARN && continue_in 5
2144
+        #echo "\"${TITLES[key]}\" is too long; please use a shorter title."
2145
+        #exit 1
2146
+    fi
2147
+fi
2148
 # warn about change in -thumb-mist option
2149
 if $FEATHER && ! $USE_FEATHER_MASK; then
2150
-    yecho
2151
-    yecho "Note: feathered thumb shapes no longer have mist background
2152
+    info_message "Note: feathered thumb shapes no longer have mist background
2153
         by default.  Use -thumb-mist [COLOR] to get the old behavior"
2154
-    yecho
2155
-    $WARN && sleep 5
2156
+    $WARN && continue_in 5
2157
 fi
2158
 #
2159
 # sanity checks for button style ( -button-style ) for menu buttons
2160
 #
2161
-
2162
 # use a suitable button style
2163
 if ! $SINGLE_SLIDESHOW; then
2164
     for ((i=0; i<${#FILES[@]}; i++)); do
2165
         if test $(wc -l <<< "$(echo -e "${TITLES[i]}")") -gt 1; then
2166
             MULTILINE_TITLE=:
2167
-            if $FEATHER && [ $THUMB_SHAPE != "normal" ]; then
2168
-                # multiline titles not suitable for text buttons
2169
-                BUTTON_STYLE="text-rect"
2170
-            elif $TEXTMENU; then
2171
-                [[ $BUTTON_STYLE != "line" ]] && BUTTON_STYLE="text-rect"
2172
-            else
2173
-                [[ $BUTTON_STYLE != "text-rect" ]] \
2174
-                && ! $USER_BSTYLE && BUTTON_STYLE="rect"
2175
-            fi
2176
         fi
2177
     done
2178
+    # multiline titles not suitable for text buttons
2179
+    if $MULTILINE_TITLE && [[ $BUTTON_STYLE = "text" ]]; then
2180
+        BUTTON_STYLE="line"
2181
+        info_message "'text' button style not suitable for multi-line
2182
+        titles, using 'line' style instead"
2183
+        $WARN && continue_in 3
2184
+    fi
2185
 
2186
-    # disallow spaces in thumb titles for text button style
2187
+    # remove multiple spaces in video titles for text button style
2188
     if [ "$BUTTON_STYLE" = "text" ]; then
2189
         for ((i=0; i<${#TITLES[@]}; i++)); do
2190
             T=$(sed 's/^[ \t]*//;s/[ \t]*$//' <<< "${TITLES[i]}")
2191
             if grep "  " <<< "$T" >/dev/null; then
2192
-                echo "Sorry, a maximum of one consecutive space is allowed
2193
+                info_message "Sorry, a maximum of one consecutive space is allowed
2194
                 in titles for text buttons.  \"${TITLES[i]}\" has more than
2195
-                one consecutive space in it" |fold -bs
2196
-                exit 1
2197
+                one consecutive space in it.  Removing the extra spaces for you."
2198
+                new_title=$("s/^ *//;s/ *$//;s/ \{1,\}/ /g" <<< "${TITLES[i]}")
2199
+                TITLES[i]="$new_title"
2200
+                $WARN && continue_in 5
2201
             fi
2202
         done
2203
     fi
2204
 fi
2205
 if { $TEXTMENU || $QUICK_MENU ; } && [[ $BUTTON_STYLE = "rect" ]]; then
2206
-    if $MULTILINE_TITLE; then
2207
-        BUTTON_STYLE="text-rect"
2208
-    else
2209
-        BUTTON_STYLE="line"
2210
-    fi
2211
+    BUTTON_STYLE="line"
2212
     if ((MENU_NUM==2)) || { ! $SWITCHED_MODE && ! $SWITCHED_MENUS ; }; then
2213
         if $USER_BSTYLE; then
2214
-            yecho
2215
-            yecho "Using button style '$BUTTON_STYLE' instead of 'rect'
2216
+            info_message "Using button style '$BUTTON_STYLE' instead of 'rect'
2217
             for textmenu menu"
2218
-            yecho
2219
-            $WARN && sleep 10
2220
-        fi
2221
-    fi
2222
-fi
2223
-# allow multiline titles in submenu
2224
-if [[ -n "$SM_TITLES" ]]; then
2225
-    for i in ${!SM_TITLES[@]}; do
2226
-        if [[ $(echo -e "${SM_TITLES[i]}" |wc -l) -gt 1 ]]; then
2227
-            SM_TITLES[i]="$(echo -e  "${SM_TITLES[i]}")"
2228
+            $WARN && continue_in 3
2229
         fi
2230
-    done
2231
-fi
2232
-# check if user passed a usable thumb or showcase shape
2233
-if [[ -n $THUMB_SHAPE ]]; then
2234
-    if ! check_maskshape $THUMB_SHAPE; then
2235
-        usage_error "Please supply a usable thumb shape with
2236
-        -thumb-shape option. You gave \"$THUMB_SHAPE\""
2237
-    fi
2238
-
2239
-fi
2240
-if [[ -n $SHOWCASE_SHAPE ]]; then
2241
-    if ! check_maskshape $SHOWCASE_SHAPE; then
2242
-        usage_error "Please supply a usable showcase shape with
2243
-        -showcase-shape option.  You gave \"$SHOWCASE_SHAPE\""
2244
     fi
2245
 fi
2246
 if [[ -n ${ROTATE_ARRAY[@]} ]]; then
2247
@@ -3693,50 +4035,50 @@
2248
          if [[ $BUTTON_STYLE = *rect* ]]; then
2249
             BUTTON_STYLE="line"
2250
             if $USER_BSTYLE; then
2251
-                yecho
2252
-                echo "'*rect' button styles with rotated thumbs don't play well"
2253
-                echo "with spumux buttons. Setting button style to "
2254
-                echo "'line'.  You may also use 'text' style"
2255
-                echo "Quit now if you wish to exit and examine your options"
2256
-                yecho
2257
-                $WARN && sleep 10
2258
+                info_message "'*rect' button styles with rotated thumbs don't
2259
+                play well with spumux buttons. Setting button style to
2260
+                'line'.  You may also use 'text' style.
2261
+                Quit now if you wish to exit and examine your options"
2262
+                $WARN && continue_in 10
2263
             fi
2264
         fi
2265
     fi
2266
 fi
2267
-if ! $SINGLE_SLIDESHOW; then
2268
-    for i in ${!FILES[@]}; do
2269
-        if [[ ! ${TITLES[i]} && $BUTTON_STYLE != "rect" ]]; then
2270
-            usage_error "You can not use \"$BUTTON_STYLE\" button style if
2271
-            you have no titles.  Use 'rect' style instead"
2272
-        fi
2273
-    done
2274
-fi
2275
 #
2276
 # end of button-style checks
2277
 #
2278
-
2279
-# transparent border around text so rect spumux outline can fit
2280
-if [[ $BUTTON_STYLE = "text-rect" ]]; then
2281
-    TEXT_BORDER="-bordercolor Transparent -border 8x8"
2282
+if [[ -n $SHOWCASE_SHAPE ]]; then
2283
+    # if -wave also (incompatible), disable -showcase-shape and give warning
2284
+    if [[ -n $WAVE ]]; then
2285
+        info_message "-showcase-shape incompatible with -wave, \
2286
+          disabling -showcase-shape for you"
2287
+        SHOWCASE_SHAPE=""
2288
+        $WARN && continue_in 3
2289
+    else
2290
+        ! check_maskshape $SHOWCASE_SHAPE && \
2291
+        usage_error "Please supply a usable showcase shape with
2292
+        -showcase-shape option.  You gave \"$SHOWCASE_SHAPE\""
2293
+    fi
2294
 fi
2295
 
2296
-# If output directory already exists, print a message and exit
2297
-if test -e "$OUT_DIR"; then
2298
-    echo "Cleaning up created dirs"
2299
-    yecho
2300
-    echo "A file or directory named \"$OUT_DIR\" already exists."
2301
-    echo "Please use a different -out name, "
2302
-    echo "or (re)move the existing file or directory."
2303
-    rm -rf "$REAL_WORK_DIR"
2304
-    rm -f "$WORK_DIR"
2305
-    exit 1
2306
+# allow multiline titles in submenu
2307
+if [[ -n "$SM_TITLES" ]]; then
2308
+    for i in ${!SM_TITLES[@]}; do
2309
+        if [[ $(echo -e "${SM_TITLES[i]}" |wc -l) -gt 1 ]]; then
2310
+            SM_TITLES[i]="$(echo -e  "${SM_TITLES[i]}")"
2311
+        fi
2312
+    done
2313
 fi
2314
-# Remove any existing log file unless recursing
2315
-if ! $SWITCHED_MODE && ! $TITLESET_MODE && \
2316
-! $MK_CAROUSEL_MODE && ! $VMGM_ONLY; then
2317
-    test -f "$LOG_FILE" && rm -fv "$LOG_FILE"
2318
+# copy symlinks for -group hack
2319
+if $GROUPING && $TITLESET_MODE; then
2320
+    find "$WORK_DIR"/  -name \*group\*.mpg -exec cp -P {} "$BASEDIR" \;
2321
 fi
2322
+# carousel's are made BEFORE switched menus - so don't do them in switched mode
2323
+$SWITCHED_MODE && DO_CAROUSEL=false
2324
+
2325
+# save value of default chapters
2326
+! $USER_CHAPTERS && (( ${#CHAPTERS[@]} == 1 )) && default_chapters=${CHAPTERS[0]}
2327
+
2328
 # see if imagemagick supports -vignette for the oval shape
2329
 if [[ $THUMB_SHAPE == "vignette" || $SHOWCASE_SHAPE == "vignette" ]]; then
2330
     if ! convert -help 2>&1 | egrep -q -- "-vignette"; then
2331
@@ -3744,81 +4086,123 @@
2332
         [[ $SHOWCASE_SHAPE == "vignette" ]] && SHOWCASE_SHAPE="oval"
2333
         ! ((USER_BLUR)) && BLUR=3
2334
         ! ((SC_USER_BLUR)) && SC_BLUR=3
2335
-        warning_message \
2336
-          "INFO: -vignette option not available in your imagemagick version.
2337
+        info_message \
2338
+          "Note: -vignette option not available in your imagemagick version.
2339
           You should upgrade it.  Using 'oval' mask shape instead which is
2340
           similar.  Setting the blur to 3 unless you used '-blur' (thumbs) or
2341
           '-showcase-blur' (showcase file)"
2342
-        $WARN && sleep 5
2343
+        $WARN && continue_in 5
2344
     fi
2345
 fi
2346
 # see if advanced options were used and give warning if so
2347
 if [[ -n "${ADV_OPT[@]}" ]] && ! $SWITCHED_MODE; then
2348
-    yecho
2349
-    yecho "***** WARNING *****"
2350
+    yecho ""
2351
+    printgreen "*** Note: ***"
2352
     yecho "You have used the following advanced options:"
2353
     yecho "${ADV_OPT[@]}" | format_output
2354
-    yecho "With these options it is possible to create a menu where things \
2355
-    overlap or are offscreen, or that has other problems, so please check it \
2356
-    with the preview.  These are things that todisc tries to avoid normally, \
2357
-    so if you have problems, please leave them out."
2358
-    yecho
2359
-    $WARN && sleep 15
2360
-fi
2361
-
2362
-# copy symlinks for -group hack
2363
-if $GROUPING && $TITLESET_MODE; then
2364
-    find "$WORK_DIR"/  -name \*group\*.mpg -exec cp -P {} "$BASEDIR" \;
2365
+    yecho "With these options it is possible to create a menu where things "
2366
+    yecho "overlap or are offscreen, or that has other problems, "
2367
+    yecho "so please check it with the preview."
2368
+    printgreen "***************"
2369
+    yecho ""
2370
+    $WARN && continue_in 7
2371
 fi
2372
-# carousel's are made BEFORE switched menus - so don't do them in switched mode
2373
-$SWITCHED_MODE && DO_CAROUSEL=false
2374
-
2375
-# save value of default chapters
2376
-! $USER_CHAPTERS && (( ${#CHAPTERS[@]} == 1 )) && default_chapters=${CHAPTERS[0]}
2377
-
2378
-# script details for the log file
2379
-PATTERN=$(for ((i=1; i<=79; i++)); do echo -n \*; done)
2380
-printf "%s\n%s\n%s\n\n\n" "$PATTERN" \
2381
-"todisc from the tovid suite ($TOVID_VERSION) - log for `date`" \
2382
-"$PATTERN" >> "$LOG_FILE"
2383
-# put the command line into the log file to aid debugging
2384
-printf  "%s\n%s\n" todisc "${args[@]}" | sed "s/    */ /g;s/^ *//" | fold -bs >> "$LOG_FILE"
2385
-# do some locale debugging
2386
-echo -e "\nYou are using the following locale settings:" >> "$LOG_FILE"
2387
-locale >>  "$LOG_FILE" 2>&1
2388
-echo >> "$LOG_FILE"
2389
 
2390
 # check aspect ratios of infiles so thumbs are in aspect without -aspect passed
2391
-if ((inc_files)) && [[ -z "$V_ASPECT" ]]; then
2392
-    yecho
2393
-    yecho "Determining aspect ratio of videos"
2394
+# this is done before makempg converts non-compliant files so it is really only
2395
+# useful to get a preview
2396
+if ((inc_files && MENU_NUM == 1)) && [[ ! "$V_ASPECT" ]] \
2397
+      && ! $VMGM_ONLY && ! $ENCODE_ONLY; then
2398
+    yecho "Determining aspect ratio of videos for the preview."
2399
+    yecho ""
2400
+    yecho "If SURE of ratios skip this step with '-aspect ASPECT' \
2401
+    (but it is best if you always run it first to check)."
2402
+    #$WARN && continue_in 3
2403
+    echo
2404
+    cur_aspect=""
2405
     for ((i=0; i<${#FILES[@]}; i++)); do
2406
-        ! $SINGLE_SLIDESHOW && yecho "Checking aspect ratios: ${FILES[i]}"
2407
-        stats[i]=$(idvid -terse -fast "${FILES[i]}" 2>/dev/null |
2408
-          awk -F= '/V_ASPECT_WIDTH=/ {print $2}' 2>/dev/null)
2409
-        cur_aspect=${stats[i]}
2410
-        if ((cur_aspect)); then
2411
-            [[ $cur_aspect = 133 ]] && ASPECT_RATIO=4:3
2412
-            [[ $cur_aspect = 177 ]] && ASPECT_RATIO=16:9
2413
-            yecho "Aspect ratio of $ASPECT_RATIO found.
2414
-            Videos in this menu (titleset) will be done using that ratio."
2415
-            ((cur_aspect==177||cur_aspect==133)) && break
2416
+        curfile=${FILES[i]}
2417
+        ! $SINGLE_SLIDESHOW && print2log "Checking aspect ratios: ${FILES[i]##*/}"
2418
+        # check if image, then check aspect ratio of image if so
2419
+        check_filetype "$curfile"
2420
+        if [[ $file_type = 'image' ]]; then
2421
+            stat=133
2422
+        elif [[ $file_type = 'video' ]]; then
2423
+            stat=$(idvid -terse -fast "${FILES[i]}" 2>/dev/null |
2424
+              awk -F= '/V_ASPECT_WIDTH=/ {print $2}' 2>/dev/null)
2425
+        else
2426
+            usage_error "Sorry could not identify file ${FILES[i]}"
2427
+        fi
2428
+        #if [[ $(file -L "$curfile"  | awk '{ $1 = ""; print }') =~ image ]]; then
2429
+        #    stat=133
2430
+        #elif mencoder -quiet -oac pcm -ovc copy \
2431
+        #    -frames 0 -o /dev/null "${FILES[i]}" &>/dev/null; then
2432
+                # it is a video, check aspect ratio
2433
+        #        stat=$(idvid -terse -fast "${FILES[i]}" 2>/dev/null |
2434
+        #          awk -F= '/V_ASPECT_WIDTH=/ {print $2}' 2>/dev/null)
2435
+        #else
2436
+        #    usage_error "Sorry could not identify file ${FILES[i]}"
2437
+        #fi
2438
+        # exit from the loop 
2439
+        # save list of files without reported aspect ratio for a warning
2440
+        { [[ $stat = 0 ]] || ! test_is_number $stat; } &&  warn_files[i]=${FILES[i]}
2441
+        stats[i]=${stat:-0}
2442
+        # round up to 177 or down to 133 in the same way as makempg does for
2443
+        # padding, so we know what aspect it will be after conversion
2444
+        if (( ${stats[i]} > 153 )); then
2445
+            ar_stats[i]=177
2446
+            # exit with usage error if videos are 16:9 and a slideshow is included
2447
+            if ((sshows >=1)); then
2448
+                usage_error \
2449
+                "Slides are encoded using 4:3 aspect ratio.  You can not mix \
2450
+                16:9 videos with a slideshow in the same titleset"
2451
+            fi
2452
         else
2453
-            yecho "No aspect ratio was determined.  Videos in ths menu
2454
-            (titleset) will be done using a ratio of 4:3"
2455
+            ar_stats[i]=133
2456
         fi
2457
-done
2458
-    yecho
2459
-fi
2460
-
2461
-# -user-thumbs is only compatible with static thumbs (-static)
2462
-if $USER_THUMBS && ! $STATIC; then
2463
-    if $SWITCHED_MENUS; then
2464
-        usage_error "If doing switched menus -user-thumbs can only be used
2465
-                    with a static menu (-static)"
2466
-    else
2467
-        usage_error "-user-thumbs option is for static buttons only (-static)"
2468
+        #if [[ -n $cur_aspect ]] && [[ ${ar_stats[i]} != $cur_aspect ]]; then
2469
+        #    # if we have a value for cur_aspect and it differs from new value 
2470
+        #    if [[ ${ar_stats[i]} != $cur_aspect ]]; then
2471
+                # we may have this already if the value was 0, but no harm done
2472
+        #        warn_files[i]=${FILES[i]}
2473
+        #    fi
2474
+        #fi
2475
+        cur_aspect=${ar_stats[i]}
2476
+        # unset stat so we can test it again
2477
+        unset stat 
2478
+    done
2479
+    # count the most frequent occurence in ar_stats of 133 or 177.
2480
+    # They should all be the same!, but user can still continue if he wants
2481
+    ws=$(grep 177 <<< "$(printf '%s\n' ${ar_stats[@]})" |wc -l)
2482
+    lb=$(grep 133 <<< "$(printf '%s\n' ${ar_stats[@]})" |wc -l)
2483
+    ((ws > lb)) && ar=177 || ar=133
2484
+    # set the global var for aspect ratio
2485
+    { [[ $ar = 177 ]] && ASPECT_RATIO=16:9; } || ASPECT_RATIO=4:3
2486
+    
2487
+    # warn about files that have a differing aspect ratio
2488
+    for i in ${!ar_stats[@]}; do
2489
+        if ! grep -q $ar <<< ${ar_stats[i]}; then
2490
+            warn_files[i]=${FILES[i]}
2491
+        fi
2492
+    done
2493
+    if [[ -n ${warn_files[@]} ]]; then
2494
+        yecho
2495
+        printred "*** CRITICAL WARNING ***"
2496
+        yecho "The following files differ from the $ASPECT_RATIO aspect ratio
2497
+        we are using, even if they are to be re-encoded by makempg here."
2498
+        echo
2499
+        printf "\"%s\"\n" ${warn_files[@]}
2500
+        echo
2501
+        yecho "You can not mix different aspect ratios in the same menu. 
2502
+        They need to be put in a separate titleset. You may want to quit 
2503
+        at the preview and re-examine the situation."
2504
+        printred "*************"
2505
+        yecho
2506
+        yecho "Press <ENTER> to continue"
2507
+        read input
2508
     fi
2509
+    print2log ""
2510
+    print2log "Videos in this titleset will be done using aspect of $ASPECT_RATIO."
2511
 fi
2512
 
2513
 ################################################
2514
@@ -3905,16 +4289,14 @@
2515
 # set some vars for the last run of switched menus (non-recursive )
2516
 $SWITCHED_MENUS && SHOWCASE_FILE=${FILES[0]}
2517
 
2518
-yecho
2519
-yecho "Creating work directories"
2520
-yecho
2521
+print2log "Creating work directories"
2522
 
2523
 # create an array of grouped files.
2524
 if $GROUPING; then
2525
 unset grp
2526
 for ((i=1; i<=${#FILES[@]}; i++)); do
2527
-    if [[ -n ${GROUP[i-1]} ]]; then
2528
-        for ((j=1; j<=${GROUP[i-1]}; j++)); do
2529
+    if [[ -n ${GROUP_ARR[i-1]} ]]; then
2530
+        for ((j=1; j<=${GROUP_ARR[i-1]}; j++)); do
2531
             if [[ -e $WORK_DIR/${TSET_NUM}-group-${i}-${j}.mpg ]]; then
2532
                 grouping[grp++]=$WORK_DIR/${TSET_NUM}-group-${i}-${j}.mpg
2533
             fi
2534
@@ -3923,34 +4305,40 @@
2535
 done
2536
 fi
2537
 
2538
-# if no bg supplied, use template.png so we can add a frame (-quick-menu only)
2539
+## if no bg supplied, use template.png so we can add a frame (-quick-menu only)
2540
+# near-black background causes ffmpeg's movie/overlay filter to act weirdly
2541
+if [[ $BG_CLR = '#101010' || $BG_CLR = black ]] && [[ -z $BACKGROUND ]] && $QUICK_MENU; then
2542
+    SUB_CLRS+=("$BG_CLR:'#000030' ('black' bg for quick menu is problematic)")
2543
+    BG_CLR='#000030'
2544
+    #BG_CLR='#101028'
2545
+fi
2546
 
2547
 # check that NTSC menu uses safe colours
2548
 if [[ $TV_STANDARD = "ntsc" ]]; then
2549
     get_safe_colour $SFRAME_CLR && FRAME_CLR=$SAFE_CLR
2550
     get_safe_colour $TITLE_CLR && TITLE_CLR=$SAFE_CLR
2551
     get_safe_colour $SM_TITLE_CLR && SM_TITLE_CLR=$SAFE_CLR
2552
-    get_safe_colour $TITLE_STROKE && TITLE_STROKE=$SAFE_CLR
2553
+    get_safe_colour $M_TITLE_STROKE && M_TITLE_STROKE=$SAFE_CLR
2554
     get_safe_colour $SUBMENU_STROKE && SUBMENU_STROKE=$SAFE_CLR
2555
     get_safe_colour $CHAPTER_STROKE && CHAPTER_STROKE=$SAFE_CLR
2556
     get_safe_colour $TITLES_CLR && TITLES_CLR=$SAFE_CLR
2557
     get_safe_colour $HLIGHT_CLR && HLIGHT_CLR=$SAFE_CLR
2558
     get_safe_colour $SELECT_CLR && SELECT_CLR=$SAFE_CLR
2559
     get_safe_colour $BG_CLR && BG_CLR=$SAFE_CLR
2560
-    get_safe_colour $TITLES_STROKE && TITLES_STROKE=$SAFE_CLR
2561
+    get_safe_colour $V_TITLES_STROKE && V_TITLES_STROKE=$SAFE_CLR
2562
     get_safe_colour $SUBMENU_BG_CLR && SUBMENU_BG_CLR=$SAFE_CLR
2563
     get_safe_colour $THUMB_FRAME_CLR && THUMB_FRAME_CLR=$SAFE_CLR
2564
     echo
2565
     if [[ -n ${SUB_CLRS[@]} ]]; then
2566
-        echo "*** Note: ***"
2567
+        printgreen "*** Note: ***"
2568
         echo "Some of the colors you passed in are not NTSC color safe. "
2569
         echo "The following substitutions were made for you:"
2570
         for i in ${!SUB_CLRS[@]}; do
2571
             echo "${SUB_CLRS[i]/:*} ===>  ${SUB_CLRS[i]/*:}"
2572
         done
2573
-        echo "*************"
2574
+        printgreen "*************"
2575
         echo
2576
-        $WARN && sleep 5
2577
+        $WARN && continue_in 5
2578
     fi
2579
 fi
2580
 
2581
@@ -3961,9 +4349,9 @@
2582
 # check file type of background file and assign to BG_VIDEO or BG_IMAGE
2583
 if [[ -n $BACKGROUND ]]; then
2584
     check_filetype "$BACKGROUND"
2585
-    if [[ $TYPE = "image" ]]; then
2586
+    if [[ $file_type = "image" ]]; then
2587
         BG_PIC="$BACKGROUND"
2588
-    elif [[ $TYPE = "video" ]]; then
2589
+    elif [[ $file_type = "video" ]]; then
2590
         BG_VIDEO="$BACKGROUND"
2591
     else
2592
         usage_error "Sorry, can not identify "$BACKGROUND""
2593
@@ -3972,7 +4360,7 @@
2594
 if [[ -n ${SM_BACKGROUND[@]} ]]; then
2595
     for smbg in ${!SM_BACKGROUND[@]}; do
2596
         check_filetype "${SM_BACKGROUND[smbg]}"
2597
-        if [[ $TYPE != "image" ]]; then
2598
+        if [[ $file_type != "image" ]]; then
2599
             usage_error "-submenu-background takes image files only"
2600
         fi
2601
     done
2602
@@ -3982,9 +4370,9 @@
2603
 if $SHOWCASE; then
2604
     if [[ -n ${SHOWCASE_FILE[@]} ]]; then
2605
         check_filetype "${SHOWCASE_FILE[@]}"
2606
-        if [[ $TYPE = "image" ]]; then
2607
+        if [[ $file_type = "image" ]]; then
2608
             SHOWCASE_IMG=${SHOWCASE_FILE[@]}
2609
-        elif [[ $TYPE = "video" ]]; then
2610
+        elif [[ $file_type = "video" ]]; then
2611
             SHOWCASE_VIDEO=${SHOWCASE_FILE[@]}
2612
         else
2613
             usage_error "Can not identify showcase file: "${SHOWCASE_FILE[@]}""
2614
@@ -3996,11 +4384,11 @@
2615
 fi
2616
 # find out the aspect ratio of the showcase file
2617
 if [[ -n $SHOWCASE_VIDEO ]]; then
2618
-    SC_AR=$(idvid -fast -terse "$SHOWCASE_VIDEO" 2>/dev/null |
2619
+    SC_AR=$( idvid -fast -terse "$SHOWCASE_VIDEO" 2>> $LOG_FILE |
2620
     awk -F= '/V_ASPECT_WIDTH/ {print $2}' 2>/dev/null)
2621
 elif [[ -n $SHOWCASE_IMG && $SHOWCASE_IMG != "dummy" ]]; then
2622
     SC_AR=$(identify -ping -format %wx%h "$SHOWCASE_IMG")
2623
-    SC_AR=$(bc_math "${SC_AR/x*} / ${SC_AR/*x}" )
2624
+    SC_AR=$( bc_math "(${SC_AR/x*} / ${SC_AR/*x}) * 100" int )
2625
 fi
2626
 
2627
 # now the showcase image is id'ed, we can find out what kind of quick menu
2628
@@ -4016,7 +4404,6 @@
2629
 if $QUICK_MENU && ! $QUICKMENU_IS_SHOWCASE && ! $QUICKMENU_IS_BACKGROUND; then
2630
     if ! $SWITCHED; then
2631
         yecho
2632
-        yecho "***** WARNING *****"
2633
         if { $DO_TITLESETS || $TITLESET_MODE ; }; then
2634
             yech=yecho
2635
         else
2636
@@ -4038,7 +4425,7 @@
2637
             BUTTON_STYLE="rect"
2638
             SHOWCASE=false
2639
         fi
2640
-        $WARN && sleep 10
2641
+        $WARN && continue_in 10
2642
     fi
2643
 fi
2644
 $QUICKMENU_IS_BACKGROUND && SHOWCASE_IMG=""
2645
@@ -4047,7 +4434,7 @@
2646
 # quick-menu needs TEXTMENU=: , and does its own showcase and bg with ffmpeg
2647
     TEXTMENU=:
2648
     SC_THUMB=false
2649
-    STATIC=: #FIXME
2650
+    STATIC=:
2651
 fi
2652
 if [[ $SC_FRAMESTYLE = "glass" ]] && [[ -z $SHOWCASE_IMG && -z $SHOWCASE_VIDEO ]]; then
2653
     yecho
2654
@@ -4086,8 +4473,9 @@
2655
 if ! $VMGM_ONLY; then
2656
     for i in "${FILES[@]}"; do
2657
         IN_FILES=("${IN_FILES[@]}" "$(readlink -f "$i")")
2658
-        (( ${#FILES[@]} < 12 )) && echo "Adding: $i" || spin "Adding: ${i##*/}"
2659
+        spin "Adding: ${i##*/}"
2660
     done
2661
+    echo
2662
 fi
2663
 
2664
 $VMGM_ONLY && V_TOTAL=$(( ${#TITLES[@]} - 1 )) || V_TOTAL=${#IN_FILES[@]}
2665
@@ -4096,11 +4484,36 @@
2666
 $DO_CAROUSEL && MONTAGE_MENU=false
2667
 
2668
 # switch title position when appropriate so it doesn't get covered up
2669
-! $USER_TITLE_GEO && [[ $BUTTON_GRAVITY = *south* ]] && TITLE_GRAVITY="north"
2670
-if [[ $BUTTON_GRAVITY = *east* || $BUTTON_GRAVITY = *west* ]]; then
2671
-    ! $USER_GEO &&  XGEO=45 && YGEO=45
2672
-    ! $SHOWCASE && ! $USER_TITLE_GEO && TITLE_GRAVITY=north
2673
+! $USER_TITLE_GEO && [[ $BUTTON_GRAVITY = south* ]] && TITLE_GRAVITY="north"
2674
+# not sure why YGEO is 45, probably from when -align didn't affect montage
2675
+#if [[ $BUTTON_GRAVITY = *east || $BUTTON_GRAVITY = *west ]]; then
2676
+if ! $SHOWCASE; then # XGEO/YGEO for montage style only
2677
+    # montage adds spacing to edge of montage so subtract it.  This is a
2678
+    # HACK, it would have been better to -trim +repage but I don't feel
2679
+    # like testing each of the myrid combos to make sure it works okay
2680
+    safe_area=$(( SAFE_AREA - 12 ))
2681
+    case $BUTTON_GRAVITY in
2682
+      northeast|southeast|northwest|southwest)
2683
+        if $USER_GRAVITY; then
2684
+            XGEO=$safe_area && YGEO=$safe_area
2685
+        else
2686
+            XGEO=45 && YGEO=45
2687
+        fi
2688
+        ;;
2689
+      east|west)
2690
+        # move to REAL center if -align centers the montage vertically
2691
+        YGEO=0 && XGEO=$SAFE_AREA
2692
+        ;;
2693
+      center)
2694
+        YGEO=0 && XGEO=0
2695
+        ;;
2696
+    esac 
2697
+else # for showcase, move Y position to true north or south at safe area edge
2698
+    :
2699
+    #[[ $BUTTON_GRAVITY = north* ]] && TEXT_YSTART=$SAFE_AREA
2700
+    #[[ $BUTTON_GRAVITY = south* ]] && TEXT_YSTART=$(( ${VIDSIZE/*x} - SAFE_AREA))
2701
 fi
2702
+    
2703
 ! $SHOWCASE && \
2704
 [[ $BUTTON_GRAVITY = "center" ]] && ! $USER_TITLE_GEO && TITLE_GRAVITY="north"
2705
 
2706
@@ -4137,10 +4550,22 @@
2707
 #CHAPTERS=( ${CHAPTERS%%+*} ) # in case of grouped chapters
2708
 # allow user to pass HH:MM:SS chapters
2709
 $USER_CHAPTERS && CHAPT_ARRAY=( ${CHAPTERS[@]} )
2710
+if $USER_CHAPTERS; then
2711
+    C=( ${CHAPTERS[@]} )
2712
+    if ((${#C[@]} == 1)) && ((${#C[@]} != ${#FILES[@]})); then
2713
+        for i in ${!FILES[@]}; do
2714
+            CHAPT_ARRAY[i]=${C[0]}
2715
+        done
2716
+    else
2717
+        CHAPT_ARRAY=( ${CHAPTERS[@]} )
2718
+    fi
2719
+fi
2720
+
2721
+
2722
 # if arbitrary grouped chapters passed, make an array of them
2723
 if $GROUPING && $USER_CHAPTERS; then
2724
     for i in ${!IN_FILES[@]}; do
2725
-        if [[ -n ${GROUP[i]} ]]; then
2726
+        if [[ -n ${GROUP_ARR[i]} ]]; then
2727
             group_arbitrary_chapters[i]=${grouped_user_chapters[i]//+/ }
2728
         else
2729
             group_arbitrary_chapters[i]=""
2730
@@ -4223,6 +4648,11 @@
2731
 # get normal CHAPTERS VAR,i.e.: 'how many chapters'
2732
 # Check if 1st is 00:00:00 and all chapters have HH:MM:SS format
2733
 if $USER_CHAPTERS; then
2734
+    if [[ ${#FILES[@]} -ne ${#CHAPTERS[@]} ]]; then
2735
+        usage_error "Please give the same number of chapter point strings as
2736
+        videos when using HH:MM:SS form chapters.  You gave ${#FILES[@]}
2737
+        videos but only ${#CHAPTERS[@]} chapter point strings."
2738
+    fi
2739
     for i in ${!CHAPT_ARRAY[@]}; do
2740
         unset newchapts
2741
         [[ ${CHAPTERS[i]} != *:* ]] && usage_error \
2742
@@ -4242,13 +4672,12 @@
2743
 for ((i=0; i<${#CHAPTERS[@]}; i++)); do
2744
     if ((${CHAPTERS[i]} == 0)) && ! ${SLIDESHOW[i]}; then
2745
         if ! $USER_CHAPTERS; then
2746
-            [[ -z ${GROUP[i]} ]] && usage_error \
2747
+            [[ -z ${GROUP_ARR[i]} ]] && usage_error \
2748
             "-chapters 0 is only for grouped videos (each video is a chapter)"
2749
-            CHAPTERS[i]=$(( ${GROUP[i]} + 1 )) && nochapt[i]=1
2750
+            CHAPTERS[i]=$(( ${GROUP_ARR[i]} + 1 )) && nochapt[i]=1
2751
         fi
2752
     fi
2753
 done
2754
-echo
2755
 
2756
 # if using chapter titles, they must equal the combined total for all files
2757
 if [[ -n ${CHAPTER_TITLES[@]} ]]; then
2758
@@ -4273,6 +4702,24 @@
2759
     fi
2760
 fi
2761
 
2762
+# allow using todisc for just encoding mpegs, then exiting
2763
+if $ENCODE_ONLY; then
2764
+    check_compliance
2765
+    if (( ${#FILES_TO_ENCODE[@]} > 1 )); then
2766
+        for f in "${FILES_TO_ENCODE[@]}"; do
2767
+            [[ -s "$f" ]] && arr+=("${f}.enc.mpg")
2768
+        done
2769
+        #((${#arr[@]} > 0)) && printf "%s\n%s.enc.mpg" \
2770
+        if ((${#arr[@]} > 0)); then
2771
+            printf "\n%s\n" "Here are your encoded files:"
2772
+            printgreen '-------------'
2773
+            printf "%s\n" "${arr[@]}"
2774
+            printgreen '-------------'
2775
+        fi
2776
+    fi
2777
+    cleanup
2778
+    exit 0
2779
+fi
2780
 # a quick way to allow user to make a dvd with no menus
2781
 if $NOMENU; then
2782
     cd "$WORK_DIR"
2783
@@ -4284,7 +4731,7 @@
2784
     for i in "${!IN_FILES[@]}"; do
2785
         ln -s "${IN_FILES[i]}" "$WORK_DIR/$(printf %03d%s%s $i .mpg)"
2786
         idvid_stats[i]=$(idvid -terse "${IN_FILES[i]}" 2>/dev/null)
2787
-        # run mencoder to get the length if using arbitrary chapters
2788
+        # run stream_length to get the length if using arbitrary chapters
2789
         if $USER_CHAPTERS; then
2790
             chapter_points[i]=${CHAPT_ARRAY[i]}
2791
         else
2792
@@ -4292,7 +4739,7 @@
2793
                 : # we don't need file length or chapters if not making chapters
2794
             else
2795
                 yecho "Getting video lengths"
2796
-                VID_LEN[i]=$(vid_length  "${IN_FILES[i]}" )
2797
+                VID_LEN[i]=$(stream_length  "${IN_FILES[i]}" )
2798
                 chapter_points[i]=$(make_chapters ${VID_LEN[i]} ${CHAPTERS[i]} )
2799
             fi
2800
         fi
2801
@@ -4318,11 +4765,9 @@
2802
         fi
2803
         nomenu_cmd+=("${IN_FILES[i]}")
2804
     done
2805
-    yecho
2806
-    echo Running: "${nomenu_cmd[@]}" -o "$OUT_DIR" | format_output
2807
-    yecho
2808
-    "${nomenu_cmd[@]}" -o "$OUT_DIR" | tee -a "$LOG_FILE" 2>&1
2809
-    dvdauthor -o "$OUT_DIR" -T
2810
+    print2log "Running: ${nomenu_cmd[@]} -o $OUT_DIR"
2811
+    "${nomenu_cmd[@]}" -o "$OUT_DIR" 2>&1| pipe2log
2812
+    dvdauthor -o "$OUT_DIR" -T 2>&1 |pipe2log
2813
     thanks_goodbye
2814
     $BURN && burn_disc
2815
     cleanup
2816
@@ -4340,14 +4785,14 @@
2817
 if $USER_THUMBS && $FRAME_SAFE; then
2818
     FRAME_SAFE=false
2819
     echo "-frame-safe and -user-thumbs incompatible, disabling -frame-safe"
2820
-    sleep 5
2821
+    $WARN && continue_in 5
2822
 fi
2823
     
2824
-yecho "Creating pics directories..."
2825
+print2log "Creating pics directories..."
2826
 for ((i=0; i<=NUM_FILES; i++)); do
2827
     mkdir -p "$REAL_WORK_DIR/pics/$i"
2828
 done
2829
-yecho "${#FILES[@]} pics directories created"
2830
+print2log "${#FILES[@]} pics directories created"
2831
 # textmenu is static unless there is an animated background or showcase video
2832
 if $TEXTMENU && [[ -z $SHOWCASE_VIDEO && -z $BG_VIDEO ]]; then STATIC=:; fi
2833
 
2834
@@ -4380,10 +4825,6 @@
2835
         ${#ROTATE_ARRAY[@]} thumb rotate values."
2836
     fi
2837
 fi
2838
-# if  -wave passed, usage error if -showcase-shape also passed
2839
-#if [[ -n $WAVE && -n $SHOWCASE_SHAPE ]]; then
2840
-#    usage_error "You can not use both -wave and a -showcase-shape"
2841
-#fi
2842
 
2843
 # if Fading menu, and no BG IMAGE OR VIDEO, fade thumbs right in after title
2844
 if $MENU_FADE; then
2845
@@ -4463,7 +4904,6 @@
2846
     alength=$(bc_math "4 / $FRAME_RATE") # 0.16 or 0.133
2847
     # float < 1  must begin with 0
2848
     [[ -n ${alength/*.} && -z ${alength/.*} ]] && alength=0${alength}
2849
-    echo
2850
     echo "Verifying that input files are video or image files"
2851
     verify_infiles infiles
2852
     if [[ ${#file_is_image[@]} -eq ${#FILES[@]} && $inc_files -gt 0 ]]; then
2853
@@ -4474,17 +4914,14 @@
2854
         echo
2855
         echo "Verifying that grouped input files are video or image files"
2856
         verify_infiles group
2857
-        echo
2858
     fi
2859
-    echo
2860
 fi
2861
-echo
2862
 # some vars for slide mix
2863
 # this is only called when todisc running recursively to make ani slideshows
2864
 # DO_CAROUSEL is set to false when the self recursion is complete
2865
 # this happens earlier in the script.
2866
 if $DO_CAROUSEL; then
2867
-    if [[ -n ${GROUP[@]} ]] && ! $MK_CAROUSEL_MODE; then
2868
+    if [[ -n ${GROUP_ARR[@]} ]] && ! $MK_CAROUSEL_MODE; then
2869
         #*slide_grp*.mpg are symlinks to the original images we have kept intact
2870
         mixgroup=( "$WORK_DIR"/${TSET_NUM}-slide_grp-*.mpg )
2871
         for g in ${!mixgroup[@]}; do
2872
@@ -4551,7 +4988,6 @@
2873
 fi
2874
 # All files must be images for slide mix.
2875
 # if all are images, then we are doing a slideshow.
2876
-echo
2877
 if $SINGLE_SLIDESHOW; then
2878
     # if -static was not passed we have already set DO_CAROUSEL to :
2879
     # So here we set STATIC to : as ani slideshow has its own code
2880
@@ -4577,7 +5013,7 @@
2881
     if [[ ${file_is_image[i]} = "yes" ]]; then
2882
         SHORTFILE=:
2883
     else
2884
-        FRAME_CK=$(vid_length "${IN_FILES[i]}" 90)
2885
+        FRAME_CK=$(stream_length "${IN_FILES[i]}" video 90)
2886
         [[ $(bc -l <<< "$FRAME_CK < 2") -eq 1 ]] && SHORTFILE=:
2887
     fi
2888
     if $SHORTFILE; then
2889
@@ -4636,7 +5072,9 @@
2890
 
2891
     # Some user feedback
2892
     if ! $SINGLE_SLIDESHOW; then
2893
-        yecho
2894
+        #yecho ""
2895
+        yecho ""
2896
+        printgreen "-------------"
2897
         if $VMGM_ONLY; then
2898
             yecho "Disc title: \"$MENU_TITLE\""
2899
         else
2900
@@ -4658,10 +5096,16 @@
2901
             else # echo titles "as is"
2902
                 echo "  \"${TITLES[i]}\" (${IN_FILES[i]})"
2903
             fi
2904
+            # FIXME move this before the aspect ratio check for IN_FILES if possible
2905
             if [[ $(echo -e "${TITLES[i]}" |wc -l) -gt 1 ]]; then
2906
                 # if there is a multiline title we need to align to right of thumbs
2907
-                SC_TITLE_ALIGN=east
2908
+                $SHOWCASE && ! [[ $SC_TITLE_ALIGN = "east" ]] && \
2909
+                  align_warning="\"${TITLE[i]}\" is more than one line: \
2910
+                   - setting '-showcase-titles-align east'"
2911
                 ALIGN_OVERRIDE=:
2912
+                if [[ ! $SC_TITLE_ALIGN = east ]]; then
2913
+                    WARN_RE_ALIGN_EAST=1
2914
+                fi
2915
             fi
2916
         done
2917
         yecho "Current font settings: "
2918
@@ -4695,29 +5139,38 @@
2919
             if [ ! $STATIC ]; then
2920
                 yecho "  -menu-audio-fade $FADE second(s)"
2921
             fi
2922
-            yecho
2923
+            #yecho ""
2924
+            printgreen "-------------"
2925
+            yecho ""
2926
         fi
2927
     fi
2928
+    if ((WARN_RE_ALIGN_EAST)); then 
2929
+        #info_message "Multiline titles must be aligned east. \
2930
+        #Setting \"-align east\" for you"
2931
+        info_message "$align_warning"
2932
+        SC_TITLE_ALIGN=east
2933
+        $WARN && continue_in 3
2934
+    fi
2935
 fi
2936
 # TODO: Merge these globals with the ones up top
2937
 # only the 1st 6 are mergable - keeping them here for debugging this beast :)
2938
 # 9 /row  
2939
-NTSC_1333_DVD=(420x280 300x200 192x128 192x128 186x124 186x124 132x88 132x88 \
2940
+NTSC_1333_DVD=(420x280 288x192 192x128 192x128 186x124 186x124 132x88 132x88 \
2941
 132x88 120x80 120x80 120x80 96x64 96x64 96x64 96x64 96x64 96x64 \
2942
 96x64 96x64 84x56 84x56 84x56 84x56 84x56 84x56 84x56 \
2943
 84x56 84x56 84x56 60x40 60x40 60x40 60x40 60x40 60x40 \
2944
 60x40 60x40 60x40 60x40 60x40 60x40 60x40 60x40 60x40
2945
 60x40 60x40 60x40 60x40)
2946
 # *_1777_DVD is for 16:9 videos displayed in proper res on a 4:3 menu
2947
-NTSC_1777_DVD=(420x210 300x150 240x120 240x120 186x98 186x98 180x90 180x90 \
2948
+NTSC_1777_DVD=(420x210 288x144 240x120 240x120 186x98 186x98 180x90 180x90 \
2949
 180x90 132x66 132x66 132x66 132x66 132x66 132x66 132x66 100x50 100x50 \
2950
 100x50 100x50 100x50 100x50 100x50 100x50 100x50 88x44 88x44 \
2951
 88x44 88x44 88x44 80x40 80x40 80x40 80x40 80x40 80x40)
2952
-PAL_1333_DVD=(420x336 300x240 190x152 190x152 190x152 190x152 130x104 130x104 \
2953
+PAL_1333_DVD=(420x336 280x224 190x152 190x152 190x152 190x152 130x104 130x104 \
2954
 130x104 130x104 130x104 130x104 100x80 100x80 100x80 100x80 100x80 100x80 \
2955
 100x80 100x80 90x72 90x72 90x72 90x72 90x72 90x72 90x72 \
2956
 90x72 90x72 90x72 60x48 60x48 60x48 60x48 60x48 60x48)
2957
-PAL_1777_DVD=(420x252 300x180 240x144 240x144 190x114 190x114 190x114 190x114 \
2958
+PAL_1777_DVD=(420x252 280x168 240x144 240x144 190x114 190x114 190x114 190x114 \
2959
 190x114 130x78 130x78 130x78 130x78 130x78 130x78 130x78 100x60 100x60
2960
 100x60 100x60 100x60 100x60 100x60 100x60 100x60 90x54 90x54 90x54 90x54 90x54
2961
 80x48 80x48 80x48 80x48 80x48 80x48)
2962
@@ -4744,35 +5197,72 @@
2963
 SC_THUMB_X_ARRAY=( ${SC_THUMB_X_ARRAY[NUM_FILES]} )
2964
 SC_THUMB_Y_ARRAY=( ${SC_THUMB_Y_ARRAY[NUM_FILES]} )
2965
 SC_TITLES_X_ARRAY=( ${SC_THUMB_X_ARRAY[@]} )
2966
-SC_TITLES_Y_ARRAY=( ${SC_TITLES_Y_ARRAY[NUM_FILES]} )
2967
+SC_TITLES_Y_ARRAY=( ${SC_TITLES_Y_ARRAY[NUM_FILES]} ) # not used by textmenu
2968
 if $TEXTMENU ; then
2969
+    # next line useless as it will always be overwritten for large # of titles
2970
     ! $USER_SPLIT && SPLIT=13 # max text only titles in one column (-textmenu)
2971
     if [[ $NUM_FILES -gt 12 ]] && ! $USER_SPLIT; then
2972
         SPLIT=$((V_TOTAL / 2))
2973
-        [[ $(( SPLIT * 2)) -ne $V_TOTAL ]] && let SPLIT=SPLIT+1
2974
+        (( (SPLIT * 2) != V_TOTAL)) && ((SPLIT++))
2975
     fi
2976
-#for ((b=0; b<=NUM_FILES; b++)); do
2977
-#((b < SPLIT)) && SC_TITLES_X_ARRAY[b]=86||SC_TITLES_X_ARRAY[b]=360
2978
-#done
2979
 fi
2980
-# needed to centre showcase img: col 1 will always be larger value than col 2
2981
+
2982
 if $SHOWCASE && ! $TEXTMENU; then
2983
-    ((NUM_FILES < 5)) && SPLIT=$((NUM_FILES+1))
2984
+    # TODO? allow user to specify the SPLIT?
2985
+    ((NUM_FILES < 5)) && SPLIT=$((NUM_FILES+1)) # col 1 always >= col 2
2986
     ((NUM_FILES == 5)) && SPLIT=3
2987
     ((NUM_FILES >= 6)) && SPLIT=4
2988
     ((NUM_FILES >= 8)) && SPLIT=5
2989
+    # -align *east or *west disallowed for 2 column showcase thumbs
2990
+    if ((NUM_FILES >= SPLIT)); then
2991
+        case $BUTTON_GRAVITY in
2992
+          *east|*west)
2993
+                butgrav=$BUTTON_GRAVITY
2994
+                # northeast or northwest
2995
+                if [[ $BUTTON_GRAVITY = north* ]]; then
2996
+                    BUTTON_GRAVITY=north && USER_GRAVITY=false
2997
+                # southeast or southwest
2998
+                elif [[ $BUTTON_GRAVITY = south* ]]; then
2999
+                    BUTTON_GRAVITY=south && USER_GRAVITY=false
3000
+                else # east or west
3001
+                    BUTTON_GRAVITY=north
3002
+                fi
3003
+                info_message "You can not use \"-align $butgrav\" with 2 \
3004
+                column -showcase, only \"north\", \"south\", \"center\". \
3005
+                Changing to \"-align ${BUTTON_GRAVITY}\", please check preview."
3006
+                $WARN && continue_in 10
3007
+            ;;
3008
+        esac
3009
+    # central alignment disallowed for 1 column showcase
3010
+    else
3011
+        if [[ $SHOWCASE_FILE ]]; then
3012
+            case $BUTTON_GRAVITY in
3013
+              center|north|south)
3014
+                [[ $BUTTON_GRAVITY = center ]] && but_grav="" || \
3015
+                  but_grav=$BUTTON_GRAVITY
3016
+                info_message "You can not use a central -align option as in \
3017
+                'north', 'center', or 'south' when using a showcase image and \
3018
+                a single column of titles.
3019
+                Setting '-align ${but_grav}west' for you, please check it with the preview."
3020
+                BUTTON_GRAVITY=${but_grav}west && USER_GRAVITY=false
3021
+                $WARN && continue_in 5
3022
+                ;;
3023
+              *east)
3024
+                #BUTTON_GRAVITY="northwest"
3025
+                bgrav=$BUTTON_GRAVITY
3026
+                BUTTON_GRAVITY=${BUTTON_GRAVITY/east/west} # could be west/nw/sw
3027
+                info_message "You can not use -align $bgrav when using a showcase image. \
3028
+                Setting -align $BUTTON_GRAVITY"
3029
+                $WARN && continue_in 3
3030
+            esac
3031
+        fi
3032
+    fi
3033
 fi
3034
 
3035
 
3036
-AUDIO_EXT="ac3"
3037
-SAMPLERATE="48000"
3038
-MPLEX_FORMAT="8"
3039
-FFMPEG_OPTS="-b 7000k  -maxrate 8000k -bufsize 224KiB $ASPECT"
3040
-SS_FFMOPTS="-b 8000k -maxrate 9000k -bufsize 224KiB $SS_ASPECT"
3041
+FFMPEG_OPTS="-b 7000k  -maxrate 8000k -bufsize 224KiB"
3042
+SS_FFMOPTS="-b 8000k -maxrate 9000k -bufsize 224KiB"
3043
 SHOWCASE_SIZE=384x256
3044
-BURN_TGT="$OUT_DIR"
3045
-BURN_TGT_STR="DVD directory"
3046
-BURN_PROG="makedvd"
3047
 if [ $TV_STANDARD = "ntsc" ]; then
3048
     if [[ $ASPECT_RATIO = "4:3" ]]; then
3049
         GEO_ARRAY=("${NTSC_1333_DVD[@]}")
3050
@@ -4783,6 +5273,7 @@
3051
     fi
3052
     VIDSIZE="720x480"
3053
     FRAME_RATE=29.970
3054
+    ff_frame_rate="30000/1001"
3055
     if [[ $SC_AR = 133 ]]; then
3056
         SHOWCASE_SIZE=384x256
3057
         SM_SHOWCASE_SIZE=288x192
3058
@@ -4794,6 +5285,7 @@
3059
     VIDSIZE="720x576"
3060
     TILE_ARRAY=("${TILE_1333[@]}")
3061
     FRAME_RATE=25
3062
+    ff_frame_rate="25/1"
3063
     if [[ $SC_AR = 133 ]]; then
3064
         SHOWCASE_SIZE=380x304
3065
         SM_SHOWCASE_SIZE=290x232
3066
@@ -4807,6 +5299,8 @@
3067
         GEO_ARRAY=("${PAL_1777_DVD[@]}")
3068
     fi
3069
 fi
3070
+# set a variable for vfilter scaling based on above sizes VFSCALE
3071
+VF_SCALE=${VIDSIZE%x*}:${VIDSIZE#*x}
3072
 if [[ $TV_STANDARD = "ntsc" ]]; then
3073
     YUV_FR=30000:1001
3074
 else
3075
@@ -4823,7 +5317,7 @@
3076
             yecho
3077
             yecho "Reducing thumb blur to 2.0 because you are using -showcase"
3078
             yecho
3079
-            $WARN && sleep 3
3080
+            $WARN && continue_in 3
3081
         fi
3082
     fi
3083
     if [ $V_TOTAL -lt 3 ]; then
3084
@@ -4849,23 +5343,33 @@
3085
     SEEK_FRAMES[i]=$(bc_math "${SEEK_VAL[i]} * $FRAME_RATE" int)
3086
 done
3087
 
3088
-# some choices needed for different title alignments
3089
+# some choices needed for different -align -showcase-titles and alignments
3090
 if $SHOWCASE && ! $TEXTMENU; then
3091
-    if [ $V_TOTAL -le 5 ]; then
3092
-        if [[ $SC_TITLE_ALIGN = "east" ]]; then
3093
-            SHOWCASE_SIZE=$SM_SHOWCASE_SIZE  # smaller to allow for titles
3094
-        fi
3095
+    JUSTIFY="west"
3096
+    
3097
+    if ((V_TOTAL <= 5)); then
3098
+        # FIXME move this before the aspect ratio check for IN_FILES if possible
3099
+        # smaller to allow for titles
3100
         AUTOORDER="rows"       # spumux var
3101
+        [[ $SC_TITLE_ALIGN = "east" ]] && SHOWCASE_SIZE=$SM_SHOWCASE_SIZE
3102
+        case $BUTTON_GRAVITY in
3103
+          south|north|center)
3104
+            SC_TITLE_ALIGN="center" # moves titles to left a bit for room
3105
+            SHOWCASE_SIZE=$SM_SHOWCASE_SIZE
3106
+            ;;
3107
+        esac
3108
     else
3109
         SHOWCASE_SIZE=$SM_SHOWCASE_SIZE  # smaller showcase thumb because we have 2 rows
3110
         AUTOORDER="columns"
3111
-        if $SC_THUMB && \
3112
-        [[ "$SC_TITLE_ALIGN" = "east" ]] && [[ -n $SHOWCASE_FILE ]]; then
3113
-            usage_error "Sorry, there is no room for the showcase thumb " \
3114
-            "if you use more than 5 videos with -showcase-titles-align " \
3115
-            "east|west (also multiline titles). Either change the problem " \
3116
-            "option, remove the showcase image/video, or use -textmenu.  Or " \
3117
-            "consider using -bgimage or -bgvideo instead of a showcase thumb."
3118
+        if [[ $SHOWCASE_FILE ]] && \
3119
+        [[ "$SC_TITLE_ALIGN" = "east" ]]; then
3120
+            info_message "Sorry, no room for showcase thumb with 2 columns and \
3121
+            \"-showcase-titles-align east\" (or multiline titles). Change the \
3122
+            option, remove the showcase image/video, or use -textmenu.  Or \
3123
+            use -bgimage or -bgvideo instead of a thumb. Changed for you to: \
3124
+            \"-showcase-titles-align center\". Continuing on to the preview ..."
3125
+            SC_TITLE_ALIGN=center
3126
+            $WARN && continue_in 15
3127
         fi
3128
     fi
3129
 elif ! $SHOWCASE && ! $TEXTMENU; then
3130
@@ -4884,94 +5388,21 @@
3131
 fi
3132
 $SINGLE_SLIDESHOW && ! $MK_CAROUSEL_MODE && CAROUSEL_SIZE=$VIDSIZE
3133
 
3134
-$TEXTMENU && LEFT_MAX=$SPLIT || LEFT_MAX=5
3135
-if [ "$SC_TITLE_ALIGN" = "west" ] || $TEXTMENU; then #FIXME
3136
-    THUMB_TITLE_ALIGN="west" # for non TEXTMENU menu
3137
-    for ((i=0; i<=NUM_FILES; i++)); do
3138
-        if [ $i -lt $LEFT_MAX ]; then
3139
-            SC_THUMB_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - \
3140
-            SAFE_OFFSET ))
3141
-            SC_TITLES_X_ARRAY[i]=$(( ${SC_TITLES_X_ARRAY[i]} - \
3142
-            SAFE_OFFSET ))
3143
-        fi
3144
-        if ! $TEXTMENU && ! [[ $SHOWCASE_FILE ]]; then
3145
-            if (( ${SC_THUMB_X_ARRAY[i]} > ( ${VIDSIZE/x*} / 2 ) )); then
3146
-                SC_THUMB_X_ARRAY[i]=$(( ${VIDSIZE/x*} / 2 ))
3147
-                SC_TITLES_X_ARRAY[i]=$(( ${VIDSIZE/x*} / 2 ))
3148
-            fi
3149
-        fi
3150
-    done
3151
-fi
3152
-# centre aligned titles are not for textmenu style
3153
-if $TEXTMENU && [[ $SC_TITLE_ALIGN = "center" ]]; then
3154
-    yecho
3155
-    yecho "Sorry, you can not use center align for textmenu titles"
3156
-    yecho "Using title alignment of 'west': please check the preview"
3157
-    yecho
3158
-    SC_TITLE_ALIGN="west"
3159
-    $WARN && sleep 10
3160
-fi
3161
+# textmenu does not use -showcase-titles-align, unset this to aid block parsing
3162
+$TEXTMENU && unset SC_TITLE_ALIGN
3163
 #  -align east uses text-rect
3164
 if [[ $BUTTON_STYLE = "text-rect" ]] \
3165
  && ! [[ $SC_TITLE_ALIGN = "east" ]] && $SHOWCASE && ! $TEXTMENU; then
3166
-    yecho "***Warning***"
3167
-    yecho "text-rect buttons need to be aligned east of thumbs:  by using:"
3168
-    yecho " '-showcase-titles-align east'"
3169
-    yecho "Setting this option for you"
3170
-    yecho "Ctrl-c now to exit if you wish to reconsider"
3171
+    info_message "text-rect buttons need to be aligned east of thumbs by using: 
3172
+     '-showcase-titles-align east'.  Setting this option for you.
3173
+    Ctrl-c now to exit if you wish to reconsider"
3174
     SC_TITLE_ALIGN="east"
3175
-    yecho
3176
-    $WARN && sleep 10
3177
-fi
3178
-if $SHOWCASE && [ "$SC_TITLE_ALIGN" = "east" ] && ! $TEXTMENU; then
3179
-    THUMB_TITLE_ALIGN="west" # align titles left to allow longer titles
3180
-    for ((i=0; i<=NUM_FILES; i++)); do
3181
-        if [ $i -lt $LEFT_MAX ] && ! $ALIGN_OVERRIDE; then
3182
-            SC_THUMB_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - \
3183
-            SAFE_OFFSET ))
3184
-            SC_TITLES_X_ARRAY[i]=$(( ${SC_TITLES_X_ARRAY[i]} - \
3185
-            SAFE_OFFSET ))
3186
-        fi
3187
-        if [ ${SC_THUMB_X_ARRAY[i]} -gt 360 ]; then
3188
-            SC_THUMB_X_ARRAY[i]=360
3189
-        fi
3190
-        SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} + \
3191
-        ${THUMB_SIZE/x*} + 5 ))
3192
-        #SC_TITLES_Y_ARRAY[i]=$(( ${SC_TITLES_Y_ARRAY[i]} + 18 ))
3193
-        SC_TITLES_Y_ARRAY[i]=${SC_THUMB_Y_ARRAY[i]} # DEBUG:why not originally?
3194
-    done
3195
+    $WARN && continue_in 10
3196
 fi
3197
-if { $USER_GRAVITY && $SHOWCASE && ! $TEXTMENU ; } \
3198
-              && [[ $BUTTON_GRAVITY != north ]]; then
3199
-    SW_CORNER=$(( ${SC_THUMB_Y_ARRAY[SPLIT-1]} + ${THUMB_SIZE/*x} ))
3200
-    if [[ $BUTTON_GRAVITY = *south* ]]; then
3201
-        Y_OFFSET=$(( ( ${VIDSIZE/*x} - SAFE_AREA) - SW_CORNER ))
3202
-    elif [[ $BUTTON_GRAVITY = *st* ]] || [[ $BUTTON_GRAVITY = *center* ]]; then
3203
-        COL1_HEIGHT=$(( SW_CORNER - ${SC_TITLES_Y_ARRAY[0]} ))
3204
-        Y_OFFSET=$(( ( ${VIDSIZE/*x} / 2) - (COL1_HEIGHT / 2) ))
3205
-        Y_OFFSET=$(( Y_OFFSET - ${SC_TITLES_Y_ARRAY[0]} ))
3206
-    fi
3207
-    for ((i=0; i<=NUM_FILES; i++)); do
3208
-        SC_THUMB_Y_ARRAY[i]=$((${SC_THUMB_Y_ARRAY[i]} + Y_OFFSET ))
3209
-        SC_TITLES_Y_ARRAY[i]=$((${SC_TITLES_Y_ARRAY[i]}+ Y_OFFSET))
3210
-    done
3211
-fi
3212
-# default for showcase style is left justification, for montages: center
3213
-$SHOWCASE && JUSTIFY="west" || JUSTIFY="center"
3214
-# find out the showcase thumb "-page" array for this arrangement
3215
-for ((i=0; i<=NUM_FILES; i++)); do
3216
-    if $TEXTMENU; then
3217
-        SCTHUMB_PAGES_ARRAY[i]=+${SC_TITLES_Y_ARRAY[i]}+${SC_TITLES_X_ARRAY[i]}
3218
-    else
3219
-        SCTHUMB_PAGES_ARRAY[i]=+${SC_THUMB_X_ARRAY[i]}+${SC_THUMB_Y_ARRAY[i]}
3220
-    fi
3221
-done
3222
 
3223
 # Do everything in $WORK_DIR
3224
-echo -e "**** NOTE ****\n"
3225
-echo "Doing all work in directory $REAL_WORK_DIR"
3226
-echo "$WORK_DIR will be a symlink pointing to this directory"
3227
-echo -e "\n**************"
3228
+yecho "Changing to ${REAL_WORK_DIR} - $WORK_DIR will be the symlink."
3229
+yecho ""
3230
 $WARN && sleep 1
3231
 cd "$WORK_DIR"
3232
 
3233
@@ -4988,9 +5419,9 @@
3234
 # no 3d thumbs for flare shape
3235
 if $THUMBS_3D || $SHOWCASE_3D && \
3236
   [[ $THUMB_SHAPE == "flare" || $SHOWCASE_SHAPE == "flare" ]]; then
3237
-    warning_message "There is no 3d thumbs available for the 'flare' shape. "
3238
+    info_message "There is no 3d thumbs available for the 'flare' shape. "
3239
     "Disabling this option for you"
3240
-    $WARN && sleep 3
3241
+    $WARN && continue_in 3
3242
 fi
3243
 
3244
 $FOURxONE && $SHOWCASE && FOURxONE=false && tile_warning
3245
@@ -5008,16 +5439,30 @@
3246
             THUMB_SIZE=${GEO_ARRAY[6]}
3247
         fi
3248
     else
3249
-        warning_message "Warning: Incorrect number of videos for ${tile_arg}:
3250
+        info_message "Warning: Incorrect number of videos for ${tile_arg}:
3251
         this option will be ignored"
3252
-        $WARN && sleep 3
3253
+        $WARN && continue_in 3
3254
     fi
3255
 fi
3256
-if ( ($DO_TITLESETS || $TITLESET_MODE) && $VMGM_MENU ) || $PLAYALL; then
3257
-    if [[ $BUTTON_GRAVITY = "south" ]]; then
3258
-        BUTTON_GRAVITY="center"
3259
-        yecho "Changing thumb alignment to 'center' \
3260
-        to make room for navigation button"
3261
+# south* aligned with nav buttons may be a problem, unless aligned southwest
3262
+if { $DO_TITLESETS || $TITLESET_MODE; } && $VMGM_MENU  || $PLAYALL; then
3263
+    bydir=${BUTTON_GRAVITY/south}
3264
+    if [[ $BUTTON_GRAVITY = south* && $bydir != west ]]; then
3265
+        if $TEXTMENU; then
3266
+            # textmenu will cover the nav button if southeast aligned
3267
+            # (center and southwest should be okay).Move to "east" (higher up).
3268
+            if [[ $bydir = east ]]; then
3269
+                BUTTON_GRAVITY=east
3270
+                info_message "Changing -align option to 'east' to make room \
3271
+                for navigation button(s) like playall '>'."
3272
+                $WARN && continue_in 5
3273
+            fi
3274
+        else
3275
+            info_message "You are using -align ${BUTTON_GRAVITY}, but need \
3276
+            room for navigation buttons like playall '>'.  Please \
3277
+            check the preview and adjust your commands if necessary."
3278
+            $WARN && continue_in 7
3279
+        fi
3280
     fi
3281
 fi
3282
 
3283
@@ -5033,7 +5478,6 @@
3284
 fi
3285
 # easier to have non transparent showcase use the transparent block
3286
 if $SHOWCASE && ! $TRANSPARENT; then TRANSPARENT=:; fi
3287
-AUDIO_OPTS="-ab 224k -ar $SAMPLERATE -acodec $AUDIO_EXT"
3288
 # spumux and dvdauthor vars
3289
 TITLES_VID_TAG="<video format=\"$TV_STANDARD\""
3290
 $WIDE_SCREEN && TITLES_VID_TAG=" $TITLES_VID_TAG widescreen=\"$WIDESCREEN\""
3291
@@ -5124,7 +5568,7 @@
3292
     # FFMPEG_OPTS="-b 7000k  -maxrate 8000k -bufsize 224KiB -aspect 4:3"
3293
    #MENU_N=$(bc_math "$FRAME_RATE * ${MENU_LEN[MENU_NUM-1]}" int)
3294
     #ffmpeg -f image2 -loop_input -t $MENU_LEN -i "$WORK_DIR/image_stack.png" \
3295
-    #-an -r $FRAME_RATE -s $VIDSIZE -tvstd $TV_STANDARD $FFMPEG_OPTS \
3296
+    #-an -r $ff_frame_rate -s $VIDSIZE $FFMPEG_OPTS \
3297
     #-f mpeg2video -y "$WORK_DIR/intro.m2v"
3298
 fi
3299
 # values to use for the blur mask
3300
@@ -5158,85 +5602,89 @@
3301
     convert "$WORK_DIR/feather_orig.png" -channel RGBA \
3302
     -blur 0x60 "$WORK_DIR/feather_mask2.png"
3303
 fi
3304
-if [[ -z "$TITLES_CLR" ]]; then
3305
-    if $USE_FEATHER_MASK && ! $SHOWCASE &&
3306
-     [[ $THUMB_BG_CLR != "none" && $THUMB_SHAPE != "normal" ]] ; then
3307
-        TITLES_CLR="#101010" # dark font for misted backgrounds
3308
-    else
3309
-        TITLES_CLR="#C6C6C6"
3310
-    fi
3311
-fi
3312
+[[ -z "$TITLES_CLR" ]] && TITLES_CLR='#EAEAEA'
3313
 # set submenu font colours to defaults if not passed in
3314
 [[ -z $CHAPTER_STROKE ]] && CHAPTER_STROKE="$SUBMENU_STROKE"
3315
 [[ -z $CHAPTER_CLR ]] && CHAPTER_CLR="$TITLES_CLR"
3316
 
3317
-# Print and execute the thumb-shape mask command
3318
 if $DO_MENU; then
3319
+    # make thumb-shape mask - showcase mask made later after its size is set
3320
     if [[ -n $THUMB_SHAPE ]]; then
3321
         make_mask $THUMB_SHAPE thumb
3322
         THUMB_MASK="$MASK"
3323
     fi
3324
-    if [[ -n $SHOWCASE_SHAPE ]]; then
3325
-        MASK="$WORK_DIR/${SHOWCASE_SHAPE}_mask.png"
3326
-        make_mask $SHOWCASE_SHAPE showcase
3327
-        convert "$MASK" -resize ${SHOWCASE_SIZE}! "$MASK"
3328
-        SHOWCASE_MASK="$MASK"
3329
-    fi
3330
-    yecho "Creating a menu title image"
3331
-    echo
3332
-    if [[ -z $TITLE_STROKE ]]; then
3333
-        if [[ -z "$BG_PIC" && -z "$BG_VIDEO" ]]; then
3334
-            TITLE_STROKE=none
3335
-        else
3336
-            TITLE_STROKE=gray
3337
-        fi
3338
+    
3339
+    # make a menu title image
3340
+    print2log "Creating a menu title image"
3341
+    if $USE_M_TITLE_DECO; then
3342
+        # using -title-stroke does a plain 'makemenu' style font with no shadow
3343
+        # but using font outline like makemenu does
3344
+        M_TITLE_CMD=(convert -size 620x100 xc:none -font "$MENU_FONT" \
3345
+        -pointsize $MENU_FONTSIZE -fill "$TITLE_CLR" -gravity center \
3346
+        "${M_TITLE_FONT_DECO[@]}" -annotate +0+0 "$MENU_TITLE")
3347
+        #-stroke none -annotate +0+0 "$MENU_TITLE")
3348
+    else
3349
+        # with no -title-stroke passed, make a font shadow for contrast
3350
+        # but no font outline (it will be a shadow on one side only
3351
+        M_TITLE_STROKE=${M_TITLE_STROKE:-black}
3352
+        M_TITLE_CMD=(convert -size 620x300 xc:none -gravity \
3353
+        $JUSTIFY -font "$MENU_FONT" -pointsize $MENU_FONTSIZE \
3354
+        -fill none  -stroke "$M_TITLE_STROKE" -strokewidth 1 \
3355
+        -annotate +0+0 "$MENU_TITLE" \
3356
+        -fill $TITLE_CLR  -stroke none \
3357
+        -annotate +1+1 "$MENU_TITLE")
3358
     fi
3359
-    [[ -z $TITLES_STROKE ]] && TITLES_STROKE='#010101'
3360
-
3361
-    # make a title image
3362
-    #! [[ -z ${STR// /} || -z $STR ]] && TRIM_CMD="-trim +repage -blur 0x0.4 "
3363
-    # allow removal of contrasting 'undercolour' with 'title-stroke none'
3364
-    # FIXME this is NOT IM syntax and it would be less confusing to adjust it
3365
-    [[ $TITLE_STROKE = 'none' ]] && undercolour='none' || undercolour='#101010'
3366
     TRIM_CMD="-trim +repage -blur 0x0.3"
3367
-    TITLE_CMD=(convert  -size 620x100 xc:none -font "$MENU_FONT" -pointsize \
3368
-    $MENU_FONTSIZE -fill $undercolour -stroke $undercolour -gravity center \
3369
-    -annotate +0+0 "$MENU_TITLE" -fill "$TITLE_CLR" \
3370
-    -stroke "$TITLE_STROKE" -strokewidth 1 -annotate +1+1 "$MENU_TITLE")
3371
-    TITLE_CMD0=(composite -blend 0x${TITLE_OPACITY}  null: - -matte)
3372
-    TITLE_CMD1=(convert - $TRIM_CMD  "$WORK_DIR/title_txt.png")
3373
+    M_TITLE_CMD0=(composite -blend 0x${TITLE_OPACITY}  null: - -matte)
3374
+    M_TITLE_CMD1=(convert - $TRIM_CMD  "$WORK_DIR/title_txt.png")
3375
 
3376
     if [[ -n $TITLE_OPACITY ]]; then
3377
-        "${TITLE_CMD[@]}" miff:- | "${TITLE_CMD0[@]}" miff:- |
3378
-        "${TITLE_CMD1[@]}" >> "$LOG_FILE" 2>&1
3379
+        "${M_TITLE_CMD[@]}" miff:- | "${M_TITLE_CMD0[@]}" miff:- |
3380
+        "${M_TITLE_CMD1[@]}" >> "$LOG_FILE" 2>&1
3381
     else
3382
-        "${TITLE_CMD[@]}" miff:- | "${TITLE_CMD1[@]}" >> "$LOG_FILE" 2>&1
3383
+        "${M_TITLE_CMD[@]}" miff:- | "${M_TITLE_CMD1[@]}" >> "$LOG_FILE" 2>&1
3384
     fi
3385
-
3386
-    # make thumb titles
3387
+fi
3388
+# this is really part of same DO_MENU block above, splitting up for readability
3389
+if $DO_MENU; then
3390
+    # make video titles
3391
     if ! $SINGLE_SLIDESHOW; then
3392
         for ((i=0; i<=NUM_FILES; i++)); do
3393
-            spin "Working on video title $((i+1)) "
3394
-            THUMB_TITLE_CMD=(convert -size 620x300 xc:none -gravity $JUSTIFY \
3395
-            -font "$TITLES_FONT" -pointsize $TITLES_FONTSIZE \
3396
-            -fill $CONTRAST_CLR  -stroke $TITLES_STROKE \
3397
-            -annotate +0+0 "${TITLES[i]}" \
3398
-            -fill $TITLES_CLR  -stroke none \
3399
-            -annotate +1+1 "${TITLES[i]}")
3400
+            print2log "Working on video title $((i+1)) "
3401
+            if $USE_V_TITLES_DECO; then
3402
+                # use a font outline makemenu style
3403
+                V_TITLES_CMD=(convert -size 620x100 xc:none \
3404
+                -font "$TITLES_FONT" -pointsize $TITLES_FONTSIZE \
3405
+                -fill "$TITLES_CLR" "${V_TITLES_FONT_DECO[@]}" \
3406
+                -gravity center -annotate +0+0 "${TITLES[i]}")
3407
+            #    #-stroke none -annotate +0+0 "${TITLES[i]}")
3408
+            else
3409
+                # default is to use a font shadow only on one side of font
3410
+                V_TITLES_STROKE=${V_TITLES_STROKE:-black}
3411
+                V_TITLES_CMD=(convert -size 620x300 xc:none -gravity $JUSTIFY \
3412
+                -font "$TITLES_FONT" -pointsize $TITLES_FONTSIZE \
3413
+                -fill none  -stroke "$V_TITLES_STROKE" -strokewidth 1 \
3414
+                -annotate +0+0 "${TITLES[i]}" \
3415
+                -fill $TITLES_CLR  -stroke none \
3416
+                -annotate +1+1 "${TITLES[i]}")
3417
+            fi
3418
             FADE_CMD=(composite -blend 0x${TITLES_OPACITY}  null: - -matte)
3419
+            # only repage and border if not 'text button'
3420
             if [[ $BUTTON_STYLE = "text" ]]; then
3421
                 TRIM_CMD=(convert - -trim "$WORK_DIR/thumb_title${i}.png")
3422
             else
3423
                 TRIM_CMD=(convert - -trim +repage $TEXT_BORDER \
3424
                 "$WORK_DIR/thumb_title${i}.png")
3425
             fi
3426
-            # make thumb title, only repage and border if not 'text button'
3427
+            # make thumb title
3428
             if [[ -n $TITLES_OPACITY ]]; then
3429
-                "${THUMB_TITLE_CMD[@]}" miff:- | "${FADE_CMD[@]}" miff:- |
3430
+                "${V_TITLES_CMD[@]}" miff:- | "${FADE_CMD[@]}" miff:- |
3431
                 "${TRIM_CMD[@]}"
3432
             else
3433
-                "${THUMB_TITLE_CMD[@]}" miff:- | "${TRIM_CMD[@]}"
3434
+                "${V_TITLES_CMD[@]}" miff:- | "${TRIM_CMD[@]}"
3435
             fi
3436
+            # save dimensions for later use
3437
+            TT_DIM[i]=$(get_image_dim "$WORK_DIR/thumb_title${i}.png")
3438
             # now get offset before repaging, for the spumux button crop later
3439
             if [[ $BUTTON_STYLE = "text" ]]; then
3440
                 titles_offset[i]=$(identify -format %O \
3441
@@ -5280,137 +5728,381 @@
3442
                 at your fontsize.  Use a smaller font with -titles-fontsize"
3443
             fi
3444
         done
3445
+        yecho ""
3446
     fi
3447
+fi
3448
+###############################################################################
3449
+############ set showcase/textmenu titles and thumb positions array ###########
3450
+###############################################################################
3451
 
3452
-    if $SHOWCASE; then
3453
-        for ((i=0; i<=NUM_FILES; i++)); do
3454
-            unset ts_dim j
3455
-            # get widest png in each colum for use later for alignment use
3456
+# this is really part of same DO_MENU block above, splitting up for readability
3457
+if $DO_MENU && $SHOWCASE; then
3458
+    # textmenu also uses this block !
3459
+    # get widest png in each colum for use later for alignment use
3460
+    for ((i=0; i<=NUM_FILES; i++)); do
3461
+        unset ts_dim j
3462
+        if ((i < SPLIT)); then
3463
+            # save widest_title x_dim as well as its array index
3464
+            val=${TT_DIM[i]/x*}
3465
+            [ -z "$widest_title" ] || ((val > widest_title)) \
3466
+              && widest_title=$val && widest_title_index=$i
3467
+        else
3468
+            val2=${TT_DIM[i]/x*}
3469
+            [ -z "$widest_title2" ] || ((val2 > widest_title2)) \
3470
+              && widest_title2=$val2 && widest_title2_index=$i
3471
+        fi
3472
+        # get just X demension to help determine final title pos below
3473
+        tt_dim=${TT_DIM[i]/x*}
3474
+    done
3475
+    # so we can do math on the var without error
3476
+    ((widest_title2)) || widest_title2=0
3477
+
3478
+    ######################################################################
3479
+    ############### showcase with thumbs only X dimension ################
3480
+    ######################################################################
3481
+
3482
+    { $TEXTMENU && LEFT_MAX=$SPLIT ; } || LEFT_MAX=5
3483
+    # textmenu doesn't use this block at all
3484
+    # TODO check_space=0 # only check if enough space once if $SHOWCASE_FILE
3485
+    # some shortened var names for the math in this block
3486
+    tt_w=${TT_DIM[i]} # title width
3487
+    tt_w=${tt_w/x*}
3488
+    t_w=${THUMB_SIZE/x*} # thumb width
3489
+    safe_w=$SAFE_AREA # safe area width
3490
+    vsize_w=${VIDSIZE/x*} # video size width (720)
3491
+    for ((i=0; i<=NUM_FILES; i++)); do
3492
+        # get array positions for thumbs and titles.  The titles_xdelta is
3493
+        # the amount we subtract later from the thumb position to re-define
3494
+        # the arrays when the various -align options are taken into account
3495
+        case $SC_TITLE_ALIGN in
3496
+          west)
3497
+            # only need extra room after 2nd column for long titles
3498
+            ovflow=$(( widest_title2 - t_w ))
3499
             if ((i < SPLIT)); then
3500
-                val=${TT_DIM[i]/x*}
3501
-                [ -z "$WIDEST_TITLE" ] || ((val > WIDEST_TITLE)) \
3502
-                  && WIDEST_TITLE=$val
3503
-            else
3504
-                val2=${TT_DIM[i]/x*}
3505
-                [ -z "$WIDEST_TITLE2" ] || ((val2 > WIDEST_TITLE2)) \
3506
-                  && WIDEST_TITLE2=$val2
3507
-            fi
3508
-            # get just X demension to help determine final title pos below
3509
-            tt_dim=${TT_DIM[i]/x*}
3510
+                SC_THUMB_X_ARRAY[i]=$((${SC_THUMB_X_ARRAY[i]} - SAFE_OFFSET))
3511
+            else
3512
+                # ovflow=0 is the right edge of thumb, so stop there
3513
+                ((ovflow < 0)) && ovflow=0
3514
+                # titles are aligned west: try to align east side close to edge
3515
+                SC_THUMB_X_ARRAY[i]=$(( vsize_w - t_w  - safe_w - ovflow ))
3516
+            fi
3517
+            SC_TITLES_X_ARRAY[i]=${SC_THUMB_X_ARRAY[i]}
3518
+            titles_xdelta[i]=0 # for using later in -align options
3519
+            ;;
3520
+          east)
3521
+            #if ((i < SPLIT)) && ! $ALIGN_OVERRIDE; then
3522
+                #SC_THUMB_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - \
3523
+                #SAFE_OFFSET ))
3524
+                #SC_TITLES_X_ARRAY[i]=$(( ${SC_TITLES_X_ARRAY[i]} - \
3525
+                #SAFE_OFFSET ))
3526
+            #fi
3527
+            if ((i >= SPLIT)); then
3528
+                # 2 cols can't -align east/west/center so no ALIGN_OVERRIDE test
3529
+                SC_THUMB_X_ARRAY[i]=$(( ( vsize_w - safe_w) - \
3530
+                    $widest_title2 - t_w - 5 ))
3531
+                    # titlesafe warnings disabled for now
3532
+                    #roffset=$(( ${SC_TITLES_X_ARRAY[i]} + 5 + safe_w ))
3533
+                    #if (( roffset + ${TT_DIM[i]/x*} > vsize_w )); then
3534
+                    #    titlesafe_error $(( roffset - vsize_w ))
3535
+                    #fi
3536
+            fi
3537
+            SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} + t_w + 5 ))
3538
+            SC_TITLES_Y_ARRAY[i]=${SC_THUMB_Y_ARRAY[i]}
3539
+            titles_xdelta[i]=$(( ${SC_THUMB_X_ARRAY[i]} - ${SC_TITLES_X_ARRAY[i]} ))
3540
+            ;;
3541
+          center)
3542
+            # make sure the showcase file is not being covered up
3543
+            ! [[ $widest_title ]] && widest_title=0
3544
+            ! [[ $widest_title2 ]] && widest_title2=0
3545
+            #if ((widest_title2)); then
3546
+            #    col2_thumb_x=$widest_title2
3547
+            #    thumbs_space=$((${THUMB_SIZE/x*} * 2))
3548
+            #else
3549
+            #    col2_thumb_x=0
3550
+            #    thumbs_space=${THUMB_SIZE/x*}
3551
+            #fi
3552
+            # need to rewrite, checking only the area on sides of the sc thumb
3553
+            #if [[ $SHOWCASE_FILE ]]; then #&& ! ((checked_space)); then
3554
+            #    safearea=$((SAFE_AREA * 2))
3555
+            #    titles_space=$((widest_title + col2_thumb_x))
3556
+            #    if $(( (VS - safearea - \
3557
+            #      titles_space - thumbs_space - ShowCaseSize) <= 0)); then
3558
+            #        : # problem: do something #FIXME run this only once
3559
+            #    fi
3560
+            #fi
3561
+            #checked_space=1
3562
+            # check if "title-safe" (not too close to screen edge or offscreen)
3563
+            # for showcase with thumbs and center aligned titles only # FIXME?
3564
             # thumb pos + 1/2 (X dim) of thumbsize - 1/2 (X dim) of title size
3565
-            if [ "$SC_TITLE_ALIGN" = "center" ]; then
3566
-                f=$(( ${THUMB_SIZE/x*} / 2 ))
3567
-                j=$(( (f + ${SC_THUMB_X_ARRAY[i]}) - (tt_dim / 2) ))
3568
-                k=( ${k[@]} "$j" )
3569
-                l=$((j + tt_dim))
3570
-                if [ $j -lt 48 ]; then
3571
+            f=$(( ${THUMB_SIZE/x*} / 2 ))
3572
+            j=$(( ( ${SC_THUMB_X_ARRAY[i]} + f ) - (${TT_DIM[i]/x*} / 2) ))
3573
+            if ((widest_title > ${TT_DIM[i]/x*})); then
3574
+                offset1=$(( (widest_title - ${TT_DIM[i]/x*}) / 2 ))
3575
+                offset2=$((widest_title2 - ${TT_DIM[i]/x*} / 2 ))
3576
+            else
3577
+                offset1=${TT_DIM[i]/x*}
3578
+            fi
3579
+            offset_from_safe_edge1=$offset # unused
3580
+            tt_x=( ${tt_x[@]} "$j" )
3581
+            l=$((j + tt_dim))
3582
+            # FIXME this test gives wrong result and is unused right now !
3583
+            if ((i < SPLIT)); then
3584
+                if (( j < SAFE_AREA + SAFE_OFFSET )); then
3585
                     off_left=$j
3586
-                    titlesafe_error $off_left
3587
-                elif [ $l -gt 672 ]; then
3588
-                    off_right=$((720 - l))
3589
-                    titlesafe_error $off_right
3590
+                    # titlesafe warnings disabled for now
3591
+                    #titlesafe_error $off_left
3592
+                fi
3593
+            else
3594
+                if (( l > vsize_w - SAFE_AREA - SAFE_OFFSET)); then
3595
+                    off_right=$(($vsize_w - l))
3596
+                    #titlesafe_error $off_right
3597
                 fi
3598
             fi
3599
-        done
3600
+            titles_xdelta[i]=$(( ${SC_THUMB_X_ARRAY[i]} - ${tt_x[i]} ))
3601
+            ;;
3602
+        esac
3603
+        # now that we have the title delta, factor in -align option (E/W/Centre)
3604
+        td=${titles_xdelta[i]}
3605
+        case $BUTTON_GRAVITY in
3606
+          *east) # single column showcase with thumbs only
3607
+            # if title is wider than thumb
3608
+            #if ((tt_w > t_w)); then
3609
+            #    SC_TITLES_X_ARRAY[i]=$(( vsize_w - safe_w - tt_w ))
3610
+            # thumb wider, or they are the same
3611
+            #else
3612
+            #    SC_TITLES_X_ARRAY[i]=$(( vsize_w - safe_w - t_w ))
3613
+            #fi
3614
+            # titles also aligned east of thumb need to Add the (neg) xdelta
3615
+            #if [[ $SC_TITLE_ALIGN = east ]]; then
3616
+            #    SC_THUMB_X_ARRAY[i]=$(( vsize_w - safe_w - t_w - (widest_title / 2) + td  ))
3617
+            #else
3618
+            #    SC_THUMB_X_ARRAY[i]=$(( vsize_w - safe_w - t_w - (widest_title / 2) ))
3619
+            #fi
3620
+            #SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - td ))
3621
+            if [[ $SC_TITLE_ALIGN = east ]]; then
3622
+                SC_TITLES_X_ARRAY[i]=$(( vsize_w - safe_w - widest_title ))
3623
+                SC_THUMB_X_ARRAY[i]=$(( ${SC_TITLES_X_ARRAY[i]} - 5 - t_w ))
3624
+            else
3625
+                SC_THUMB_X_ARRAY[i]=$(( vsize_w - safe_w - t_w - (widest_title / 2) ))
3626
+                SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - td ))
3627
+            fi
3628
+            ;;
3629
+          *west)  # single column showcase with thumbs only
3630
+            # they are the same, as the west sides are flush (titles_xdelta=0)
3631
+            SC_THUMB_X_ARRAY[i]=$((SAFE_AREA + SAFE_OFFSET))
3632
+            SC_TITLES_X_ARRAY[i]=$((${SC_THUMB_X_ARRAY[i]} - td))
3633
+            ;;
3634
+          north|south|center) # either single or 2 column showcase with thumbs
3635
+            if ((NUM_FILES >= SPLIT)); then # 2 column showcase (N/S/C only)
3636
+                #if ((widest_title2 > t_w)); then
3637
+                #    SC_THUMB_X_ARRAY[i]=$((vsize_w - safe_w - t_w + td))
3638
+                #fi
3639
+                SC_TITLES_X_ARRAY[i]=$((${SC_THUMB_X_ARRAY[i]} - td))
3640
+            else # single column showcase (all -align opt should work)
3641
+                SC_THUMB_X_ARRAY[i]=$(( (vsize_w / 2) - (t_w / 2) ))
3642
+                SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - td ))
3643
+            fi
3644
+            #if ((tt_w > t_w)); then
3645
+            #    SC_THUMB_X_ARRAY[i]=$(( (vsize_w / 2) - (t_w / 2) ))
3646
+            #    SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - td ))
3647
+            #else
3648
+            #    SC_THUMB_X_ARRAY[i]=$(( (vsize_w / 2) - (t_w / 2) ))
3649
+            #    SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - td ))
3650
+            #fi
3651
+            #echo thumb: ${SC_THUMB_X_ARRAY[i]} title: ${SC_TITLES_X_ARRAY[i]}
3652
+                ;;
3653
+          *)
3654
+            # default is to use original arrays.  Subtract titles_xdelta
3655
+            SC_TITLES_X_ARRAY[i]=$(( ${SC_THUMB_X_ARRAY[i]} - td ))
3656
+            ;;
3657
+        esac
3658
+    done
3659
+    ######################################################################
3660
+    ############### showcase with thumbs only Y dimension ################
3661
+    ######################################################################
3662
+
3663
+    # bottom edge of last thumb vertically
3664
+    SW_CORNER=$(( ${SC_THUMB_Y_ARRAY[SPLIT-1]} + ${THUMB_SIZE/*x} ))
3665
+    # TODO add north) so user can align flush with top safearea edge
3666
+    # as the default is not 'exactly' north in these terms, but a compromise
3667
+    # center aligned titles only can use *west -align options
3668
+    case $BUTTON_GRAVITY in
3669
+      northwest)
3670
+        : # no offset
3671
+        ;;
3672
+      south*)
3673
+        Y_OFFSET=$(( ( ${VIDSIZE/*x} - SAFE_AREA) - SW_CORNER ))
3674
+        ;;
3675
+      *east|*west|center)
3676
+        COL1_HEIGHT=$(( SW_CORNER - ${SC_TITLES_Y_ARRAY[0]} ))
3677
+        Y_OFFSET=$(( ( ${VIDSIZE/*x} / 2) - (COL1_HEIGHT / 2) ))
3678
+        Y_OFFSET=$(( Y_OFFSET - ${SC_TITLES_Y_ARRAY[0]} ))
3679
+        ;;
3680
+    esac
3681
+    #if [[ $BUTTON_GRAVITY = south* ]]; then
3682
+    #    Y_OFFSET=$(( ( ${VIDSIZE/*x} - SAFE_AREA) - SW_CORNER ))
3683
+    #elif [[ $BUTTON_GRAVITY = *st* ]] || [[ $BUTTON_GRAVITY = *center* ]]; then
3684
+    #    COL1_HEIGHT=$(( SW_CORNER - ${SC_TITLES_Y_ARRAY[0]} ))
3685
+    #    Y_OFFSET=$(( ( ${VIDSIZE/*x} / 2) - (COL1_HEIGHT / 2) ))
3686
+    #    Y_OFFSET=$(( Y_OFFSET - ${SC_TITLES_Y_ARRAY[0]} ))
3687
+    #fi
3688
+    for ((i=0; i<=NUM_FILES; i++)); do
3689
+        SC_THUMB_Y_ARRAY[i]=$((${SC_THUMB_Y_ARRAY[i]} + Y_OFFSET ))
3690
+        SC_TITLES_Y_ARRAY[i]=$((${SC_TITLES_Y_ARRAY[i]} + Y_OFFSET))
3691
+    done
3692
+    #fi
3693
+    # showcase style default: left justification. montages default: center.
3694
+    # find out the showcase thumb "-page" array for this arrangement
3695
+    for ((i=0; i<=NUM_FILES; i++)); do
3696
         if $TEXTMENU; then
3697
-            # text-rect is OK with a small space between titles for spumux
3698
-            [[ $BUTTON_STYLE = "text-rect" ]] && \
3699
-              SPACER=${SPACER:-"10"} || SPACER=${SPACER:-"15"}
3700
-            # get an array of title Y positions
3701
-            offsets1=$(for ((c=0; c<NUM_FILES; c++)); do
3702
-            ((c < (LEFT_MAX-1))) && echo $((${TT_DIM[c]#*x} + SPACER)); done)
3703
-            if [[ $NUM_FILES -ge $SPLIT ]]; then
3704
-                offsets2=$(for ((d=0; d<=NUM_FILES; d++)); do
3705
-                ((d >= LEFT_MAX)) && echo $((${TT_DIM[d]#*x} + SPACER)); done)
3706
-                [[ $offsets2 ]] && offsets2="$TEXT_YSTART $offsets2"
3707
-                tt_ygeos_col2=$(running_total <<< $offsets2)
3708
-            fi
3709
-            offsets1="$TEXT_YSTART $offsets1"
3710
-            tt_ygeos_col1=$(running_total <<< $offsets1)
3711
-            tt_ygeos="$tt_ygeos_col1 $tt_ygeos_col2"
3712
-            unset SC_TITLES_Y_ARRAY
3713
-            SC_TITLES_Y_ARRAY=( $tt_ygeos_col1 $tt_ygeos_col2 )
3714
-            # get y position of the last title in 1st column (tt_ygeos_col1)
3715
-            endtitle_col1=$(wc -w <<< "$tt_ygeos_col1")
3716
-            endtitle_col1_ygeo=${SC_TITLES_Y_ARRAY[endtitle_col1-1]/*x}
3717
-            # add y dimension of the last title size to the above y position
3718
-            SW_YCORNER=$((${TT_DIM[endtitle_col1-1]/*x} + $endtitle_col1_ygeo))
3719
-            avail_space1=$(( ( ${VIDSIZE/*x} - SAFE_AREA ) - $SW_YCORNER ))
3720
-            # if there are 2 columns, get same data for column 2
3721
-            if [[ -n $tt_ygeos_col2 ]]; then
3722
-                endtitle_col2=$NUM_FILES
3723
-                endtitle_col2_ygeo=${SC_TITLES_Y_ARRAY[endtitle_col2]/*x}
3724
-                endtitle_col2_xgeo=${SC_TITLES_Y_ARRAY[endtitle_col2]/x*}
3725
-                SE_YCORNER=$((${TT_DIM[endtitle_col2]/*x}+$endtitle_col2_ygeo))
3726
-                avail_space2=$(( ( ${VIDSIZE/*x} - SAFE_AREA ) - $SE_YCORNER ))
3727
-            fi
3728
-            # available space is lowest value of 2 *space* vars ( if 2 columns)
3729
-            if [[ -n $tt_ygeos_col2 ]] && ((SE_YCORNER > SW_YCORNER)); then
3730
-                avail_space=$avail_space2
3731
-            else
3732
-                avail_space=$avail_space1
3733
-            fi
3734
-            # get the height of each column for -align centre
3735
-            if [[ $BUTTON_GRAVITY = "center" \
3736
-              || $BUTTON_GRAVITY = "east" || $BUTTON_GRAVITY = "west" ]]; then
3737
-                WEST_YSPACE=$(( SW_YCORNER - TEXT_YSTART))
3738
-                EAST_YSPACE=$((SE_YCORNER - TEXT_YSTART))
3739
-                ((WEST_YSPACE > EAST_YSPACE)) && YSPACE=$WEST_YSPACE \
3740
-                  || YSPACE=$EAST_YSPACE
3741
-                CANVAS=$(( ${VIDSIZE/*x} - (SAFE_AREA * 2) ))
3742
-                NEW_TEXT_YSTART=$(( ((CANVAS - YSPACE) / 2) + SAFE_AREA ))
3743
-                TEXT_YSTART_OFFSET=$((NEW_TEXT_YSTART - TEXT_YSTART))
3744
-            fi
3745
-            # add available space to each title position for south alignment
3746
-            if [[ $BUTTON_GRAVITY = *south* ]] && ((avail_space > 0)); then
3747
-                for ((d=0; d<=NUM_FILES; d++)); do
3748
-                    SC_TITLES_Y_ARRAY[d]=$(( $avail_space + \
3749
-                      ${SC_TITLES_Y_ARRAY[d]} ))
3750
-                done
3751
-            elif  [[ $BUTTON_GRAVITY = "center" \
3752
-              || $BUTTON_GRAVITY = "east" || $BUTTON_GRAVITY = "west" ]]; then
3753
-                for ((d=0; d<=NUM_FILES; d++)); do
3754
-                    SC_TITLES_Y_ARRAY[d]=$(($TEXT_YSTART_OFFSET + \
3755
-                      ${SC_TITLES_Y_ARRAY[d]} ))
3756
-                done
3757
-            fi
3758
-                # justify titles to the right on the east side of the menu
3759
-                ((NUM_FILES >= SPLIT-1)) && WIDE_TITLE=$WIDEST_TITLE2 \
3760
-                  || WIDE_TITLE=$WIDEST_TITLE
3761
-                for ((d=0; d<=NUM_FILES; d++)); do
3762
-                    ([[ "$BUTTON_GRAVITY" = *east* ]] \
3763
-                      || [[ -n $tt_ygeos_col2 ]]) && \
3764
-                        east_offset=$(( ( ${VIDSIZE/x*} - SAFE_AREA ) - \
3765
-                        ${TT_DIM[d]/x*} ))
3766
-                    if (($NUM_FILES < SPLIT)); then
3767
-                        SC_TITLES_X_ARRAY[d]=$SAFE_AREA
3768
-                        [[ "$BUTTON_GRAVITY" = *east* ]] && \
3769
-                          SC_TITLES_X_ARRAY[d]=$east_offset
3770
-                    else
3771
-                        if ((d >= LEFT_MAX)); then
3772
-                            SC_TITLES_X_ARRAY[d]=$east_offset
3773
-                        else
3774
-                            SC_TITLES_X_ARRAY[d]=$SAFE_AREA
3775
-                        fi
3776
-                    fi
3777
-                done
3778
-            unset MAX_VAL val max_key
3779
+            SCTHUMB_PAGES_ARRAY[i]=+${SC_TITLES_Y_ARRAY[i]}+${SC_TITLES_X_ARRAY[i]}
3780
+        else
3781
+            SCTHUMB_PAGES_ARRAY[i]=+${SC_THUMB_X_ARRAY[i]}+${SC_THUMB_Y_ARRAY[i]}
3782
         fi
3783
-        # make SHOWCASE_PAGE arrayS for thumbs and THUMBTITLES_ARRAY for titles
3784
-        # use preset values unless doing centre align for titles
3785
-        for ((i=0; i<=NUM_FILES; i++)); do
3786
-            if [ "$SC_TITLE_ALIGN" != "center" ]; then
3787
-                SC_TITLES_ARR[i]=+${SC_TITLES_X_ARRAY[i]}+${SC_TITLES_Y_ARRAY[i]}
3788
+    done
3789
+fi
3790
+
3791
+##############################################################################
3792
+#################                 textmenu only              #################
3793
+##############################################################################
3794
+
3795
+if $DO_MENU && $TEXTMENU; then
3796
+    #############            textmenu  Y dimension               #############
3797
+    # text-rect is OK with a small space between titles for spumux
3798
+    [[ $BUTTON_STYLE = "text-rect" ]] && \
3799
+      SPACER=${SPACER:-"10"} || SPACER=${SPACER:-"15"}
3800
+
3801
+    # get array of titles Y positions for textmenu
3802
+    offsets1=$(for ((c=0; c<NUM_FILES; c++)); do
3803
+    ((c < (LEFT_MAX-1))) && echo $((${TT_DIM[c]#*x} + SPACER)); done)
3804
+    if ((NUM_FILES >= SPLIT)); then
3805
+        # to line up rows across, use taller of 2 images for space calc.
3806
+        if (( ${TT_DIM[c-SPLIT]#*x} > ${TT_DIM[c]#*x} )); then
3807
+            tt_yspace=${TT_DIM[c-SPLIT]#*x}
3808
+        else
3809
+            tt_yspace=${TT_DIM[c]#*x}
3810
+        fi
3811
+        offsets1=$(for ((c=0; c<NUM_FILES; c++)); do
3812
+        ((c < (LEFT_MAX-1))) && echo $((tt_yspace + SPACER)); done)
3813
+        offsets2=$(for ((d=0; d<=NUM_FILES; d++)); do
3814
+        ((d >= LEFT_MAX)) && echo $((tt_yspace + SPACER)); done)
3815
+        [[ $offsets2 ]] && offsets2="$TEXT_YSTART $offsets2"
3816
+        tt_ygeos_col2=$(running_total <<< $offsets2)
3817
+    fi
3818
+    offsets1="$TEXT_YSTART $offsets1"
3819
+    tt_ygeos_col1=$(running_total <<< $offsets1)
3820
+    tt_ygeos="$tt_ygeos_col1 $tt_ygeos_col2"
3821
+    unset SC_TITLES_Y_ARRAY
3822
+    SC_TITLES_Y_ARRAY=( $tt_ygeos_col1 $tt_ygeos_col2 )
3823
+    # get y position of the last title in 1st column (tt_ygeos_col1)
3824
+    endtitle_col1=$(wc -w <<< "$tt_ygeos_col1")
3825
+    endtitle_col1_ygeo=${SC_TITLES_Y_ARRAY[endtitle_col1-1]/*x}
3826
+    # add y dimension of the last title size to the above y position
3827
+    SW_YCORNER=$((${TT_DIM[endtitle_col1-1]/*x} + $endtitle_col1_ygeo))
3828
+    avail_space1=$(( ( ${VIDSIZE/*x} - SAFE_AREA ) - $SW_YCORNER ))
3829
+    # if there are 2 columns, get same data for column 2
3830
+    if [[ -n $tt_ygeos_col2 ]]; then
3831
+        endtitle_col2=$NUM_FILES
3832
+        endtitle_col2_ygeo=${SC_TITLES_Y_ARRAY[endtitle_col2]/*x}
3833
+        endtitle_col2_xgeo=${SC_TITLES_Y_ARRAY[endtitle_col2]/x*}
3834
+        SE_YCORNER=$((${TT_DIM[endtitle_col2]/*x}+$endtitle_col2_ygeo))
3835
+        avail_space2=$(( ( ${VIDSIZE/*x} - SAFE_AREA ) - SE_YCORNER ))
3836
+    fi
3837
+    # available space is lowest value of 2 *space* vars ( if 2 columns)
3838
+    if [[ -n $tt_ygeos_col2 ]] && ((SE_YCORNER > SW_YCORNER)); then
3839
+        avail_space=$avail_space2
3840
+        end_title_pos=$SE_YCORNER
3841
+    else
3842
+        avail_space=$avail_space1
3843
+        end_title_pos=$SW_YCORNER
3844
+    fi
3845
+    # get the height of each column for -align centre
3846
+    if [[ $BUTTON_GRAVITY = "center" \
3847
+      || $BUTTON_GRAVITY = "east" || $BUTTON_GRAVITY = "west" ]]; then
3848
+        WEST_YSPACE=$(( SW_YCORNER - TEXT_YSTART))
3849
+        EAST_YSPACE=$((SE_YCORNER - TEXT_YSTART))
3850
+        ((WEST_YSPACE > EAST_YSPACE)) && YSPACE=$WEST_YSPACE \
3851
+          || YSPACE=$EAST_YSPACE
3852
+        CANVAS_Y=$(( ${VIDSIZE/*x} - (SAFE_AREA * 2) ))
3853
+        NEW_TEXT_YSTART=$(( ( (CANVAS_Y - YSPACE) / 2) + SAFE_AREA ))
3854
+        TEXT_YSTART_OFFSET=$((NEW_TEXT_YSTART - TEXT_YSTART))
3855
+    fi
3856
+    # add available space to each title position for south alignment
3857
+    if [[ $BUTTON_GRAVITY = *south* ]] && ((avail_space > 0)); then
3858
+        for ((d=0; d<=NUM_FILES; d++)); do
3859
+            SC_TITLES_Y_ARRAY[d]=$(( $avail_space + \
3860
+              ${SC_TITLES_Y_ARRAY[d]} ))
3861
+        done
3862
+    elif  [[ $BUTTON_GRAVITY = "center" \
3863
+      || $BUTTON_GRAVITY = "east" || $BUTTON_GRAVITY = "west" ]]; then
3864
+        for ((d=0; d<=NUM_FILES; d++)); do
3865
+            SC_TITLES_Y_ARRAY[d]=$(($TEXT_YSTART_OFFSET + \
3866
+              ${SC_TITLES_Y_ARRAY[d]} ))
3867
+        done
3868
+    fi
3869
+fi
3870
+    ########################  textmenu X dimension  ##########################
3871
+# this is really part of block above, split up for readability
3872
+if $DO_MENU && $TEXTMENU; then
3873
+    XSPACE=$(( ${VIDSIZE/x*} - SAFE_AREA ))
3874
+    # title Xdim location for ONE column on right side (left justified)
3875
+    ljustify_eoffset=$((XSPACE-widest_title))
3876
+    # same as above, but for 2nd column when using TWO title columns
3877
+    ljustify_eoffset2=$((XSPACE-widest_title2))
3878
+    for ((d=0; d<=NUM_FILES; d++)); do
3879
+        ([[ "$BUTTON_GRAVITY" = *east* ]] \
3880
+          || [[ -n $tt_ygeos_col2 ]]) && \
3881
+            rjustify_eoffset=$(( XSPACE - ${TT_DIM[d]/x*} ))
3882
+        if ((d < SPLIT)); then
3883
+            # default is northwest alignment
3884
+            SC_TITLES_X_ARRAY[d]=$SAFE_AREA
3885
+            # for centred align add safe area from both sides
3886
+            case "$BUTTON_GRAVITY" in
3887
+              "center" | "north" | "south")
3888
+                SC_TITLES_X_ARRAY[d]=$((( (XSPACE + SAFE_AREA) / 2) - \
3889
+                (${TT_DIM[d]/x*} / 2) ))
3890
+                ;;
3891
+              "northeast"|"southeast"|"east")
3892
+                # allow justifying east column to right instead of left
3893
+                if $EDGE_JUSTIFY; then
3894
+                    SC_TITLES_X_ARRAY[d]=$rjustify_eoffset
3895
+                else
3896
+                    SC_TITLES_X_ARRAY[d]=$ljustify_eoffset
3897
+                fi
3898
+                ;;
3899
+            esac
3900
+        else # could be single column or a 2nd column, aligned east
3901
+            if ((d >= LEFT_MAX)); then # therefore this is an east column
3902
+                # allow justifying east column to right instead of left
3903
+                if $EDGE_JUSTIFY; then
3904
+                    SC_TITLES_X_ARRAY[d]=$rjustify_eoffset
3905
+                else
3906
+                    SC_TITLES_X_ARRAY[d]=$ljustify_eoffset2
3907
+                fi
3908
             else
3909
-                SC_TITLES_ARR[i]=+${k[i]}+${SC_TITLES_Y_ARRAY[i]}
3910
+                SC_TITLES_X_ARRAY[d]=$SAFE_AREA
3911
             fi
3912
-
3913
-            SHOWCASE_THUMB_PAGES[i]="-page ${SCTHUMB_PAGES_ARRAY[i]}"
3914
-            THUMBTITLES_ARRAY[i]="-page ${SC_TITLES_ARR[i]}"
3915
-        done
3916
-    fi
3917
+        fi
3918
+    done
3919
+    unset MAX_VAL val max_key
3920
+    # END textmenu block
3921
 fi
3922
+if $SHOWCASE; then
3923
+    # make -page arrays for thumbs, and for titles
3924
+    # use values set in the above block for textmenu
3925
+    # and for showcase with thumbs unless doing centre align for titles
3926
+    for ((i=0; i<=NUM_FILES; i++)); do
3927
+        #if [ "$SC_TITLE_ALIGN" != "center" ]; then
3928
+        SC_TITLES_ARR[i]=+${SC_TITLES_X_ARRAY[i]}+${SC_TITLES_Y_ARRAY[i]}
3929
+        #else
3930
+        #    SC_TITLES_ARR[i]=+${tt_x[i]}+${SC_TITLES_Y_ARRAY[i]}
3931
+        #fi
3932
 
3933
+        SHOWCASE_THUMB_PAGES[i]="-page ${SCTHUMB_PAGES_ARRAY[i]}"
3934
+        THUMBTITLES_ARRAY[i]="-page ${SC_TITLES_ARR[i]}"
3935
+    done
3936
+    echo 
3937
+fi
3938
 # make a button for playall and one for jumping to the vmgm menu, if called for
3939
 # or make a 'play' button if doing a montage slideshow menu
3940
 pa_ind=$((NUM_FILES+1))
3941
@@ -5550,17 +6242,23 @@
3942
 if $MIST; then
3943
     mist_dim=$(get_image_dim "$WORK_DIR/white.png" )
3944
     mist_xdim=${mist_dim/x*}
3945
-    mist_xdim_offset=$(( (mist_xdim - TITLE_TEXT_XDIM) / 2 ))
3946
-    if [[ $TITLE_GRAVITY = *st* ]]; then
3947
+    mist_xoffset=$(( (mist_xdim - TITLE_TEXT_XDIM) / 2 ))
3948
+    case $TITLE_GRAVITY in
3949
+      northeast|southeast|east)
3950
         title_xoffset=${title_xoffset:-"+50"}
3951
-        mist_xoffset="$(bc_math "${title_xoffset#*[-+]} \
3952
-          - $mist_xdim_offset" int)"
3953
+        mist_xoffset="$(bc_math "${title_xoffset#*[-+]} - $mist_xoffset" int)"
3954
         [[ ${mist_xoffset:0:1} != [+-] ]] && mist_xoffset=+${mist_xoffset}
3955
-    else
3956
+        ;;
3957
+      *)
3958
         title_xoffset=${title_xoffset:-"+0"}
3959
         mist_xoffset=$title_xoffset
3960
-    fi
3961
+        ;;
3962
+    esac
3963
 else
3964
+        # make sure the offset supplied is >= safe_area
3965
+        if [[ $TITLE_GRAVITY = east || $TITLE_GRAVITY = west ]]; then
3966
+            ((${title_xoffset#*[-+]} < SAFE_AREA)) && title_xoffset=+${SAFE_AREA}
3967
+        fi
3968
         title_xoffset=${title_xoffset:-"+0"}
3969
 fi
3970
 ###############################################################################
3971
@@ -5575,27 +6273,36 @@
3972
     else
3973
         bg_post_seek="-ss $BG_SEEK" && unset bg_pre_seek
3974
     fi
3975
-    FFMPEG_CMD=(ffmpeg $bg_pre_seek -i "$BG_VIDEO" -s $VIDSIZE -vframes 1 \
3976
-    -an $bg_post_seek -f image2 -y "$WORK_DIR/pics/template.$IMG_FMT")
3977
-    echo -e "\nRunning: "${FFMPEG_CMD[@]}"\n" | fold -bs >> "$LOG_FILE"
3978
+    FFMPEG_CMD=($FFmpeg $bg_pre_seek -i "$BG_VIDEO" $VF scale=$VF_SCALE \
3979
+    -an $bg_post_seek -f image2 -vframes 1 -y "$WORK_DIR/pics/template.$IMG_FMT")
3980
+    #echo -e "\nRunning: "${FFMPEG_CMD[@]}"\n" | fold -bs >> "$LOG_FILE"
3981
+    print2log "Running ${FFMPEG_CMD[@]}"
3982
     SED_VAR="frame="
3983
-    if ! "${FFMPEG_CMD[@]}" 2>&1 |strings  >> "$LOG_FILE";then
3984
+    "${FFMPEG_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
3985
+    if ((${PIPESTATUS[0]} != 0)); then
3986
         runtime_error "Problem creating images from the video."
3987
     fi
3988
+    echo | tee -a "$LOG_FILE"
3989
 fi
3990
-if $SHOWCASE && ($SC_THUMB || $QUICK_MENU); then
3991
-    if [[ $SC_TITLE_ALIGN = "east" ]] && ! $TEXTMENU; then
3992
-        TS="+ ${THUMB_SIZE/x*}"
3993
-    else
3994
-        TS=0
3995
-    fi
3996
-    if (( (WIDEST_TITLE + SAFE_AREA + TS + \
3997
-      ${SHOWCASE_SIZE/x*}) > ( ${VIDSIZE/x*} - SAFE_AREA) )); then
3998
+if $SHOWCASE && { $SC_THUMB || $QUICK_MENU ; }; then
3999
+    #if [[ $SC_TITLE_ALIGN = "east" ]] && ! $TEXTMENU; then
4000
+    #    TS=${THUMB_SIZE/x*}
4001
+    #else
4002
+    #    TS=0
4003
+    #fi
4004
+    if ((V_TOTAL > SPLIT)); then
4005
             SHOWCASE_SIZE=$SM_SHOWCASE_SIZE
4006
     fi
4007
     if $TEXTMENU && [[ -n $tt_ygeos_col2 ]]; then
4008
         SHOWCASE_SIZE=$SM_SHOWCASE_SIZE
4009
     fi
4010
+    # make mask for showcase shape, now that the showcase size is set
4011
+    if [[ -n $SHOWCASE_SHAPE ]]; then
4012
+        MASK="$WORK_DIR/${SHOWCASE_SHAPE}_mask.png"
4013
+        make_mask $SHOWCASE_SHAPE showcase
4014
+        convert "$MASK" -resize ${SHOWCASE_SIZE}! "$MASK"
4015
+        SHOWCASE_MASK="$MASK"
4016
+    fi
4017
 
4018
     if $SHOWCASE_3D && [[ -n $SHOWCASE_SHAPE ]]; then
4019
         CURVE_VARS="5 3 5 1 1"
4020
@@ -5615,7 +6322,8 @@
4021
         if $SWITCHED && $USER_THUMBS; then
4022
             echo "Using supplied image for showcased thumb"
4023
         else
4024
-            echo "Getting video images from $SHOWCASE_VIDEO"
4025
+            ! $QUICK_MENU && \
4026
+              yecho "Getting showcase video images from $SHOWCASE_VIDEO"
4027
         fi
4028
         if [[ "$SC_FRAMESTYLE" = "glass" ]]; then
4029
             # some vars for get_framed_pics function
4030
@@ -5626,10 +6334,10 @@
4031
             FRAME_SIZE=$SHOWCASE_SIZE
4032
             MPLAYER_SEEK_VAL=$SHOWCASE_SEEK_VAL
4033
             $SWITCHED && MPLAYER_SEEK_VAL=${SEEK_VAL[MENU_NUM-1]}
4034
-            echo "Using mplayer to get framed images from the showcase video"
4035
+            yecho "Using mplayer to get framed images from the showcase video"
4036
             get_framed_pics "$SHOWCASE_VIDEO" >> "$LOG_FILE" 2>&1
4037
             largest_img=$(get_largest 8 30 )
4038
-            mv -v "$largest_img" "$OUT"
4039
+            mv "$largest_img" "$OUT"
4040
             rm -f "$WORK_DIR"/00000*.png
4041
             convert "$WORK_DIR/showcase_img.png" \
4042
             -background none $ROTATE $WAVE miff:-|
4043
@@ -5650,13 +6358,13 @@
4044
                 convert ${USER_PICS[MENU_NUM-1]} -resize $SHOWCASE_SIZE \
4045
                 "$WORK_DIR/showcase_img.png"
4046
             else
4047
-                FFMPEG_CMD=(ffmpeg $ffm_pre_seek -i "$SHOWCASE_VIDEO" \
4048
-                -s $SHOWCASE_SIZE -an $ffm_post_seek -vframes 1 -f image2 -y \
4049
-                "$WORK_DIR/showcase_img.png")
4050
-                echo -e "\nRunning: "${FFMPEG_CMD[@]}"\n" | fold -bs \
4051
-                  |tee -a "$LOG_FILE"
4052
+                FFMPEG_CMD=($FFmpeg $ffm_pre_seek -i "$SHOWCASE_VIDEO" \
4053
+                $VF scale=${SHOWCASE_SIZE%x*}:${SHOWCASE_SIZE#*x} -an \
4054
+                $ffm_post_seek -f image2 -y -vframes 1 "$WORK_DIR/showcase_img.png")
4055
+                print2log "Running: ${FFMPEG_CMD[@]}"
4056
                 SED_VAR="frame="
4057
-                if ! "${FFMPEG_CMD[@]}" 2>&1 | strings >> "$LOG_FILE";then
4058
+                "${FFMPEG_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
4059
+                if ((${PIPESTATUS[0]} != 0)); then
4060
                     runtime_error "Problem creating images from the video."
4061
                 fi
4062
             fi
4063
@@ -5682,6 +6390,7 @@
4064
         else
4065
             SHAPE_CMD=(convert -size  $SHOWCASE_SIZE "$SHOWCASE_IMG" \
4066
             -resize $SHOWCASE_SIZE! $SHOWCASE_FRAME $SC_RAISE)
4067
+            print2log "Running ${SHAPE_CMD[@]}"
4068
         fi
4069
         "${SHAPE_CMD[@]}" miff:- |
4070
         "${sc_3d_cmd[@]}" miff:- |
4071
@@ -5698,6 +6407,7 @@
4072
 
4073
 # create the preview images
4074
 if ! $TEXTMENU && ! $SINGLE_SLIDESHOW && $DO_MENU && ! $USER_THUMBS; then
4075
+    print2log "Getting images from your video(s) for the preview"
4076
     for ((i=0; i<=NUM_FILES; i++)) ; do
4077
         # fast seek disabled by default
4078
         if $FAST_SEEK; then
4079
@@ -5711,13 +6421,13 @@
4080
         SV=${SEEK_VAL[i]}; CURFILE="${IN_FILES[i]##*/}"
4081
         spin "[$((i + 1)) of ${#FILES[@]}] Seeking to $SV seconds in $CURFILE"
4082
 
4083
-        FFMPEG_CMD=(ffmpeg $fmt $ffm_pre_seek -i "${IN_FILES[i]}" -an \
4084
+        FFMPEG_CMD=($FFmpeg $fmt $ffm_pre_seek -i "${IN_FILES[i]}" -an \
4085
         $ffm_postseek -f image2 -vframes $V_FRAMES \
4086
-        -s $THUMB_SIZE -y $WORK_DIR/pics/$i/%06d.$IMG_FMT)
4087
+        $VF scale=${THUMB_SIZE%x*}:${THUMB_SIZE#*x} -y $WORK_DIR/pics/$i/%06d.$IMG_FMT)
4088
         CMD=( "${FFMPEG_CMD[@]}" )
4089
         SED_VAR="frame="
4090
         ! [[ "$SC_FRAMESTYLE" = "glass" ]] \
4091
-        && echo -e "\nRunning: "${CMD[@]}"\n" | fold -bs >> "$LOG_FILE"
4092
+        && print2log "Running: ${CMD[@]}"
4093
         # some vars for get_framed_pics function
4094
         VOUT="png:z=7"; FRAMES=30
4095
         FRAME_SIZE=$THUMB_SIZE
4096
@@ -5730,14 +6440,14 @@
4097
             mv -f $largest_img "$WORK_DIR/pics/$i/$(printf "%06d%s" 0 .$IMG_FMT)"
4098
             rm -f "$WORK_DIR"/000*[0-9].png
4099
         elif [ "$SC_FRAMESTYLE" = "none" ]; then
4100
-            if ! "${FFMPEG_CMD[@]}" 2>&1 |strings >> "$LOG_FILE";then
4101
+            "${FFMPEG_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/} 2>&1
4102
+            if ((${PIPESTATUS[0]} != 0)); then
4103
                 runtime_error "Problem creating images from the video."
4104
             fi
4105
             
4106
             # get largest image of 9 if static menu and -frame-safe
4107
-            if $FRAME_SAFE; then #FIXME $STATIC not necessary, this is a preview!
4108
+            if $FRAME_SAFE; then
4109
                 largest_img=$(get_largest 6 $V_FRAMES "$WORK_DIR/pics/$i")
4110
-                echo Using $largest_img for menu >2&
4111
                 mv -f "$largest_img" "$WORK_DIR/pics/largest.$IMG_FMT"
4112
                 rm -f "$WORK_DIR"/pics/$i/*.$IMG_FMT
4113
                 mv  "$WORK_DIR/pics/largest.$IMG_FMT" \
4114
@@ -5746,21 +6456,21 @@
4115
         fi
4116
 
4117
         wait
4118
-        unset NAVSEEK_CMD rectangle run_transcode FFMPEG_CMD TRANSCODE_CMD
4119
+        unset NAVSEEK_CMD rectangle FFMPEG_CMD TRANSCODE_CMD
4120
     done
4121
     echo
4122
 fi
4123
 # for user supplied thumbs, resize and copy to appropriate directories
4124
-if ! $SWITCHED; then
4125
+if ! $SWITCHED && $USER_THUMBS; then
4126
     for i in ${!USER_PICS[@]}; do
4127
         convert "${USER_PICS[i]}" -resize $THUMB_SIZE \
4128
         "$WORK_DIR/pics/$i/000001.$IMG_FMT"
4129
     done
4130
 fi
4131
-# overlay menu title and thumb titles on template
4132
+# overlay menu title and video titles on template
4133
 if $MIST; then
4134
     # overlay white.png onto background
4135
-    echo "Overlaying the text mist on the background"
4136
+    print2log "Overlaying the text mist on the background"
4137
     composite -dissolve $MIST_OPACITY -gravity $TITLE_GRAVITY \
4138
     -geometry ${mist_xoffset}${mist_yoffset} \
4139
     "$WORK_DIR/white.png" "$WORK_DIR/pics/template.png" \
4140
@@ -5771,10 +6481,10 @@
4141
         sc_thumb_title_cmd=( "${sc_thumb_title_cmd[@]}" \
4142
         "${THUMBTITLES_ARRAY[i]}" "$WORK_DIR/thumb_title${i}.png")
4143
     done
4144
-    echo "Running:
4145
-    convert  -size $VIDSIZE -background none "$WORK_DIR/pics/template.png"
4146
-    ${sc_thumb_title_cmd[@]} -page +210+400 "$WORK_DIR/title_txt.png" \
4147
-    -mosaic "$WORK_DIR/pics/template.png" "| format_output >> "$LOG_FILE"
4148
+    print2log "Running \
4149
+    convert  -size $VIDSIZE -background none $WORK_DIR/pics/template.png \
4150
+    ${sc_thumb_title_cmd[@]} -page +210+400 $WORK_DIR/title_txt.png \
4151
+    -mosaic $WORK_DIR/pics/template.png"
4152
     convert -size $VIDSIZE -background none "$WORK_DIR/pics/template.png" \
4153
     ${sc_thumb_title_cmd[@]} -mosaic "$WORK_DIR/pics/template.png"
4154
     convert "$WORK_DIR/pics/template.png" "$WORK_DIR/title_txt.png" \
4155
@@ -5790,7 +6500,7 @@
4156
 
4157
 # copy the preview for -quick-menu
4158
 if $QUICK_MENU && [[ -s "$WORK_DIR/showcase_img.png" ]]; then
4159
-    cp -v "$WORK_DIR/pics/template.png" "$WORK_DIR/quick_menu_bg.png"
4160
+    cp "$WORK_DIR/pics/template.png" "$WORK_DIR/quick_menu_bg.png"
4161
 fi
4162
 
4163
 # lets be sure of order by using a loop
4164
@@ -5887,8 +6597,7 @@
4165
 ##############################################################################
4166
 
4167
 if $DO_BUTTONS; then
4168
-    echo
4169
-    echo "Creating the highlight and selection PNGs for the main menu"
4170
+    print2log "Creating the highlight and selection PNGs for the main menu"
4171
     if [ "$BUTTON_STYLE" = "rect" ]; then
4172
         MENU_BUTTON_SIZE=$THUMB_SIZE
4173
         get_button_geo
4174
@@ -6152,7 +6861,7 @@
4175
             # make sure coordinates are even
4176
             ((X0%2 && X0--)); ((Y0%2 && Y0--))
4177
             ((X1%2 && X1++)); ((Y1%2 && Y1++))
4178
-            button_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\") #FIXME
4179
+            button_geos=(x0=\"$X0\" y0=\"$Y0\" x1=\"$X1\" y1=\"$Y1\")
4180
             btn_geos[i]=${button_geos[@]}
4181
             unset button_geos
4182
             echo \
4183
@@ -6277,7 +6986,6 @@
4184
         echo text ${i},20 \'$i\'
4185
     done >> "$WORK_DIR/grid2.mvg"
4186
 fi
4187
-
4188
 if $SHOWCASE && $DO_MENU; then
4189
     if $SC_THUMB; then
4190
         # find out where to put the showcase image/video in the X axis
4191
@@ -6287,40 +6995,65 @@
4192
     fi
4193
     $QUICK_MENU && \
4194
     sc_width=${SHOWCASE_SIZE/x*} && sc_height=${SHOWCASE_SIZE/*x}
4195
-    if $SC_THUMB || $QUICK_MENU; then #&& ! $TEXTMENU; then
4196
+    if $SC_THUMB || $QUICK_MENU; then
4197
         if [[ "$SC_TITLE_ALIGN" = "center" ]]; then
4198
-            if [[ $WIDEST_TITLE -ge ${THUMB_SIZE/x*} ]]; then
4199
-                BUTTON_COLUMN1=$(((${THUMB_SIZE/x*} / 2) + (WIDEST_TITLE / 2)))
4200
+            if [[ $widest_title -ge ${THUMB_SIZE/x*} ]]; then
4201
+                BUTTON_COLUMN1=$(((${THUMB_SIZE/x*} / 2) + (widest_title / 2)))
4202
             else
4203
                 BUTTON_COLUMN1=${THUMB_SIZE/x*}
4204
             fi
4205
         elif [[ "$SC_TITLE_ALIGN" = "west" ]]; then
4206
-            if [[ $WIDEST_TITLE -ge ${THUMB_SIZE/x*} ]]; then
4207
-                BUTTON_COLUMN1=$((WIDEST_TITLE + 5))
4208
+            if [[ $widest_title -ge ${THUMB_SIZE/x*} ]]; then
4209
+                BUTTON_COLUMN1=$((widest_title + 5))
4210
             else
4211
                 BUTTON_COLUMN1=${THUMB_SIZE/x*}
4212
             fi
4213
         elif [[ "$SC_TITLE_ALIGN" = "east" ]]; then
4214
-            BUTTON_COLUMN1=$(( ${THUMB_SIZE/x*} + WIDEST_TITLE ))
4215
+            BUTTON_COLUMN1=$(( ${THUMB_SIZE/x*} + widest_title ))
4216
         fi
4217
-        if ! $TEXTMENU; then
4218
-        sc_space=$((${VIDSIZE%x*} - \
4219
-            ${SC_THUMB_X_ARRAY[0]} - BUTTON_COLUMN1 - SAFE_AREA))
4220
-        SC_X=$(( ${SC_THUMB_X_ARRAY[0]} + BUTTON_COLUMN1 \
4221
-            + (sc_space / 2) - (sc_width / 2) ))
4222
-        else
4223
-            BUTTON_COLUMN1=$((WIDEST_TITLE + 5))
4224
+        # work out the general position of the showcase image
4225
+        # these will be modified later according to -align options
4226
+        # TODO it's already consolidated, now split in 1 vs 2 column if/else
4227
+        if $TEXTMENU; then
4228
+            # this is the default, *west aligned, for one column textmenu
4229
+            BUTTON_COLUMN1=$((widest_title + 5))
4230
             sc_space=$((${VIDSIZE%x*} - \
4231
                 ${SC_TITLES_X_ARRAY[0]} - BUTTON_COLUMN1 - SAFE_AREA))
4232
             SC_X=$(( ${SC_TITLES_X_ARRAY[0]} + BUTTON_COLUMN1 \
4233
             + (sc_space / 2) - (sc_width / 2) ))
4234
             if [[ $BUTTON_GRAVITY = *east* ]]; then
4235
-                BUTTON_COLUMN1=$WIDEST_TITLE
4236
+                BUTTON_COLUMN1=$widest_title
4237
                 sc_space=$((${VIDSIZE%x*} - (SAFE_AREA * 2) - BUTTON_COLUMN1))
4238
                 SC_X=$((SAFE_AREA + (sc_space / 2) - (sc_width / 2) ))
4239
             fi
4240
+            center_showcase_pos=$(( (${VIDSIZE/x*} / 2) - (sc_width / 2) ))
4241
+            # this next block is *east or *west for 2 columns, and N|S|Center
4242
+            case $BUTTON_GRAVITY in
4243
+              *east|*west)
4244
+                # for 2 columns the showcase thumb will always be centered
4245
+                [[ -n $tt_ygeos_col2 ]] && SC_X=$center_showcase_pos
4246
+                ;;
4247
+              north|south|center)
4248
+                # for centered 1 column the showcase has no room, so center it
4249
+                # these -align args have no effect on 2 column titles position
4250
+                SC_X=$center_showcase_pos
4251
+                ;;
4252
+            esac
4253
+        else
4254
+            sc_space=$((${VIDSIZE%x*} - \
4255
+            ${SC_THUMB_X_ARRAY[0]} - BUTTON_COLUMN1 - SAFE_AREA))
4256
+            SC_X=$(( ${SC_THUMB_X_ARRAY[0]} + BUTTON_COLUMN1 \
4257
+            + (sc_space / 2) - (sc_width / 2) ))
4258
+            if ((V_TOTAL > 5)); then
4259
+                # for 2 columns just center the thumb between edges of columns
4260
+                inner_edge_col1=$(( ${SC_THUMB_X_ARRAY[0]} + ${THUMB_SIZE/x*} ))
4261
+                inner_edge_col2=${SC_THUMB_X_ARRAY[SPLIT]}
4262
+                canvas=$(( (inner_edge_col2 - inner_edge_col1) / 2 ))
4263
+                canvas=$(( inner_edge_col1 + canvas ))
4264
+                SC_X=$(( canvas - (sc_width / 2) ))
4265
+            fi
4266
         fi
4267
-        # find out where to put the showcase image in the Y axis
4268
+        # work out the position of the showcase image in the Y axis
4269
         if ! $TEXTMENU; then
4270
             Y1=${SC_THUMB_Y_ARRAY[0]}
4271
             Y2=${SC_THUMB_Y_ARRAY[NUM_FILES]}
4272
@@ -6343,18 +7076,16 @@
4273
 
4274
         fi
4275
 
4276
-        ! $TEXTMENU && [[ $V_TOTAL -gt 5 ]] && \
4277
-        SC_X=$(( ( ${VIDSIZE/x*} / 2 ) - (sc_width / 2) ))
4278
-        $TEXTMENU && [[ -n $tt_ygeos_col2 ]] \
4279
-        && SC_X=$(( ( ${VIDSIZE/x*} / 2 ) - (sc_width / 2) ))
4280
-        $USER_SC_GEO && SC_X=${SHOWCASE_GEO/x*}
4281
-        $USER_SC_GEO && SC_Y=${SHOWCASE_GEO/*x}
4282
-
4283
         # make sure its divisible by 2 for ffmpeg's padding with -quick-menu
4284
         if $QUICK_MENU; then
4285
             SC_Y=$(( (SC_Y /2) * 2 ))
4286
             SC_X=$(( (SC_X / 2) * 2 ))
4287
         fi
4288
+        # finally if user passes in a prefered location for showcase, use it
4289
+        $USER_SC_GEO && SC_X=$(awk -F+ '{print $2}' <<< $SHOWCASE_GEO)
4290
+        $USER_SC_GEO && SC_Y=$(awk -F+ '{print $3}' <<< $SHOWCASE_GEO)
4291
+
4292
+        # make the -page part of the IM command for the showcase image
4293
         SC_IMG_PAGE="-page +$SC_X+$SC_Y"
4294
         SC_IMG_CMD="$SC_IMG_PAGE "$WORK_DIR/showcase_img.png""
4295
     fi
4296
@@ -6376,15 +7107,15 @@
4297
             IM_CMD3=(convert - -background none $WORK_DIR/title_txt.png  \
4298
             -gravity $TITLE_GRAVITY -geometry \
4299
             ${title_xoffset}${title_yoffset} -composite "$PREVIEW_IMG" )
4300
-            echo "Running ${IM_CMD0[@]} miff:- | ${IM_CMD1[@]} miff:- |
4301
-            ${IM_CMD2[@]} miff:- | ${IM_CMD3[@]}" |format_output >> "$LOG_FILE"
4302
+            print2log "Running ${IM_CMD0[@]} miff:- | ${IM_CMD1[@]} miff:- | \
4303
+            ${IM_CMD2[@]} miff:- | ${IM_CMD3[@]}"
4304
             "${IM_CMD0[@]}" miff:- | "${IM_CMD1[@]}" miff:- |
4305
             "${IM_CMD2[@]}" miff:- | "${IM_CMD3[@]}"
4306
         else
4307
             IM_CMD=(convert  -size $VIDSIZE "$WORK_DIR/pics/template.png" \
4308
             -background none ${sc_cmd[@]} $SC_IMG_CMD \
4309
             -mosaic "$PREVIEW_IMG")
4310
-            echo "Running ${IM_CMD[@]}" |format_output >> "$LOG_FILE"
4311
+            print2log "Running ${IM_CMD[@]}"
4312
             "${IM_CMD[@]}"
4313
         fi
4314
         unset sc_cmd IM_CMD05 IM_CMD04 IM_CMD03 IM_CMD4
4315
@@ -6400,8 +7131,7 @@
4316
         IM_CMD3=(convert - -background none "$WORK_DIR/title_txt.png"  \
4317
         -gravity $TITLE_GRAVITY -geometry ${title_xoffset}${title_yoffset} \
4318
         -composite "$PREVIEW_IMG")
4319
-        echo "Running ${IM_CMD1[@]} | ${IM_CMD2[@]} | ${IM_CMD3[@]}" |
4320
-        format_output >> "$LOG_FILE"
4321
+        print2log "Running ${IM_CMD1[@]} | ${IM_CMD2[@]} | ${IM_CMD3[@]}"
4322
         "${IM_CMD1[@]}" | "${IM_CMD2[@]}" | "${IM_CMD3[@]}"
4323
     else # Not transparent
4324
         IM_CMD1=(montage ${PICS[@]} $MTG_FRM -tile ${TILE_ARRAY[NUM_FILES]} \
4325
@@ -6411,8 +7141,7 @@
4326
         "$WORK_DIR/title_txt.png" -gravity $TITLE_GRAVITY \
4327
         -geometry ${title_xoffset}${title_yoffset} -composite - -gravity \
4328
         $BUTTON_GRAVITY -geometry +${XGEO}+${YGEO} -composite "$PREVIEW_IMG")
4329
-        echo "Running ${IM_CMD1[@]} | ${IM_CMD1[@]}" |
4330
-        format_output >> "$LOG_FILE"
4331
+        print2log "Running ${IM_CMD1[@]} | ${IM_CMD2[@]}"
4332
         "${IM_CMD1[@]}" | "${IM_CMD2[@]}"
4333
     fi
4334
 fi
4335
@@ -6424,7 +7153,7 @@
4336
     IM_CMD2=(convert - -background none "$WORK_DIR/title_txt.png" \
4337
     -gravity $TITLE_GRAVITY -geometry ${title_xoffset}${title_yoffset} \
4338
     -composite "${add_playbtn[@]}" "$PREVIEW_IMG" )
4339
-    echo "Running ${IM_CMD1[@]} | ${IM_CMD1[@]}" | format_output >> "$LOG_FILE"
4340
+    print2log "Running ${IM_CMD1[@]} | ${IM_CMD2[@]}"
4341
     "${IM_CMD1[@]}" | "${IM_CMD2[@]}"
4342
 fi
4343
 # if there is quickmenu bg, cut out transparent hole for showcase image/video
4344
@@ -6436,8 +7165,8 @@
4345
         # make a similar framed blank to composite onto the background
4346
         frame_cmd=(convert -size $SHOWCASE_SIZE xc:black \
4347
         $SHOWCASE_FRAME "$WORK_DIR/showcase_frame.png")
4348
-        yecho "Running ${frame_cmd[@]}" | format_output >> "$LOG_FILE"
4349
-        "${frame_cmd[@]}" >> "$LOG_FILE"
4350
+        print2log "Running ${frame_cmd[@]}"
4351
+        "${frame_cmd[@]}" | pipe2log convert
4352
         # composite the framed blank onto background subtracting the width \
4353
         # of the frame (border) when calculating XxY geometry
4354
         convert "$WORK_DIR/pics/template.png" \
4355
@@ -6471,7 +7200,7 @@
4356
     echo "(Press 'q' or ESC in the preview window to close it.)"
4357
 fi
4358
 # make the fake montage with highlighted 1st button and display it
4359
-if $DO_MENU && ! $SINGLE_SLIDESHOW; then #FIXME ?
4360
+if $DO_MENU && ! $SINGLE_SLIDESHOW; then
4361
     composite -compose Over "$WORK_DIR/fake_montage.png" \
4362
       "$PREVIEW_IMG" "$PREVIEW_IMG"
4363
 fi
4364
@@ -6526,7 +7255,7 @@
4365
 if [[ -n "$BG_AUDIO" ]]; then
4366
     yecho "Getting length of bg audio"
4367
     $SINGLE_SLIDESHOW && end_pos="" || end_pos=${MENU_LEN[MENU_NUM-1]}
4368
-    BG_AUDIOLENGTH=$(audio_length "$BG_AUDIO")
4369
+    BG_AUDIOLENGTH=$(stream_length "$BG_AUDIO" audio)
4370
 
4371
     # make sure user isn't trying to get a longer menu than the audio allows
4372
     if [[ $(bc <<< "${MENU_LEN[MENU_NUM-1]} \
4373
@@ -6571,7 +7300,6 @@
4374
 # to make sure files get symlinked properly (Hack)
4375
 if [[ $MENU_NUM = [1-2] || -n ${file_is_image[@]}  ]]; then
4376
     if ! $MK_CAROUSEL_MODE; then
4377
-        echo
4378
         check_compliance
4379
         $GROUPING && check_compliance group
4380
     fi
4381
@@ -6598,7 +7326,6 @@
4382
         done
4383
     fi
4384
 fi
4385
-echo
4386
 
4387
 # animated slideshows join the slides and can add audio (-bgaudio)
4388
 if $DO_CAROUSEL && ! $USE_DVD_SLIDESHOW; then
4389
@@ -6611,9 +7338,8 @@
4390
             fi
4391
         done
4392
     done
4393
-    IMGENC_CMD=(ffmpeg -f yuv4mpegpipe -r $FRAME_RATE -i - -s $VIDSIZE \
4394
-    $SS_FFMOPTS -r $FRAME_RATE -bf 2 -y "$WORK_DIR/slideshow.m2v")
4395
-    echo
4396
+    IMGENC_CMD=($FFmpeg -f yuv4mpegpipe -i - $VF scale=${VF_SCALE},${ASPECT} \
4397
+    $SS_FFMOPTS -r $ff_frame_rate -bf 2 -y "$WORK_DIR/slideshow.m2v")
4398
     for p in ${!MIX_IN[@]}; do
4399
         if [[ "${F2BIN[p]}" = "yes" ]]; then
4400
             BINNING_CMD=(convert "${MIX_IN[p]}" -depth 8 \
4401
@@ -6650,11 +7376,14 @@
4402
             MIX_IN[p]="$WORK_DIR/${p}.ppm"
4403
         fi
4404
     done
4405
-    echo
4406
+    printf "\n\n" | tee -a "$LOG_FILE"
4407
     sstime1=$(date +%s)
4408
     # make a fifo to send raw yuv to, to be encoded by ffmpeg
4409
     mkfifo "$WORK_DIR/ppm.fifo"
4410
-    "${IMGENC_CMD[@]}" 2>/dev/null < "$WORK_DIR/ppm.fifo" &
4411
+    print2log "Running ${IMGENC_CMD[@]}"
4412
+    "${IMGENC_CMD[@]}" < "$WORK_DIR/ppm.fifo" 2>&1 | \
4413
+      pipe2log ${FFmpeg##*/} &
4414
+    #"${IMGENC_CMD[@]}" 2>/dev/null < "$WORK_DIR/ppm.fifo" &
4415
     encpids="$encpids $!"
4416
     #exec 3> "$WORK_DIR/ppm.fifo"
4417
 
4418
@@ -6697,20 +7426,20 @@
4419
         fi
4420
         # encode still frames
4421
         # need yuvcorrect if for fade style (remove headers)
4422
-        [[ $EFFECT = "fade" ]] && YUVCORRECT="yuvcorrect -T NO_HEADER"
4423
+        [[ $EFFECT = "fade" ]] && YUVCORRECT="$yuv_correct"
4424
         if [[ $EFFECT = "crossfade" ]]; then
4425
             # encoding 1st slide
4426
             if ((f==0)); then
4427
                 YUVCORRECT="cat"
4428
             else # subsequent slides and fades need header removed
4429
-                YUVCORRECT="yuvcorrect -T NO_HEADER"
4430
+                YUVCORRECT="$yuv_correct"
4431
             fi
4432
         fi
4433
         spin "Doing stills for slide $((f+1))" >&2
4434
         "${TOYUV_STILLS_CMD[@]}" "${MIX_IN[f]}" 2>/dev/null |
4435
         $YUVCORRECT 2> /dev/null
4436
         # now we need yuvcorrect for everything
4437
-        YUVCORRECT="yuvcorrect -T NO_HEADER"
4438
+        YUVCORRECT="$yuv_correct"
4439
         # do a transition to the next slide
4440
         [[ $EFFECT = "fade" ]] && fadetype=fadeout || fadetype="crossfade"
4441
         spin "Doing $fadetype for slide $((f+1))" >&2
4442
@@ -6753,28 +7482,28 @@
4443
     if $MK_CAROUSEL_MODE; then
4444
         # move the m2v to BASEDIR (basedir of -carousel_menu_mode)
4445
         echo
4446
-        mv -v "$WORK_DIR/slideshow.m2v" "$BASEDIR/carousel-${CAROUSEL_NUM}.m2v"
4447
+        mv "$WORK_DIR/slideshow.m2v" "$BASEDIR/carousel-${CAROUSEL_NUM}.m2v"
4448
         cleanup
4449
         exit 0
4450
     fi
4451
 
4452
     # get length
4453
-    bgaudio_time=$(vid_length "$WORK_DIR/slideshow.m2v")
4454
+    bgaudio_time=$(stream_length "$WORK_DIR/slideshow.m2v" m2v)
4455
 
4456
     if [[ -n $BG_AUDIO ]]; then
4457
         # convert background audio to wav
4458
-        BGAUDIO_CMD=(ffmpeg -i "$BG_AUDIO" -t $bgaudio_time -ar 48000 \
4459
+        BGAUDIO_CMD=($FFmpeg -i "$BG_AUDIO" -t $bgaudio_time -ar 48000 \
4460
          -acodec pcm_s16le -y $WORK_DIR/slideshow.wav)
4461
     else
4462
         # generate silence
4463
-        BGAUDIO_CMD=(ffmpeg -f s16le -ar 48000 -t $bgaudio_time -i /dev/zero
4464
-        -ar 48000 -ac 2 -acodec pcm_s16le -y $WORK_DIR/slideshow.wav)
4465
+        BGAUDIO_CMD=($FFmpeg -f s16le -ar 48000 -i /dev/zero -ar 48000 \
4466
+        -ac 2 -t $bgaudio_time -acodec pcm_s16le -y $WORK_DIR/slideshow.wav)
4467
     fi
4468
     echo
4469
-    echo "Encoding audio to wav with: ${BGAUDIO_CMD[@]}" | format_output |
4470
-    tee -a "$LOG_FILE"
4471
+    echo "Encoding audio to wav with: ${BGAUDIO_CMD[@]}" | format_output | \
4472
+    pipe2log
4473
     echo
4474
-    "${BGAUDIO_CMD[@]}" >> "$LOG_FILE" 2>&1
4475
+    "${BGAUDIO_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
4476
     # fade wav if background audio used and user did not disable fading
4477
     if [[ -n $BG_AUDIO ]] && $AUDIO_FADE; then
4478
         sox "$WORK_DIR/slideshow.wav" "$WORK_DIR/slideshow-faded.wav" \
4479
@@ -6784,20 +7513,17 @@
4480
     fi
4481
 
4482
     # convert the wav to target format
4483
-    echo
4484
     echo "Converting wav to $TARGET format"
4485
-    BGAUDIO_CMD=(ffmpeg -i "$WORK_DIR/slideshow.wav" \
4486
-     $AUDIO_OPTS -y "$WORK_DIR/slideshow.ac3")
4487
-    echo "Runnning ${BGAUDIO_CMD[@]}" | tee -a "$LOG_FILE"
4488
-    "${BGAUDIO_CMD[@]}" | format_output >> "$LOG_FILE" 2>&1
4489
     echo
4490
+    BGAUDIO_CMD=($FFmpeg -i "$WORK_DIR/slideshow.wav" \
4491
+     $AUDIO_OPTS -y "$WORK_DIR/slideshow.ac3")
4492
+    print2log "Runnning ${BGAUDIO_CMD[@]}"
4493
+    "${BGAUDIO_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
4494
     # multiplex to mpeg-2 ( svcd or dvd )
4495
     MPLEX_CMD=(mplex -V -f $MPLEX_FORMAT -o "$WORK_DIR/slideshow.mpg" \
4496
     "$WORK_DIR/slideshow.$AUDIO_EXT" "$WORK_DIR/slideshow.m2v")
4497
-    yecho
4498
-    echo "Running ${MPLEX_CMD[@]}" |format_output |tee -a "$LOG_FILE"
4499
-    "${MPLEX_CMD[@]}" |format_output >> "$LOG_FILE" 2>&1
4500
-    yecho
4501
+    print2log "Running ${MPLEX_CMD[@]}"
4502
+    "${MPLEX_CMD[@]}" 2>&1 | pipe2log mplex
4503
     if [[ -s "$WORK_DIR/slideshow.mpg" ]]; then
4504
         mv "$WORK_DIR/slideshow.mpg" "$WORK_DIR/intro.mpg"
4505
     else
4506
@@ -6817,7 +7543,7 @@
4507
     "${SS_AUDIO[@]}" -f "$WORK_DIR/dvd-slideshow.conf"
4508
     mv "$WORK_DIR/slideshow.vob" "$WORK_DIR/intro.mpg"
4509
 fi
4510
-# check bgvideo and showcase VIDEO for compliance ( if present ) #FIXME
4511
+# check bgvideo and showcase VIDEO for compliance ( if present )
4512
 if [[ -n $BG_VIDEO && $BG_VIDEO = $BG_AUDIO ]]; then
4513
     # do not reencode animated slideshow made in MK_CAROUSEL_MODE
4514
     if ! [[ $BG_VIDEO = $WORK_DIR/carousel-00.m2v ]]; then
4515
@@ -6840,7 +7566,7 @@
4516
 
4517
 # symlink IN_FILES in $WORK_DIR to solve some quoting issues for dvdauthor
4518
 if [[ $MENU_NUM -eq 1 ]]; then
4519
-    yecho "Symlinking files to $WORK_DIR"
4520
+    print2log "Symlinking files to $WORK_DIR"
4521
     for i in ${!IN_FILES[@]}; do
4522
         if ! [[ -e $BASEDIR/${TSET_NUM}-$((i+1)).mpg ]]; then
4523
             (cd "$REAL_WORK_DIR" &&  ln -sf "${IN_FILES[i]}" \
4524
@@ -6851,8 +7577,9 @@
4525
 $SINGLE_SLIDESHOW && echo "Getting stats on the slides now"
4526
 for ((i=0; i<${#IN_FILES[@]}; i++)); do
4527
     if [[ $MENU_NUM -eq 1 ]]; then
4528
-        ! $SINGLE_SLIDESHOW && spin "Getting stats on ${IN_FILES[i]}"
4529
-        idvid_stats[i]=$(idvid -terse -accurate "${IN_FILES[i]}" 2>/dev/null)
4530
+        ! $SINGLE_SLIDESHOW && \
4531
+          spin "getting stats for the log" $SPINNER #on ${IN_FILES[i]##*/}"
4532
+        idvid_stats[i]=$(idvid -terse -accurate "${IN_FILES[i]}" 2> /dev/null)
4533
     fi
4534
     if [ -s  "${IN_FILES[i]}.nav_log" ]; then
4535
         length[i]=$(awk 'END{print NR}' "${IN_FILES[i]}.nav_log")
4536
@@ -6860,19 +7587,18 @@
4537
 done
4538
 
4539
 if $GROUPING &&  [[ $MENU_NUM -eq 1 ]]; then
4540
-    echo
4541
-    echo ". . . Getting stats on grouped files now . . ."
4542
-    echo
4543
+    print2log ". . . Getting stats on grouped files now . . ."
4544
     for u in ${!grouping[@]}; do
4545
         CUR_VID=$(readlink -f "${grouping[u]}")
4546
-        spin "Getting stats on "${CUR_VID##*/}""
4547
-        group_idvid_stats[u]=$(idvid -terse -accurate "$CUR_VID" 2>/dev/null)
4548
+        spin "Getting grouped video stats for the log on "${CUR_VID##*/}""
4549
+        group_idvid_stats[u]=$(idvid -terse -accurate "$CUR_VID" 2> /dev/null)
4550
         if [ -s "$CUR_VID.nav_log" ]; then
4551
             group_length[u]=$(awk 'END{print NR}' "$CUR_VID.nav_log")
4552
         fi
4553
     done
4554
     echo
4555
 fi
4556
+#echo -e "\nCheck the stats in todisc.log if you wish"
4557
 
4558
 # get length of videos in a separate loop from other stats
4559
 # if we are doing SVCD there will be no nav_seek file
4560
@@ -6880,8 +7606,8 @@
4561
     # if we have a non empty nav_log get the length from that
4562
     if [ -s "${IN_FILES[i]}".nav_log ]; then
4563
         VID_LEN[i]=$(bc_math "${length[i]} / $FRAME_RATE")
4564
-    else # otherwise, we run mencoder to get the length
4565
-        VID_LEN[i]=$(vid_length  "${IN_FILES[i]}" )
4566
+    else # otherwise, we run ffmpeg to get the length
4567
+        VID_LEN[i]=$(stream_length  "${IN_FILES[i]}" )
4568
     fi
4569
     if [[ ${VID_LEN[i]%.*} -lt ${SEEK_VAL[i]%.*} ]]; then
4570
         usage_error "A seek of ${SEEK_VAL[i]} seconds is too large for
4571
@@ -6907,14 +7633,14 @@
4572
     # if we have a value for ${group_length[g]}  get the length from that
4573
     if [[ -n "${group_length[g]}" ]]; then
4574
         GROUP_VID_LEN[g]=$(bc_math "${group_length[g]} / $FRAME_RATE")
4575
-    else # otherwise, we run mencoder to get the length
4576
-        GROUP_VID_LEN[g]=$(vid_length "${grouping[g]}")
4577
+    else # otherwise, we run stream_length to get the length
4578
+        GROUP_VID_LEN[g]=$(stream_length "${grouping[g]}")
4579
     fi
4580
 done
4581
 if $GROUPING; then
4582
     index=0
4583
     for i in "${!IN_FILES[@]}"; do
4584
-        if [[ ${GROUP[i]} ]]; then
4585
+        if [[ ${GROUP_ARR[i]} ]]; then
4586
             iter=( $BASEDIR/${TSET_NUM}-group-$((i+1))-*.mpg )
4587
             for ((t=index; t<index+${#iter[@]}; t++)); do
4588
                 # get lengths of group videos also in a seperate loop
4589
@@ -6941,20 +7667,19 @@
4590
 # put in the log file in case anyone is interested
4591
 if ! $VMGM_ONLY &&  [[ $MENU_NUM -eq 1 ]] && $DO_STATS; then
4592
     get_stats files
4593
-    echo
4594
+    print2log ""
4595
 fi
4596
 if ! $VMGM_ONLY &&  [[ $MENU_NUM -eq 1 ]] && $GROUPING && $DO_STATS; then
4597
     get_stats group
4598
-    echo; echo $SEPARATOR
4599
+    print2log ""
4600
 fi
4601
-echo
4602
 
4603
 # run quick_menu to create an almost finished menu file ( intro.m2v )
4604
 $QUICK_MENU && quick_menu
4605
 # if doing switched menus, use the bgaudio from each video
4606
 # unless "none" is passed for -bgaudio
4607
 if $SWITCHED; then
4608
-    yecho
4609
+    yecho ""
4610
     let vid=MENU_NUM-1
4611
     SHOWCASE_SEEK_VAL=${SEEK_VAL[vid]}
4612
     # use silence if a short file ( probably a slide ) and no background audio
4613
@@ -6993,10 +7718,9 @@
4614
                 # the menu audio will be the same length as the switched video
4615
             fi
4616
             yecho "Using audio from "${FILES[vid]}" for the audio background,"
4617
-            ! $STATIC && yecho \
4618
-            "using the same seek value for the audio as the video"
4619
-            yecho "If you wish to use silence for the switched menu,"
4620
-            yecho "use '-bgaudio none'"
4621
+            ! $STATIC && info_message "using the same seek value for the audio \
4622
+            as the video. If you wish to use silence for the switched menu,
4623
+            use '-bgaudio none'"
4624
         else
4625
             if [[ $BG_AUDIO = "none" ]]; then # no audio if -bgaudio none
4626
                 BG_AUDIO=""
4627
@@ -7010,7 +7734,7 @@
4628
             fi
4629
         fi
4630
     fi
4631
-    yecho
4632
+    yecho ""
4633
 fi
4634
 for ((i=0; i<${#VID_LEN[@]}; i++)); do
4635
     NEW_LENGTH=( ${NEW_LENGTH[@]}   ${VID_LEN[i]%.*} )
4636
@@ -7104,7 +7828,7 @@
4637
                   $WORK_DIR/pics/$i/$(printf "%06d%s" $p .png) 2>/dev/null
4638
             done
4639
         elif [[ ${file_is_image[i]} = "yes" ]]; then
4640
-            spin "Convert ${FILES[i]} to proper size/format"
4641
+            spin "Convert ${FILES[i]##*/} to proper size/format"
4642
             convert "${FILES[i]}" -depth 8 \
4643
               -resize ${THUMB_SIZE}! \
4644
               "$WORK_DIR/pics/$i/$(printf "%06d%s"  0 .${IMG_FMT})"
4645
@@ -7120,30 +7844,46 @@
4646
                 thumb_frames=$THUMB_FRAMES
4647
             fi
4648
             # warning to ignore transcode error messages
4649
-            print_tcode_info
4650
+            $use_transcode && print_tcode_info
4651
             if [ -s  "${IN_FILES[i]}.nav_log" ]; then
4652
                 NAV_SEEK[i]="--nav_seek"
4653
                 NAVSEEK[i]=${IN_FILES[i]}.nav_log
4654
             fi
4655
-            yuv_fifo="$WORK_DIR/pics/$i/out.yuv"
4656
-            log_tmp="$WORK_DIR/pics/$i/log.tmp"
4657
-            [[ ! -p "$yuv_fifo" ]] && mkfifo "$yuv_fifo"
4658
+            ff_log_tmp="$WORK_DIR/pics/$i/ff_log.tmp"
4659
+            tc_log_tmp="$WORK_DIR/pics/$i/tc_log.tmp"
4660
+            if $use_transcode; then
4661
+                vid_stream="$WORK_DIR/pics/$i/out.yuv"
4662
+                 [[ ! -p "$vid_stream" ]] && mkfifo "$vid_stream"
4663
+                ff_seek=""
4664
+                ff_frames=""
4665
+            else
4666
+                # using ffmpeg directly on file, PIPE_FORMAT not needed
4667
+                vid_stream="${IN_FILES[i]}"
4668
+                unset PIPE_FORMAT
4669
+                ff_seek="-ss ${SEEK_VAL[i]}"
4670
+                ff_frames="-vframes $thumb_frames"
4671
+            fi
4672
+
4673
             # resize using ffmpeg instead of transcode
4674
-            FFMPEG_CMD2=(ffmpeg $PIPE_FORMAT -i "$yuv_fifo" -f image2 -s $THUMB_SIZE -y \
4675
-            "$WORK_DIR/pics/$i/%06d.$IMG_FMT")
4676
+            FFMPEG_CMD2=($FFmpeg $PIPE_FORMAT -i "$vid_stream" $ff_seek \
4677
+            $ff_frames -f image2 $VF scale=${THUMB_SIZE%x*}:${THUMB_SIZE#*x} \
4678
+            -y "$WORK_DIR/pics/$i/%06d.$IMG_FMT")
4679
             TRANSCODE_CMD2=(transcode --progress_rate 10 \
4680
             --write_pid $WORK_DIR/tcode$i.pid -q 1 -i "${IN_FILES[i]}" \
4681
             -c ${SEEK_FRAMES[i]}-$((${SEEK_FRAMES[i]} + $thumb_frames)) \
4682
-            ${NAV_SEEK[i]} "${NAVSEEK[i]}" -o "$yuv_fifo" \
4683
+            ${NAV_SEEK[i]} "${NAVSEEK[i]}" -o "$vid_stream" \
4684
             -f $FRAME_RATE $EXPORT)
4685
-            yecho "Running ${TRANSCODE_CMD2[@]}" | fold -bs
4686
-            yecho "Running ${FFMPEG_CMD2[@]}" | fold -bs
4687
-            "${TRANSCODE_CMD2[@]}"  2>&1 | strings >> "$LOG_FILE" &
4688
-            "${FFMPEG_CMD2[@]}" > "$log_tmp" 2>&1 &
4689
+            if $use_transcode; then
4690
+                print2log "Running ${TRANSCODE_CMD2[@]}"
4691
+                "${TRANSCODE_CMD2[@]}"  2>&1 | pipe2log transcode &
4692
+            fi
4693
+            print2log "Running ${FFMPEG_CMD2[@]}"
4694
+            "${FFMPEG_CMD2[@]}" > "$ff_log_tmp" 2>&1 &
4695
             ffm_pid=$!
4696
-            wait_for "$WORK_DIR/tcode$i.pid"
4697
-            TRANSCODE_PID=$(<$WORK_DIR/tcode$i.pid)
4698
-            tcode_pids="$tcode_pids $TRANSCODE_PID"
4699
+            if $use_transcode; then
4700
+                wait_for "$WORK_DIR/tcode$i.pid"
4701
+                tcode_pids="$tcode_pids $(<$WORK_DIR/tcode$i.pid)"
4702
+            fi
4703
             if [[ -n "$ffm_pid" ]]; then
4704
                 wait_for "$WORK_DIR/pics/$i/000001.$IMG_FMT"
4705
                 while ps -p $ffm_pid >/dev/null; do
4706
@@ -7153,12 +7893,27 @@
4707
                     awk -F / '{ field = $NF }; END{ print field }')
4708
                     spin "Seeking in video and creating images: $last_image"
4709
                 done
4710
-                wait # wait for ffmpeg and transcode to finish
4711
+                # wait for ffmpeg and transcode to finish
4712
+                wait $ffm_pid # get exit code of ffmpeg
4713
+                if (($? != 0)); then
4714
+                    cat "$ff_log_tmp" | sed '/time=10000000000.00/d' | pipe2log ${FFmpeg##*/}
4715
+                    rm -f "$ff_log_tmp"
4716
+                    runtime_error \
4717
+                      "Problem with ${FFmpeg##*/} while creating images from video"
4718
+                fi
4719
+                if $use_transcode; then
4720
+                    wait $(<$WORK_DIR/tcode$i.pid)
4721
+                    # get exit code of transcode
4722
+                    if (($? != 0)); then
4723
+                        runtime_error \
4724
+                        "Problem with transcode while creating images from video"
4725
+                    fi
4726
+                fi
4727
                 # get the largest image if static menu(we made 9)
4728
                 # get largest image of 9 if static menu and not -frame-safe
4729
                 if $STATIC && $FRAME_SAFE; then
4730
                     largest=$(get_largest 6 $V_FRAMES "$WORK_DIR/pics/$i/")
4731
-                    # remove the unused images after saving the largest as 1st
4732
+                    # remove unused images after saving the largest as 1st
4733
                     mv "$largest" "$WORK_DIR/pics/$i/000001.$IMG_FMT" 2>/dev/null
4734
                     rm -f "$WORK_DIR"/pics/$i/00000{2..9}.png
4735
                 fi
4736
@@ -7167,12 +7922,13 @@
4737
                 ((numpics > ani_pics)) && ani_pics=$numpics
4738
                 # append ffmpeg output to the log
4739
                 echo -e \
4740
-                "\n$ME Log from ffmpeg (processing transcode stream)\n" \
4741
+                "\n$ME Log from ${FFmpeg##*/} (processing video stream)\n" \
4742
                 >> "$LOG_FILE"
4743
-                strings "$log_tmp" |   sed '/time=10000000000.00/d' >> "$LOG_FILE"
4744
-                rm -f "$log_tmp"
4745
+                cat "$ff_log_tmp" | sed '/time=10000000000.00/d' | pipe2log ${FFmpeg##*/}
4746
+                rm -f "$ff_log_tmp"
4747
                 echo
4748
-                echo "Created $numpics images of $THUMB_FRAMES"
4749
+                echo -n "Created $numpics images of $THUMB_FRAMES"
4750
+                echo -ne "\r$(printf %60s)" # print spaces to overwrite previous line
4751
             else
4752
                 runtime_error "Problem creating images from the video."
4753
             fi
4754
@@ -7180,10 +7936,14 @@
4755
         fi
4756
         # copy 000001 image to 000000 as we use 0 based counting (transcode)
4757
         # TODO transition to using "1" based' images as we use ffmpeg now
4758
-        cp "$WORK_DIR/pics/$i/000001.$IMG_FMT" "$WORK_DIR/pics/$i/000000.$IMG_FMT"
4759
-        last=$(find $WORK_DIR/pics/$i -maxdepth 1 -name \*.$IMG_FMT | \
4760
-        sort | awk 'END{print}')
4761
-        rm -f "$last"
4762
+        [[ -s "$WORK_DIR/pics/$i/000001.$IMG_FMT" ]] && cp \
4763
+        "$WORK_DIR/pics/$i/000001.$IMG_FMT" "$WORK_DIR/pics/$i/000000.$IMG_FMT"
4764
+        dir_cnt=$(find "$WORK_DIR/pics/$i" -maxdepth 1 -name "*.$IMG_FMT" |wc -l)
4765
+        if ((dir_cnt > 1)); then
4766
+            last=$(find $WORK_DIR/pics/$i -maxdepth 1 -name \*.$IMG_FMT | \
4767
+            sort | awk 'END{print}')   
4768
+            rm -f "$last"
4769
+        fi
4770
     done
4771
 fi
4772
 # create the pics for background image
4773
@@ -7266,8 +8026,7 @@
4774
 if $SUB_MENU; then
4775
     for ((s=0; s<=NUM_FILES; s++)); do
4776
         if ! ${SLIDESHOW[s]}; then
4777
-            echo
4778
-            echo "Creating highlight and select PNGs for submenu $((s + 1))"
4779
+            print2log "Creating highlight and select PNGs for submenu $((s + 1))"
4780
             C=$((${CHAPTERS[s]} - 1))
4781
             MENU_BUTTON_SIZE=${GEO_ARRAY[C]}
4782
             get_button_geo
4783
@@ -7367,7 +8126,8 @@
4784
     echo
4785
     for ((i=0; i<=NUM_FILES; i++)); do
4786
         ! ${SLIDESHOW[i]} && \
4787
-        echo -e "Chapters for "${IN_FILES[i]}" are: \n"${CHAPT_ARRAY[i]}"\n"
4788
+        echo -e "Chapters for "${IN_FILES[i]}" are: \n"${CHAPT_ARRAY[i]}"\n" | \
4789
+        pipe2log
4790
     done
4791
 fi
4792
 # get button coordinates if text-rect buttons (showcase menu only)
4793
@@ -7474,7 +8234,7 @@
4794
         fi
4795
         if ((i==NUM_FILES+2)); then # quick-nav assumes titlesets
4796
             # VMGM_MENU means NOT -no-vmgm
4797
-            if $VMGM_MENU && $PLAYALL && ! $VMGM_ONLY; then #DEBUG
4798
+            if $VMGM_MENU && $PLAYALL && ! $VMGM_ONLY; then
4799
                 echo -n "       <button name=\"$i\" ${btn_geos[i-1]} "
4800
                 echo -e "up=\"$((i-1))\" down=\"$((i+1))\"/>"
4801
                 echo -e "       <button name=\"$((i+1))\" ${btn_geos[i]} $down/>"
4802
@@ -7522,7 +8282,7 @@
4803
         fi
4804
     else
4805
         for ((i=1; i<=NUM_BUTTONS; i++)); do
4806
-            if $SHOWCASE && [[ $NUM_FILES -ge $SPLIT ]]; then
4807
+            if $SHOWCASE && ((NUM_FILES >= SPLIT)); then
4808
                 if ((i>SPLIT)) && ((i<NUM_BUTTONS)); then
4809
                     left="left=\"$((i-SPLIT))\""; right=""
4810
                 elif  (( i<=SPLIT)) && (( (i+SPLIT) <= (NUM_FILES+1) )); then
4811
@@ -7760,12 +8520,12 @@
4812
     if [[ -n $AUDIO_CHANNEL ]]; then
4813
         echo "${VOB_PRE[i]}"
4814
     fi
4815
-    if [[ -n ${GROUP[i]} ]]; then
4816
+    if [[ -n ${GROUP_ARR[i]} ]]; then
4817
        ((MENU_NUM == 1 && ${CHAPTERS[i]} != 0)) && get_group_chapters $i format
4818
         if ((${nochapt[i]})); then
4819
             ! ${SLIDESHOW[i]} && echo -e \
4820
              "        <vob file=\"$BASEDIR/${TSET_NUM}-$((i+1)).mpg\" $vid_pause/>"
4821
-            for ((m=1; m<=$((${GROUP[i]})); m++)); do
4822
+            for ((m=1; m<=$((${GROUP_ARR[i]})); m++)); do
4823
                 mpg="$BASEDIR/${TSET_NUM}-group-$((i+1))-${m}.mpg"
4824
                 [[ -e $mpg ]] && \
4825
                 echo -e "        <vob file=\"$mpg\" $grp_vid_pause/>"
4826
@@ -7773,7 +8533,7 @@
4827
         else
4828
             ! ${SLIDESHOW[i]} && echo -e \
4829
              "        <vob file=\"$BASEDIR/${TSET_NUM}-$((i+1)).mpg\" $chpts0 $vid_pause/>"
4830
-            for ((m=1; m<=$((${GROUP[i]})); m++)); do
4831
+            for ((m=1; m<=$((${GROUP_ARR[i]})); m++)); do
4832
                 mpg="$BASEDIR/${TSET_NUM}-group-$((i+1))-${m}.mpg"
4833
                 [[ -e $mpg ]] && echo -e \
4834
                  "        <vob file=\"$mpg\" ${chpts[++j]} $grp_vid_pause/>"
4835
@@ -7884,6 +8644,7 @@
4836
 
4837
 # make dummy VMGM mpeg
4838
 if ! $TITLESET_MODE && ! $DO_TITLESETS; then
4839
+    yecho "Creating a blank mpeg for the vmgm menu"
4840
     make_dummy
4841
 fi
4842
 # do submenu 1st for debug purposes
4843
@@ -7892,7 +8653,7 @@
4844
     yecho
4845
     yecho "Building submenus"
4846
     yecho
4847
-    yecho "Creating images for each chapter"
4848
+    print2log "Creating images for each chapter"
4849
     if [ -z "$SM_TITLES" ]; then
4850
         if $MULTILINE_TITLE; then
4851
             for i in ${!TITLES[@]}; do
4852
@@ -7909,7 +8670,7 @@
4853
     #     Audio and no -submenu-length given: full length of the audio file
4854
     if $SUBMENU_AUDIO; then
4855
         if [[ -n $SM_AUDIO_FILE ]]; then
4856
-            SM_AUDIOLEN=$(audio_length "$SM_AUDIO_FILE")
4857
+            SM_AUDIOLEN=$(stream_length "$SM_AUDIO_FILE" audio)
4858
         fi
4859
         for ((i=0; i<=NUM_FILES; i++)); do
4860
             [[ -n $SM_AUDIO_FILE ]] && SUBMENU_AUDIOLEN[i]=$SM_AUDIOLEN
4861
@@ -7919,7 +8680,7 @@
4862
                 if ${SLIDESHOW[i]}; then
4863
                     yecho
4864
                     spin "getting length of ${SM_AUDIO[i]} "
4865
-                    SUBMENU_AUDIOLEN[i]=$(audio_length "${SM_AUDIO[i]}")
4866
+                    SUBMENU_AUDIOLEN[i]=$(stream_length "${SM_AUDIO[i]}" audio)
4867
                     SUBMENU_LEN[i]=${SUBMENU_AUDIOLEN[i]}
4868
                 else
4869
                     SUBMENU_AUDIOLEN[i]=$( unformat_time ${SUBMENU_LEN[i]} )
4870
@@ -7954,9 +8715,10 @@
4871
         smframes=${SUBMENU_FRAMES[i]}
4872
         if ! ${SLIDESHOW[i]}; then
4873
             C=$((${CHAPTERS[i]} - 1))
4874
+            VSIZE=${GEO_ARRAY[C]}
4875
             SN_BTN_XY=${GEO_ARRAY[C]} # button dimensions
4876
             NUM_CHAPTERS=${CHAPTERS[i]}
4877
-            yecho "Creating a transparent title PNG"
4878
+            print2log "Creating a transparent title PNG"
4879
             SMTITLE_CMD=(convert -size 620x300 xc:none -font "$SM_TITLE_FONT" \
4880
             -pointsize $SUBMENU_FONTSIZE -fill "$SM_TITLE_CLR" \
4881
             -draw "gravity center text 2,2 \"${SM_TITLES[i]}\"" \
4882
@@ -8001,7 +8763,7 @@
4883
                 TOTAL_IMGS=${CHAPTERS[i]}
4884
                 PREFIX=${i}-
4885
             fi
4886
-            if [[ -n ${GROUP[i]} ]]; then
4887
+            if [[ -n ${GROUP_ARR[i]} ]]; then
4888
                 unset x CUT c FILE_IN
4889
                 # this will also take care of grouped USER_CHAPTERS
4890
                 BASE=$WORK_DIR/${TSET_NUM}-group
4891
@@ -8054,19 +8816,20 @@
4892
             if $USER_CHAPTERS; then
4893
                 # 1 second seek for 1st chapt (00:00:00), to avoid black frames
4894
                 cmd[0]=30-$(bc_math "30 + $CUT_TIME" int)
4895
-            elif [[ -z ${GROUP[i]} ]]; then
4896
+            elif [[ -z ${GROUP_ARR[i]} ]]; then
4897
                 # auto chapters needs the last seek removed
4898
                 key=$((${#cmd[@]} - 1))
4899
                 unset cmd[key]
4900
             fi
4901
-            yecho
4902
-            yecho "Creating $TOTAL_IMGS chapter images for ${IN_FILES[i]}"
4903
-            yecho
4904
-            unset cf frm
4905
-            for t in "${cmd[@]}"; do
4906
+            print2log ""
4907
+            print2log "Creating $TOTAL_IMGS chapter images for ${IN_FILES[i]}"
4908
+            print2log ""
4909
+            unset cf f
4910
+            for t in "${!cmd[@]}"; do
4911
+                ! $use_transcode && break # don't run block if just using ffmpeg
4912
                 # warning to ignore transcode error messages
4913
                 print_tcode_info
4914
-                if [[ -n ${GROUP[i]} ]]; then
4915
+                if [[ -n ${GROUP_ARR[i]} ]]; then
4916
                     CUR_FILE="${FILE_IN[cf++]}"
4917
                 else
4918
                     CUR_FILE="${IN_FILES[i]}"
4919
@@ -8077,53 +8840,51 @@
4920
                 else
4921
                     unset NAVSEEK NAVLOG
4922
                 fi
4923
-                log_tmp="$PICS_OUT/log.tmp"
4924
+                ff_log_tmp="$PICS_OUT/ff_log.tmp"
4925
+                tc_log_tmp="$PICS_OUT/tc_log.tmp"
4926
                 yuv_fifo="$PICS_OUT/out.yuv"
4927
                 [[ ! -p "$yuv_fifo" ]] && mkfifo "$yuv_fifo"
4928
                 # resize using ffmpeg instead of transcode
4929
-                FFMPEG_CMD=(ffmpeg $PIPE_FORMAT -i "$yuv_fifo" \
4930
-                -f image2 -s ${GEO_ARRAY[C]} -y "$PICS_OUT/%06d.$SM_IMG_FMT")
4931
+                FFMPEG_CMD=($FFmpeg $PIPE_FORMAT -i "$yuv_fifo" \
4932
+                -f image2 $VF scale=${VSIZE%x*}:${VSIZE#*x} -y "$PICS_OUT/%06d.$SM_IMG_FMT")
4933
                 TCODE_CMD=(nice transcode --progress_rate 10 \
4934
                 --write_pid $WORK_DIR/tcode$i.pid -q 1 -i "$CUR_FILE" \
4935
                 $NAVSEEK "$NAVLOG" -o "$yuv_fifo" -f \
4936
-                $FRAME_RATE -c $t $EXPORT)
4937
-                yecho "Running ${TCODE_CMD[@]}" | fold -bs
4938
-                yecho "Running ${FFMPEG_CMD[@]}" | fold -bs
4939
-                "${TCODE_CMD[@]}"  2>&1 | strings >> "$LOG_FILE" &
4940
-                "${FFMPEG_CMD[@]}" > "$log_tmp" 2>&1 &
4941
+                $FRAME_RATE -c ${cmd[t]} $EXPORT)
4942
+                print2log "Running ${TCODE_CMD[@]}"
4943
+                print2log "Running ${FFMPEG_CMD[@]}"
4944
+                "${TCODE_CMD[@]}"  2>&1 | pipe2log transcode &
4945
+                "${FFMPEG_CMD[@]}" > "$ff_log_tmp" 2>&1 &
4946
                 ffm_pid=$!
4947
                 wait_for "$WORK_DIR/tcode$i.pid"
4948
                 TCODE_PID=$(<$WORK_DIR/tcode$i.pid)
4949
                 tcode_pids="$tcode_pids $TCODE_PID"
4950
-                if [[ -n "$TCODE_PID" ]]; then
4951
+                if [[ -n $TCODE_PID ]]; then
4952
                     while ps -p $ffm_pid >/dev/null; do
4953
                         wait_for "$IMG_DIR/000001.$SM_IMG_FMT"
4954
                         sleep 1 # spinner interval
4955
                         end=$(find "$IMG_DIR" -maxdepth 1 -name \*.$SM_IMG_FMT |
4956
                         sort | awk -F / '{ field = $NF }; END{ print field }')
4957
-                        spin "Seeking in video and creating images: $end"
4958
+                        e=${end##*/};  e=${e%%.*}; e=${e##*0} # strip to digit
4959
+                        spin \
4960
+                          "Seeking and making $e images for chapter $((t+1)): $end"
4961
                     done
4962
-                    echo
4963
                     total_imgs=$(find "$IMG_DIR" -name "*.$SM_IMG_FMT" | wc -l)
4964
                     wait
4965
-                    echo "Created $total_imgs $sm_img_fmt of $TOTAL_IMGS"
4966
+                    #yecho ""
4967
+                    print2log "Created $total_imgs $sm_img_fmt of $TOTAL_IMGS"
4968
                 else
4969
                     runtime_error "Problem creating images from the video."
4970
                 fi
4971
-                echo -e \
4972
-                "\n$ME Log from ffmpeg (processing transcode stream)\n" \
4973
-                >> "$LOG_FILE"
4974
-                strings "$log_tmp" >> "$LOG_FILE"
4975
-                rm -f "$log_tmp"
4976
-                unset TCODE_CMD cmd run_transcode
4977
+                cat "$ff_log_tmp" | pipe2log ${FFmpeg##*/}
4978
+                rm -f "$ff_log_tmp"
4979
+                unset TCODE_CMD
4980
+                # transcode loops so each loop uses %06d, then moved to %08d
4981
                 if ! $ANI_SUB_MENU ; then
4982
-                    echo
4983
                     mv $WORK_DIR/submenu/000001.$SM_IMG_FMT \
4984
-                    $WORK_DIR/submenu/$(printf "%08d%s\n" $((frm++)) .$SM_IMG_FMT)
4985
-                    let frm+=1
4986
+                    $WORK_DIR/submenu/$(printf "%08d%s\n" $((f++)) .$SM_IMG_FMT)
4987
+                    let f+=1
4988
                 elif $ANI_SUB_MENU; then
4989
-                    echo "renaming images by frame number"
4990
-                    echo
4991
                     u=${t/*-}; v=${t/-*}
4992
                     # names now start with 000001.  Rename starting at 000000.
4993
                     for ((n=1; n<smframes+1; n++)); do
4994
@@ -8133,17 +8894,69 @@
4995
                         lastimage=$WORK_DIR/animenu/$(printf \
4996
                         "%06d%s\n" $((n-1)) .$SM_IMG_FMT)
4997
                         nextimage=$WORK_DIR/animenu/$(printf \
4998
-                        "%08d%s\n" $((frm++ )) .$SM_IMG_FMT)
4999
+                        "%08d%s\n" $((f++ )) .$SM_IMG_FMT)
5000
                         if [[ ! -e $curimage ]]; then
5001
                             cp "$lastimage" "$nextimage"
5002
                         else
5003
                             mv "$curimage" "$nextimage"
5004
                         fi
5005
-                        let frm+=1
5006
+                        let f+=1
5007
                     done
5008
                 fi
5009
             done
5010
-            # make the chapter titles if called for.  Shadow is hardcoded at #101010
5011
+            if ! $use_transcode; then # don't run block if using transcode
5012
+                if [[ -n ${GROUP_ARR[i]} ]]; then
5013
+                    CUR_FILE="${FILE_IN[cf++]}"
5014
+                else
5015
+                    CUR_FILE="${IN_FILES[i]}"
5016
+                fi
5017
+                ff_log_tmp="$PICS_OUT/ff_log.tmp"
5018
+                frames=$CUT_TIME
5019
+
5020
+                # avconv has no 'between' expr but keep commented code below
5021
+                #frames=$((CUT_TIME - 1))
5022
+                #[[ ${FFmpeg##*/} =~ avconv ]] && frames=$CUT_TIME
5023
+                # between filter is "inclusive" so between(300, 300) is 300
5024
+                #cur_frame=${cf%-*}
5025
+                #if [[ ${FFmpeg##*/} =~ avconv ]]; then
5026
+                #else # ffmpeg
5027
+                # "select using "between" expr
5028
+                #    for fr in ${cmd[@]}; do
5029
+                #        cur_frame=${fr%-*}
5030
+                #        select1+="between(n,${cur_frame},$(( cur_frame + frames)))+"
5031
+                #    done
5032
+                #fi
5033
+
5034
+                for fr in ${cmd[@]}; do
5035
+                    cur_frame=${fr%-*}
5036
+                    select1+="(gt(n,${cur_frame}))*lte(n,$(( cur_frame + frames)))+"
5037
+                done
5038
+
5039
+                # remove last '+' sign
5040
+                select1=${select1%+}
5041
+                select1="'${select1}'",setpts="'N/($ff_frame_rate*TB)'"
5042
+                scale1=scale=${VSIZE%x*}:${VSIZE#*x}
5043
+                ffm_cmd=($FFmpeg -i "$CUR_FILE" -vf select="${select1}",${scale1} \
5044
+                -y "$IMG_DIR/%08d.$SM_IMG_FMT")
5045
+                print2log "Running ${ffm_cmd[@]}"
5046
+                "${ffm_cmd[@]}" > "$ff_log_tmp" 2>&1 &
5047
+                ffm_pid=$!
5048
+                while ps -p $ffm_pid >/dev/null; do
5049
+                    wait_for "$IMG_DIR/00000001.$SM_IMG_FMT"
5050
+                    sleep 1 # spinner interval
5051
+                    end=$(find "$IMG_DIR" -maxdepth 1 -name \*.$SM_IMG_FMT |
5052
+                    sort | awk -F / '{ field = $NF }; END{ print field }')
5053
+                    e=${end##*/};  e=${e%%.*}; e=${e##*0} # strip to digit
5054
+                    spin \
5055
+                      "Seeking and making $TOTAL_IMGS images for chapters: $end"
5056
+                done
5057
+                total_imgs=$(find "$IMG_DIR" -name "*.$SM_IMG_FMT" | wc -l)
5058
+                print2log "Created $total_imgs $sm_img_fmt of $TOTAL_IMGS"
5059
+                wait
5060
+                cat "$ff_log_tmp" | pipe2log ${FFmpeg##*/}
5061
+                unset select1 ffm_cmd
5062
+            fi
5063
+            # make the chapter titles if needed.  Shadow is hardcoded at #101010
5064
             if [[ -n  ${CHAPTER_TITLES[@]} ]]; then
5065
                 echo "Making Chapter titles for Video $((i+1))"
5066
                 for ((a=0; a<${CHAPTERS[i]}; a++)); do
5067
@@ -8172,7 +8985,7 @@
5068
                 done
5069
             fi
5070
             if $ANI_SUB_MENU ; then
5071
-                # move submenu images to each subdir: $WORK_DIR/animenu/{0,1,2,etc}
5072
+                # move submenu images to subdirs: $WORK_DIR/animenu/{0,1,2,etc}
5073
                 # or if making chapter titles, output to subdirs; rm original
5074
                 for ((a=0; a<${CHAPTERS[i]}; a++)); do
5075
                     unset num_procs smpids curimgs
5076
@@ -8213,14 +9026,14 @@
5077
 
5078
             if $ANI_SUB_MENU; then
5079
                 $DEBUG && stime=$(date +%s)
5080
-                TOYUV_CMD=(ppmtoy4m -v 0 -n $smframes -A $PIXEL_AR -F $YUV_FR -I p \
5081
-                -S 420mpeg2 -r)
5082
-                IMGENC_CMD=(ffmpeg -f yuv4mpegpipe -r $FRAME_RATE -i - -an \
5083
-                -r $FRAME_RATE -s $VIDSIZE -tvstd $TV_STANDARD $FFMPEG_OPTS \
5084
+                TOYUV_CMD=(ppmtoy4m -v 0 -n $smframes -A $PIXEL_AR -F $YUV_FR \
5085
+                -I p -S 420mpeg2 -r)
5086
+                IMGENC_CMD=($FFmpeg -f yuv4mpegpipe -i - -an $FFMPEG_OPTS \
5087
+                -r $ff_frame_rate $VF scale=${VF_SCALE},${ASPECT} \
5088
                 -y "$WORK_DIR/menu$i.m2v")
5089
-                echo
5090
-                yecho "Running ${TOYUV_CMD[@]} < $WORK_DIR/ppm.fifo |
5091
-                ${IMGENC_CMD[@]}" | fold -bs
5092
+                yecho ""
5093
+                print2log "Running ${TOYUV_CMD[@]} < $WORK_DIR/ppm.fifo |
5094
+                ${IMGENC_CMD[@]}"
5095
                 mkfifo "$WORK_DIR/ppm.fifo" 2>/dev/null
5096
                 mkfifo "$WORK_DIR/enc.fifo" 2>/dev/null
5097
                 "${TOYUV_CMD[@]}" < "$WORK_DIR/ppm.fifo" > \
5098
@@ -8229,7 +9042,8 @@
5099
                 "${IMGENC_CMD[@]}" <  "$WORK_DIR/enc.fifo"  2>/dev/null &
5100
                 encpids="$encpids $!"
5101
                 echo
5102
-                echo "Encoding $smframes frames for "${IN_FILES[i]}"" >&2
5103
+                v=${IN_FILES[i]}
5104
+                #echo "Encoding $smframes frames for "${IN_FILES[i]}"" >&2
5105
                 # make fifos for intermediary piping
5106
                 for ((f=1; f<=max_procs; f++)); do
5107
                     [[ ! -p "$WORK_DIR/temp-${f}.ppm" ]] && \
5108
@@ -8259,7 +9073,7 @@
5109
                     smpids="$smpids $!"
5110
                     ppm_fifos+=("$out_ppm") # all frames waiting to be processed
5111
                     if ((num_procs==max_procs || a == smframes-1 )); then
5112
-                        spin "\rProcessing frame $((a+1)) of $smframes  " >&2
5113
+                        spin "\r${v##*/}: Processing frame $((a+1)) of $smframes  " >&2
5114
                         cat "${ppm_fifos[@]}"
5115
                         wait $smpids 2>/dev/null
5116
                         unset smpids num_procs ppm_fifos
5117
@@ -8271,12 +9085,13 @@
5118
 
5119
                 # wait for ppmtoy4m and ffmpeg to finish
5120
                 wait
5121
+                echo >&2
5122
 
5123
-                unset IM_CMD IM_CMD2 d f P
5124
+                unset IM_CMD IM_CMD2 d f P v
5125
 
5126
             else # not $ANI_SUB_MENU
5127
 
5128
-                yecho
5129
+                yecho ""
5130
                 yecho "Making montage images for "${IN_FILES[i]}""
5131
                 # just use $CHAPTERS number of images
5132
                 imgs=( $(find $WORK_DIR/submenu -name \*.$SM_IMG_FMT |
5133
@@ -8305,26 +9120,23 @@
5134
             fi
5135
             if ! $ANI_SUB_MENU; then
5136
 
5137
-                yecho
5138
+                yecho ""
5139
                 yecho "Converting chapter montage of ${IN_FILES[i]}
5140
                 to m2v video format"
5141
                 IMG_STREAM_CMD1=(convert "$PICS_IN" ppm:-)
5142
                 IMG_STREAM_CMD2=(ppmtoy4m -v 0 -n ${SM_LOOPS[i]} -A $PIXEL_AR -F $YUV_FR -I p \
5143
                 -S 420mpeg2 -r)
5144
-                ENC_CMD1=(ffmpeg -f yuv4mpegpipe -r $FRAME_RATE -i - \
5145
-                -r $FRAME_RATE -s $VIDSIZE -tvstd $TV_STANDARD $FFMPEG_OPTS \
5146
+                ENC_CMD1=($FFmpeg -f yuv4mpegpipe -i - \
5147
+                -r $ff_frame_rate $VF scale=${VF_SCALE},${ASPECT} $FFMPEG_OPTS \
5148
                 -y "$WORK_DIR/menu$i.m2v")
5149
-                echo "Running ${IMG_STREAM_CMD1[@]} | ${IMG_STREAM_CMD2[@]} | \
5150
+                print2log "Running ${IMG_STREAM_CMD1[@]} | ${IMG_STREAM_CMD2[@]} | \
5151
                 ${ENC_CMD1[@]}"| format_output | tee -a "$LOG_FILE" 2>&1
5152
-                if ! "${IMG_STREAM_CMD1[@]}" | "${IMG_STREAM_CMD2[@]}" |
5153
-                "${ENC_CMD1[@]}" 2>&1|strings >> "$LOG_FILE"; then
5154
-                    runtime_error
5155
-                fi
5156
+                "${IMG_STREAM_CMD1[@]}" | "${IMG_STREAM_CMD2[@]}" |
5157
+                "${ENC_CMD1[@]}" 2>&1|strings >> "$LOG_FILE"
5158
             fi
5159
 
5160
             # check if m2v was created ok before proceeding
5161
-            if mencoder -quiet -oac pcm -ovc copy -frames 0 \
5162
-            "$WORK_DIR/menu$i.m2v" -o /dev/null &>/dev/null; then
5163
+            if is_video "$WORK_DIR/menu$i.m2v"; then
5164
                 :
5165
             else
5166
                 echo
5167
@@ -8333,7 +9145,7 @@
5168
             fi
5169
             # clean out submenu dirs of images
5170
             echo
5171
-            echo "Cleaning up leftover pics in $REAL_WORK_DIR/animenu"
5172
+            print2log "Cleaning up leftover pics in $REAL_WORK_DIR/animenu"
5173
             rm -f $WORK_DIR/submenu/*
5174
             find $WORK_DIR/animenu/ -maxdepth 1 -type f -exec rm -f {} \;
5175
             if $ANI_SUB_MENU; then
5176
@@ -8366,11 +9178,11 @@
5177
 
5178
                 # encode to m2v
5179
                 yecho "Encoding to compliant m2v video format"
5180
-                PPM_CMD=(ppmtoy4m -v 0 -n ${SM_LOOPS[i]} -A $PIXEL_AR -I p -F $YUV_FR \
5181
-                -S 420mpeg2 -r)
5182
-                FFM_CMD=(ffmpeg $INSIZE -r $FRAME_RATE -pix_fmt yuv420p \
5183
-                -f yuv4mpegpipe -i - -an -r $FRAME_RATE -s $VIDSIZE \
5184
-                -tvstd $TV_STANDARD $FFMPEG_OPTS -y "$WORK_DIR/menu${i}.m2v")
5185
+                PPM_CMD=(ppmtoy4m -v 0 -n ${SM_LOOPS[i]} -A $PIXEL_AR -I p \
5186
+                -F $YUV_FR -S 420mpeg2 -r)
5187
+                FFM_CMD=($FFmpeg $PIPE_FORMAT -i - \
5188
+                -an -r $ff_frame_rate $VF scale=${VF_SCALE},${ASPECT} \
5189
+                $FFMPEG_OPTS -y "$WORK_DIR/menu${i}.m2v")
5190
                 yecho "Running ${PPM_CMD[@]} | ${FFM_CMD[@]}" | format_output
5191
                 cat "$WORK_DIR/polaroid_stack${i}.ppm" |
5192
                 "${PPM_CMD[@]}" | "${FFM_CMD[@]}" 2>&1 | strings >> "$LOG_FILE"
5193
@@ -8378,41 +9190,42 @@
5194
         fi
5195
     done
5196
     unset IMG_STREAM_CMD1 ENC_CMD1 JPEG2YUV_OPTS
5197
+    yecho "Working on submenu audio"
5198
     for ((s=0; s<=NUM_FILES; s++)); do
5199
         # create audio background for either animated or plain submenus
5200
-        yecho
5201
-        yecho "Creating an audio background"
5202
-        yecho "Working on submenu audio for "${IN_FILES[s]}""
5203
+        #yecho "Creating an audio background"
5204
+        #yecho "Working on submenu audio for "${IN_FILES[s]}""
5205
         if $SUBMENU_AUDIO; then # user supplied audio file for ths video
5206
             if [[ -n "$SM_AUDIO_FILE" ]]; then # user supplied "1" audio file
5207
                 COPY_AC3=(cp -v $WORK_DIR/submenu.$AUDIO_EXT \
5208
                 $WORK_DIR/menu$s.$AUDIO_EXT)
5209
-                BGAUDIO_CMD=(ffmpeg -i "$SM_AUDIO_FILE" \
5210
+                BGAUDIO_CMD=($FFmpeg -i "$SM_AUDIO_FILE" \
5211
                 -t ${SUBMENU_AUDIOLEN[s]} -ar 48000 -acodec pcm_s16le \
5212
                 -y $WORK_DIR/submenu.wav)
5213
             elif [[ "${SM_AUDIO[s]}" = "none" ]]; then # user asked for silence
5214
-                SUBMENU_AUDIOLEN[s]=$(vid_length "$WORK_DIR/menu$s.m2v")
5215
-                BGAUDIO_CMD=(ffmpeg -f s16le -ar 48000 -i /dev/zero $AUDIO_OPTS \
5216
+                SUBMENU_AUDIOLEN[s]=$(stream_length "$WORK_DIR/menu$s.m2v" m2v)
5217
+                BGAUDIO_CMD=($FFmpeg -f s16le -ar 48000 -i /dev/zero $AUDIO_OPTS \
5218
                 -t ${SUBMENU_AUDIOLEN[s]} -y $WORK_DIR/menu$s.$AUDIO_EXT)
5219
             else
5220
                 # SM_AUDIO[s] is an audio file we will process it
5221
                 # do separate wavs for each supplied audio bg for each submenu
5222
-                BGAUDIO_CMD=(ffmpeg -i "${SM_AUDIO[s]}" \
5223
+                # again using default or given submenu length
5224
+                BGAUDIO_CMD=($FFmpeg -i "${SM_AUDIO[s]}" \
5225
                 -t ${SUBMENU_AUDIOLEN[s]} -ar 48000 -acodec pcm_s16le \
5226
                 -y $WORK_DIR/menu$s.wav)
5227
-                BGAUDIO_CMD2=(ffmpeg -i $WORK_DIR/menu$s.wav \
5228
+                BGAUDIO_CMD2=($FFmpeg -i $WORK_DIR/menu$s.wav \
5229
                 $AUDIO_OPTS -y $WORK_DIR/menu$s.$AUDIO_EXT)
5230
             fi
5231
         else # no supplied audio for submenu so create silence
5232
-            SUBMENU_AUDIOLEN[s]=$(vid_length "$WORK_DIR/menu$s.m2v")
5233
-            BGAUDIO_CMD=(ffmpeg -f s16le -ar 48000 -i /dev/zero $AUDIO_OPTS \
5234
+            SUBMENU_AUDIOLEN[s]=$(stream_length "$WORK_DIR/menu$s.m2v" m2v)
5235
+            BGAUDIO_CMD=($FFmpeg -f s16le -ar 48000 -i /dev/zero $AUDIO_OPTS \
5236
             -t ${SUBMENU_AUDIOLEN[s]} -y $WORK_DIR/menu$s.$AUDIO_EXT)
5237
         fi
5238
         # run if wav doesn't exist, or its a slideshow
5239
         if [[ ! -s $WORK_DIR/submenu.wav ]] || ${SLIDESHOW[s]}; then
5240
-            yecho "Running ${BGAUDIO_CMD[@]}"
5241
+            print2log "Running ${BGAUDIO_CMD[@]}"
5242
             # run command, error out if problem
5243
-            ! "${BGAUDIO_CMD[@]}" 2>&1 |strings >> "$LOG_FILE" 2>&1 \
5244
+            ! "${BGAUDIO_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/} \
5245
             && runtime_error "Problem getting audio for the submenu"
5246
         fi
5247
         # convert to DVD/SVCD format as long as not "none" or single audio file
5248
@@ -8420,18 +9233,17 @@
5249
         && [[ ! "${SM_AUDIO[s]}" = "none" && -z "$SM_AUDIO_FILE" ]]; then
5250
             if $SM_AUDIO_FADE; then
5251
                 #TIME=$(audio_length "$WORK_DIR/menu$s.wav")
5252
-                echo -e "Running:
5253
+                print2log "Running:
5254
                 sox $WORK_DIR/menu$s.wav $WORK_DIR/menu$s-processed.wav fade t
5255
-                $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE" |
5256
-                sed 's/    */ /g' | format_output
5257
+                $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE"
5258
                 sox -q $WORK_DIR/menu$s.wav $WORK_DIR/menu$s-processed.wav \
5259
                  fade t $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE
5260
                 rm $WORK_DIR/menu$s.wav
5261
                 mv $WORK_DIR/menu$s-processed.wav $WORK_DIR/menu$s.wav
5262
             fi
5263
-            echo "Running "${BGAUDIO_CMD2[@]}"" | fold -bs >> "$LOG_FILE"
5264
-            ! "${BGAUDIO_CMD2[@]}" 2>&1 |strings >> "$LOG_FILE" \
5265
-            && runtime_error "Problem getting audio for the submenu"
5266
+            print2log "Running ${BGAUDIO_CMD2[@]}"
5267
+            "${BGAUDIO_CMD2[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
5268
+             ((${PIPESTATUS[0]} != 0)) && runtime_error "Problem getting audio for the submenu"
5269
             unset TIME
5270
         fi
5271
         # if "1" audio file, then convert it if it has not been done yet
5272
@@ -8439,51 +9251,52 @@
5273
         && ! -s $WORK_DIR/submenu-processed.wav ]]; then
5274
             if $SM_AUDIO_FADE; then
5275
                 #TIME=$(audio_length "$WORK_DIR/submenu.wav")
5276
-                echo -e "Running:
5277
+                print2log "Running:
5278
                 sox $WORK_DIR/submenu.wav $WORK_DIR/submenu-processed.wav \
5279
-                fade t $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE" |
5280
-                format_output >> "$LOG_FILE"
5281
+                fade t $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE"
5282
 
5283
                 sox -q $WORK_DIR/submenu.wav $WORK_DIR/submenu-processed.wav \
5284
                  fade t $SM_FADE ${SUBMENU_AUDIOLEN[s]} $SM_FADE
5285
                 rm -f $WORK_DIR/submenu.wav
5286
                 cp  $WORK_DIR/submenu-processed.wav $WORK_DIR/submenu.wav
5287
             fi
5288
-            BGAUDIO_CMD3=(ffmpeg -i $WORK_DIR/submenu.wav \
5289
+            BGAUDIO_CMD3=($FFmpeg -i $WORK_DIR/submenu.wav \
5290
             $AUDIO_OPTS -y $WORK_DIR/submenu.$AUDIO_EXT)
5291
             if [ -s $WORK_DIR/submenu.$AUDIO_EXT ]; then # if exists do nothing
5292
                 :
5293
             else
5294
-                echo "Running "${BGAUDIO_CMD3[@]}"" >> "$LOG_FILE.tmp" 2>&1
5295
-                ! "${BGAUDIO_CMD3[@]}" 2>&1 |strings >> "$LOG_FILE" \
5296
-                && runtime_error
5297
+                print2log "Running ${BGAUDIO_CMD3[@]}"
5298
+                "${BGAUDIO_CMD3[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
5299
+                ((${PIPESTATUS[0]} != 0)) && runtime_error "Problem getting audio for the submenu"
5300
             fi
5301
         fi
5302
         # copy the final file for each submenu if only 1 supplied
5303
         "${COPY_AC3[@]}"
5304
-        yecho
5305
-        yecho "Multiplexing video and audio together"
5306
+        print2log "Multiplexing video and audio together"
5307
         S=$((s + 1))
5308
         MPLEX_CMD=(mplex -V -f $MPLEX_FORMAT -o $WORK_DIR/menu$S.mpg \
5309
         $WORK_DIR/menu$s.$AUDIO_EXT $WORK_DIR/menu$s.m2v)
5310
-        echo "Running: "${MPLEX_CMD[@]}"" | fold -bs >> "$LOG_FILE"
5311
-        ! "${MPLEX_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"  && runtime_error
5312
+        print2log "Running: ${MPLEX_CMD[@]}"
5313
+        "${MPLEX_CMD[@]}" 2>&1 |pipe2log mplex
5314
+        ((${PIPESTATUS[0]} != 0)) && runtime_error \
5315
+          "Problem muxing audio and video with mplex"
5316
         # remove wav to save space
5317
-        rm -fv $WORK_DIR/menu$s.wav
5318
+        rm -f $WORK_DIR/menu$s.wav
5319
     done
5320
-    rm -fv $WORK_DIR/submenu.{wav,$AUDIO_EXT}
5321
+    rm -f $WORK_DIR/submenu.{wav,$AUDIO_EXT}
5322
     rm -fr $WORK_DIR/animenu/*
5323
 fi
5324
 ##############################################################################
5325
-#                              End of submenus                               #
5326
+# End of submenus                                                            #
5327
 ##############################################################################
5328
 
5329
 ##############################################################################
5330
-#                            Work on main menu                               #
5331
+# Work on main menu                                                          #
5332
 ##############################################################################
5333
 if $DO_MENU; then
5334
     yecho
5335
     yecho "Building main menu"
5336
+    yecho
5337
 fi
5338
 if [[ -n "$BG_VIDEO" ]] && ! $QUICK_MENU; then
5339
     if $FAST_SEEK; then
5340
@@ -8492,11 +9305,11 @@
5341
         bg_post_seek="-ss $BG_SEEK" && unset bg_pre_seek
5342
     fi
5343
     yecho "Getting background video from $BG_VIDEO"
5344
-    FFMPEG_CMD=(ffmpeg $bg_pre_seek -i "$BG_VIDEO" -an $bg_post_seek \
5345
-    -vframes $BG_VIDEO_FRAMES -s $VIDSIZE  -f image2 \
5346
-    -y "$WORK_DIR/bg/%d.$IMG_FMT")
5347
-    yecho "Extracting/resizing background images"
5348
-    echo "Running: ${FFMPEG_CMD[@]}" | format_output >> "$LOG_FILE"
5349
+    FFMPEG_CMD=($FFmpeg $bg_pre_seek -i "$BG_VIDEO" -an $bg_post_seek \
5350
+    $VF scale=$VF_SCALE -f image2 \
5351
+    -vframes $BG_VIDEO_FRAMES -y "$WORK_DIR/bg/%d.$IMG_FMT")
5352
+    print2log "Extracting/resizing background images"
5353
+    print2log "Running: ${FFMPEG_CMD[@]}"
5354
     # Run command and check for failure
5355
     if ! "${FFMPEG_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"; then
5356
         runtime_error "Problem creating images from the background video"
5357
@@ -8547,12 +9360,13 @@
5358
             #convert ${USER_PICS[MENU_NUM-1]} -resize $SHOWCASE_SIZE \
5359
             cp "$WORK_DIR/showcase_img.png" "$WORK_DIR/showcase/000001.png"
5360
         else
5361
-            FFMPEG_CMD=(ffmpeg $ffm_pre_seek -i "$SHOWCASE_VIDEO" -s \
5362
-            $SHOWCASE_SIZE -vframes $FRAMES -an $ffm_post_seek -f image2 \
5363
-            -y "$WORK_DIR/showcase/%06d.png")
5364
-            echo -e "\nRunning: "${FFMPEG_CMD[@]}"\n" | fold -bs >> "$LOG_FILE"
5365
+            FFMPEG_CMD=($FFmpeg $ffm_pre_seek -i "$SHOWCASE_VIDEO" \
5366
+            $VF scale=${SHOWCASE_SIZE%x*}:${SHOWCASE_SIZE#*x} -an -vframes \
5367
+            $FRAMES $ffm_post_seek -f image2 -y "$WORK_DIR/showcase/%06d.png")
5368
+            print2log "Running: ${FFMPEG_CMD[@]}"
5369
             SED_VAR="frame="
5370
-            "${FFMPEG_CMD[@]}" >> "$LOG_FILE.tmp" 2>&1 &
5371
+            #"${FFMPEG_CMD[@]}" >> "$LOG_FILE.tmp" 2>&1 &
5372
+            "${FFMPEG_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/} &
5373
             ffm_pid=$!
5374
             while ps -p $ffm_pid >/dev/null; do
5375
                 sleep 1
5376
@@ -8561,8 +9375,6 @@
5377
             wait $ffm_pid
5378
             (($?)) && runtime_error "Problem creating images from the video."
5379
 
5380
-            strings "$LOG_FILE.tmp" >> "$LOG_FILE"
5381
-            rm -f "$LOG_FILE.tmp"
5382
             echo
5383
         fi
5384
     fi
5385
@@ -8614,7 +9426,7 @@
5386
                 else
5387
                     { convert -size $SHOWCASE_SIZE "$pic" $SC_RAISE miff:- |
5388
                     convert - $SHOWCASE_FRAME -background none $ROTATE $WAVE miff:- |
5389
-                    convert - $QUALITY  resize ${SHOWCASE_SIZE}! "$pic"  ; } \
5390
+                    convert - $QUALITY  -resize ${SHOWCASE_SIZE}! "$pic"  ; } \
5391
                       2>> "$LOG_FILE" &
5392
                 fi
5393
             fi
5394
@@ -8644,7 +9456,7 @@
5395
 ((num_scpics > ani_pics)) && ani_pics=$num_scpics
5396
 unset IMAGES last_pic next_pic FFMPEG_CMD pic
5397
 
5398
-yecho
5399
+yecho ""
5400
 if [[ ! "$SC_FRAMESTYLE" = "glass" && ! $TEXTMENU ]]; then
5401
     if $SHOWCASE; then
5402
         yecho "Processing video images"
5403
@@ -8809,14 +9621,14 @@
5404
     done
5405
 fi
5406
 if ! $QUICK_MENU && $DO_MENU; then
5407
-    yecho
5408
-    yecho "Making $FRAMES final montage frames and compositing onto \
5409
+    yecho ""
5410
+    yecho "Making $FRAMES final montage frame(s) and compositing onto \
5411
     background with title"
5412
-    yecho
5413
+    yecho ""
5414
 fi
5415
 if $STATIC; then
5416
     # we have a value for MENU_AUDIOLEN AND BG_AUDIO
5417
-    if [[ -n "$BG_AUDIO" && "$BG_AUDIO" != "none" ]]; then
5418
+    if [[ -n "$BG_AUDIO" && "$BG_AUDIO" != "none" ]] && ! $MENU_FADE; then
5419
         LOOPS=$( bc <<< "$MENU_AUDIOLEN * $FRAME_RATE" 2>/dev/null)
5420
         LOOPS=${LOOPS%.*}
5421
     # switched menu: no bg audio or video and not menu fade
5422
@@ -8832,7 +9644,6 @@
5423
     PPM_LOOPS=$LOOPS
5424
 fi
5425
 if ! $QUICK_MENU && $DO_MENU; then
5426
-    $STATIC && INSIZE="-s $VIDSIZE"
5427
     echo
5428
     echo \
5429
     "Converting images to video and encoding to $TARGET-compliant format" >&2
5430
@@ -8846,17 +9657,21 @@
5431
         PPM_FRAMES=$((PPM_FRAMES+18))
5432
     TOYUV_CMD=(ppmtoy4m -v 2 -n $PPM_FRAMES -A $PIXEL_AR -I p -F $YUV_FR \
5433
     -S 420mpeg2 -r)
5434
-    IMGENC_CMD=(ffmpeg $INSIZE -r $FRAME_RATE $PIPE_FORMAT -i - -an \
5435
-    -r $FRAME_RATE -s $VIDSIZE -tvstd $TV_STANDARD $FFMPEG_OPTS \
5436
+    IMGENC_CMD=($FFmpeg $PIPE_FORMAT -i - -an \
5437
+    -r $ff_frame_rate $VF scale=${VF_SCALE},${ASPECT} $FFMPEG_OPTS \
5438
     -y $WORK_DIR/intro.m2v)
5439
-    yecho "Running ${TOYUV_CMD[@]} < $WORK_DIR/ppm.fifo | ${IMGENC_CMD[@]}" |
5440
-    fold -bs
5441
+    #print2log "Running ${TOYUV_CMD[@]} < $WORK_DIR/ppm.fifo | ${IMGENC_CMD[@]}" |
5442
+    print2log "Running:"
5443
+    echo "${TOYUV_CMD[@]} < $WORK_DIR/ppm.fifo | ${IMGENC_CMD[@]}" | \
5444
+    while read -r line; do
5445
+        print2log "$line"
5446
+    done
5447
     mkfifo "$WORK_DIR/ppm.fifo" 2>/dev/null
5448
     mkfifo "$WORK_DIR/enc.fifo" 2>/dev/null
5449
     "${TOYUV_CMD[@]}" < "$WORK_DIR/ppm.fifo" > "$WORK_DIR/enc.fifo" \
5450
-     2>> "$LOG_FILE" & #/dev/null &
5451
+     2>> "${LOG_FILE}.1-tmp" & #/dev/null &
5452
     encpids="$encpids $!"
5453
-    "${IMGENC_CMD[@]}" <  "$WORK_DIR/enc.fifo"  2>> "$LOG_FILE" & #/dev/null &
5454
+    "${IMGENC_CMD[@]}" <  "$WORK_DIR/enc.fifo"  2>> "${LOG_FILE}.2-tmp" & #/dev/null &
5455
     encpids="$encpids $!"
5456
 fi
5457
 # make intermediary fifos for images.  They will get catted to ppm.fifo
5458
@@ -8986,9 +9801,11 @@
5459
         # -menu-fade working with -static
5460
         $SINGLE_SLIDESHOW && \
5461
         IM_CMD1=(convert "$WORK_DIR/polaroid_stack.png" miff:- )
5462
-
5463
-        $TEXTMENU && unset MONTAGE_CMD
5464
-        $TEXTMENU && MONTAGE_CMD=( "${MONTAGE_CMD03[@]}" )
5465
+        # -text-menu can have showcase image so don't unset if it is present
5466
+        if $TEXTMENU && [[ -z "$SHOWCASE_IMG" ]]; then
5467
+            unset MONTAGE_CMD
5468
+            MONTAGE_CMD=( "${MONTAGE_CMD03[@]}" )
5469
+        fi
5470
         # if doing less animated frames than the total # of frames
5471
         # break from the loop and use ppmtoy4m to repeat last frame
5472
         # if we are not doing a fadeout, or if doing fadeout, cat the last
5473
@@ -9059,7 +9876,7 @@
5474
                     2>> "$LOG_FILE" &
5475
                 else # not SHOWCASE_VIDEO (SHOWCASE_IMG)
5476
                     { "${MONTAGE_CMD[@]}" miff:- | "${MONTAGE_CMD02[@]}" miff:- |
5477
-                    "${MONTAGE_CMD2c[@]}" miff:- |"${MONTAGE_CMD5[@]}" |
5478
+                    "${MONTAGE_CMD2c[@]}" miff:- | "${MONTAGE_CMD5[@]}" |
5479
                     "${MONTAGE_CMD6[@]}" | "${MONTAGE_CMD3[@]}" miff:- |
5480
                     "${MONTAGE_CMD4[@]}" | "${MONTAGE_CMD7[@]}" ; } \
5481
                     2>> "$LOG_FILE" &
5482
@@ -9311,95 +10128,105 @@
5483
 fi # end making final montages
5484
 # wait for ppmtoy4m and ffmpeg to finish
5485
 wait
5486
+# send formated ffmpeg output to log
5487
+if [[ -e "${LOG_FILE}.1-tmp" ]]; then
5488
+    cat "${LOG_FILE}.1-tmp" | pipe2log ppmtoy4m
5489
+    rm -f "${LOG_FILE}.1-tmp"
5490
+fi
5491
+if [[ -e "${LOG_FILE}.2-tmp" ]]; then
5492
+    cat "${LOG_FILE}.2-tmp" | pipe2log ${FFmpeg##*/}
5493
+    rm -f "${LOG_FILE}.2-tmp"
5494
+fi
5495
 
5496
 if ! $QUICK_MENU && $DO_MENU; then
5497
     echo
5498
-    echo "Cleaning up montage images"
5499
+    print2log "Cleaning up montage images"
5500
     rm -f $WORK_DIR/animenu/*.$IMG_FMT
5501
     rm -f $WORK_DIR/animenu/*.png
5502
 fi
5503
 # check if m2v was created ok before proceeding
5504
 if $DO_MENU; then
5505
-    if ! mencoder -quiet -oac pcm -ovc copy -frames 0 \
5506
-      "$WORK_DIR/intro.m2v" -o /dev/null &> /dev/null; then
5507
+    if ! is_video "$WORK_DIR/intro.m2v"; then
5508
         echo
5509
         runtime_error  "The menu video file has not been created !"
5510
     fi
5511
 fi
5512
 if $DO_MENU; then
5513
-    MENU_ATIME=$(vid_length "$WORK_DIR/intro.m2v")
5514
+    MENU_ATIME=$(stream_length "$WORK_DIR/intro.m2v" m2v)
5515
     $SWITCHED && MENU_ATIME=${MENU_LEN[MENU_NUM-1]}
5516
 fi
5517
-
5518
 # use mplayer to dump audio if mplayer used for video
5519
 # but first check if audio same file as video and its not a static menu
5520
 if [[ $SC_FRAMESTYLE = "glass" && $BG_AUDIO = $SHOWCASE_VIDEO ]]; then
5521
     ! $STATIC && USE_MPLAYER_4AUDIO=:
5522
 fi
5523
 BG_AUDIO_LENGTH="-t $MENU_ATIME"
5524
-# create audio background for the main menu
5525
+# audio background for main menu #
5526
 if $DO_MENU; then
5527
-    sample_size=$(get_sox_arg)
5528
     if [[ -z "$BG_AUDIO" || "$BG_AUDIO" = "none" ]]; then # use silence
5529
         ! $SWITCHED && AUDIO_FADE=false # do not fade silence
5530
-        echo "Running cat /dev/zero 2>/dev/null | nice -n 0 sox -t raw -c 2 -r 48000 \
5531
-        $sample_size -s - $WORK_DIR/intro.wav  trim 0 $MENU_ATIME" |fold -bs
5532
-        cat /dev/zero 2>/dev/null | nice -n 0 sox -t raw -c 2 -r 48000 \
5533
-        $sample_size -s - $WORK_DIR/intro.wav  trim 0 $MENU_ATIME
5534
+        BGAUDIO_CMD=($FFmpeg -f s16le -ar 48000 -i /dev/zero -ar 48000 \
5535
+        -t $MENU_ATIME -ac 2 -acodec pcm_s16le -y $WORK_DIR/intro.wav)
5536
+        print2log "Running ${BGAUDIO_CMD[@]}"
5537
+        "${BGAUDIO_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
5538
+        if [[ ! -s "$WORK_DIR/intro.wav" ]]; then
5539
+            runtime_error "There was a problem creating menu background silence"
5540
+        fi
5541
     # Make sure file exists
5542
     elif test ! -s "$BG_AUDIO"; then
5543
         runtime_error "Cannot find background audio file: $BG_AUDIO"
5544
-    else # audio supplied: convert to wav then later to dvd/svcd format
5545
+    else # audio supplied: convert to wav then later to dvd format
5546
         # TODO if ! $BG_AUDIOVIDEO_FILE; then  # check if same file and if so
5547
         # decode the audio and jpegs in one step above, and skip this block
5548
         if $USE_MPLAYER_4AUDIO; then
5549
-            BGAUDIO_CMD=(mplayer  -quiet -vc null -vo null -ss \
5550
+            pipe_prog=mplayer
5551
+            BGAUDIO_CMD=(mplayer -quiet -vc null -vo null -ss \
5552
             $MPLAYER_SEEK_VAL -ao pcm:waveheader:file="$WORK_DIR/intro.wav" \
5553
             -endpos $MENU_ATIME  "$BG_AUDIO")
5554
         else
5555
-            BGAUDIO_CMD=(ffmpeg -y -async 1 -ss $BG_AUDIO_SEEK \
5556
-            $BG_AUDIO_LENGTH -i "$BG_AUDIO" -r $FRAME_RATE -ar 48000 \
5557
+            pipe_prog=${FFmpeg##*/}
5558
+            BGAUDIO_CMD=($FFmpeg -y \
5559
+            -i "$BG_AUDIO" -vn -ss $BG_AUDIO_SEEK $BG_AUDIO_LENGTH -ar 48000 \
5560
             -acodec pcm_s16le $WORK_DIR/intro.wav)
5561
         fi
5562
-        yecho
5563
-        echo "Running ${BGAUDIO_CMD[@]}" |format_output|tee -a "$LOG_FILE" 2>&1
5564
-        ! "${BGAUDIO_CMD[@]}" 2>&1 |strings >> "$LOG_FILE" && runtime_error
5565
+        print2log "Running ${BGAUDIO_CMD[@]}"
5566
+        "${BGAUDIO_CMD[@]}" 2>&1 |pipe2log $pipe_prog
5567
+        ((${PIPESTATUS[0]} != 0)) && runtime_error \
5568
+          "Problem creating wav file during background audio processing"
5569
 
5570
         if $AUDIO_FADE; then  # bgaudio supplied and audio fade selected
5571
-            WAV_TIME=$(audio_length "$WORK_DIR/intro.wav")
5572
-            echo "Running:
5573
+            WAV_TIME=$(stream_length "$WORK_DIR/intro.wav" audio)
5574
+            print2log "Running:
5575
             sox $WORK_DIR/intro.wav $WORK_DIR/intro-processed.wav fade t
5576
-            $FADE $WAV_TIME $FADE" |format_output
5577
+            $FADE $WAV_TIME $FADE"
5578
             sox $WORK_DIR/intro.wav \
5579
-            $WORK_DIR/intro-processed.wav fade t $FADE $WAV_TIME $FADE
5580
-            rm $WORK_DIR/intro.wav
5581
+            $WORK_DIR/intro-processed.wav fade t $FADE $WAV_TIME $FADE 2>&1 | pipe2log sox
5582
+            $KEEP_FILES || rm $WORK_DIR/intro.wav
5583
             mv $WORK_DIR/intro-processed.wav $WORK_DIR/intro.wav
5584
         fi
5585
     fi
5586
-fi
5587
-unset BGAUDIO_CMD TIME
5588
+    unset BGAUDIO_CMD TIME
5589
+
5590
+    # convert to proper audio format
5591
+    BGAUDIO_CMD=($FFmpeg -i $WORK_DIR/intro.wav \
5592
+    $AUDIO_OPTS -y $WORK_DIR/intro.$AUDIO_EXT)
5593
+    echo "Running "${BGAUDIO_CMD[@]}"" | pipe2log
5594
+    "${BGAUDIO_CMD[@]}" 2>&1 | pipe2log ${FFmpeg##*/}
5595
 
5596
-# convert to proper audio format
5597
-BGAUDIO_CMD=(ffmpeg -i $WORK_DIR/intro.wav \
5598
-$AUDIO_OPTS -y $WORK_DIR/intro.$AUDIO_EXT)
5599
-yecho "Running "${BGAUDIO_CMD[@]}"" | fold -bs >> "$LOG_FILE"
5600
-"${BGAUDIO_CMD[@]}" 2>&1 |strings >> "$LOG_FILE"
5601
-if $DO_MENU; then
5602
      ! [[ -s $WORK_DIR/intro.$AUDIO_EXT ]] && runtime_error
5603
     unset BGAUDIO_CMD
5604
-    rm -fv "$WORK_DIR/intro.wav"
5605
-    echo
5606
-    echo "Multiplexing main menu audio and video together"
5607
+    $KEEP_FILES || rm -f "$WORK_DIR/intro.wav"
5608
+    print2log "Multiplexing main menu audio and video together"
5609
     # mplex main menu audio and video together
5610
     INTRO_MPLEX_CMD="mplex -V -f $MPLEX_FORMAT -o $WORK_DIR/intro.mpg \
5611
       $WORK_DIR/intro.$AUDIO_EXT $WORK_DIR/intro.m2v"
5612
-    echo -e "\nRunning: $INTRO_MPLEX_CMD\n" |fold -bs >> "$LOG_FILE"
5613
-    yecho
5614
-    ! ${INTRO_MPLEX_CMD[@]} 2>&1 |strings >> "$LOG_FILE" && runtime_error
5615
+    print2log "Running: $INTRO_MPLEX_CMD"
5616
+    ${INTRO_MPLEX_CMD[@]} 2>&1 |pipe2log mplex
5617
+    ((${PIPESTATUS[0]} != 0)) && runtime_error \
5618
+      "Problem muxing the menu video and audio with mplex"  
5619
 
5620
-    yecho
5621
     if $SWITCHED_MODE || $SWITCHED_MENUS; then
5622
-        yecho "Copying the menu mpeg"
5623
+        echo "Copying the menu mpeg" |pipe2log
5624
         if [[ $MENU_NUM -ne 1 ]]; then
5625
             cp -v "$REAL_WORK_DIR/intro.mpg" \
5626
               "$BASEDIR/${TSET_NUM}-${MENU_NUM}intro.mpg"
5627
@@ -9416,31 +10243,43 @@
5628
         fi
5629
     fi
5630
     if $SWITCHED_MENUS; then
5631
+        print2log "Running spumux to create navigation buttons."
5632
         for ((i=1; i<=${#FILES[@]}; i++)); do
5633
             MENU_FILE="$BASEDIR/animenu${TSET_NUM}-${i}.mpg"
5634
-            yecho "Running spumux "$SPUMUX_XML" \
5635
-              < "$REAL_WORK_DIR/${TSET_NUM}-${i}intro.mpg" > "$MENU_FILE""
5636
+            print2log "Running spumux $SPUMUX_XML \
5637
+              < $REAL_WORK_DIR/${TSET_NUM}-${i}intro.mpg > $MENU_FILE"
5638
             spumux "$SPUMUX_XML" < "$WORK_DIR/${TSET_NUM}-${i}intro.mpg" \
5639
-              > "$MENU_FILE" 2>> "$LOG_FILE"
5640
+              > "$MENU_FILE" 2>> "${LOG_FILE}.tmp"
5641
+            wait
5642
+            [[ -e ${LOG_FILE}.tmp ]] && cat "${LOG_FILE}.tmp" | pipe2log spumux
5643
+            rm -f ${LOG_FILE}.tmp
5644
             check_menufile
5645
         done
5646
     fi
5647
 fi
5648
 if ! $SWITCHED_MENUS && ! $SWITCHED_MODE; then
5649
-    yecho "Running spumux "$SPUMUX_XML" < $WORK_DIR/intro.mpg > "$MENU_FILE""
5650
-    spumux "$SPUMUX_XML" < $WORK_DIR/intro.mpg > "$MENU_FILE" 2>> "$LOG_FILE"
5651
+    print2log "Running spumux $SPUMUX_XML < $WORK_DIR/intro.mpg > $MENU_FILE"
5652
+    spumux "$SPUMUX_XML" < $WORK_DIR/intro.mpg > "$MENU_FILE" 2>> "${LOG_FILE}.tmp"
5653
+    wait
5654
+    [[ -e ${LOG_FILE}.tmp ]] && cat "${LOG_FILE}.tmp" | pipe2log spumux
5655
+    rm -f ${LOG_FILE}.tmp
5656
     check_menufile
5657
 fi
5658
 if $SUB_MENU; then
5659
-    echo "Creating submenus"
5660
+    echo "Creating submenus" | pipe2log
5661
+    print2log "Running spumux to create navigation buttons"
5662
     for ((x=1; x<=V_TOTAL; x++)); do
5663
-        yecho "Running spumux "$WORK_DIR/submenu${x}_spumux.xml" < \
5664
+        print2log "Running spumux "$WORK_DIR/submenu${x}_spumux.xml" < \
5665
         $WORK_DIR/menu${x}.mpg > \
5666
         $(sed 's/\(.*\)menu/\1Menu/' <<< $WORK_DIR/menu${x}.mpg)"|fold -bs
5667
         spumux "$WORK_DIR/submenu${x}_spumux.xml" < \
5668
         $WORK_DIR/menu${x}.mpg > \
5669
         $(sed 's/\(.*\)menu/\1Menu/' <<< $BASEDIR/${TSET_NUM}-menu${x}.mpg) \
5670
-        2>> "$LOG_FILE"
5671
+        2>> "${LOG_FILE}.tmp"
5672
+        wait
5673
+        [[ -e ${LOG_FILE}.tmp ]] && cat "${LOG_FILE}.tmp" | pipe2log spumux
5674
+        rm -f ${LOG_FILE}.tmp
5675
+        
5676
     done
5677
 fi
5678
 if $TITLESET_MODE; then
5679
@@ -9448,14 +10287,14 @@
5680
 fi
5681
 
5682
 if $AUTHOR && ! $VMGM_ONLY && ! $DO_TITLESETS && ! $SWITCHED_MODE; then
5683
-    echo "Running dvdauthor to create the DVD filesystem"
5684
-    dvdauthor -x "$DVDAUTHOR_XML" 2>&1  | tee -a  "$LOG_FILE.tmp"
5685
+    yecho "Running dvdauthor to create the DVD filesystem"
5686
+    dvdauthor -x "$DVDAUTHOR_XML" 2>&1  | pipe2log dvdauthor
5687
     if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
5688
         dvdauthor_error
5689
     fi
5690
-    strings "$LOG_FILE.tmp" >> "$LOG_FILE" && rm -f "$LOG_FILE.tmp"
5691
+    #strings "$LOG_FILE.tmp" >> "$LOG_FILE" && rm -f "$LOG_FILE.tmp"
5692
 fi
5693
-echo "Cleaning up unwanted files in $REAL_WORK_DIR"
5694
+print2log "Cleaning up unwanted files in $REAL_WORK_DIR"
5695
 find "$WORK_DIR"/ -name '*.$IMG_FMT' ! -name preview.$IMG_FMT -exec rm -f {} \; \
5696
 > /dev/null 2>&1
5697
 rm -fr "$WORK_DIR/animenu" "$WORK_DIR/pics" "$WORK_DIR/submenu"
5698
tovid-0.34.tar.bz2/src/todisc-fade-routine -> tovid-0.35.tar.gz/src/todisc-fade-routine Changed
10
 
1
@@ -7,7 +7,7 @@
2
 #
3
 # Project homepage: http://tovid.wikia.com
4
 #
5
-# Copyright (C) 2005-2010
6
+# Copyright (C) 2005-2015
7
 #
8
 # This program is free software; you can redistribute it and/or
9
 # modify it under the terms of the GNU General Public License
10
tovid-0.34.tar.bz2/src/todiscgui -> tovid-0.35.tar.gz/src/todiscgui Changed
23
 
1
@@ -4,6 +4,20 @@
2
 import sys
3
 from libtovid.guis import todisc
4
 
5
+command = []
6
+position = ''
7
+project = ''
8
 if __name__ == '__main__':
9
-    todisc.run(sys.argv[1:])
10
+    args = sys.argv[1:]
11
+    while args:
12
+        arg = args.pop(0)
13
+        # if passing --position pop next arg as well
14
+        if arg in ['--position', '-position']:
15
+            position = args.pop(0)
16
+        elif arg in ['--project', '-project']:
17
+            project = args.pop(0)
18
+        else:
19
+            # if --position or --project not passed, all args append to command
20
+            command.append(arg)
21
+    todisc.run(command, position=position, project=project)
22
 
23
tovid-0.34.tar.bz2/src/tovid -> tovid-0.35.tar.gz/src/tovid Changed
136
 
1
@@ -1,4 +1,4 @@
2
-#! /usr/bin/env python
3
+#!/usr/bin/python
4
 # tovid.py
5
 
6
 """Frontend to the tovid suite.
7
@@ -10,19 +10,24 @@
8
 
9
 Where 'command' is one of the following:
10
 
11
-    Command     Description                                 Formerly
12
-    -----------------------------------------------------------------
13
-    id          Identify one or more video files            idvid
14
-    dvd         Author and/or burn a DVD                    makedvd
15
-    menu        Create an MPEG menu                         makemenu
16
-    vcd         Author and/or burn a VCD                    makevcd
17
-    xml         Create (S)VCD or DVD .xml file              makexml
18
-    postproc    Post-process an MPEG video file             postproc
19
-    disc        Create a DVD with menus                     todisc
20
-    gui         Start the tovid GUI                         todiscgui
21
-    mpg         Encode videos to MPEG format                tovid
22
-    titlesets   Start the titleset wizard                   (new)
23
-    chapters    Set video chapter points with mplayer       (new)
24
+    Main commands (one step DVD creation)
25
+
26
+    Command     Description                                       Formerly
27
+    -----------------------------------------------------------------------
28
+    disc        Options to encode, make menus, author and burn    todisc
29
+    gui         Start the tovid GUI                               todiscgui
30
+    titlesets   Start the titleset wizard GUI                     (new)
31
+
32
+
33
+    Helper commands (used by 'Main commands' or run standalone)
34
+
35
+    Command     Description                                       Formerly
36
+    -----------------------------------------------------------------------
37
+    mpg         Encode videos to MPEG format                      tovid
38
+    id          Identify one or more video files                  idvid
39
+    dvd         Author and/or burn a DVD                          makedvd
40
+    chapters    A GUI to set chapter points with mplayer          (new)
41
+
42
 
43
 The following general options are also available:
44
     --prefix | -prefix      Return the tovid install prefix
45
@@ -41,16 +46,16 @@
46
 import time
47
 import shlex
48
 import shutil
49
-from ConfigParser import ConfigParser
50
+# python 3 compatibility
51
+try:
52
+    from ConfigParser import ConfigParser
53
+except ImportError:
54
+    from configparser import ConfigParser
55
 
56
 # Command names to script mappings
57
 _scripts = {
58
     'id': 'idvid',
59
     'dvd': 'makedvd',
60
-    'menu': 'makemenu',
61
-    'vcd': 'makevcd',
62
-    'xml': 'makexml',
63
-    'postproc': 'postproc',
64
     'disc': 'todisc',
65
     'gui': 'todiscgui',
66
     'mpg': 'makempg',
67
@@ -86,8 +91,11 @@
68
         """Return the tovid version string.
69
         """
70
         tovid_init = self.script_dir + '/tovid-init'
71
-        cmd = shlex.split("bash -c '. %s && printf $TOVID_VERSION'" % tovid_init)
72
-        return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
73
+        # can't just source tovid-init to get TOVID_VERSION - sourcing may fail
74
+        cmd = shlex.split("awk -F= '/^TOVID_VERSION/ {print $2}' %s" % tovid_init)
75
+        result = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]
76
+        # Python 3 needs decode("utf-8") as it returns a byte string not str
77
+        return result.decode("utf-8").replace('"', '').strip()
78
 
79
 
80
     def parse_options(self, args):
81
@@ -98,11 +106,11 @@
82
             arg = args.pop(0)
83
 
84
             if arg in ['-prefix', '--prefix']:
85
-                print self.prefix
86
+                print(self.prefix)
87
                 sys.exit(0)
88
 
89
             elif arg in ['-version', '--version']:
90
-                print self.version
91
+                print(self.version)
92
                 sys.exit(0)
93
 
94
             elif arg in ['-info', '--info']:
95
@@ -166,23 +174,30 @@
96
             return
97
 
98
         # Create ~/.tovid if it doesn't exist already
99
-        user_tovid_dir = os.path.expanduser('~/.tovid')
100
-        if not os.path.exists(user_tovid_dir):
101
-            print("Creating '%s'" % user_tovid_dir)
102
-            os.mkdir(user_tovid_dir)
103
-
104
+        # honour TOVID_HOME environment variable
105
+        self.user_tovid_dir = os.getenv('TOVID_HOME') or os.path.expanduser('~/.tovid')
106
+        #user_tovid_dir = os.path.expanduser('~/.tovid')
107
+
108
+        if not os.path.exists(self.user_tovid_dir):
109
+            try:
110
+                os.mkdir(self.user_tovid_dir)
111
+                print("Creating '%s'" % self.user_tovid_dir)
112
+            except OSError:
113
+                print("Cannot create %s, exiting ..." %self.user_tovid_dir)
114
+                sys.exit(1)
115
         # Copy default tovid.ini to ~/.tovid if it doesn't exist already
116
-        user_tovid_ini = os.path.join(user_tovid_dir, 'tovid.ini')
117
-        if not os.path.exists(user_tovid_ini):
118
-            print("Creating '%s'" % user_tovid_ini)
119
-            shutil.copy(default_tovid_ini, user_tovid_ini)
120
+        self.user_tovid_ini = os.path.join(self.user_tovid_dir, 'tovid.ini')
121
+        if not os.path.exists(self.user_tovid_ini):
122
+            print("Creating '%s'" % self.user_tovid_ini)
123
+            shutil.copy(default_tovid_ini, self.user_tovid_ini)
124
 
125
 
126
     def get_config_options(self, command):
127
         """Return any options found in ~/.tovid/tovid.ini for the given command.
128
         """
129
         # Parse the user's tovid.ini file
130
-        filename = os.path.expanduser('~/.tovid/tovid.ini')
131
+        #filename = os.path.expanduser('~/.tovid/tovid.ini')
132
+        filename = self.user_tovid_ini
133
         config = ConfigParser()
134
         config.read(filename)
135
         # If no [command] section exists, or if there's no 'options' setting,
136
tovid-0.34.tar.bz2/src/tovid-init -> tovid-0.35.tar.gz/src/tovid-init Changed
185
 
1
@@ -8,7 +8,7 @@
2
 #
3
 # Project homepage: http://tovid.wikia.com
4
 #
5
-# Copyright (C) 2005-2010
6
+# Copyright (C) 2005-2014
7
 #
8
 # This program is free software; you can redistribute it and/or
9
 # modify it under the terms of the GNU General Public License
10
@@ -45,7 +45,7 @@
11
 #set -u
12
 
13
 # Suite version
14
-TOVID_VERSION="0.34"
15
+TOVID_VERSION="0.35"
16
 
17
 # String used to separate blocks of output
18
 SEPARATOR="========================================================="
19
@@ -53,7 +53,7 @@
20
 TOVID_HOME="$HOME/.tovid"
21
 TOVID_HOME_PAGE="http://tovid.wikia.com"
22
 TOVID_FORUMS="http://groups.google.com/group/tovid-users"
23
-
24
+TOVID_ISSUES="http://code.google.com/p/tovid/issues/list"
25
 
26
 # ******************************************************************************
27
 # ******************************************************************************
28
@@ -180,9 +180,8 @@
29
 # ******************************************************************************
30
 # Take a string containing a time (like "02:15:25.3") and
31
 # format it as an integer number of seconds. Fractional seconds
32
-# are truncated. Result is echoed to stdout, so to use the output
33
-# as a "return value", call the function like this:
34
-#     RETURN_VALUE=$(unformat_time $TIME_STRING)
35
+# are truncated. Result is echoed to stdout, so to use the output you can
36
+# call the function like this: var=$(unformat_time $TIME_STRING)
37
 # ******************************************************************************
38
 function unformat_time()
39
 {
40
@@ -195,7 +194,11 @@
41
     else
42
         TOT_SECONDS=$1
43
     fi
44
-    echo $TOT_SECONDS
45
+    if [[ -n $2 && $2 = "int" ]]; then
46
+        echo ${TOT_SECONDS%%.*}
47
+    else
48
+        echo $TOT_SECONDS
49
+    fi
50
 }
51
 
52
 # *****************************************************************************
53
@@ -278,15 +281,17 @@
54
     # Wait for input file to appear
55
     # After a 30-second timeout, exit gracefully
56
     CUR_TIME=30
57
-    while test $CUR_TIME -gt 0; do
58
+    while test $CUR_TIME -gt 0; do 
59
+        sleep 3
60
         # If file exists, wait a few more seconds, then break out
61
         if test -e "$FOP_OUTFILE"; then
62
-            printf "Processing started. Please wait...                                               "
63
-            sleep 3s
64
+            $QUIET || printf "Processing started. Please wait...                                               "
65
+            sleep 1
66
+            CUR_TIME=1
67
             break
68
         fi
69
         printf "Waiting $CUR_TIME seconds for output file \"$FOP_BASENAME_NAME\" to appear...\r"
70
-        sleep 1s
71
+        sleep 1
72
         CUR_TIME=$(expr $CUR_TIME - 1)
73
     done
74
 
75
@@ -319,12 +324,12 @@
76
 
77
         # Doze a bit to let the file size increase
78
         # (SLEEP_TIME defaults to 1s if unset)
79
-        sleep ${SLEEP_TIME-"1s"}
80
+        sleep ${SLEEP_TIME-"1"}
81
 
82
         FOP_LAST_SIZE=$FOP_CUR_SIZE
83
         FOP_CUR_SIZE=$(du -b "$FOP_OUTFILE" | awk '{print $1}')
84
     done
85
-    printf "\n\n"
86
+    $QUIET && printf "\n" || printf "\n\n"
87
 }
88
 
89
 # ******************************************************************************
90
@@ -412,8 +417,8 @@
91
     count=$(seq 1 $LAST)
92
     for _CNTR in $(sort -nr <<< "$count")
93
     do
94
-        echo -n -e " in $_CNTR seconds...\r";
95
-        sleep 1s;
96
+        echo -n -e " in $_CNTR seconds...or press <ENTER>\r";
97
+        read  -t 1 && break;
98
     done
99
 }
100
 
101
@@ -437,7 +442,18 @@
102
     done
103
     return 0
104
 }
105
-
106
+# *****************************************************************************
107
+# takes 1 arg:  [name to prefix each line of output]
108
+# uses stdbuf (coreutils) if present so stdin is line buffered
109
+send_to_log()
110
+{
111
+    [[ $1 ]] && prog_name="[$1]: " || prog_name="[${0##*/}]: "
112
+    $std_buf tr "\015" "\n" < /dev/stdin | \
113
+    while read line; do
114
+        printf "%s %s\n" "$prog_name" "$line"
115
+    done
116
+    printf "\n"
117
+}
118
 
119
 # ******************************************************************************
120
 #
121
@@ -456,7 +472,8 @@
122
 KERNEL=$(uname)
123
 if test "$KERNEL" = "Linux"; then
124
     # Linux should have /proc/cpuinfo
125
-    CPU_MODEL=$(awk -F ":" '/model name/ {print $2}' /proc/cpuinfo | head -n 1)
126
+    CPU_MODEL=$(awk -F ":" '/model name/ {print $2}' \
127
+    /proc/cpuinfo | head -n 1 | sed 's/^  *//g')
128
     CPU_SPEED=$(awk 'BEGIN { IGNORECASE = 1 } /MHz/ { print $4 }' /proc/cpuinfo | head -n 1)
129
     # Test for multiple CPUs. If they are available, try to use them.
130
     if test $(grep "^processor" /proc/cpuinfo | wc -l) -ge "2"; then
131
@@ -529,14 +546,29 @@
132
 # tovid preferences
133
 # Configures working directory for all scripts and
134
 # output directory for the makempg script
135
+# also used for setting ffmpeg/avconv program
136
 #WORKING_DIR=/tmp
137
 #OUTPUT_DIR=/video/outfiles
138
+#TOVID_FFMPEG=ffmpeg
139
 EOF`
140
     printf "$PREFS_CONTENTS\n" > "$USER_PREFS"
141
 fi
142
 # if preferences vars are set in the environment, use those (takes precedence).
143
 [[ $TOVID_WORKING_DIR ]] && WORKING_DIR="$TOVID_WORKING_DIR"
144
 [[ $TOVID_OUTPUT_DIR ]] && OUTPUT_DIR="$TOVID_WORKING_DIR"
145
+[[ $TOVID_FFMPEG_CMD ]] && TOVID_FFMPEG="$TOVID_FFMPEG_CMD"
146
+# FFmpeg and FFprobe are vars used for ffmpeg by scripts needing ffmpeg/avconv
147
+# if avconv is installed, use that unless env var set
148
+hash avconv 2>/dev/null && TOVID_FFMPEG=${TOVID_FFMPEG:-avconv}
149
+hash avprobe 2>/dev/null && TOVID_FFPROBE=${TOVID_FFPROBE:=avprobe}
150
+# finally, default to ffmpeg if non of the above override it
151
+FFmpeg=${TOVID_FFMPEG:=ffmpeg}
152
+[[ $FFmpeg =~ ffmpeg ]] && TOVID_FFPROBE=ffprobe
153
+[[ $FFmpeg =~ avconv ]] && TOVID_FFPROBE=avprobe
154
+FFprobe=${TOVID_FFPROBE:=ffprobe}
155
+
156
+# stdbuf (coreutils>=7.5) is useful to todisc and makempg, use it if present
157
+hash stdbuf 2>/dev/null && std_buf="stdbuf -oL" || std_buf=""
158
 
159
 # ******************************************************************************
160
 # Check for run-time dependencies
161
@@ -561,7 +593,7 @@
162
     # *************************************************************************
163
     # Required Dependencies
164
     # *************************************************************************
165
-    core="grep sed md5sum mplayer mencoder mplex mpeg2enc yuvfps yuvdenoise ppmtoy4m mp2enc jpeg2yuv ffmpeg"
166
+    core="grep sed md5sum mplayer mplex mpeg2enc yuvfps yuvdenoise ppmtoy4m mp2enc jpeg2yuv"
167
 
168
     # *************************************************************************
169
     # Optional Dependencies
170
@@ -596,9 +628,13 @@
171
 
172
     # -------------------------------------------------------------------------
173
     # todisc dependencies
174
-    todisc_deps="$magick mogrify spumux dvdauthor transcode sox"
175
+    todisc_deps="$magick mogrify spumux dvdauthor sox"
176
 
177
     # Quit and complain if ANY core dependency is missing.
178
     assert_dep "$core" "You are missing CORE tovid dependencies!"
179
+    # ffmpeg is also a part of core deps, but is taken care of here
180
+    ffmpeg_alts="Use either ffmpeg (ffmpeg.org) or avconv (libav.org)."
181
+    ffmpeg_pref="Set choice in ${USER_PREFS}. As in: TOVID_FFMPEG=ffmpeg"
182
+    assert_dep $FFmpeg "You are missing $FFmpeg ! $ffmpeg_alts ${ffmpeg_pref}."
183
 
184
 # End tovid-init
185
tovid-0.34.tar.bz2/src/tovid-init.in -> tovid-0.35.tar.gz/src/tovid-init.in Changed
176
 
1
@@ -8,7 +8,7 @@
2
 #
3
 # Project homepage: http://tovid.wikia.com
4
 #
5
-# Copyright (C) 2005-2010
6
+# Copyright (C) 2005-2014
7
 #
8
 # This program is free software; you can redistribute it and/or
9
 # modify it under the terms of the GNU General Public License
10
@@ -53,7 +53,7 @@
11
 TOVID_HOME="$HOME/.tovid"
12
 TOVID_HOME_PAGE="http://tovid.wikia.com"
13
 TOVID_FORUMS="http://groups.google.com/group/tovid-users"
14
-
15
+TOVID_ISSUES="http://code.google.com/p/tovid/issues/list"
16
 
17
 # ******************************************************************************
18
 # ******************************************************************************
19
@@ -180,9 +180,8 @@
20
 # ******************************************************************************
21
 # Take a string containing a time (like "02:15:25.3") and
22
 # format it as an integer number of seconds. Fractional seconds
23
-# are truncated. Result is echoed to stdout, so to use the output
24
-# as a "return value", call the function like this:
25
-#     RETURN_VALUE=$(unformat_time $TIME_STRING)
26
+# are truncated. Result is echoed to stdout, so to use the output you can
27
+# call the function like this: var=$(unformat_time $TIME_STRING)
28
 # ******************************************************************************
29
 function unformat_time()
30
 {
31
@@ -195,7 +194,11 @@
32
     else
33
         TOT_SECONDS=$1
34
     fi
35
-    echo $TOT_SECONDS
36
+    if [[ -n $2 && $2 = "int" ]]; then
37
+        echo ${TOT_SECONDS%%.*}
38
+    else
39
+        echo $TOT_SECONDS
40
+    fi
41
 }
42
 
43
 # *****************************************************************************
44
@@ -278,15 +281,17 @@
45
     # Wait for input file to appear
46
     # After a 30-second timeout, exit gracefully
47
     CUR_TIME=30
48
-    while test $CUR_TIME -gt 0; do
49
+    while test $CUR_TIME -gt 0; do 
50
+        sleep 3
51
         # If file exists, wait a few more seconds, then break out
52
         if test -e "$FOP_OUTFILE"; then
53
-            printf "Processing started. Please wait...                                               "
54
-            sleep 3s
55
+            $QUIET || printf "Processing started. Please wait...                                               "
56
+            sleep 1
57
+            CUR_TIME=1
58
             break
59
         fi
60
         printf "Waiting $CUR_TIME seconds for output file \"$FOP_BASENAME_NAME\" to appear...\r"
61
-        sleep 1s
62
+        sleep 1
63
         CUR_TIME=$(expr $CUR_TIME - 1)
64
     done
65
 
66
@@ -319,12 +324,12 @@
67
 
68
         # Doze a bit to let the file size increase
69
         # (SLEEP_TIME defaults to 1s if unset)
70
-        sleep ${SLEEP_TIME-"1s"}
71
+        sleep ${SLEEP_TIME-"1"}
72
 
73
         FOP_LAST_SIZE=$FOP_CUR_SIZE
74
         FOP_CUR_SIZE=$(du -b "$FOP_OUTFILE" | awk '{print $1}')
75
     done
76
-    printf "\n\n"
77
+    $QUIET && printf "\n" || printf "\n\n"
78
 }
79
 
80
 # ******************************************************************************
81
@@ -412,8 +417,8 @@
82
     count=$(seq 1 $LAST)
83
     for _CNTR in $(sort -nr <<< "$count")
84
     do
85
-        echo -n -e " in $_CNTR seconds...\r";
86
-        sleep 1s;
87
+        echo -n -e " in $_CNTR seconds...or press <ENTER>\r";
88
+        read  -t 1 && break;
89
     done
90
 }
91
 
92
@@ -437,7 +442,18 @@
93
     done
94
     return 0
95
 }
96
-
97
+# *****************************************************************************
98
+# takes 1 arg:  [name to prefix each line of output]
99
+# uses stdbuf (coreutils) if present so stdin is line buffered
100
+send_to_log()
101
+{
102
+    [[ $1 ]] && prog_name="[$1]: " || prog_name="[${0##*/}]: "
103
+    $std_buf tr "\015" "\n" < /dev/stdin | \
104
+    while read line; do
105
+        printf "%s %s\n" "$prog_name" "$line"
106
+    done
107
+    printf "\n"
108
+}
109
 
110
 # ******************************************************************************
111
 #
112
@@ -456,7 +472,8 @@
113
 KERNEL=$(uname)
114
 if test "$KERNEL" = "Linux"; then
115
     # Linux should have /proc/cpuinfo
116
-    CPU_MODEL=$(awk -F ":" '/model name/ {print $2}' /proc/cpuinfo | head -n 1)
117
+    CPU_MODEL=$(awk -F ":" '/model name/ {print $2}' \
118
+    /proc/cpuinfo | head -n 1 | sed 's/^  *//g')
119
     CPU_SPEED=$(awk 'BEGIN { IGNORECASE = 1 } /MHz/ { print $4 }' /proc/cpuinfo | head -n 1)
120
     # Test for multiple CPUs. If they are available, try to use them.
121
     if test $(grep "^processor" /proc/cpuinfo | wc -l) -ge "2"; then
122
@@ -529,14 +546,29 @@
123
 # tovid preferences
124
 # Configures working directory for all scripts and
125
 # output directory for the makempg script
126
+# also used for setting ffmpeg/avconv program
127
 #WORKING_DIR=/tmp
128
 #OUTPUT_DIR=/video/outfiles
129
+#TOVID_FFMPEG=ffmpeg
130
 EOF`
131
     printf "$PREFS_CONTENTS\n" > "$USER_PREFS"
132
 fi
133
 # if preferences vars are set in the environment, use those (takes precedence).
134
 [[ $TOVID_WORKING_DIR ]] && WORKING_DIR="$TOVID_WORKING_DIR"
135
 [[ $TOVID_OUTPUT_DIR ]] && OUTPUT_DIR="$TOVID_WORKING_DIR"
136
+[[ $TOVID_FFMPEG_CMD ]] && TOVID_FFMPEG="$TOVID_FFMPEG_CMD"
137
+# FFmpeg and FFprobe are vars used for ffmpeg by scripts needing ffmpeg/avconv
138
+# if avconv is installed, use that unless env var set
139
+hash avconv 2>/dev/null && TOVID_FFMPEG=${TOVID_FFMPEG:-avconv}
140
+hash avprobe 2>/dev/null && TOVID_FFPROBE=${TOVID_FFPROBE:=avprobe}
141
+# finally, default to ffmpeg if non of the above override it
142
+FFmpeg=${TOVID_FFMPEG:=ffmpeg}
143
+[[ $FFmpeg =~ ffmpeg ]] && TOVID_FFPROBE=ffprobe
144
+[[ $FFmpeg =~ avconv ]] && TOVID_FFPROBE=avprobe
145
+FFprobe=${TOVID_FFPROBE:=ffprobe}
146
+
147
+# stdbuf (coreutils>=7.5) is useful to todisc and makempg, use it if present
148
+hash stdbuf 2>/dev/null && std_buf="stdbuf -oL" || std_buf=""
149
 
150
 # ******************************************************************************
151
 # Check for run-time dependencies
152
@@ -561,7 +593,7 @@
153
     # *************************************************************************
154
     # Required Dependencies
155
     # *************************************************************************
156
-    core="grep sed md5sum mplayer mencoder mplex mpeg2enc yuvfps yuvdenoise ppmtoy4m mp2enc jpeg2yuv ffmpeg"
157
+    core="grep sed md5sum mplayer mplex mpeg2enc yuvfps yuvdenoise ppmtoy4m mp2enc jpeg2yuv"
158
 
159
     # *************************************************************************
160
     # Optional Dependencies
161
@@ -596,9 +628,13 @@
162
 
163
     # -------------------------------------------------------------------------
164
     # todisc dependencies
165
-    todisc_deps="$magick mogrify spumux dvdauthor transcode sox"
166
+    todisc_deps="$magick mogrify spumux dvdauthor sox"
167
 
168
     # Quit and complain if ANY core dependency is missing.
169
     assert_dep "$core" "You are missing CORE tovid dependencies!"
170
+    # ffmpeg is also a part of core deps, but is taken care of here
171
+    ffmpeg_alts="Use either ffmpeg (ffmpeg.org) or avconv (libav.org)."
172
+    ffmpeg_pref="Set choice in ${USER_PREFS}. As in: TOVID_FFMPEG=ffmpeg"
173
+    assert_dep $FFmpeg "You are missing $FFmpeg ! $ffmpeg_alts ${ffmpeg_pref}."
174
 
175
 # End tovid-init
176
tovid-0.34.tar.bz2/src/tovid.ini -> tovid-0.35.tar.gz/src/tovid.ini Changed
54
 
1
@@ -17,6 +17,10 @@
2
 ; command, you can specify one or more "default" options that will always be
3
 ; passed to the 'tovid' script when used with that command.
4
 ;
5
+; Note that in the [gui] section you should use only boolean options as others
6
+; may have trouble loading, particularly options that 'optionally' take args or
7
+; optionally take one or many args
8
+;
9
 ; You can include all your desired default options on a single line, like this:
10
 ;
11
 ;     [mpg]
12
@@ -69,30 +73,6 @@
13
 ;    -device /dev/hdb
14
 ;    -speed 8
15
 
16
-[menu]
17
-options =
18
-;    -dvd
19
-;    -align center
20
-;    -textcolor #FF0000
21
-;    -overwrite
22
-
23
-[vcd]
24
-options =
25
-;    -device /dev/hdb
26
-;    -speed 24
27
-;    -quiet
28
-
29
-[xml]
30
-options =
31
-;    -overwrite
32
-;    -quiet
33
-;    -nochapters
34
-
35
-[postproc]
36
-options =
37
-;    -parallel
38
-;    -normalize
39
-
40
 [disc]
41
 options =
42
 ;    -thumb-shape plectrum
43
@@ -112,5 +92,9 @@
44
 
45
 [gui]
46
 options =
47
-
48
+;   -no-ask
49
+;   -no-warn
50
+;   -no-confirm-backup
51
+;   -ffmpeg
52
+;   -static
53
 
54
tovid-0.34.tar.bz2/tovidgui.desktop -> tovid-0.35.tar.gz/tovidgui.desktop Changed
16
 
1
@@ -4,10 +4,10 @@
2
 Exec=tovid gui
3
 Icon=tovid
4
 Terminal=false
5
-GenericName=DVD creation with menus
6
-GenericName[en_US]=DVD creation with menus
7
-Comment=Author videos to DVD with menus
8
-Comment[en_US]=Author videos to DVD with menus
9
+GenericName=DVD creation with optional menus
10
+GenericName[en_US]=DVD creation with optional menus
11
+Comment=Author videos to DVD with optional menus
12
+Comment[en_US]=Author videos to DVD with optional menus
13
 Categories=AudioVideo;Video;
14
 StartupNotify=true
15
 X-KDE-SubstituteUID=false
16