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