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: morphbr@497: class Media(object): renatofilho@484: renatofilho@484: def __init__(self, config): renatofilho@484: renatofilho@484: self.config = config morphbr@504: self.args = "" 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: morphbr@504: if opt == "local": renatofilho@484: self.mplayer = os.popen("which mplayer").read().strip() renatofilho@484: morphbr@497: 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: morphbr@497: elif opt.find("format=") >= 0: morphbr@497: try: morphbr@497: self.mux += " -mpegopts format=%s" % opt.split("=")[1] morphbr@497: except: morphbr@497: lib.log("Bad format option") morphbr@497: renatofilho@484: renatofilho@484: def run_mplayer(self): renatofilho@484: msg = "%s 1>/dev/null 2>/dev/null" % self.filename morphbr@497: morphbr@498: 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: morphbr@504: def setup_mencoder(self): morphbr@499: self.path = self.config.get("Mencoder", "path") morphbr@499: a, b = os.popen2(self.path) morphbr@499: version = b.read().split("MEncoder ")[1].split(" (C)")[0].split("-")[-1] morphbr@499: morphbr@499: if version > "4.1.1": self.mencoder_old = False morphbr@499: else: self.mencoder_old = True morphbr@499: morphbr@504: lib.log("Mencoder version: %s" % version) morphbr@504: morphbr@499: a.close() morphbr@499: b.close() morphbr@499: morphbr@499: if self.mencoder_old: morphbr@499: self.fifo = self.config.get("Mencoder", "fifo_path") morphbr@499: else: morphbr@499: self.fifo = "-" renatofilho@484: morphbr@504: def setup_filename(self, filename): morphbr@504: try: morphbr@504: self.kind, self.filename = filename.split("://") morphbr@504: except: morphbr@504: return (False, "Wrong filename protocol") morphbr@504: morphbr@504: if self.acodec == "mp3lame": morphbr@504: audio = "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate morphbr@504: else: morphbr@504: audio = "-oac lavc -lavcopts acodec=%s:abitrate=%s" % (\ morphbr@504: self.acodec, self.abitrate) morphbr@504: morphbr@504: if self.kind == "file": morphbr@504: if not os.path.exists(self.filename): morphbr@504: msg = "File requested does not exist. SETUP failed." morphbr@504: lib.log(msg) morphbr@504: return (False, msg) morphbr@504: morphbr@504: self.args += " %s -mf fps=%s -of %s %s"\ morphbr@504: " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -vf scale=%s:%s"\ morphbr@504: " -really-quiet -o %s 2>/dev/null" % ( morphbr@504: self.filename, self.fps, self.mux, audio, self.vcodec, morphbr@504: self.vbitrate, self.width, self.height, self.fifo) morphbr@504: morphbr@504: elif self.kind == "dvd": morphbr@504: self.args += " dvd://%s -alang %s -vf scale=%s:%s %s"\ morphbr@504: " -of %s -ovc lavc -lavcopts vcodec=%s:vbitrate=%s"\ morphbr@504: " -ofps %s -really-quiet -o %s 2>/dev/null" % ( morphbr@504: self.filename, self.language, self.width, self.height, audio, morphbr@504: self.mux, self.vcodec, self.vbitrate, self.fps, self.fifo) morphbr@504: morphbr@504: return (True, "") morphbr@504: morphbr@504: ''' morphbr@504: MENCODER SETUP DESCRIPTION morphbr@504: =========================== morphbr@504: morphbr@504: -> mux, vcodecs and acodecs morphbr@504: |-> mencoder (-of | -ovc | -oac) help morphbr@504: morphbr@504: -> if used mpeg as mux: morphbr@504: |-> to setup format: format=%s as an option at the end morphbr@504: morphbr@504: ''' morphbr@504: morphbr@504: def setup(self, filename, mux, vcodec, vbitrate,\ morphbr@504: fps, acodec, abitrate, width, height, port, options): morphbr@504: morphbr@504: self.mux = mux morphbr@504: self.vcodec = vcodec morphbr@504: self.vbitrate = vbitrate morphbr@504: self.fps = fps morphbr@504: self.acodec = acodec morphbr@504: self.abitrate = abitrate morphbr@504: self.width = width morphbr@504: self.height = height morphbr@504: self.port = int(port) morphbr@504: morphbr@504: self.setup_mencoder() morphbr@504: ret_val = self.setup_filename(filename) morphbr@504: morphbr@504: if not ret_val[0]: morphbr@504: return ret_val[1] morphbr@504: renatofilho@484: self.set_args(options) renatofilho@484: morphbr@498: # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240 5000 file morphbr@504: # /tmp/dvb.mpg mpeg mpeg1video 400 25 mp2 192 320 240 5000 format=mpeg1 file morphbr@497: #4 mpeg mpeg1video 400 25 mp3lame 192 400 240 5000 language=en local dvd morphbr@498: 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: morphbr@499: if self.mencoder_old: morphbr@499: try: morphbr@499: os.mkfifo(self.fifo) morphbr@499: except: morphbr@499: lib.log("Fifo already exists") morphbr@499: renatofilho@484: renatofilho@484: lib.log("Starting Mencoder: %s %s" % (self.path, self.args) ) renatofilho@484: # exec Mencoder morphbr@499: if self.mencoder_old: morphbr@499: self.mencoder_pid = Popen(self.path + self.args, shell=True) morphbr@504: self.pout = open(self.fifo) morphbr@499: else: morphbr@499: self.path += self.args morphbr@499: pin, self.pout = os.popen2(self.path) renatofilho@484: renatofilho@484: self.child_pid = os.fork() renatofilho@484: morphbr@498: 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: morphbr@499: data = self.pout.read(1024) morphbr@499: renatofilho@484: conn.settimeout(5) renatofilho@484: retry = 0 renatofilho@484: morphbr@498: 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) morphbr@498: 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: morphbr@499: data = self.pout.read(1024) renatofilho@484: morphbr@497: 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: morphbr@499: if self.mplayer_old: morphbr@499: os.kill(self.mencoder_pid.pid + 1, signal.SIGKILL) morphbr@499: else: morphbr@499: self.pout.close() renatofilho@484: self.mplayer = None renatofilho@484: except: renatofilho@484: lib.log("Trying to stop before playing...") renatofilho@484: morphbr@498: 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") morphbr@498: if self.child_pid != None: renatofilho@484: os.kill(self.child_pid, signal.SIGABRT)