1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/gmyth-stream/server/plugins/media/mencoder.py Tue Apr 03 16:42:04 2007 +0100
1.3 @@ -0,0 +1,175 @@
1.4 +import os
1.5 +import sys
1.6 +import lib
1.7 +import time
1.8 +import signal
1.9 +import socket
1.10 +import ConfigParser
1.11 +
1.12 +from select import *
1.13 +from subprocess import *
1.14 +
1.15 +class Media:
1.16 +
1.17 + def __init__(self, config):
1.18 +
1.19 + self.config = config
1.20 + self.language = "en"
1.21 + self.socket = None
1.22 + self.child_pid = None
1.23 + self.mplayer = None
1.24 + self.mencoder_pid = None
1.25 + self.mplayer_pid = None
1.26 + signal.signal(signal.SIGABRT, self.kill_handler)
1.27 +
1.28 + def kill_handler(self, sig, frame):
1.29 + try:
1.30 + os.kill(self.mplayer_pid.pid + 1, signal.SIGKILL)
1.31 + sys.exit(0)
1.32 + except:
1.33 + lib.log("Problems closing child")
1.34 +
1.35 + def set_args(self, options):
1.36 +
1.37 + for opt in options:
1.38 +
1.39 + if (opt == "file" or opt == "dvd"):
1.40 + if (self.acodec == "mp3lame"):
1.41 + audio = "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate
1.42 + else:
1.43 + audio = "-oac lavc -lavcopts acodec=%s abitrate=%s" % (\
1.44 + self.acodec, self.abitrate)
1.45 +
1.46 + if (opt == "file"):
1.47 + self.kind = "file"
1.48 + self.args += " %s -mf fps=%s -of %s %s"\
1.49 + " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -vf scale=%s:%s"\
1.50 + " -o %s 1> /dev/null 2> /dev/null" % (
1.51 + self.filename, self.fps, self.mux, audio, self.vcodec,
1.52 + self.vbitrate, self.width, self.height, self.fifo)
1.53 +
1.54 + elif (opt == "dvd"):
1.55 + self.kind = "dvd"
1.56 + self.args += " dvd://%s -alang %s -vf scale=%s:%s %s"\
1.57 + " -of %s -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -o %s"\
1.58 + " -ofps %s 1> /dev/null 2> /dev/null" % (
1.59 + self.filename, self.language, self.width, self.height, audio,
1.60 + self.mux, self.vcodec, self.vbitrate, self.fifo, self.fps)
1.61 +
1.62 + elif (opt == "local"):
1.63 + self.mplayer = os.popen("which mplayer").read().strip()
1.64 +
1.65 + elif (opt.find("language=") >= 0):
1.66 + try:
1.67 + self.language = opt.split("=")[1]
1.68 + except:
1.69 + lib.log("Bad language option")
1.70 +
1.71 +
1.72 + def run_mplayer(self):
1.73 + msg = "%s 1>/dev/null 2>/dev/null" % self.filename
1.74 + if (self.kind == "dvd"):
1.75 + msg = "dvd://" + msg
1.76 +
1.77 + self.mplayer += " " + msg
1.78 + self.mplayer_pid = Popen(self.mplayer, shell=True)
1.79 +
1.80 + def setup(self, filename, mux, vcodec, vbitrate,\
1.81 + fps, acodec, abitrate, width, height, port, options):
1.82 +
1.83 + self.filename = filename
1.84 + self.mux = mux
1.85 + self.vcodec = vcodec
1.86 + self.vbitrate = vbitrate
1.87 + self.fps = fps
1.88 + self.acodec = acodec
1.89 + self.abitrate = abitrate
1.90 + self.width = width
1.91 + self.height = height
1.92 +
1.93 + self.port = int(port)
1.94 + self.fifo = self.config.get("Mencoder", "fifo_path")
1.95 +
1.96 + self.args = ""
1.97 + self.kind = ""
1.98 + self.set_args(options)
1.99 +
1.100 + if (self.kind == "file" and not os.path.exists(self.filename)):
1.101 + msg = "File requested does not exist. SETUP failed."
1.102 + lib.log(msg)
1.103 + return msg
1.104 +
1.105 + # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240 5000
1.106 + self.path = self.config.get("Mencoder", "path")
1.107 +
1.108 + if (self.socket != None):
1.109 + del(self.socket)
1.110 +
1.111 + self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
1.112 + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
1.113 + self.socket.bind( ('', self.port) )
1.114 + self.socket.listen(1)
1.115 +
1.116 + return 0
1.117 +
1.118 +
1.119 + def play(self):
1.120 +
1.121 + try:
1.122 + os.mkfifo(self.fifo)
1.123 + except:
1.124 + lib.log("Fifo already exists")
1.125 +
1.126 + lib.log("Starting Mencoder: %s %s" % (self.path, self.args) )
1.127 + # exec Mencoder
1.128 + self.mencoder_pid = Popen(self.path + self.args, shell=True)
1.129 +
1.130 + fifo = open(self.fifo)
1.131 +
1.132 + self.child_pid = os.fork()
1.133 +
1.134 + if (self.child_pid == 0):
1.135 + conn,addr= self.socket.accept()
1.136 + lib.log("Sending Data to client: %s" % addr[0])
1.137 +
1.138 + data = fifo.read(1024)
1.139 + conn.settimeout(5)
1.140 + retry = 0
1.141 +
1.142 + while( data != "" and retry < 5):
1.143 + try:
1.144 + conn.send(data)
1.145 + r, w, x = select([conn], [], [], 0)
1.146 + if conn in r:
1.147 + back = conn.recv(1024)
1.148 + if (back == "OK" and self.mplayer and not self.mplayer_pid):
1.149 + self.run_mplayer()
1.150 +
1.151 + except socket.error:
1.152 + lib.log("Socket error (maybe timeout ?)")
1.153 + retry += 1
1.154 +
1.155 + data = fifo.read(1024)
1.156 +
1.157 + if (retry < 5):
1.158 + lib.log("Finished sending Data to client: %s" % addr[0])
1.159 + else:
1.160 + lib.log("Client timed out")
1.161 +
1.162 + sys.exit(0)
1.163 +
1.164 +
1.165 + def stop(self):
1.166 + try:
1.167 + os.kill(self.mencoder_pid.pid + 1, signal.SIGKILL)
1.168 + self.mplayer = None
1.169 + except:
1.170 + lib.log("Trying to stop before playing...")
1.171 +
1.172 + if (self.socket != None):
1.173 + lib.log("Closing socket")
1.174 + self.socket.close()
1.175 +
1.176 + lib.log("Trying to stop Mencoder process")
1.177 + if (self.child_pid != None):
1.178 + os.kill(self.child_pid, signal.SIGABRT)