morphbr@565: import lib.utils as utils morphbr@565: import lib.server as server morphbr@565: import os morphbr@565: import signal morphbr@565: import subprocess morphbr@565: morphbr@565: __all__ = ("TranscoderMencoder",) morphbr@565: morphbr@565: class TranscoderMencoder(server.Transcoder): morphbr@565: mencoder_path = utils.which("mencoder") morphbr@565: name = "mencoder" morphbr@565: priority = -1 morphbr@565: morphbr@569: def _setup_params(self): morphbr@569: params_first = self.params_first morphbr@569: morphbr@569: # general_opts morphbr@569: self.args["local"] = params_first("local", False) morphbr@569: self.args["language"] = params_first("language", False) morphbr@569: self.args["subtitle"] = params_first("subtitle", False) morphbr@569: self.args["format"] = params_first("format", "") morphbr@569: self.args["outfile"] = params_first("outfile", "-") morphbr@569: morphbr@569: # input_opt morphbr@569: self.args["type"] = params_first("type", "file") morphbr@569: self.args["input"] = params_first("input", "-") morphbr@569: morphbr@569: # audio_opts morphbr@569: self.args["acodec"] = params_first("acodec", "mp2") morphbr@569: self.args["abitrate"] = params_first("abitrate", 192) morphbr@569: self.args["volume"] = params_first("volume", 5) morphbr@569: morphbr@569: # video_opts morphbr@569: self.args["mux"] = params_first("mux", "mpeg") morphbr@569: self.args["fps"] = params_first("fps", 25) morphbr@569: self.args["vcodec"] = params_first("vcodec", "mpeg1video") morphbr@569: self.args["vbitrate"] = params_first("vbitrate", 400) morphbr@569: self.args["width"] = params_first("width", 320) morphbr@569: self.args["height"] = params_first("height", 240) morphbr@569: # _setup_params() morphbr@569: morphbr@569: morphbr@569: def _setup_audio(self): morphbr@569: if self.args["acodec"] == "mp3lame": morphbr@569: audio = "-oac mp3lame -lameopts cbr:br=%s vol=%s" % ( morphbr@569: self.args["abitrate"], self.args["volume"]) morphbr@569: else: morphbr@569: audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % ( morphbr@569: self.args["acodec"], self.args["abitrate"]) morphbr@569: morphbr@569: return audio morphbr@569: # _setup_audio() morphbr@569: morphbr@569: morphbr@569: def _setup_video(self): morphbr@569: video = " -of %s" % self.mux morphbr@569: video += " -ofps %s" % self.fps morphbr@569: morphbr@569: vcodec = self.args["vcodec"] morphbr@569: if vcodec == "nuv" or vcodec == "xvid"\ morphbr@569: or vcodec == "qtvideo" or vcodec == "copy": morphbr@569: video += " -ovc %s" % vcodec morphbr@569: else: morphbr@569: video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % ( morphbr@569: vcodec, self.args["vbitrate"]) morphbr@569: morphbr@569: video += " %s" % self.args["format"] morphbr@569: video += " -vf scale=%s:%s" % (self.args["width"], self.args["height"]) morphbr@569: morphbr@569: return video morphbr@569: # _setup_video() morphbr@569: morphbr@569: morphbr@569: def _arg_append(self, args, options): morphbr@569: for arg in shlex.split(options) morphbr@569: args.append(arg) morphbr@569: # arg_append() morphbr@569: morphbr@569: def _setup_mencoder_opts(self, args): morphbr@569: args.append(self.mencoder_path) morphbr@569: args.append("-") morphbr@569: morphbr@569: if self.args["language"]: morphbr@569: self._arg_append(args, "-alang %s" % self.args["language"]) morphbr@569: morphbr@569: if self.args["subtitle"]: morphbr@569: self._arg_append(args, "-slang %s" % self.args["subtitle"]) morphbr@569: self._arg_append(args, "-subfps %s" % self.args["fps"]) morphbr@569: morphbr@569: self._arg_append(args, "-idx") morphbr@569: self._arg_append(args, self._setup_audio) morphbr@569: self._arg_append(args, self._setup_video) morphbr@569: morphbr@569: self._arg_append(args, "-really-quiet") morphbr@569: self._arg_append(args, "-o %s" % self.args["outfile"]) morphbr@569: self._arg_append(args, "2> %s" % os.devnull) morphbr@569: # _setup_args() morphbr@569: morphbr@569: morphbr@569: def _setup_filename(self): morphbr@569: _type = self.args["type"] morphbr@569: morphbr@569: if _type == "file": morphbr@569: if not os.path.exists(self.args["input"]): morphbr@569: raise IOError, "File requested does not exist." morphbr@569: morphbr@569: elif _type == "dvd": morphbr@569: self.args["input"] = "dvd://".join(self.args["input"]) morphbr@569: morphbr@569: elif _type == "myth": morphbr@569: self.args["input"] = "myth://".join(self.args["input"]) morphbr@569: self.gst_pipe = os.pipe() morphbr@569: # _setup_filename() morphbr@569: morphbr@569: morphbr@572: def __init__(self, params): morphbr@565: server.Transcoder.__init__(self, params) morphbr@565: self.proc = None morphbr@565: self.args = None morphbr@569: self.mencoder_opts = None morphbr@565: morphbr@569: try: morphbr@569: self._setup_params() morphbr@569: self._setup_filename() morphbr@569: self._setup_mencoder_opts(self.mencoder_opts) morphbr@569: except Exception, e: morphbr@569: self.log.error(e) morphbr@569: return False morphbr@565: morphbr@569: return True morphbr@565: # __init__() morphbr@565: morphbr@565: morphbr@565: def start(self, outfd): morphbr@565: cmd = " ".join(self.args) morphbr@565: self.log.info("Mencoder: %s" % cmd) morphbr@565: morphbr@569: if self.args["type"] == "file": morphbr@569: _input = open(self.args["input"]) morphbr@569: morphbr@565: try: morphbr@565: self.proc = subprocess.Popen(self.args, close_fds=True) morphbr@565: except Exception, e: morphbr@565: self.log.error("Error executing mencoder: %s" % cmd) morphbr@565: return False morphbr@565: morphbr@565: try: morphbr@565: fifo_read = open(self.mencoder_outfile) morphbr@565: except Exception, e: morphbr@565: self.log.error("Error opening fifo: %s" % cmd) morphbr@565: return False morphbr@565: morphbr@565: try: morphbr@565: while self.proc and self.proc.poll() == None: morphbr@565: d = fifo_read.read(1024) morphbr@565: outfd.write(d) morphbr@565: except Exception, e: morphbr@565: self.log.error("Problems handling data: %s" % e) morphbr@565: return False morphbr@565: morphbr@565: return True morphbr@565: # start() morphbr@565: morphbr@565: morphbr@565: def stop(self): morphbr@565: if self.proc: morphbr@565: try: morphbr@565: os.kill(self.proc.pid, signal.SIGTERM) morphbr@565: except OSError, e: morphbr@565: pass morphbr@565: morphbr@565: try: morphbr@565: self.proc.wait() morphbr@565: except Exception, e: morphbr@565: pass morphbr@565: morphbr@565: self.proc = None morphbr@569: # stop() morphbr@565: morphbr@565: # TranscoderMencoder