# HG changeset patch # User renatofilho # Date 1175614924 -3600 # Node ID 27e83a8f68d750f1b22dc185d736b5d950d6b8f5 # Parent 8edb3b445cacb59d7769cc8e5c02421fc43ec1ca [svn r489] moved server implementation to new dir diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/lib.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/lib.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,9 @@ +import time + +def now(): + return time.strftime("%Y-%m-%d %H:%M:%S"); + +def log(msg): + new_msg = "[%s] %s" % (now(), msg) + print new_msg + return new_msg diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/main.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/main.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,81 @@ +#!/usr/bin/python + +import os +import lib +import sys +import ConfigParser + +config = ConfigParser.ConfigParser() +config.read("stream.conf") + +media_plugin = config.get("Media", "engine") +exec("from plugins.media.%s import *" % media_plugin) + +media = Media(config) + +comm_plugin = config.get("Comm", "engine") +exec("from plugins.comm.%s import *" % comm_plugin) + +# Start Our Server: +server = Server(config) + +lib.log("Starting GMyth-Stream server") + +while (server.finish == 0): + con, client = server.getRequest() + + while True: + msg = server.getMsg(1024).strip() + + if not msg: break + + lib.log("Received %s from: %s" % (msg, client) ) + + if (msg == "SETUP"): + setup = server.getMsg(1024).strip().split(" ") + size = len(setup) + options = [] + + if ( size < 10 ): + server.sendMsg(lib.log("Wrong SETUP command from: %s" % client[0])) + + else: + + if ( size > 10 ): + i = 10 + while (i < size): + options.append(setup[i]) + i += 1 + + ret = media.setup(setup[0], setup[1], setup[2], \ + setup[3], setup[4], setup[5], + setup[6], setup[7], setup[8], + setup[9], options) + + if (ret == 0): + server.Ack("SETUP") + else: + server.sendMsg(lib.log(ret)) + + + elif (msg == "PLAY"): + media.play() + server.Ack("PLAY") + + elif (msg == "STOP"): + media.stop() + server.Ack("STOP") + + elif (msg == "CLOSE"): + server.finish = 1 + media.stop() + server.Ack("CLOSE") + break + + lib.log("Closing connection with %s" % client[0]) + server.disconnect_client(con) + +server.stop() +del(server) +lib.log("Server stopped. Closing...") + diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/plugins/comm/tcp.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/plugins/comm/tcp.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,36 @@ +import lib +import time +import socket + +class Server: + + def __init__(self, config): + self.host = '' + self.port = int(config.get("Comm", "port")) + self.finish = 0 + + self.tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.tcp.bind( (self.host, self.port) ) + self.tcp.listen(1) + + def getMsg(self, size): + return self.con.recv(size) + + def sendMsg(self, msg): + self.con.send(msg + "\n") + + def Ack(self, command): + msg = "[%s] Command %s received" % (lib.now(), command) + self.sendMsg(msg) + + def getRequest(self): + self.con, self.client = self.tcp.accept() + print "[%s] Received request from ip=%s" % (lib.now(), self.client ) + return (self.con, self.client) + + def disconnect_client(self, connection): + connection.close() + + def stop(self): + self.tcp.close() diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/plugins/comm/xmlrpc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/plugins/comm/xmlrpc.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,94 @@ +import lib +import SimpleXMLRPCServer + + +class Handler: + + def __init__(self, recv_pool, send_pool): + self.recv_pool = recv_pool + self.send_pool = send_pool + self.getMsg = self.sendMsg + + def _listMethods(self): + return ['setup', 'play', 'stop', 'close', 'getMsg'] + + def _methodHelp(self, method): + + if method == 'setup': + return "Setup the Media: setup( filename, mux, vcodec, vbitrate, fps, acodec, abitrate, width, height, port" + elif method == 'play': + return "Play the Media: play()" + elif method == 'stop': + return "Stop the Media: stop()" + elif method == 'close': + return "Close the connection: close()" + elif method == 'getMsg': + return "Return the first message in the pool: getMsg()" + else: + # By convention, return empty + # string if no help is available + return "" + + def setup(self, filename, mux, vcodec, vbitrate,\ + fps, acodec, abitrate, width, height, port): + self.recv_pool.append("SETUP") + self.recv_pool.append("%s %s %s %s %s %s %s" % (filename, mux, vcodec, vbitrate,\ + fps, acodec, abitrate, width, height, port) + return self.sendMsg() + + def play(self): + self.recv_pool.append("PLAY") + return self.sendMsg() + + def stop(self): + self.recv_pool.append("STOP") + return self.sendMsg() + + def close(self): + self.recv_pool.append("CLOSE") + return self.sendMsg() + + def sendMsg(self): + if self.send_pool != []: + return self.send_pool.pop(0) + else: + return "" + + +class Server: + + def __init__(self, config): + self.host = 'localhost' + self.port = int(config.get("Comm", "port")) + self.finish = 0 + self.recv_pool = [] + self.send_pool = [] + + self.handler = Handler(self.recv_pool, self.send_pool) + + self.xmlrpc = SimpleXMLRPCServer.SimpleXMLRPCServer((self.host, self.port)) + self.xmlrpc.register_instance(self.handler) + + + def getMsg(self, size): + if self.recv_pool != []: + return self.recv_pool.pop(0) + else: + return "" + + def sendMsg(self, msg): + self.send_pool.append(msg) + + def Ack(self, command): + msg = "[%s] Command %s received" % (lib.now(), command) + self.sendMsg(msg + "\n") + + def getRequest(self): + self.xmlrpc.handle_request() + return (0, "RPC Client") + + def disconnect_client(self, connection): + connection = 0 + + def stop(self): + self.xmlrpc.server_close() diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/plugins/media/ffmpeg.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/plugins/media/ffmpeg.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,91 @@ +import os +import sys +import lib +import time +import socket +import ConfigParser + +class Media: + + def __init__(self, config): + + self.config = config + self.socket = None + self.child_pid = None + + def setup(self, filename, mux, vcodec, vbitrate,\ + fps, acodec, abitrate, width, height, port): + + self.filename = filename + self.mux = mux + self.vcodec = vcodec + self.vbitrate = int(vbitrate) + self.fps = int(fps) + self.acodec = acodec + self.abitrate = int(abitrate) + self.width = int(width) + self.height = int(height) + + self.port = int(port) + + # good one: /tmp/mpg/cpm.mpg mpeg mpeg1video 400 25 mp2 192 320 240 5000 + self.path = self.config.get("FFmpeg", "path") + self.path += " -i %s -f %s -vcodec %s -b %d -r %d -acodec %s -ab %d -s %dx%d -" % ( + self.filename, self.mux, self.vcodec, self.vbitrate,\ + self.fps, self.acodec, self.abitrate, self.width, self.height) + + 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.settimeout(10) + self.socket.listen(1) + + def play(self): + + lib.log("Starting FFmpeg: %s" % self.path) + + # exec FFmpeg and get stdout + child_stdin, child_stdout = os.popen2(self.path) + child_stdin.close() + + self.child_pid = os.fork() + if (self.child_pid == 0): + #child + + conn,addr= self.socket.accept() + lib.log("Sending Data to client: %s" % addr[0]) + data = child_stdout.read(1024) + conn.settimeout(5) + retry = 0 + + while( data != "" and retry < 5): + try: + conn.send(data) + except socket.error: + lib.log("Socket error (maybe timeout ?)") + retry = retry + 1 + + data = child_stdout.read(1024) + + if (retry < 5): + lib.log("Finished sending Data to client: %s" % addr[0]) + else: + lib.log("Client timed out") + + child_stdout.close() + #conn.close() + #sys.exit() + + + def stop(self): + + if (self.socket != None): + lib.log("Closing socket") + self.socket.close() + + lib.log("Trying to stop FFmpeg process") + if (self.child_pid != None): + os.kill(self.child_pid, 9) diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/plugins/media/gstreamer-rtp.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/plugins/media/gstreamer-rtp.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,218 @@ +import pygst +pygst.require("0.10") +import gst +import gobject + +class Media: + class StreamData: + stream_count = 0 + + def __init__ (self, pipe, abin, vbin): + + self.stream_count += 1 + self.Id = self.stream_count + self.Pipe = pipe + self.Abin = abin + self.Vbin = vbin + self.Loop = gobject.MainLoop() + self.ACaps = "" + self.VCaps = "" + self.Ready = False + + + def __init__(self, config): + # set gstreamer basic options + self.config = config + self.pipe = None + self.streams = [] + + + def setup(self, filename, mux, vcodec, vbitrate, + fps, acodec, abitrate, width, height, port, options): + + ## Pipelines + self.pipe = gst.Pipeline () + uri = "file://" + filename + print "Opening Uri:" + uri + src = gst.element_make_from_uri (gst.URI_SRC, uri, "src") + if (src is None): + return None + + decode = gst.element_factory_make ("decodebin", "decode") + if (decode is None): + return None + + + #video encode + #queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate ! ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink host=224.0.0.1 port=5000 + vbin = gst.Bin () + vqueue = gst.element_factory_make ("queue", "vqueue") + vscale = gst.element_factory_make ("videoscale", "vscale") + vrate = gst.element_factory_make ("videorate", "vrate") + vencode = gst.element_factory_make ("ffenc_mpeg4", "vencode") + vpay = gst.element_factory_make ("rtpmp4vpay", "vpay") + vsink = gst.element_factory_make ("udpsink", "vsink") + + if (None in [vbin, vqueue, vscale, vrate, vencode, vpay, vsink]): + print "Fail to create video encode elements." + return None + + vscale_pad = vscale.get_pad("sink") + if (vscale_pad is None): + print "Fail to get vscale sink pad." + return None + + vscale_caps = gst.caps_from_string ("video/x-raw-yuv, width=%s, height=%s" % (width, height)) + if (vscale_caps is None): + print "Fail to create video caps" + return None + + if (not vscale_pad.set_caps (vscale_caps)): + print "Fail to set video output caps" + return None + + vencode.set_property ("bitrate", 256000) + vencode.set_property ("me-method", 2) + + vsink.set_property ("host", "224.0.0.1") + vsink.set_property ("port", 5000) + + vbin.add (vqueue, vscale, vrate, vencode, vpay, vsink) + if (not gst.element_link_many (vqueue, vscale, vrate, vencode, vpay, vsink)): + print "Fail to link video elements" + return None + + vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink"))) + + #audio encode + #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002 + abin = gst.Bin () + aqueue = gst.element_factory_make ("queue", "vqueue") + aconvert = gst.element_factory_make ("audioconvert", "aconvert") + aencode = gst.element_factory_make ("faac", "aencode") + apay = gst.element_factory_make ("rtpmp4gpay", "apay") + asink = gst.element_factory_make ("udpsink", "asink") + + if (None in [abin, aqueue, aconvert, aencode, apay, asink]): + print "Fail to create video encode elements." + return None + + asink.set_property ("host", "224.0.0.1") + asink.set_property ("port", 5002) + + abin.add (aqueue, aconvert, aencode, apay, asink) + if (not gst.element_link_many (aqueue, aconvert, aencode, apay, asink)): + print "Fail to link video elements" + return None + + abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink"))) + + self.pipe.add (src, decode, abin, vbin) + gst.element_link_many (src, decode) + + stream_data = self.StreamData (self.pipe, abin, vbin) + + bus = self.pipe.get_bus() + bus.add_signal_watch() + bus.connect("message", self.__on_bus_message, stream_data) + + decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data) + decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data) + + + self.pipe.set_state (gst.STATE_PAUSED) + print "Running Pipe" + stream_data.Loop.run () + print "End run" + + a_caps = stream_data.ACaps + v_caps = stream_data.VCaps + stream_id = stream_data.Id + + self.streams.append (stream_data) + + def play(self): + + print "Trying to play pipeline: %s" % self.pipe + try: + if (self.pipe): + self.pipe.set_state(gst.STATE_PLAYING) + except gobject.GError, e: + print "Error: " + str(e) + + + def stop(self): + + print "Trying to stop pipeline: %s" % self.pipe + try: + if (self.pipeline): + self.pipeline.set_state(gst.STATE_NULL) + except gobject.GError, e: + print "Error: " + str(e) + + def __on_bus_message (self, bus, message, stream_data): + + t = message.type + if (t == gst.MESSAGE_STATE_CHANGED): + oldstate = -1 + newstate = -1 + pending = -1 + oldstate, newstate, pending = message.parse_state_changed () + if ((oldstate == gst.STATE_READY) and \ + (newstate == gst.STATE_PAUSED) and \ + (pending == gst.STATE_VOID_PENDING) and \ + (stream_data.Ready == False)): + state_changed_status, current_state, pending_state = stream_data.Pipe.get_state () + if ((current_state == gst.STATE_PAUSED) and \ + (pending_state == gst.STATE_VOID_PENDING)): + print "Pipe paused" + self.__fill_sink_pads (stream_data) + stream_data.Loop.quit () + stream_data.Ready = True + elif (t == gst.MESSAGE_ERROR): + err, debug = message.parse_error() + print "Error: %s" % err, debug + stream_data.Loop.quit () + stream_data.Ready = False + + return True + + + def __fill_sink_pads (self, stream_data): + + asink = stream_data.Abin.get_by_name ("asink") + vsink = stream_data.Vbin.get_by_name ("vsink") + + asink_pad = asink.get_pad ("sink") + stream_data.ACaps = asink_pad.get_negotiated_caps().to_string() + print "ACAPS " + stream_data.ACaps + + vsink_pad = vsink.get_pad ("sink") + stream_data.VCaps = vsink_pad.get_negotiated_caps().to_string() + print "ACAPS " + stream_data.VCaps + + + + def __on_decode_unknown_type (self, decode, pad, caps, stream_data): + + print "Unknown Type" + return None + + def __on_decode_new_pad (self, decode, pad, arg1, stream_data): + + caps = pad.get_caps().to_string() + print "New pad " + caps + if (caps.rfind ("audio") != -1): + apad = stream_data.Abin.get_pad ("sink") + if (pad.link (apad) != gst.PAD_LINK_OK): + print "Error on link audio pad" + return None + elif (caps.rfind ("video") != -1): + vpad = stream_data.Vbin.get_pad ("sink") + if (pad.link (vpad) != gst.PAD_LINK_OK): + print "Error on link video pad" + return None + else: + print "Invalid caps" + + diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/plugins/media/gstreamer.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/plugins/media/gstreamer.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,235 @@ +import pygst +pygst.require("0.10") +import gst +import gobject +import socket + +class Media: + class StreamData: + stream_count = 0 + + def __init__ (self, pipe, abin, vbin, sink): + + self.stream_count += 1 + self.Id = self.stream_count + self.Pipe = pipe + self.Abin = abin + self.Vbin = vbin + self.Sink = sink + self.Loop = gobject.MainLoop() + self.ACaps = "" + self.VCaps = "" + self.Ready = False + + + def __init__(self, config): + # set gstreamer basic options + self.config = config + self.pipe = None + self.streams = [] + self.socket = None + self.connection = None + self.addr = None + + + def setup(self, filename, mux, vcodec, vbitrate, + fps, acodec, abitrate, width, height, port, options): + + ## Pipelines + self.pipe = gst.Pipeline () + uri = "file://" + filename + print "Opening Uri:" + uri + src = gst.element_make_from_uri (gst.URI_SRC, uri, "src") + if (src is None): + return None + + decode = gst.element_factory_make ("decodebin", "decode") + if (decode is None): + return None + + mux = gst.element_factory_make ("avimux", "mux") + if (mux is None): + return None + + sink = gst.element_factory_make ("fdsink", "sink") + if (sink is None): + return None + + #Create socket + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.socket.bind(('', int (port))) + + #video encode + #queue ! videoscale ! video/x-raw-yuv,width=240,height=144 ! videorate ! ffenc_h263p bitrate=256000 me-method=2 ! rtph263ppay ! udpsink host=224.0.0.1 port=5000 + vbin = gst.Bin () + vqueue = gst.element_factory_make ("queue", "vqueue") + vscale = gst.element_factory_make ("videoscale", "vscale") + vrate = gst.element_factory_make ("videorate", "vrate") + vencode = gst.element_factory_make ("ffenc_h263p", "vencode") + + if (None in [vbin, vqueue, vscale, vrate, vencode]): + print "Fail to create video encode elements." + return None + + vscale_pad = vscale.get_pad("sink") + if (vscale_pad is None): + print "Fail to get vscale sink pad." + return None + + vscale_caps = gst.caps_from_string ("video/x-raw-yuv, width=%s, height=%s" % (width, height)) + if (vscale_caps is None): + print "Fail to create video caps" + return None + + if (not vscale_pad.set_caps (vscale_caps)): + print "Fail to set video output caps" + return None + + vbin.add (vqueue, vscale, vrate, vencode) + if (not gst.element_link_many (vqueue, vscale, vrate, vencode)): + print "Fail to link video elements" + return None + + vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink"))) + vbin.add_pad (gst.GhostPad ("src", vencode.get_pad ("src"))) + + #audio encode + #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002 + abin = gst.Bin () + aqueue = gst.element_factory_make ("queue", "vqueue") + aconvert = gst.element_factory_make ("audioconvert", "aconvert") + aencode = gst.element_factory_make ("ffenc_ac3", "aencode") + + if (None in [abin, aqueue, aconvert, aencode]): + print "Fail to create video encode elements." + return None + + abin.add (aqueue, aconvert, aencode) + if (not gst.element_link_many (aqueue, aconvert, aencode)): + print "Fail to link video elements" + return None + + abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink"))) + abin.add_pad (gst.GhostPad ("src", aencode.get_pad ("src"))) + + #Finish Pipeline + + self.pipe.add (src, decode, abin, vbin, mux, sink) + gst.element_link_many (src, decode) + gst.element_link_many (mux, sink) + + #Linking decode with mux + mux_audio = mux.get_pad ("audio_0") + mux_video = mux.get_pad ("video_0") + + audio_pad = abin.get_pad ("src") + video_pad = vbin.get_pad ("src") + + if (audio_pad.link (mux_audio) != gst.PAD_LINK_OK): + print "Fail to link audio with mux" + return None + + if (video_pad.link (mux_video) != gst.PAD_LINK_OK): + print "Fail to link audio with mux" + return None + + stream_data = self.StreamData (self.pipe, abin, vbin, sink) + + bus = self.pipe.get_bus() + bus.add_signal_watch() + bus.connect("message", self.__on_bus_message, stream_data) + + decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data) + decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data) + + + self.pipe.set_state (gst.STATE_PAUSED) + print "Running Pipe" + stream_data.Loop.run () + print "End run" + + a_caps = stream_data.ACaps + v_caps = stream_data.VCaps + stream_id = stream_data.Id + + self.streams.append (stream_data) + + def play(self): + + print "Trying to play pipeline: %s" % self.pipe + try: + if (self.pipe): + print "Waiting for connection" + self.socket.listen(1) + print "Connection Requested" + #Create socket + self.connection, self.addr = self.socket.accept () + + stream_data = self.streams[0] + stream_data.Sink.set_property ("fd", self.connection.fileno()); + print "Connected" + + self.pipe.set_state(gst.STATE_PLAYING) + except gobject.GError, e: + print "Error: " + str(e) + + + def stop(self): + + print "Trying to stop pipeline: %s" % self.pipe + try: + if (self.pipeline): + self.connection.close () + self.pipeline.set_state(gst.STATE_NULL) + except gobject.GError, e: + print "Error: " + str(e) + + def __on_bus_message (self, bus, message, stream_data): + + t = message.type + if (t == gst.MESSAGE_STATE_CHANGED): + oldstate = -1 + newstate = -1 + pending = -1 + oldstate, newstate, pending = message.parse_state_changed () + if ((oldstate == gst.STATE_READY) and \ + (newstate == gst.STATE_PAUSED) and \ + (pending == gst.STATE_VOID_PENDING) and \ + (stream_data.Ready == False)): + state_changed_status, current_state, pending_state = stream_data.Pipe.get_state () + if ((current_state == gst.STATE_PAUSED) and \ + (pending_state == gst.STATE_VOID_PENDING)): + print "Pipe paused" + stream_data.Loop.quit () + stream_data.Ready = True + elif (t == gst.MESSAGE_ERROR): + err, debug = message.parse_error() + print "Error: %s" % err, debug + stream_data.Loop.quit () + stream_data.Ready = False + + return True + + def __on_decode_unknown_type (self, decode, pad, caps, stream_data): + + print "Unknown Type" + return None + + def __on_decode_new_pad (self, decode, pad, arg1, stream_data): + + caps = pad.get_caps().to_string() + print "New pad " + caps + if (caps.rfind ("audio") != -1): + apad = stream_data.Abin.get_pad ("sink") + if (pad.link (apad) != gst.PAD_LINK_OK): + print "Error on link audio pad" + return None + elif (caps.rfind ("video") != -1): + vpad = stream_data.Vbin.get_pad ("sink") + if (pad.link (vpad) != gst.PAD_LINK_OK): + print "Error on link video pad" + return None + else: + print "Invalid caps" + + diff -r 8edb3b445cac -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) diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/plugins/media/vlc.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/plugins/media/vlc.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,80 @@ +import os +import sys +import time +import socket +import ConfigParser + +class Media: + + def __init__(self, config): + + self.config = config + self.pipe = "" + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + self.path = config.get("Vlc", "path") + self.host = config.get("Vlc", "host") + self.port = int(config.get("Vlc", "port")) + self.pwd = config.get("Vlc", "pwd") + + # exec VLC + pid = os.fork() + if (pid == 0): + #child + print "ESTOU EM CHILD" + self.path += " -I telnet -d 1> /dev/null 2> /dev/null &" + os.system(self.path) + sys.exit(0) + else: + print "ESTOU EM PARENT 1" + time.sleep(3) + print "ESTOU EM PARENT 2" + self.sock.connect( (self.host, self.port) ) + self.sock.send("%s\n" % self.pwd) + + + def insert_file(self, filename): + + self.sock.send("setup output0 input %s\n" % filename) + + + + def setup(self, filename, mux, vcodec, vbitrate,\ + fps, acodec, abitrate, width, height, port): + + self.filename = filename + self.mux = mux + self.vcodec = vcodec + self.vbitrate = int(vbitrate) + self.fps = int(fps) + self.acodec = acodec + self.abitrate = int(abitrate) + self.width = int(width) + self.height = int(height) + + self.port = int(port) + + + self.pipe = "#transcode{vcodec=%s,vb=%d,"\ + "fps=25.0,scale=1,acodec=mpga,"\ + "ab=64,channels=1,width=%d,height=%d}"\ + ":duplicate{dst=std{access=http,"\ + "mux=mpeg1,dst=:%d}}" % (self.vcodec, self.vbitrate,\ + self.widht, self.height,\ + self.port) + + self.sock.send("setup output0 broadcast %s\n" % self.pipe) + self.insert_file(self.filename) + + def play(self): + + print "Trying to play: %s" % self.pipe + self.sock.send("control output0 play\n") + + + def stop(self): + + print "Trying to stop: %s" % self.pipe + self.sock.send("control output0 stop\n") + + diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/stream.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/stream.conf Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,23 @@ +[Comm] +engine = tcp +port = 12345 + + +[Media] +engine = mencoder + + +[Vlc] +path = /usr/local/bin/vlc +host = 127.0.0.1 +port = 4212 +pwd = admin + + +[FFmpeg] +path = /usr/bin/ffmpeg + + +[Mencoder] +path = /usr/local/bin/mencoder +fifo_path = /tmp/teste diff -r 8edb3b445cac -r 27e83a8f68d7 gmyth-stream/server/tests/client_ffmpeg.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gmyth-stream/server/tests/client_ffmpeg.py Tue Apr 03 16:42:04 2007 +0100 @@ -0,0 +1,48 @@ +import os +import sys +import time +import socket + + +if len(sys.argv) < 2: + HOST = 'localhost' + PORT = 5000 +elif len(sys.argv) == 2: + HOST = sys.argv[1] + PORT = 5000 +else: + HOST = sys.argv[1] + PORT = int(sys.argv[2]) + +socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) +socket.settimeout(10) + +try: + socket.connect( (HOST,PORT) ) +except: + print "\n--> Could not connect to ('%s':'%d')\n" % (HOST,PORT) + sys.exit(-1) + + +mplayer = os.popen("which mplayer").read().strip() +mplayer += " - 1> /dev/null" +pin, pout = os.popen2(mplayer) + +data = socket.recv(1024) +i = 0 + +while (data != ""): + pin.write(data) + data = socket.recv(1024) + if (i == 500): + socket.send("OK") + i += 1 + +pin.close() +socket.close() + + +# from select import select +# r, w, x = select([pout], []. [], 0) +# if pout in r: +# pout.read(32)