gmyth-stream/server/plugins/media/mencoder.py
author rosfran
Tue Apr 03 19:39:23 2007 +0100 (2007-04-03)
branchtrunk
changeset 486 56b98fd15019
child 492 63d9475228ac
permissions -rw-r--r--
[svn r491] Solve bug with the --enable-debug on configure.ac; reversed changes in the GMythBackendInfo object; procedure to close the Recorder in not mandatory.
     1 import os
     2 import sys
     3 import lib
     4 import time
     5 import signal
     6 import socket
     7 import ConfigParser
     8 
     9 from select import *
    10 from subprocess import *
    11 
    12 class Media:
    13 
    14     def __init__(self, config):
    15 
    16         self.config = config
    17         self.language = "en"
    18         self.socket = None
    19         self.child_pid = None
    20         self.mplayer = None
    21         self.mencoder_pid = None
    22         self.mplayer_pid = None
    23         signal.signal(signal.SIGABRT, self.kill_handler)
    24 
    25     def kill_handler(self, sig, frame):
    26         try:
    27             os.kill(self.mplayer_pid.pid + 1, signal.SIGKILL)
    28             sys.exit(0)
    29         except:
    30             lib.log("Problems closing child")
    31 
    32     def set_args(self, options):
    33 
    34         for opt in options:
    35 
    36             if (opt == "file" or opt == "dvd"):
    37                 if (self.acodec == "mp3lame"):
    38                     audio = "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate
    39                 else:
    40                     audio = "-oac lavc -lavcopts acodec=%s abitrate=%s" % (\
    41                         self.acodec, self.abitrate)
    42 
    43             if (opt == "file"):
    44                 self.kind = "file"
    45                 self.args += " %s -mf fps=%s -of %s %s"\
    46                              " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -vf scale=%s:%s"\
    47                              " -o %s 1> /dev/null 2> /dev/null" % (
    48                     self.filename, self.fps, self.mux, audio, self.vcodec,
    49                     self.vbitrate, self.width, self.height, self.fifo)
    50 
    51             elif (opt == "dvd"):
    52                 self.kind = "dvd"
    53                 self.args += " dvd://%s -alang %s -vf scale=%s:%s %s"\
    54                              " -of %s -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -o %s"\
    55                              " -ofps %s 1> /dev/null 2> /dev/null" % (
    56                     self.filename, self.language, self.width, self.height, audio,
    57                     self.mux, self.vcodec, self.vbitrate, self.fifo, self.fps)
    58 
    59             elif (opt == "local"):
    60                 self.mplayer = os.popen("which mplayer").read().strip()
    61 
    62             elif (opt.find("language=") >= 0):
    63                 try:
    64                     self.language = opt.split("=")[1]
    65                 except:
    66                     lib.log("Bad language option")
    67 
    68 
    69     def run_mplayer(self):
    70         msg = "%s 1>/dev/null 2>/dev/null" % self.filename
    71         if (self.kind == "dvd"):
    72             msg = "dvd://" + msg
    73 
    74         self.mplayer += " " + msg
    75         self.mplayer_pid = Popen(self.mplayer, shell=True)
    76 
    77     def setup(self, filename, mux, vcodec, vbitrate,\
    78               fps, acodec, abitrate, width, height, port, options):
    79 
    80         self.filename = filename
    81         self.mux = mux
    82         self.vcodec = vcodec
    83         self.vbitrate = vbitrate
    84         self.fps = fps
    85         self.acodec = acodec
    86         self.abitrate = abitrate
    87         self.width = width
    88         self.height = height
    89 
    90         self.port = int(port)
    91         self.fifo = self.config.get("Mencoder", "fifo_path")
    92 
    93         self.args = ""
    94         self.kind = ""
    95         self.set_args(options)
    96 
    97         if (self.kind == "file" and not os.path.exists(self.filename)):
    98             msg = "File requested does not exist. SETUP failed."
    99             lib.log(msg)
   100             return msg
   101 
   102         # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240 5000
   103         self.path = self.config.get("Mencoder", "path")
   104 
   105         if (self.socket != None):
   106             del(self.socket)
   107 
   108         self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
   109         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
   110         self.socket.bind( ('', self.port) )
   111         self.socket.listen(1)
   112 
   113         return 0
   114 
   115 
   116     def play(self):
   117 
   118         try:
   119             os.mkfifo(self.fifo)
   120         except:
   121             lib.log("Fifo already exists")
   122 
   123         lib.log("Starting Mencoder: %s %s" % (self.path, self.args) )
   124         # exec Mencoder
   125         self.mencoder_pid = Popen(self.path + self.args, shell=True)
   126 
   127         fifo = open(self.fifo)
   128 
   129         self.child_pid = os.fork()
   130 
   131         if (self.child_pid == 0):
   132             conn,addr= self.socket.accept()
   133             lib.log("Sending Data to client: %s" % addr[0])
   134 
   135             data = fifo.read(1024)
   136             conn.settimeout(5)
   137             retry = 0
   138 
   139             while( data != "" and retry < 5):
   140                 try:
   141                     conn.send(data)
   142                     r, w, x = select([conn], [], [], 0)
   143                     if conn in r:
   144                         back = conn.recv(1024)
   145                         if (back == "OK" and self.mplayer and not self.mplayer_pid):
   146                             self.run_mplayer()
   147 
   148                 except socket.error:
   149                     lib.log("Socket error (maybe timeout ?)")
   150                     retry += 1
   151 
   152                 data = fifo.read(1024)
   153 
   154             if (retry < 5):
   155                 lib.log("Finished sending Data to client: %s" % addr[0])
   156             else:
   157                 lib.log("Client timed out")
   158 
   159             sys.exit(0)
   160 
   161 
   162     def stop(self):
   163         try:
   164             os.kill(self.mencoder_pid.pid + 1, signal.SIGKILL)
   165             self.mplayer = None
   166         except:
   167             lib.log("Trying to stop before playing...")
   168 
   169         if (self.socket != None):
   170             lib.log("Closing socket")
   171             self.socket.close()
   172 
   173             lib.log("Trying to stop Mencoder process")
   174             if (self.child_pid != None):
   175                 os.kill(self.child_pid, signal.SIGABRT)