diff -r b5352888e3c2 -r 605cbc483e09 gmyth-stream/server/plugins/media/mencoder.py --- a/gmyth-stream/server/plugins/media/mencoder.py Mon Apr 09 16:22:37 2007 +0100 +++ b/gmyth-stream/server/plugins/media/mencoder.py Wed Apr 11 18:40:50 2007 +0100 @@ -2,9 +2,11 @@ import sys import lib import time +import shlex import signal import socket import ConfigParser +import logging as log from select import * from subprocess import * @@ -14,28 +16,20 @@ def __init__(self, config): self.config = config - self.args = "" - self.language = "en" + self.path = "" + self.args = [] + self.language = None + self.subtitle = None + self.mpegopts = None 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) # __init__ - def kill_handler(self, sig, frame): - try: - os.kill(self.mplayer_pid.pid, signal.SIGKILL) - log.debug("Killed Mplayer") - sys.exit(0) - except: - log.error("Problems closing child") - - # kill_handler - - def set_args(self, options): + def setup_opts(self, options): for opt in options: @@ -44,17 +38,27 @@ elif opt.find("language=") >= 0: try: - self.language = opt.split("=")[1] - except: - log.error("Bad language option") + lan = opt.split("=")[1] + if len(lan) < 2: + self.language = lan + except Exception, e: + log.error("Bad language option: %s" % e) + + elif opt.find("subtitle=") >= 0: + try: + sub = opt.split("=")[1] + if len(sub) < 2: + self.language = sub + except Exception, e: + log.error("Bad subtitle option: %s" % e) elif opt.find("format=") >= 0: try: - self.mux += " -mpegopts format=%s" % opt.split("=")[1] - except: - log.error("Bad format option") + self.mpegopts = opt.split("=")[1] + except Exception, e: + log.error("Bad format option: %s" % e) - # set_args + # setup_opts def run_mplayer(self): msg = self.filename @@ -67,7 +71,6 @@ # run_mplayer - def setup_mencoder(self): self.path = self.config.get("Mencoder", "path") mp = Popen([self.path], stdout=PIPE, close_fds=True) @@ -81,67 +84,117 @@ log.info("Mencoder version: %s" % version) if self.mencoder_old: - self.fifo = self.config.get("Mencoder", "fifo_path") + try: + self.fifo = self.config.get("Mencoder", "fifo_path") + os.mkfifo(self.fifo) + except Exception, e: + log.info("Fifo: %s" % e) else: self.fifo = "-" # setup_mencoder - def setup_audio(self, acodec): + def setup_audio(self): - if acodec == "mp3lame": + if self.acodec == "mp3lame": return "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate else: - return = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (\ + return "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (\ self.acodec, self.abitrate) + # setup_audio + + + def setup_video(self): + + video = "" + + video += " -of %s" % self.mux + video += " -ofps %s" % self.fps + + if self.vcodec == "nuv" or self.vcodec == "xvid"\ + or self.vcodec == "qtvideo" or self.vcodec == "copy": + video += " -ovc %s" % self.vcodec + else: + video += " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s" % ( + self.vcodec, self.vbitrate) + + if self.mux == "mpeg" and self.mpegopts is not None: + video += " -mpegopts format=%s" % self.mpegopts + + video += " -vf scale=%s:%s" % (self.width, self.height) + + return video + + # setup_video + + + def arg_append(self, args, options): + l = shlex.split(options) + for i in l: + args.append(i) + + # arg_append + + def setup_args(self, args): + + args.append(self.path) + args.append(self.filename) + + if self.language != None: + self.arg_append(args, "-alang %s" % self.language) + + if self.subtitle != None: + self.arg_append(args, "-slang %s" % self.subtitle) + self.arg_append(args, "-subfps %s" % self.fps) + + self.arg_append(args, "-idx") + self.arg_append(args, self.audio_opts) + self.arg_append(args, self.video_opts) + + self.arg_append(args, "-really-quiet") + self.arg_append(args, "-o %s" % self.fifo) + self.arg_append(args, "2> %s" % os.devnull) + + # setup_args + def setup_filename(self, filename): try: self.kind, self.filename = filename.split("://") except: return (False, "Wrong filename protocol") - audio = setup_audio(self.acodec) - if self.kind == "file": if not os.path.exists(self.filename): msg = "File requested does not exist. SETUP failed." log.error(msg) return (False, msg) - self.args += " %s -mf fps=%s -of %s %s"\ - " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -vf scale=%s:%s"\ - " -really-quiet -o %s 2>/dev/null" % ( - self.filename, self.fps, self.mux, audio, self.vcodec, - self.vbitrate, self.width, self.height, self.fifo) - elif self.kind == "dvd": - self.args += " dvd://%s -alang %s -vf scale=%s:%s %s"\ - " -of %s -ovc lavc -lavcopts vcodec=%s:vbitrate=%s"\ - " -ofps %s -really-quiet -o %s 2>/dev/null" % ( - self.filename, self.language, self.width, self.height, audio, - self.mux, self.vcodec, self.vbitrate, self.fps, self.fifo) + self.filename = "dvd://" + filename return (True, "") # setup_filename - def setup_socket(self, socket): - if socket != None: - del(socket) + def setup_socket(self): + if self.socket != None: + del(self.socket) - socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) - socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: - socket.bind( ('', self.port) ) - socket.listen(1) + self.socket.bind( ('', self.port) ) + self.socket.listen(1) except Exception, e: log.error("Could not create socket: %s" % e) return (False, e) return (True, "") + # setup_socket + ''' MENCODER SETUP DESCRIPTION =========================== @@ -154,6 +207,12 @@ ''' + + # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240 + # file:///tmp/dvb.mpg mpeg mpeg1video 400 25 mp2 192 320 240 format=mpeg1 + # dvd://4 mpeg mpeg1video 400 25 mp3lame 192 400 240 language=en local + # file:///tmp/mpg/bad_day.mpg avi mpeg4 400 25 mp3 192 320 240 + def setup(self, filename, mux, vcodec, vbitrate,\ fps, acodec, abitrate, width, height, port, options): @@ -168,18 +227,17 @@ self.port = int(port) self.setup_mencoder() + ret_val = self.setup_filename(filename) - if not ret_val[0]: return ret_val[1] - self.set_args(options) + self.setup_opts(options) + self.audio_opts = self.setup_audio() + self.video_opts = self.setup_video() + self.setup_args(self.args) - # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240 5000 file - # /tmp/dvb.mpg mpeg mpeg1video 400 25 mp2 192 320 240 5000 format=mpeg1 file - #4 mpeg mpeg1video 400 25 mp3lame 192 400 240 5000 language=en local dvd - ret_val = setup_socket(self.socket) - + ret_val = self.setup_socket() if not ret_val[0]: return ret_val[1] @@ -189,30 +247,25 @@ def play(self): - if self.mencoder_old: - try: - os.mkfifo(self.fifo) - except: - lib.log("Fifo already exists") + log.info("Starting Mencoder: %s" % self.args ) + try: + self.mencoder_pid = Popen(self.args, stdout=PIPE, close_fds=True) + except Exception, e: + msg = "Could not init Mencoder: %s" % e + log.error(msg) + return msg - lib.log("Starting Mencoder: %s %s" % (self.path, self.args) ) - # exec Mencoder - if self.mencoder_old: - self.mencoder_pid = Popen(self.path + self.args, shell=True, - close_fds=True) - self.pout = open(self.fifo) - else: - self.path += self.args - pin, self.pout = os.popen2(self.path) + if self.mencoder_old: self.pout = open(self.fifo) + else: self.pout = self.mencoder_pid.stdout self.child_pid = os.fork() if self.child_pid == 0: - conn,addr= self.socket.accept() - lib.log("Sending Data to client: %s" % addr[0]) + conn, addr = self.socket.accept() + log.info("Sending Data to client: %s" % addr[0]) - data = self.pout.read(1024) + data = self.pout.read(4096) conn.settimeout(5) retry = 0 @@ -226,34 +279,43 @@ if back == "OK" and self.mplayer and not self.mplayer_pid: self.run_mplayer() - except socket.error: - lib.log("Socket error (maybe timeout ?)") + except socket.error, e: + log.error("Socket error: %s" % e) retry += 1 - data = self.pout.read(1024) + data = self.pout.read(4096) if retry < 5: - lib.log("Finished sending Data to client: %s" % addr[0]) + log.info("Finished sending Data to client: %s" % addr[0]) else: - lib.log("Client timed out") + log.error("Client timed out, retried more than %s times" % retry) + os.kill(self.mencoder_pid.pid, signal.SIGKILL) sys.exit(0) + return True + + # play + def stop(self): try: - if self.mplayer_old: - os.kill(self.mencoder_pid.pid + 1, signal.SIGKILL) - else: - self.pout.close() - self.mplayer = None - except: - lib.log("Trying to stop before playing...") - if self.socket != None: - lib.log("Closing socket") - self.socket.close() + if self.mencoder_pid: + os.kill(self.mencoder_pid.pid, signal.SIGKILL) + self.mencoder_pid = None - lib.log("Trying to stop Mencoder process") + if self.mplayer_pid: + os.kill(self.mplayer_pid.pid, signal.SIGKILL) + self.mplayer_pid = None + + if self.socket != None: + self.socket.close() + if self.child_pid != None: - os.kill(self.child_pid, signal.SIGABRT) + os.kill(self.child_pid, signal.SIGKILL) + + except Exception, e: + log.error("Stop error: %s" % e) + + # stop