gmyth-stream/server/plugins/media/mencoder.py
branchtrunk
changeset 533 e55310730feb
parent 516 f353f0da6f07
child 534 cb1c3e2988b9
     1.1 --- a/gmyth-stream/server/plugins/media/mencoder.py	Tue Apr 10 01:07:35 2007 +0100
     1.2 +++ b/gmyth-stream/server/plugins/media/mencoder.py	Thu Apr 12 15:12:12 2007 +0100
     1.3 @@ -1,3 +1,5 @@
     1.4 +from __future__ import division
     1.5 +
     1.6  import os
     1.7  import sys
     1.8  import lib
     1.9 @@ -16,6 +18,12 @@
    1.10      def __init__(self, config):
    1.11  
    1.12          self.config = config
    1.13 +        self.do_cleanup()
    1.14 +
    1.15 +    # __init__()
    1.16 +
    1.17 +
    1.18 +    def do_cleanup(self):
    1.19          self.path = ""
    1.20          self.args = []
    1.21          self.language = None
    1.22 @@ -26,8 +34,14 @@
    1.23          self.mplayer = None
    1.24          self.mencoder_pid = None
    1.25          self.mplayer_pid = None
    1.26 +        self.audio_opts = None
    1.27 +        self.video_opts = None
    1.28 +        self.gst_pipe = None
    1.29 +        self.gst_pid = None
    1.30 +        self.transcode_local = None
    1.31  
    1.32 -    # __init__
    1.33 +    # do_cleanup()
    1.34 +
    1.35  
    1.36      def setup_opts(self, options):
    1.37  
    1.38 @@ -42,7 +56,7 @@
    1.39                      if len(lan) < 2:
    1.40                          self.language = lan
    1.41                  except Exception, e:
    1.42 -                    log.error("Bad language option: %s" % e)
    1.43 +                    log.error("Bad language option: %s" % opt)
    1.44  
    1.45              elif opt.find("subtitle=") >= 0:
    1.46                  try:
    1.47 @@ -50,15 +64,22 @@
    1.48                      if len(sub) < 2:
    1.49                          self.language = sub
    1.50                  except Exception, e:
    1.51 -                    log.error("Bad subtitle option: %s" % e)
    1.52 +                    log.error("Bad subtitle option: %s" % opt)
    1.53  
    1.54              elif opt.find("format=") >= 0:
    1.55                  try:
    1.56                      self.mpegopts = opt.split("=")[1]
    1.57                  except Exception, e:
    1.58 -                    log.error("Bad format option: %s" % e)
    1.59 +                    log.error("Bad format option: %s" % opt)
    1.60  
    1.61 -    # setup_opts
    1.62 +            elif opt.find("outfile=") >= 0:
    1.63 +                try:
    1.64 +                    self.transcode_local = opt.split("=")[1]
    1.65 +                except Exception, e:
    1.66 +                    log.error("Bad outfile option: %s" % opt)
    1.67 +
    1.68 +    # setup_opts()
    1.69 +
    1.70  
    1.71      def run_mplayer(self):
    1.72          msg = self.filename
    1.73 @@ -69,7 +90,8 @@
    1.74          self.mplayer_pid = Popen([self.mplayer, self.filename, "1> %s" % os.devnull,\
    1.75                                    "2> %s" % os.devnull], stdout=PIPE, close_fds=True)
    1.76  
    1.77 -    # run_mplayer
    1.78 +    # run_mplayer()
    1.79 +
    1.80  
    1.81      def setup_mencoder(self):
    1.82          self.path = self.config.get("Mencoder", "path")
    1.83 @@ -92,7 +114,8 @@
    1.84          else:
    1.85              self.fifo = "-"
    1.86  
    1.87 -    # setup_mencoder
    1.88 +    # setup_mencoder()
    1.89 +
    1.90  
    1.91      def setup_audio(self):
    1.92  
    1.93 @@ -102,7 +125,7 @@
    1.94              return "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (\
    1.95                  self.acodec, self.abitrate)
    1.96  
    1.97 -    # setup_audio
    1.98 +    # setup_audio()
    1.99  
   1.100  
   1.101      def setup_video(self):
   1.102 @@ -126,7 +149,7 @@
   1.103  
   1.104          return video
   1.105  
   1.106 -    # setup_video
   1.107 +    # setup_video()
   1.108  
   1.109  
   1.110      def arg_append(self, args, options):
   1.111 @@ -134,12 +157,15 @@
   1.112          for i in l:
   1.113              args.append(i)
   1.114  
   1.115 -    # arg_append
   1.116 +    # arg_append()
   1.117 +
   1.118  
   1.119      def setup_args(self, args):
   1.120  
   1.121          args.append(self.path)
   1.122 -        args.append(self.filename)
   1.123 +
   1.124 +        #args.append(self.filename)
   1.125 +        args.append("-")
   1.126  
   1.127          if self.language != None:
   1.128              self.arg_append(args, "-alang %s" % self.language)
   1.129 @@ -156,7 +182,8 @@
   1.130          self.arg_append(args, "-o %s" % self.fifo)
   1.131          self.arg_append(args, "2> %s" % os.devnull)
   1.132  
   1.133 -    # setup_args
   1.134 +    # setup_args()
   1.135 +
   1.136  
   1.137      def setup_filename(self, filename):
   1.138          try:
   1.139 @@ -173,13 +200,20 @@
   1.140          elif self.kind == "dvd":
   1.141              self.filename = "dvd://" + filename
   1.142  
   1.143 +        elif self.kind == "myth":
   1.144 +            self.filename = "myth://" + filename
   1.145 +            self.gst_pipe = os.pipe()
   1.146 +            print self.gst_pipe[0]
   1.147 +            print self.gst_pipe[1]
   1.148 +
   1.149          return (True, "")
   1.150  
   1.151 -    # setup_filename
   1.152 +    # setup_filename()
   1.153 +
   1.154  
   1.155      def setup_socket(self):
   1.156          if self.socket != None:
   1.157 -            del(self.socket)
   1.158 +            self.socket = None
   1.159  
   1.160          self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   1.161          self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
   1.162 @@ -193,7 +227,8 @@
   1.163  
   1.164          return (True, "")
   1.165  
   1.166 -    # setup_socket
   1.167 +    # setup_socket()
   1.168 +
   1.169  
   1.170      '''
   1.171      MENCODER SETUP DESCRIPTION
   1.172 @@ -216,6 +251,9 @@
   1.173      def setup(self, filename, mux, vcodec, vbitrate,\
   1.174                fps, acodec, abitrate, width, height, port, options):
   1.175  
   1.176 +        if self.args != []:
   1.177 +            self.do_cleanup()
   1.178 +
   1.179          self.mux = mux
   1.180          self.vcodec = vcodec
   1.181          self.vbitrate = vbitrate
   1.182 @@ -230,7 +268,7 @@
   1.183  
   1.184          ret_val = self.setup_filename(filename)
   1.185          if not ret_val[0]:
   1.186 -            return ret_val[1]
   1.187 +            return ret_val
   1.188  
   1.189          self.setup_opts(options)
   1.190          self.audio_opts = self.setup_audio()
   1.191 @@ -238,38 +276,17 @@
   1.192          self.setup_args(self.args)
   1.193  
   1.194          ret_val = self.setup_socket()
   1.195 -        if not ret_val[0]:
   1.196 -            return ret_val[1]
   1.197 +        return ret_val
   1.198  
   1.199 -        return True
   1.200 +    # setup()
   1.201  
   1.202 -    # setup
   1.203 +    def play_loop(self, conn):
   1.204 +        data = self.pout.read(4096)
   1.205  
   1.206 -    def play(self):
   1.207 +        conn.settimeout(5)
   1.208 +        retry = 0
   1.209  
   1.210 -        log.info("Starting Mencoder: %s" % self.args )
   1.211 -
   1.212 -        try:
   1.213 -            self.mencoder_pid = Popen(self.args, stdout=PIPE, close_fds=True)
   1.214 -        except Exception, e:
   1.215 -            msg = "Could not init Mencoder: %s" % e
   1.216 -            log.error(msg)
   1.217 -            return msg
   1.218 -
   1.219 -        if self.mencoder_old: self.pout = open(self.fifo)
   1.220 -        else: self.pout = self.mencoder_pid.stdout
   1.221 -
   1.222 -        self.child_pid = os.fork()
   1.223 -
   1.224 -        if self.child_pid == 0:
   1.225 -            conn, addr = self.socket.accept()
   1.226 -            log.info("Sending Data to client: %s" % addr[0])
   1.227 -
   1.228 -            data = self.pout.read(4096)
   1.229 -
   1.230 -            conn.settimeout(5)
   1.231 -            retry = 0
   1.232 -
   1.233 +        if not self.transcode_local:
   1.234              while data != "" and retry < 5:
   1.235                  try:
   1.236                      conn.send(data)
   1.237 @@ -285,6 +302,67 @@
   1.238  
   1.239                  data = self.pout.read(4096)
   1.240  
   1.241 +        else:
   1.242 +            local = open(self.transcode_local, "w")
   1.243 +            total = os.path.getsize(self.filename)
   1.244 +            partial = 4096
   1.245 +
   1.246 +            while data != "":
   1.247 +                try:
   1.248 +                    local.write(data)
   1.249 +                except Exception, e:
   1.250 +                    log.error("Write error: %s" % e)
   1.251 +
   1.252 +                data = self.pout.read(4096)
   1.253 +                partial += len(data)
   1.254 +                conn.send("%.2f\n" % (partial * 100 / total) )
   1.255 +
   1.256 +            local.close()
   1.257 +            conn.send("DONE\n")
   1.258 +
   1.259 +        return retry
   1.260 +
   1.261 +    # play_loop()
   1.262 +
   1.263 +
   1.264 +    def play(self):
   1.265 +
   1.266 +        log.info("Starting Mencoder: %s" % self.args )
   1.267 +
   1.268 +        if self.gst_pipe:
   1.269 +            try:
   1.270 +                gst = [ lib.which("gst-launch-0.10") ]
   1.271 +                self.arg_append(gst, "filesrc location=/tmp/mpg/bad_day.mpg")
   1.272 +                self.arg_append(gst, "! fdsink fd=%d" % self.gst_pipe[1])
   1.273 +                self.gst_pid = Popen(gst, stdout=self.gst_pipe[1], close_fds=True)
   1.274 +            except Exception, e:
   1.275 +                msg = "Could not init Gstreamer: %s" % e
   1.276 +                log.error(msg)
   1.277 +                return (False, msg)
   1.278 +
   1.279 +        try:
   1.280 +            if not self.gst_pipe:
   1.281 +                self.stdin = open(self.filename)
   1.282 +            else:
   1.283 +                self.stdin = self.gst_pipe[0]
   1.284 +
   1.285 +            self.mencoder_pid = Popen(self.args, stdin=self.stdin, stdout=PIPE, close_fds=True)
   1.286 +        except Exception, e:
   1.287 +            msg = "Could not init Mencoder: %s" % e
   1.288 +            log.error(msg)
   1.289 +            return (False, msg)
   1.290 +
   1.291 +        if self.mencoder_old: self.pout = open(self.fifo)
   1.292 +        else: self.pout = self.mencoder_pid.stdout
   1.293 +
   1.294 +        self.child_pid = os.fork()
   1.295 +
   1.296 +        if self.child_pid == 0:
   1.297 +            conn, addr = self.socket.accept()
   1.298 +
   1.299 +            log.info("Sending Data to client: %s" % addr[0])
   1.300 +            retry = self.play_loop(conn)
   1.301 +
   1.302              if retry < 5:
   1.303                  log.info("Finished sending Data to client: %s" % addr[0])
   1.304              else:
   1.305 @@ -293,29 +371,39 @@
   1.306              os.kill(self.mencoder_pid.pid, signal.SIGKILL)
   1.307              sys.exit(0)
   1.308  
   1.309 -        return True
   1.310 +        return (True, "")
   1.311  
   1.312 -        # play
   1.313 +    # play()
   1.314  
   1.315  
   1.316      def stop(self):
   1.317          try:
   1.318  
   1.319              if self.mencoder_pid:
   1.320 -                os.kill(self.mencoder_pid.pid, signal.SIGKILL)
   1.321 +                os.kill(self.mencoder_pid.pid, signal.SIGTERM)
   1.322                  self.mencoder_pid = None
   1.323  
   1.324              if self.mplayer_pid:
   1.325 -                os.kill(self.mplayer_pid.pid, signal.SIGKILL)
   1.326 +                os.kill(self.mplayer_pid.pid, signal.SIGTERM)
   1.327                  self.mplayer_pid = None
   1.328  
   1.329 -            if self.socket != None:
   1.330 +            if self.socket:
   1.331                  self.socket.close()
   1.332 +                self.socket = None
   1.333  
   1.334 -            if self.child_pid != None:
   1.335 -                os.kill(self.child_pid, signal.SIGKILL)
   1.336 +            if self.child_pid:
   1.337 +                os.kill(self.child_pid, signal.SIGTERM)
   1.338 +                self.child_pid = None
   1.339 +
   1.340 +            if self.gst_pid:
   1.341 +                os.kill(self.gst_pid.pid, signal.SIGTERM)
   1.342 +                self.gst_pid = None
   1.343 +
   1.344 +            self.do_cleanup()
   1.345 +
   1.346 +            os.wait()
   1.347  
   1.348          except Exception, e:
   1.349              log.error("Stop error: %s" % e)
   1.350  
   1.351 -    # stop
   1.352 +    # stop()