+class FatalException(Exception):
+ pass
+
+def mkarg(arg):
+ if re.match("^[a-zA-Z0-9\-\\.,/@_:=]*$", arg):
+ return arg
+
+ if "'" not in arg:
+ return "'%s'" % arg
+ out = "\""
+ for c in arg:
+ if c in "\\$\"`":
+ out += "\\"
+ out += c
+ out += "\""
+ return out
+
+class Command(object):
+ def __init__(self, profile, opts):
+ self.profile = profile
+ self.opts = opts
+
+ def print_install_message(self):
+ print >>sys.stderr, "Problem with command: %s", self.name
+ if self.package:
+ print >>sys.stderr, "Try running:\n# aptitude install %s", self.package
+
+ def check_command(self, cmd):
+ if self.opts.dump:
+ return
+ if subprocess.Popen(["which", cmd], stdout=open("/dev/null", "w")).wait() != 0:
+ raise FatalException("Command '%s' is required" % cmd)
+
+ def check_no_file(self, path):
+ if os.path.exists(path):
+ raise FatalException("Output file '%s' exists." % path)
+
+ def do_exec(self, args):
+ if self.opts.dump:
+ print " ".join(map(mkarg, args))
+ else:
+ if subprocess.Popen(args).wait() != 0:
+ raise FatalException("Failure executing command: %s" % args)
+
+
+class MP4Box(Command):
+ codec2exts = {
+ "xvid": "m4v",
+ "x264": "h264",
+ "faac": "aac",
+ }
+
+ def check(self):
+ self.check_command("mencoder")
+ self.check_command("MP4Box")
+ self.check_no_file(self.opts.output + ".mp4")
+
+ def run(self):
+ p = self.profile
+ input = self.opts.output + ".avi" # From Mencoder command
+ output = self.opts.output + ".mp4"
+
+ # Check FPS
+ fps = "???"
+ if not self.opts.dump:
+ process = subprocess.Popen(
+ ["mplayer", "-frames", "0", "-identify", input],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ for line in process.stdout:
+ try:
+ key, value = line.split("=")
+ except ValueError:
+ continue
+ if key == "ID_VIDEO_FPS":
+ fps = value
+
+ # Strip out video & audio
+ video = "video.%s" % self.codec2exts[p.vcodec]
+ audio = "audio.%s" % self.codec2exts[p.acodec]
+ mencoder = ["mencoder", input, "-ovc", "copy", "-oac", "copy", "-of"]
+ self.do_exec(["rm", "-f", output])
+ self.do_exec(mencoder + ["rawvideo", "-o", video])
+ self.do_exec(mencoder + ["rawaudio", "-o", audio])
+
+ # Mux them back together
+ self.do_exec(["MP4Box", "-add", video, "-add", audio, "-fps", fps, output])
+
+ # Clean up temp files
+ self.do_exec(["rm", "-f", video, audio, input])
+
+
+
+class MKVMerge(Command):
+ def check(self):
+ self.check_command("mkvmerge")
+ self.check_no_file(self.opts.output + ".mkv")
+
+ def run(self):
+ input = self.opts.output + ".avi" # From Mencoder command
+ output = self.opts.output + ".mkv"
+ self.do_exec(["mkvmerge", "-o", output, input])
+ self.do_exec(["rm", "-f", input])
+
+
+
+class Mencoder(Command):