git @ Cat's Eye Technologies kinoje / b2ab037
Split final-movie-compilers off into their own module. Chris Pressey 5 years ago
2 changed file(s) with 59 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
0 import os
1
2
3 class Compiler(object):
4 def __init__(self, dirname, outfilename, options, exe):
5 self.dirname = dirname
6 self.options = options
7 self.exe = exe
8 self.outfilename = outfilename
9
10
11 class GifCompiler(Compiler):
12
13 def compile(self, num_frames):
14 # TODO: show some warning if this is not an integer delay
15 delay = int(100.0 / self.options.fps)
16
17 filenames = [os.path.join(self.dirname, self.options.frame_fmt % f) for f in xrange(0, num_frames)]
18 if self.options.twitter:
19 filespec = ' '.join(filenames[:-1] + ['-delay', str(delay / 2), filenames[-1]])
20 else:
21 filespec = ' '.join(filenames)
22
23 # -strip is there to force convert to process all input files. (if no transformation is given,
24 # it can sometimes stop reading input files. leading to skippy animations. who knows why.)
25 self.exe.do_it("convert -delay %s -loop 0 %s -strip %s" % (
26 delay, filespec, self.outfilename
27 ))
28
29 def view(self):
30 self.exe.do_it("eog %s" % self.outfilename)
31
32
33 class MpegCompiler(Compiler):
34
35 def compile(self, num_frames):
36 ifmt = os.path.join(self.dirname, self.options.frame_fmt)
37 # fun fact: even if you say -r 30, ffmpeg still picks 25 fps
38 cmd = "ffmpeg -i %s -c:v libx264 -profile:v baseline -pix_fmt yuv420p -r %s -y %s" % (
39 ifmt, int(self.options.fps), self.outfilename
40 )
41 self.exe.do_it(cmd)
42
43 def view(self):
44 self.exe.do_it("vlc %s" % self.outfilename)
2020
2121 from kinoje.utils import LoggingExecutor
2222 from kinoje.renderer import Renderer
23 from kinoje.compiler import GifCompiler, MpegCompiler
2324
2425
2526 SUPPORTED_OUTPUT_FORMATS = ('.m4v', '.mp4', '.gif')
131132
132133 tempdir = mkdtemp()
133134
134 framerate = options.fps
135
136135 duration = options.duration
137136 if duration is None:
138137 duration = config['duration']
140139 start_time = options.start * duration
141140 stop_time = options.stop * duration
142141 requested_duration = stop_time - start_time
143 num_frames = int(requested_duration * framerate)
144 t_step = 1.0 / (duration * framerate)
142 num_frames = int(requested_duration * options.fps)
143 t_step = 1.0 / (duration * options.fps)
145144
146145 print "Start time: t=%s, %s seconds" % (options.start, start_time)
147146 print "Stop time: t=%s, %s seconds" % (options.stop, stop_time)
148147 print "Requested duration: %s seconds" % requested_duration
149 print "Frame rate: %s fps" % framerate
150 print "Number of frames: %s (rounded to %s)" % (requested_duration * framerate, num_frames)
148 print "Frame rate: %s fps" % options.fps
149 print "Number of frames: %s (rounded to %s)" % (requested_duration * options.fps, num_frames)
151150 print "t-Step: %s" % t_step
152151
153152 exe = LoggingExecutor(os.path.join(tempdir, 'movie.log'))
175174 exe.do_it("eog %s" % fn)
176175 sys.exit(0)
177176
178 if outext == '.gif':
179 # TODO: show some warning if this is not an integer delay
180 delay = int(100.0 / framerate)
177 compiler = {
178 '.gif': GifCompiler,
179 '.mp4': MpegCompiler,
180 '.m4v': MpegCompiler,
181 }[outext](tempdir, outfilename, options, exe)
181182
182 filenames = [os.path.join(tempdir, options.frame_fmt % f) for f in xrange(0, num_frames)]
183 if options.twitter:
184 filespec = ' '.join(filenames[:-1] + ['-delay', str(delay / 2), filenames[-1]])
185 else:
186 filespec = ' '.join(filenames)
183 compiler.compile(num_frames)
184 finished_at = datetime.now()
187185
188 # -strip is there to force convert to process all input files. (if no transformation is given,
189 # it can sometimes stop reading input files. leading to skippy animations. who knows why.)
190 exe.do_it("convert -delay %s -loop 0 %s -strip %s" % (
191 delay, filespec, outfilename
192 ))
193 finished_at = datetime.now()
194 if options.view:
195 exe.do_it("eog %s" % outfilename)
196 elif outext in ('.mp4', '.m4v'):
197 ifmt = os.path.join(tempdir, options.frame_fmt)
198 # fun fact: even if you say -r 30, it still picks 25 fps
199 cmd = "ffmpeg -i %s -c:v libx264 -profile:v baseline -pix_fmt yuv420p -r %s -y %s" % (
200 ifmt, int(framerate), outfilename
201 )
202 exe.do_it(cmd)
203 finished_at = datetime.now()
204 if options.view:
205 exe.do_it("vlc %s" % outfilename)
206 else:
207 raise NotImplementedError
186 if options.view:
187 compiler.view()
208188
209189 exe.close()
210190