gmyth-stream/server/0.2/plugins/transcoders/mencoder.py
author melunko
Tue Apr 24 00:43:20 2007 +0100 (2007-04-24)
branchtrunk
changeset 590 1c421f2531d3
parent 577 7dc357cbaa40
child 595 5c5cff842d57
permissions -rw-r--r--
[svn r596] Fixed memory leak when dealocating GMythChannelInfo.
     1 import os
     2 import shlex
     3 import signal
     4 import subprocess
     5 
     6 import lib.utils as utils
     7 import lib.server as server
     8 
     9 __all__ = ("TranscoderMencoder",)
    10 
    11 class TranscoderMencoder(server.Transcoder):
    12     """Transcoder class that implements a transcoder using Mencoder"""
    13     mencoder_path = utils.which("mencoder")
    14     name = "mencoder"
    15     priority = -1
    16     args = {}
    17     proc = None
    18 
    19     def _setup_params(self):
    20         params_first = self.params_first
    21 
    22         # general_opts
    23         self.args["local"]    = params_first("local", False)
    24         self.args["language"] = params_first("language", False)
    25         self.args["subtitle"] = params_first("subtitle", False)
    26         self.args["format"]   = params_first("format", "")
    27         self.args["outfile"]  = params_first("outfile", "-")
    28 
    29         # input_opt
    30         uri = params_first("uri", "file://-").split("://")
    31         self.args["type"]     = uri[0]
    32         self.args["input"]    = uri[1]
    33 
    34         # audio_opts
    35         self.args["acodec"]   = params_first("acodec", "mp2")
    36         self.args["abitrate"] = params_first("abitrate", 192)
    37         self.args["volume"]   = params_first("volume", 5)
    38 
    39         # video_opts
    40         self.args["mux"]      = params_first("mux", "mpeg")
    41         self.args["fps"]      = params_first("fps", 25)
    42         self.args["vcodec"]   = params_first("vcodec", "mpeg1video")
    43         self.args["vbitrate"] = params_first("vbitrate", 400)
    44         self.args["width"]    = params_first("width", 320)
    45         self.args["height"]   = params_first("height", 240)
    46     # _setup_params()
    47 
    48 
    49     def _setup_audio(self):
    50         if self.args["acodec"] == "mp3lame":
    51             audio = "-oac mp3lame -lameopts cbr:br=%s vol=%s" % (
    52                 self.args["abitrate"], self.args["volume"])
    53         else:
    54             audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (
    55                 self.args["acodec"], self.args["abitrate"])
    56 
    57         return audio
    58     # _setup_audio()
    59 
    60 
    61     def _setup_video(self):
    62         video = " -of %s" % self.args["mux"]
    63         video += " -ofps %s" % self.args["fps"]
    64 
    65         vcodec = self.args["vcodec"]
    66         if vcodec == "nuv" or vcodec == "xvid"\
    67                or vcodec == "qtvideo" or vcodec == "copy":
    68             video += " -ovc %s" % vcodec
    69         else:
    70             video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % (
    71                 vcodec, self.args["vbitrate"])
    72 
    73         video += " %s" % self.args["format"]
    74         video += " -vf scale=%s:%s" % (self.args["width"], self.args["height"])
    75 
    76         return video
    77     # _setup_video()
    78 
    79 
    80     def _arg_append(self, args, options):
    81         for arg in shlex.split(options):
    82             args.append(arg)
    83     # arg_append()
    84 
    85     def _setup_mencoder_opts(self, args):
    86         args.append(self.mencoder_path)
    87         args.append(self.args["input"])
    88 
    89         if self.args["language"]:
    90             self._arg_append(args, "-alang %s" % self.args["language"])
    91 
    92         if self.args["subtitle"]:
    93             self._arg_append(args, "-slang %s" % self.args["subtitle"])
    94             self._arg_append(args, "-subfps %s" % self.args["fps"])
    95 
    96         self._arg_append(args, "-idx")
    97         self._arg_append(args, self._setup_audio())
    98         self._arg_append(args, self._setup_video())
    99 
   100         self._arg_append(args, "-really-quiet")
   101         self._arg_append(args, "-o %s" % self.args["outfile"])
   102         self._arg_append(args, "2> %s" % os.devnull)
   103     # _setup_args()
   104 
   105 
   106     def _setup_filename(self):
   107         _type = self.args["type"]
   108 
   109         if _type == "file":
   110             if not os.path.exists(self.args["input"]):
   111                 raise IOError,\
   112                       "File requested does not exist: %s." % self.args["input"]
   113 
   114         elif _type == "dvd":
   115             self.args["input"] = "dvd://".join(self.args["input"])
   116     # _setup_filename()
   117 
   118 
   119     def __init__(self, params):
   120         server.Transcoder.__init__(self, params)
   121         self.mencoder_opts = []
   122 
   123         try:
   124             self._setup_params()
   125             self._setup_filename()
   126             self._setup_mencoder_opts(self.mencoder_opts)
   127         except Exception, e:
   128             self.log.error(e)
   129     # __init__()
   130 
   131 
   132     def start(self, outfd):
   133         cmd = " ".join(self.mencoder_opts)
   134         self.log.debug("Mencoder: %s" % cmd)
   135 
   136         try:
   137             self.proc = subprocess.Popen(self.mencoder_opts, stdout=subprocess.PIPE, close_fds=True)
   138         except Exception, e:
   139             self.log.error("Error executing mencoder: %s" % e)
   140             return False
   141 
   142         try:
   143             while self.proc and self.proc.poll() == None:
   144                 d = self.proc.stdout.read(1024)
   145                 outfd.write(d)
   146         except Exception, e:
   147             self.log.error("Problems handling data: %s" % e)
   148             return False
   149 
   150         return True
   151     # start()
   152 
   153 
   154     def stop(self):
   155         if self.proc:
   156             try:
   157                 os.kill(self.proc.pid, signal.SIGTERM)
   158             except OSError, e:
   159                 pass
   160 
   161             try:
   162                 self.proc.wait()
   163             except Exception, e:
   164                 pass
   165 
   166             self.proc = None
   167     # stop()
   168 
   169 # TranscoderMencoder