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