renatofilho@484: import os
renatofilho@484: import sys
renatofilho@484: import lib
renatofilho@484: import time
renatofilho@484: import signal
renatofilho@484: import socket
renatofilho@484: import ConfigParser
renatofilho@484: 
renatofilho@484: from select import *
renatofilho@484: from subprocess import *
renatofilho@484: 
renatofilho@484: class Media:
renatofilho@484: 
renatofilho@484:     def __init__(self, config):
renatofilho@484: 
renatofilho@484:         self.config = config
renatofilho@484:         self.language = "en"
renatofilho@484:         self.socket = None
renatofilho@484:         self.child_pid = None
renatofilho@484:         self.mplayer = None
renatofilho@484:         self.mencoder_pid = None
renatofilho@484:         self.mplayer_pid = None
renatofilho@484:         signal.signal(signal.SIGABRT, self.kill_handler)
renatofilho@484: 
renatofilho@484:     def kill_handler(self, sig, frame):
renatofilho@484:         try:
renatofilho@484:             os.kill(self.mplayer_pid.pid + 1, signal.SIGKILL)
renatofilho@484:             sys.exit(0)
renatofilho@484:         except:
renatofilho@484:             lib.log("Problems closing child")
renatofilho@484: 
renatofilho@484:     def set_args(self, options):
renatofilho@484: 
renatofilho@484:         for opt in options:
renatofilho@484: 
renatofilho@484:             if (opt == "file" or opt == "dvd"):
renatofilho@484:                 if (self.acodec == "mp3lame"):
renatofilho@484:                     audio = "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate
renatofilho@484:                 else:
morphbr@492:                     audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (\
renatofilho@484:                         self.acodec, self.abitrate)
renatofilho@484: 
renatofilho@484:             if (opt == "file"):
renatofilho@484:                 self.kind = "file"
morphbr@492:                 self.args += " %s -mf fps=%s -of %s -noodml %s"\
renatofilho@484:                              " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -vf scale=%s:%s"\
renatofilho@484:                              " -o %s 1> /dev/null 2> /dev/null" % (
renatofilho@484:                     self.filename, self.fps, self.mux, audio, self.vcodec,
renatofilho@484:                     self.vbitrate, self.width, self.height, self.fifo)
renatofilho@484: 
renatofilho@484:             elif (opt == "dvd"):
renatofilho@484:                 self.kind = "dvd"
renatofilho@484:                 self.args += " dvd://%s -alang %s -vf scale=%s:%s %s"\
renatofilho@484:                              " -of %s -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -o %s"\
renatofilho@484:                              " -ofps %s 1> /dev/null 2> /dev/null" % (
renatofilho@484:                     self.filename, self.language, self.width, self.height, audio,
renatofilho@484:                     self.mux, self.vcodec, self.vbitrate, self.fifo, self.fps)
renatofilho@484: 
renatofilho@484:             elif (opt == "local"):
renatofilho@484:                 self.mplayer = os.popen("which mplayer").read().strip()
renatofilho@484: 
renatofilho@484:             elif (opt.find("language=") >= 0):
renatofilho@484:                 try:
renatofilho@484:                     self.language = opt.split("=")[1]
renatofilho@484:                 except:
renatofilho@484:                     lib.log("Bad language option")
renatofilho@484: 
renatofilho@484: 
renatofilho@484:     def run_mplayer(self):
renatofilho@484:         msg = "%s 1>/dev/null 2>/dev/null" % self.filename
renatofilho@484:         if (self.kind == "dvd"):
renatofilho@484:             msg = "dvd://" + msg
renatofilho@484: 
renatofilho@484:         self.mplayer += " " + msg
renatofilho@484:         self.mplayer_pid = Popen(self.mplayer, shell=True)
renatofilho@484: 
renatofilho@484:     def setup(self, filename, mux, vcodec, vbitrate,\
renatofilho@484:               fps, acodec, abitrate, width, height, port, options):
renatofilho@484: 
renatofilho@484:         self.filename = filename
renatofilho@484:         self.mux = mux
renatofilho@484:         self.vcodec = vcodec
renatofilho@484:         self.vbitrate = vbitrate
renatofilho@484:         self.fps = fps
renatofilho@484:         self.acodec = acodec
renatofilho@484:         self.abitrate = abitrate
renatofilho@484:         self.width = width
renatofilho@484:         self.height = height
renatofilho@484: 
renatofilho@484:         self.port = int(port)
renatofilho@484:         self.fifo = self.config.get("Mencoder", "fifo_path")
renatofilho@484: 
renatofilho@484:         self.args = ""
renatofilho@484:         self.kind = ""
renatofilho@484:         self.set_args(options)
renatofilho@484: 
renatofilho@484:         if (self.kind == "file" and not os.path.exists(self.filename)):
renatofilho@484:             msg = "File requested does not exist. SETUP failed."
renatofilho@484:             lib.log(msg)
renatofilho@484:             return msg
renatofilho@484: 
renatofilho@484:         # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240 5000
renatofilho@484:         self.path = self.config.get("Mencoder", "path")
renatofilho@484: 
renatofilho@484:         if (self.socket != None):
renatofilho@484:             del(self.socket)
renatofilho@484: 
renatofilho@484:         self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
renatofilho@484:         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
renatofilho@484:         self.socket.bind( ('', self.port) )
renatofilho@484:         self.socket.listen(1)
renatofilho@484: 
renatofilho@484:         return 0
renatofilho@484: 
renatofilho@484: 
renatofilho@484:     def play(self):
renatofilho@484: 
renatofilho@484:         try:
renatofilho@484:             os.mkfifo(self.fifo)
renatofilho@484:         except:
renatofilho@484:             lib.log("Fifo already exists")
renatofilho@484: 
renatofilho@484:         lib.log("Starting Mencoder: %s %s" % (self.path, self.args) )
renatofilho@484:         # exec Mencoder
renatofilho@484:         self.mencoder_pid = Popen(self.path + self.args, shell=True)
renatofilho@484: 
renatofilho@484:         fifo = open(self.fifo)
renatofilho@484: 
renatofilho@484:         self.child_pid = os.fork()
renatofilho@484: 
renatofilho@484:         if (self.child_pid == 0):
renatofilho@484:             conn,addr= self.socket.accept()
renatofilho@484:             lib.log("Sending Data to client: %s" % addr[0])
renatofilho@484: 
renatofilho@484:             data = fifo.read(1024)
renatofilho@484:             conn.settimeout(5)
renatofilho@484:             retry = 0
renatofilho@484: 
renatofilho@484:             while( data != "" and retry < 5):
renatofilho@484:                 try:
renatofilho@484:                     conn.send(data)
renatofilho@484:                     r, w, x = select([conn], [], [], 0)
renatofilho@484:                     if conn in r:
renatofilho@484:                         back = conn.recv(1024)
renatofilho@484:                         if (back == "OK" and self.mplayer and not self.mplayer_pid):
renatofilho@484:                             self.run_mplayer()
renatofilho@484: 
renatofilho@484:                 except socket.error:
renatofilho@484:                     lib.log("Socket error (maybe timeout ?)")
renatofilho@484:                     retry += 1
renatofilho@484: 
renatofilho@484:                 data = fifo.read(1024)
renatofilho@484: 
renatofilho@484:             if (retry < 5):
renatofilho@484:                 lib.log("Finished sending Data to client: %s" % addr[0])
renatofilho@484:             else:
renatofilho@484:                 lib.log("Client timed out")
renatofilho@484: 
renatofilho@484:             sys.exit(0)
renatofilho@484: 
renatofilho@484: 
renatofilho@484:     def stop(self):
renatofilho@484:         try:
renatofilho@484:             os.kill(self.mencoder_pid.pid + 1, signal.SIGKILL)
renatofilho@484:             self.mplayer = None
renatofilho@484:         except:
renatofilho@484:             lib.log("Trying to stop before playing...")
renatofilho@484: 
renatofilho@484:         if (self.socket != None):
renatofilho@484:             lib.log("Closing socket")
renatofilho@484:             self.socket.close()
renatofilho@484: 
renatofilho@484:             lib.log("Trying to stop Mencoder process")
renatofilho@484:             if (self.child_pid != None):
renatofilho@484:                 os.kill(self.child_pid, signal.SIGABRT)