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