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