1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/gmyth-stream/server/lib.py Tue Apr 03 16:42:04 2007 +0100
1.3 @@ -0,0 +1,9 @@
1.4 +import time
1.5 +
1.6 +def now():
1.7 + return time.strftime("%Y-%m-%d %H:%M:%S");
1.8 +
1.9 +def log(msg):
1.10 + new_msg = "[%s] %s" % (now(), msg)
1.11 + print new_msg
1.12 + return new_msg
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/gmyth-stream/server/main.py Tue Apr 03 16:42:04 2007 +0100
2.3 @@ -0,0 +1,81 @@
2.4 +#!/usr/bin/python
2.5 +
2.6 +import os
2.7 +import lib
2.8 +import sys
2.9 +import ConfigParser
2.10 +
2.11 +config = ConfigParser.ConfigParser()
2.12 +config.read("stream.conf")
2.13 +
2.14 +media_plugin = config.get("Media", "engine")
2.15 +exec("from plugins.media.%s import *" % media_plugin)
2.16 +
2.17 +media = Media(config)
2.18 +
2.19 +comm_plugin = config.get("Comm", "engine")
2.20 +exec("from plugins.comm.%s import *" % comm_plugin)
2.21 +
2.22 +# Start Our Server:
2.23 +server = Server(config)
2.24 +
2.25 +lib.log("Starting GMyth-Stream server")
2.26 +
2.27 +while (server.finish == 0):
2.28 + con, client = server.getRequest()
2.29 +
2.30 + while True:
2.31 + msg = server.getMsg(1024).strip()
2.32 +
2.33 + if not msg: break
2.34 +
2.35 + lib.log("Received %s from: %s" % (msg, client) )
2.36 +
2.37 + if (msg == "SETUP"):
2.38 + setup = server.getMsg(1024).strip().split(" ")
2.39 + size = len(setup)
2.40 + options = []
2.41 +
2.42 + if ( size < 10 ):
2.43 + server.sendMsg(lib.log("Wrong SETUP command from: %s" % client[0]))
2.44 +
2.45 + else:
2.46 +
2.47 + if ( size > 10 ):
2.48 + i = 10
2.49 + while (i < size):
2.50 + options.append(setup[i])
2.51 + i += 1
2.52 +
2.53 + ret = media.setup(setup[0], setup[1], setup[2], \
2.54 + setup[3], setup[4], setup[5],
2.55 + setup[6], setup[7], setup[8],
2.56 + setup[9], options)
2.57 +
2.58 + if (ret == 0):
2.59 + server.Ack("SETUP")
2.60 + else:
2.61 + server.sendMsg(lib.log(ret))
2.62 +
2.63 +
2.64 + elif (msg == "PLAY"):
2.65 + media.play()
2.66 + server.Ack("PLAY")
2.67 +
2.68 + elif (msg == "STOP"):
2.69 + media.stop()
2.70 + server.Ack("STOP")
2.71 +
2.72 + elif (msg == "CLOSE"):
2.73 + server.finish = 1
2.74 + media.stop()
2.75 + server.Ack("CLOSE")
2.76 + break
2.77 +
2.78 + lib.log("Closing connection with %s" % client[0])
2.79 + server.disconnect_client(con)
2.80 +
2.81 +server.stop()
2.82 +del(server)
2.83 +lib.log("Server stopped. Closing...")
2.84 +
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/gmyth-stream/server/plugins/comm/tcp.py Tue Apr 03 16:42:04 2007 +0100
3.3 @@ -0,0 +1,36 @@
3.4 +import lib
3.5 +import time
3.6 +import socket
3.7 +
3.8 +class Server:
3.9 +
3.10 + def __init__(self, config):
3.11 + self.host = ''
3.12 + self.port = int(config.get("Comm", "port"))
3.13 + self.finish = 0
3.14 +
3.15 + self.tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3.16 + self.tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
3.17 + self.tcp.bind( (self.host, self.port) )
3.18 + self.tcp.listen(1)
3.19 +
3.20 + def getMsg(self, size):
3.21 + return self.con.recv(size)
3.22 +
3.23 + def sendMsg(self, msg):
3.24 + self.con.send(msg + "\n")
3.25 +
3.26 + def Ack(self, command):
3.27 + msg = "[%s] Command %s received" % (lib.now(), command)
3.28 + self.sendMsg(msg)
3.29 +
3.30 + def getRequest(self):
3.31 + self.con, self.client = self.tcp.accept()
3.32 + print "[%s] Received request from ip=%s" % (lib.now(), self.client )
3.33 + return (self.con, self.client)
3.34 +
3.35 + def disconnect_client(self, connection):
3.36 + connection.close()
3.37 +
3.38 + def stop(self):
3.39 + self.tcp.close()
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/gmyth-stream/server/plugins/comm/xmlrpc.py Tue Apr 03 16:42:04 2007 +0100
4.3 @@ -0,0 +1,94 @@
4.4 +import lib
4.5 +import SimpleXMLRPCServer
4.6 +
4.7 +
4.8 +class Handler:
4.9 +
4.10 + def __init__(self, recv_pool, send_pool):
4.11 + self.recv_pool = recv_pool
4.12 + self.send_pool = send_pool
4.13 + self.getMsg = self.sendMsg
4.14 +
4.15 + def _listMethods(self):
4.16 + return ['setup', 'play', 'stop', 'close', 'getMsg']
4.17 +
4.18 + def _methodHelp(self, method):
4.19 +
4.20 + if method == 'setup':
4.21 + return "Setup the Media: setup( filename, mux, vcodec, vbitrate, fps, acodec, abitrate, width, height, port"
4.22 + elif method == 'play':
4.23 + return "Play the Media: play()"
4.24 + elif method == 'stop':
4.25 + return "Stop the Media: stop()"
4.26 + elif method == 'close':
4.27 + return "Close the connection: close()"
4.28 + elif method == 'getMsg':
4.29 + return "Return the first message in the pool: getMsg()"
4.30 + else:
4.31 + # By convention, return empty
4.32 + # string if no help is available
4.33 + return ""
4.34 +
4.35 + def setup(self, filename, mux, vcodec, vbitrate,\
4.36 + fps, acodec, abitrate, width, height, port):
4.37 + self.recv_pool.append("SETUP")
4.38 + self.recv_pool.append("%s %s %s %s %s %s %s" % (filename, mux, vcodec, vbitrate,\
4.39 + fps, acodec, abitrate, width, height, port)
4.40 + return self.sendMsg()
4.41 +
4.42 + def play(self):
4.43 + self.recv_pool.append("PLAY")
4.44 + return self.sendMsg()
4.45 +
4.46 + def stop(self):
4.47 + self.recv_pool.append("STOP")
4.48 + return self.sendMsg()
4.49 +
4.50 + def close(self):
4.51 + self.recv_pool.append("CLOSE")
4.52 + return self.sendMsg()
4.53 +
4.54 + def sendMsg(self):
4.55 + if self.send_pool != []:
4.56 + return self.send_pool.pop(0)
4.57 + else:
4.58 + return ""
4.59 +
4.60 +
4.61 +class Server:
4.62 +
4.63 + def __init__(self, config):
4.64 + self.host = 'localhost'
4.65 + self.port = int(config.get("Comm", "port"))
4.66 + self.finish = 0
4.67 + self.recv_pool = []
4.68 + self.send_pool = []
4.69 +
4.70 + self.handler = Handler(self.recv_pool, self.send_pool)
4.71 +
4.72 + self.xmlrpc = SimpleXMLRPCServer.SimpleXMLRPCServer((self.host, self.port))
4.73 + self.xmlrpc.register_instance(self.handler)
4.74 +
4.75 +
4.76 + def getMsg(self, size):
4.77 + if self.recv_pool != []:
4.78 + return self.recv_pool.pop(0)
4.79 + else:
4.80 + return ""
4.81 +
4.82 + def sendMsg(self, msg):
4.83 + self.send_pool.append(msg)
4.84 +
4.85 + def Ack(self, command):
4.86 + msg = "[%s] Command %s received" % (lib.now(), command)
4.87 + self.sendMsg(msg + "\n")
4.88 +
4.89 + def getRequest(self):
4.90 + self.xmlrpc.handle_request()
4.91 + return (0, "RPC Client")
4.92 +
4.93 + def disconnect_client(self, connection):
4.94 + connection = 0
4.95 +
4.96 + def stop(self):
4.97 + self.xmlrpc.server_close()
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/gmyth-stream/server/plugins/media/ffmpeg.py Tue Apr 03 16:42:04 2007 +0100
5.3 @@ -0,0 +1,91 @@
5.4 +import os
5.5 +import sys
5.6 +import lib
5.7 +import time
5.8 +import socket
5.9 +import ConfigParser
5.10 +
5.11 +class Media:
5.12 +
5.13 + def __init__(self, config):
5.14 +
5.15 + self.config = config
5.16 + self.socket = None
5.17 + self.child_pid = None
5.18 +
5.19 + def setup(self, filename, mux, vcodec, vbitrate,\
5.20 + fps, acodec, abitrate, width, height, port):
5.21 +
5.22 + self.filename = filename
5.23 + self.mux = mux
5.24 + self.vcodec = vcodec
5.25 + self.vbitrate = int(vbitrate)
5.26 + self.fps = int(fps)
5.27 + self.acodec = acodec
5.28 + self.abitrate = int(abitrate)
5.29 + self.width = int(width)
5.30 + self.height = int(height)
5.31 +
5.32 + self.port = int(port)
5.33 +
5.34 + # good one: /tmp/mpg/cpm.mpg mpeg mpeg1video 400 25 mp2 192 320 240 5000
5.35 + self.path = self.config.get("FFmpeg", "path")
5.36 + self.path += " -i %s -f %s -vcodec %s -b %d -r %d -acodec %s -ab %d -s %dx%d -" % (
5.37 + self.filename, self.mux, self.vcodec, self.vbitrate,\
5.38 + self.fps, self.acodec, self.abitrate, self.width, self.height)
5.39 +
5.40 + if (self.socket != None):
5.41 + del(self.socket)
5.42 +
5.43 + self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
5.44 + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
5.45 + self.socket.bind( ('', self.port) )
5.46 + self.socket.settimeout(10)
5.47 + self.socket.listen(1)
5.48 +
5.49 + def play(self):
5.50 +
5.51 + lib.log("Starting FFmpeg: %s" % self.path)
5.52 +
5.53 + # exec FFmpeg and get stdout
5.54 + child_stdin, child_stdout = os.popen2(self.path)
5.55 + child_stdin.close()
5.56 +
5.57 + self.child_pid = os.fork()
5.58 + if (self.child_pid == 0):
5.59 + #child
5.60 +
5.61 + conn,addr= self.socket.accept()
5.62 + lib.log("Sending Data to client: %s" % addr[0])
5.63 + data = child_stdout.read(1024)
5.64 + conn.settimeout(5)
5.65 + retry = 0
5.66 +
5.67 + while( data != "" and retry < 5):
5.68 + try:
5.69 + conn.send(data)
5.70 + except socket.error:
5.71 + lib.log("Socket error (maybe timeout ?)")
5.72 + retry = retry + 1
5.73 +
5.74 + data = child_stdout.read(1024)
5.75 +
5.76 + if (retry < 5):
5.77 + lib.log("Finished sending Data to client: %s" % addr[0])
5.78 + else:
5.79 + lib.log("Client timed out")
5.80 +
5.81 + child_stdout.close()
5.82 + #conn.close()
5.83 + #sys.exit()
5.84 +
5.85 +
5.86 + def stop(self):
5.87 +
5.88 + if (self.socket != None):
5.89 + lib.log("Closing socket")
5.90 + self.socket.close()
5.91 +
5.92 + lib.log("Trying to stop FFmpeg process")
5.93 + if (self.child_pid != None):
5.94 + os.kill(self.child_pid, 9)
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/gmyth-stream/server/plugins/media/gstreamer-rtp.py Tue Apr 03 16:42:04 2007 +0100
6.3 @@ -0,0 +1,218 @@
6.4 +import pygst
6.5 +pygst.require("0.10")
6.6 +import gst
6.7 +import gobject
6.8 +
6.9 +class Media:
6.10 + class StreamData:
6.11 + stream_count = 0
6.12 +
6.13 + def __init__ (self, pipe, abin, vbin):
6.14 +
6.15 + self.stream_count += 1
6.16 + self.Id = self.stream_count
6.17 + self.Pipe = pipe
6.18 + self.Abin = abin
6.19 + self.Vbin = vbin
6.20 + self.Loop = gobject.MainLoop()
6.21 + self.ACaps = ""
6.22 + self.VCaps = ""
6.23 + self.Ready = False
6.24 +
6.25 +
6.26 + def __init__(self, config):
6.27 + # set gstreamer basic options
6.28 + self.config = config
6.29 + self.pipe = None
6.30 + self.streams = []
6.31 +
6.32 +
6.33 + def setup(self, filename, mux, vcodec, vbitrate,
6.34 + fps, acodec, abitrate, width, height, port, options):
6.35 +
6.36 + ## Pipelines
6.37 + self.pipe = gst.Pipeline ()
6.38 + uri = "file://" + filename
6.39 + print "Opening Uri:" + uri
6.40 + src = gst.element_make_from_uri (gst.URI_SRC, uri, "src")
6.41 + if (src is None):
6.42 + return None
6.43 +
6.44 + decode = gst.element_factory_make ("decodebin", "decode")
6.45 + if (decode is None):
6.46 + return None
6.47 +
6.48 +
6.49 + #video encode
6.50 + #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
6.51 + vbin = gst.Bin ()
6.52 + vqueue = gst.element_factory_make ("queue", "vqueue")
6.53 + vscale = gst.element_factory_make ("videoscale", "vscale")
6.54 + vrate = gst.element_factory_make ("videorate", "vrate")
6.55 + vencode = gst.element_factory_make ("ffenc_mpeg4", "vencode")
6.56 + vpay = gst.element_factory_make ("rtpmp4vpay", "vpay")
6.57 + vsink = gst.element_factory_make ("udpsink", "vsink")
6.58 +
6.59 + if (None in [vbin, vqueue, vscale, vrate, vencode, vpay, vsink]):
6.60 + print "Fail to create video encode elements."
6.61 + return None
6.62 +
6.63 + vscale_pad = vscale.get_pad("sink")
6.64 + if (vscale_pad is None):
6.65 + print "Fail to get vscale sink pad."
6.66 + return None
6.67 +
6.68 + vscale_caps = gst.caps_from_string ("video/x-raw-yuv, width=%s, height=%s" % (width, height))
6.69 + if (vscale_caps is None):
6.70 + print "Fail to create video caps"
6.71 + return None
6.72 +
6.73 + if (not vscale_pad.set_caps (vscale_caps)):
6.74 + print "Fail to set video output caps"
6.75 + return None
6.76 +
6.77 + vencode.set_property ("bitrate", 256000)
6.78 + vencode.set_property ("me-method", 2)
6.79 +
6.80 + vsink.set_property ("host", "224.0.0.1")
6.81 + vsink.set_property ("port", 5000)
6.82 +
6.83 + vbin.add (vqueue, vscale, vrate, vencode, vpay, vsink)
6.84 + if (not gst.element_link_many (vqueue, vscale, vrate, vencode, vpay, vsink)):
6.85 + print "Fail to link video elements"
6.86 + return None
6.87 +
6.88 + vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink")))
6.89 +
6.90 + #audio encode
6.91 + #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002
6.92 + abin = gst.Bin ()
6.93 + aqueue = gst.element_factory_make ("queue", "vqueue")
6.94 + aconvert = gst.element_factory_make ("audioconvert", "aconvert")
6.95 + aencode = gst.element_factory_make ("faac", "aencode")
6.96 + apay = gst.element_factory_make ("rtpmp4gpay", "apay")
6.97 + asink = gst.element_factory_make ("udpsink", "asink")
6.98 +
6.99 + if (None in [abin, aqueue, aconvert, aencode, apay, asink]):
6.100 + print "Fail to create video encode elements."
6.101 + return None
6.102 +
6.103 + asink.set_property ("host", "224.0.0.1")
6.104 + asink.set_property ("port", 5002)
6.105 +
6.106 + abin.add (aqueue, aconvert, aencode, apay, asink)
6.107 + if (not gst.element_link_many (aqueue, aconvert, aencode, apay, asink)):
6.108 + print "Fail to link video elements"
6.109 + return None
6.110 +
6.111 + abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink")))
6.112 +
6.113 + self.pipe.add (src, decode, abin, vbin)
6.114 + gst.element_link_many (src, decode)
6.115 +
6.116 + stream_data = self.StreamData (self.pipe, abin, vbin)
6.117 +
6.118 + bus = self.pipe.get_bus()
6.119 + bus.add_signal_watch()
6.120 + bus.connect("message", self.__on_bus_message, stream_data)
6.121 +
6.122 + decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
6.123 + decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
6.124 +
6.125 +
6.126 + self.pipe.set_state (gst.STATE_PAUSED)
6.127 + print "Running Pipe"
6.128 + stream_data.Loop.run ()
6.129 + print "End run"
6.130 +
6.131 + a_caps = stream_data.ACaps
6.132 + v_caps = stream_data.VCaps
6.133 + stream_id = stream_data.Id
6.134 +
6.135 + self.streams.append (stream_data)
6.136 +
6.137 + def play(self):
6.138 +
6.139 + print "Trying to play pipeline: %s" % self.pipe
6.140 + try:
6.141 + if (self.pipe):
6.142 + self.pipe.set_state(gst.STATE_PLAYING)
6.143 + except gobject.GError, e:
6.144 + print "Error: " + str(e)
6.145 +
6.146 +
6.147 + def stop(self):
6.148 +
6.149 + print "Trying to stop pipeline: %s" % self.pipe
6.150 + try:
6.151 + if (self.pipeline):
6.152 + self.pipeline.set_state(gst.STATE_NULL)
6.153 + except gobject.GError, e:
6.154 + print "Error: " + str(e)
6.155 +
6.156 + def __on_bus_message (self, bus, message, stream_data):
6.157 +
6.158 + t = message.type
6.159 + if (t == gst.MESSAGE_STATE_CHANGED):
6.160 + oldstate = -1
6.161 + newstate = -1
6.162 + pending = -1
6.163 + oldstate, newstate, pending = message.parse_state_changed ()
6.164 + if ((oldstate == gst.STATE_READY) and \
6.165 + (newstate == gst.STATE_PAUSED) and \
6.166 + (pending == gst.STATE_VOID_PENDING) and \
6.167 + (stream_data.Ready == False)):
6.168 + state_changed_status, current_state, pending_state = stream_data.Pipe.get_state ()
6.169 + if ((current_state == gst.STATE_PAUSED) and \
6.170 + (pending_state == gst.STATE_VOID_PENDING)):
6.171 + print "Pipe paused"
6.172 + self.__fill_sink_pads (stream_data)
6.173 + stream_data.Loop.quit ()
6.174 + stream_data.Ready = True
6.175 + elif (t == gst.MESSAGE_ERROR):
6.176 + err, debug = message.parse_error()
6.177 + print "Error: %s" % err, debug
6.178 + stream_data.Loop.quit ()
6.179 + stream_data.Ready = False
6.180 +
6.181 + return True
6.182 +
6.183 +
6.184 + def __fill_sink_pads (self, stream_data):
6.185 +
6.186 + asink = stream_data.Abin.get_by_name ("asink")
6.187 + vsink = stream_data.Vbin.get_by_name ("vsink")
6.188 +
6.189 + asink_pad = asink.get_pad ("sink")
6.190 + stream_data.ACaps = asink_pad.get_negotiated_caps().to_string()
6.191 + print "ACAPS " + stream_data.ACaps
6.192 +
6.193 + vsink_pad = vsink.get_pad ("sink")
6.194 + stream_data.VCaps = vsink_pad.get_negotiated_caps().to_string()
6.195 + print "ACAPS " + stream_data.VCaps
6.196 +
6.197 +
6.198 +
6.199 + def __on_decode_unknown_type (self, decode, pad, caps, stream_data):
6.200 +
6.201 + print "Unknown Type"
6.202 + return None
6.203 +
6.204 + def __on_decode_new_pad (self, decode, pad, arg1, stream_data):
6.205 +
6.206 + caps = pad.get_caps().to_string()
6.207 + print "New pad " + caps
6.208 + if (caps.rfind ("audio") != -1):
6.209 + apad = stream_data.Abin.get_pad ("sink")
6.210 + if (pad.link (apad) != gst.PAD_LINK_OK):
6.211 + print "Error on link audio pad"
6.212 + return None
6.213 + elif (caps.rfind ("video") != -1):
6.214 + vpad = stream_data.Vbin.get_pad ("sink")
6.215 + if (pad.link (vpad) != gst.PAD_LINK_OK):
6.216 + print "Error on link video pad"
6.217 + return None
6.218 + else:
6.219 + print "Invalid caps"
6.220 +
6.221 +
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/gmyth-stream/server/plugins/media/gstreamer.py Tue Apr 03 16:42:04 2007 +0100
7.3 @@ -0,0 +1,235 @@
7.4 +import pygst
7.5 +pygst.require("0.10")
7.6 +import gst
7.7 +import gobject
7.8 +import socket
7.9 +
7.10 +class Media:
7.11 + class StreamData:
7.12 + stream_count = 0
7.13 +
7.14 + def __init__ (self, pipe, abin, vbin, sink):
7.15 +
7.16 + self.stream_count += 1
7.17 + self.Id = self.stream_count
7.18 + self.Pipe = pipe
7.19 + self.Abin = abin
7.20 + self.Vbin = vbin
7.21 + self.Sink = sink
7.22 + self.Loop = gobject.MainLoop()
7.23 + self.ACaps = ""
7.24 + self.VCaps = ""
7.25 + self.Ready = False
7.26 +
7.27 +
7.28 + def __init__(self, config):
7.29 + # set gstreamer basic options
7.30 + self.config = config
7.31 + self.pipe = None
7.32 + self.streams = []
7.33 + self.socket = None
7.34 + self.connection = None
7.35 + self.addr = None
7.36 +
7.37 +
7.38 + def setup(self, filename, mux, vcodec, vbitrate,
7.39 + fps, acodec, abitrate, width, height, port, options):
7.40 +
7.41 + ## Pipelines
7.42 + self.pipe = gst.Pipeline ()
7.43 + uri = "file://" + filename
7.44 + print "Opening Uri:" + uri
7.45 + src = gst.element_make_from_uri (gst.URI_SRC, uri, "src")
7.46 + if (src is None):
7.47 + return None
7.48 +
7.49 + decode = gst.element_factory_make ("decodebin", "decode")
7.50 + if (decode is None):
7.51 + return None
7.52 +
7.53 + mux = gst.element_factory_make ("avimux", "mux")
7.54 + if (mux is None):
7.55 + return None
7.56 +
7.57 + sink = gst.element_factory_make ("fdsink", "sink")
7.58 + if (sink is None):
7.59 + return None
7.60 +
7.61 + #Create socket
7.62 + self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
7.63 + self.socket.bind(('', int (port)))
7.64 +
7.65 + #video encode
7.66 + #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
7.67 + vbin = gst.Bin ()
7.68 + vqueue = gst.element_factory_make ("queue", "vqueue")
7.69 + vscale = gst.element_factory_make ("videoscale", "vscale")
7.70 + vrate = gst.element_factory_make ("videorate", "vrate")
7.71 + vencode = gst.element_factory_make ("ffenc_h263p", "vencode")
7.72 +
7.73 + if (None in [vbin, vqueue, vscale, vrate, vencode]):
7.74 + print "Fail to create video encode elements."
7.75 + return None
7.76 +
7.77 + vscale_pad = vscale.get_pad("sink")
7.78 + if (vscale_pad is None):
7.79 + print "Fail to get vscale sink pad."
7.80 + return None
7.81 +
7.82 + vscale_caps = gst.caps_from_string ("video/x-raw-yuv, width=%s, height=%s" % (width, height))
7.83 + if (vscale_caps is None):
7.84 + print "Fail to create video caps"
7.85 + return None
7.86 +
7.87 + if (not vscale_pad.set_caps (vscale_caps)):
7.88 + print "Fail to set video output caps"
7.89 + return None
7.90 +
7.91 + vbin.add (vqueue, vscale, vrate, vencode)
7.92 + if (not gst.element_link_many (vqueue, vscale, vrate, vencode)):
7.93 + print "Fail to link video elements"
7.94 + return None
7.95 +
7.96 + vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink")))
7.97 + vbin.add_pad (gst.GhostPad ("src", vencode.get_pad ("src")))
7.98 +
7.99 + #audio encode
7.100 + #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002
7.101 + abin = gst.Bin ()
7.102 + aqueue = gst.element_factory_make ("queue", "vqueue")
7.103 + aconvert = gst.element_factory_make ("audioconvert", "aconvert")
7.104 + aencode = gst.element_factory_make ("ffenc_ac3", "aencode")
7.105 +
7.106 + if (None in [abin, aqueue, aconvert, aencode]):
7.107 + print "Fail to create video encode elements."
7.108 + return None
7.109 +
7.110 + abin.add (aqueue, aconvert, aencode)
7.111 + if (not gst.element_link_many (aqueue, aconvert, aencode)):
7.112 + print "Fail to link video elements"
7.113 + return None
7.114 +
7.115 + abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink")))
7.116 + abin.add_pad (gst.GhostPad ("src", aencode.get_pad ("src")))
7.117 +
7.118 + #Finish Pipeline
7.119 +
7.120 + self.pipe.add (src, decode, abin, vbin, mux, sink)
7.121 + gst.element_link_many (src, decode)
7.122 + gst.element_link_many (mux, sink)
7.123 +
7.124 + #Linking decode with mux
7.125 + mux_audio = mux.get_pad ("audio_0")
7.126 + mux_video = mux.get_pad ("video_0")
7.127 +
7.128 + audio_pad = abin.get_pad ("src")
7.129 + video_pad = vbin.get_pad ("src")
7.130 +
7.131 + if (audio_pad.link (mux_audio) != gst.PAD_LINK_OK):
7.132 + print "Fail to link audio with mux"
7.133 + return None
7.134 +
7.135 + if (video_pad.link (mux_video) != gst.PAD_LINK_OK):
7.136 + print "Fail to link audio with mux"
7.137 + return None
7.138 +
7.139 + stream_data = self.StreamData (self.pipe, abin, vbin, sink)
7.140 +
7.141 + bus = self.pipe.get_bus()
7.142 + bus.add_signal_watch()
7.143 + bus.connect("message", self.__on_bus_message, stream_data)
7.144 +
7.145 + decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
7.146 + decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
7.147 +
7.148 +
7.149 + self.pipe.set_state (gst.STATE_PAUSED)
7.150 + print "Running Pipe"
7.151 + stream_data.Loop.run ()
7.152 + print "End run"
7.153 +
7.154 + a_caps = stream_data.ACaps
7.155 + v_caps = stream_data.VCaps
7.156 + stream_id = stream_data.Id
7.157 +
7.158 + self.streams.append (stream_data)
7.159 +
7.160 + def play(self):
7.161 +
7.162 + print "Trying to play pipeline: %s" % self.pipe
7.163 + try:
7.164 + if (self.pipe):
7.165 + print "Waiting for connection"
7.166 + self.socket.listen(1)
7.167 + print "Connection Requested"
7.168 + #Create socket
7.169 + self.connection, self.addr = self.socket.accept ()
7.170 +
7.171 + stream_data = self.streams[0]
7.172 + stream_data.Sink.set_property ("fd", self.connection.fileno());
7.173 + print "Connected"
7.174 +
7.175 + self.pipe.set_state(gst.STATE_PLAYING)
7.176 + except gobject.GError, e:
7.177 + print "Error: " + str(e)
7.178 +
7.179 +
7.180 + def stop(self):
7.181 +
7.182 + print "Trying to stop pipeline: %s" % self.pipe
7.183 + try:
7.184 + if (self.pipeline):
7.185 + self.connection.close ()
7.186 + self.pipeline.set_state(gst.STATE_NULL)
7.187 + except gobject.GError, e:
7.188 + print "Error: " + str(e)
7.189 +
7.190 + def __on_bus_message (self, bus, message, stream_data):
7.191 +
7.192 + t = message.type
7.193 + if (t == gst.MESSAGE_STATE_CHANGED):
7.194 + oldstate = -1
7.195 + newstate = -1
7.196 + pending = -1
7.197 + oldstate, newstate, pending = message.parse_state_changed ()
7.198 + if ((oldstate == gst.STATE_READY) and \
7.199 + (newstate == gst.STATE_PAUSED) and \
7.200 + (pending == gst.STATE_VOID_PENDING) and \
7.201 + (stream_data.Ready == False)):
7.202 + state_changed_status, current_state, pending_state = stream_data.Pipe.get_state ()
7.203 + if ((current_state == gst.STATE_PAUSED) and \
7.204 + (pending_state == gst.STATE_VOID_PENDING)):
7.205 + print "Pipe paused"
7.206 + stream_data.Loop.quit ()
7.207 + stream_data.Ready = True
7.208 + elif (t == gst.MESSAGE_ERROR):
7.209 + err, debug = message.parse_error()
7.210 + print "Error: %s" % err, debug
7.211 + stream_data.Loop.quit ()
7.212 + stream_data.Ready = False
7.213 +
7.214 + return True
7.215 +
7.216 + def __on_decode_unknown_type (self, decode, pad, caps, stream_data):
7.217 +
7.218 + print "Unknown Type"
7.219 + return None
7.220 +
7.221 + def __on_decode_new_pad (self, decode, pad, arg1, stream_data):
7.222 +
7.223 + caps = pad.get_caps().to_string()
7.224 + print "New pad " + caps
7.225 + if (caps.rfind ("audio") != -1):
7.226 + apad = stream_data.Abin.get_pad ("sink")
7.227 + if (pad.link (apad) != gst.PAD_LINK_OK):
7.228 + print "Error on link audio pad"
7.229 + return None
7.230 + elif (caps.rfind ("video") != -1):
7.231 + vpad = stream_data.Vbin.get_pad ("sink")
7.232 + if (pad.link (vpad) != gst.PAD_LINK_OK):
7.233 + print "Error on link video pad"
7.234 + return None
7.235 + else:
7.236 + print "Invalid caps"
7.237 +
7.238 +
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/gmyth-stream/server/plugins/media/mencoder.py Tue Apr 03 16:42:04 2007 +0100
8.3 @@ -0,0 +1,175 @@
8.4 +import os
8.5 +import sys
8.6 +import lib
8.7 +import time
8.8 +import signal
8.9 +import socket
8.10 +import ConfigParser
8.11 +
8.12 +from select import *
8.13 +from subprocess import *
8.14 +
8.15 +class Media:
8.16 +
8.17 + def __init__(self, config):
8.18 +
8.19 + self.config = config
8.20 + self.language = "en"
8.21 + self.socket = None
8.22 + self.child_pid = None
8.23 + self.mplayer = None
8.24 + self.mencoder_pid = None
8.25 + self.mplayer_pid = None
8.26 + signal.signal(signal.SIGABRT, self.kill_handler)
8.27 +
8.28 + def kill_handler(self, sig, frame):
8.29 + try:
8.30 + os.kill(self.mplayer_pid.pid + 1, signal.SIGKILL)
8.31 + sys.exit(0)
8.32 + except:
8.33 + lib.log("Problems closing child")
8.34 +
8.35 + def set_args(self, options):
8.36 +
8.37 + for opt in options:
8.38 +
8.39 + if (opt == "file" or opt == "dvd"):
8.40 + if (self.acodec == "mp3lame"):
8.41 + audio = "-oac mp3lame -lameopts cbr:br=%s vol=5" % self.abitrate
8.42 + else:
8.43 + audio = "-oac lavc -lavcopts acodec=%s abitrate=%s" % (\
8.44 + self.acodec, self.abitrate)
8.45 +
8.46 + if (opt == "file"):
8.47 + self.kind = "file"
8.48 + self.args += " %s -mf fps=%s -of %s %s"\
8.49 + " -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -vf scale=%s:%s"\
8.50 + " -o %s 1> /dev/null 2> /dev/null" % (
8.51 + self.filename, self.fps, self.mux, audio, self.vcodec,
8.52 + self.vbitrate, self.width, self.height, self.fifo)
8.53 +
8.54 + elif (opt == "dvd"):
8.55 + self.kind = "dvd"
8.56 + self.args += " dvd://%s -alang %s -vf scale=%s:%s %s"\
8.57 + " -of %s -ovc lavc -lavcopts vcodec=%s:vbitrate=%s -o %s"\
8.58 + " -ofps %s 1> /dev/null 2> /dev/null" % (
8.59 + self.filename, self.language, self.width, self.height, audio,
8.60 + self.mux, self.vcodec, self.vbitrate, self.fifo, self.fps)
8.61 +
8.62 + elif (opt == "local"):
8.63 + self.mplayer = os.popen("which mplayer").read().strip()
8.64 +
8.65 + elif (opt.find("language=") >= 0):
8.66 + try:
8.67 + self.language = opt.split("=")[1]
8.68 + except:
8.69 + lib.log("Bad language option")
8.70 +
8.71 +
8.72 + def run_mplayer(self):
8.73 + msg = "%s 1>/dev/null 2>/dev/null" % self.filename
8.74 + if (self.kind == "dvd"):
8.75 + msg = "dvd://" + msg
8.76 +
8.77 + self.mplayer += " " + msg
8.78 + self.mplayer_pid = Popen(self.mplayer, shell=True)
8.79 +
8.80 + def setup(self, filename, mux, vcodec, vbitrate,\
8.81 + fps, acodec, abitrate, width, height, port, options):
8.82 +
8.83 + self.filename = filename
8.84 + self.mux = mux
8.85 + self.vcodec = vcodec
8.86 + self.vbitrate = vbitrate
8.87 + self.fps = fps
8.88 + self.acodec = acodec
8.89 + self.abitrate = abitrate
8.90 + self.width = width
8.91 + self.height = height
8.92 +
8.93 + self.port = int(port)
8.94 + self.fifo = self.config.get("Mencoder", "fifo_path")
8.95 +
8.96 + self.args = ""
8.97 + self.kind = ""
8.98 + self.set_args(options)
8.99 +
8.100 + if (self.kind == "file" and not os.path.exists(self.filename)):
8.101 + msg = "File requested does not exist. SETUP failed."
8.102 + lib.log(msg)
8.103 + return msg
8.104 +
8.105 + # good one: /tmp/dvb.mpg avi mpeg4 400 25 mp3lame 192 320 240 5000
8.106 + self.path = self.config.get("Mencoder", "path")
8.107 +
8.108 + if (self.socket != None):
8.109 + del(self.socket)
8.110 +
8.111 + self.socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
8.112 + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
8.113 + self.socket.bind( ('', self.port) )
8.114 + self.socket.listen(1)
8.115 +
8.116 + return 0
8.117 +
8.118 +
8.119 + def play(self):
8.120 +
8.121 + try:
8.122 + os.mkfifo(self.fifo)
8.123 + except:
8.124 + lib.log("Fifo already exists")
8.125 +
8.126 + lib.log("Starting Mencoder: %s %s" % (self.path, self.args) )
8.127 + # exec Mencoder
8.128 + self.mencoder_pid = Popen(self.path + self.args, shell=True)
8.129 +
8.130 + fifo = open(self.fifo)
8.131 +
8.132 + self.child_pid = os.fork()
8.133 +
8.134 + if (self.child_pid == 0):
8.135 + conn,addr= self.socket.accept()
8.136 + lib.log("Sending Data to client: %s" % addr[0])
8.137 +
8.138 + data = fifo.read(1024)
8.139 + conn.settimeout(5)
8.140 + retry = 0
8.141 +
8.142 + while( data != "" and retry < 5):
8.143 + try:
8.144 + conn.send(data)
8.145 + r, w, x = select([conn], [], [], 0)
8.146 + if conn in r:
8.147 + back = conn.recv(1024)
8.148 + if (back == "OK" and self.mplayer and not self.mplayer_pid):
8.149 + self.run_mplayer()
8.150 +
8.151 + except socket.error:
8.152 + lib.log("Socket error (maybe timeout ?)")
8.153 + retry += 1
8.154 +
8.155 + data = fifo.read(1024)
8.156 +
8.157 + if (retry < 5):
8.158 + lib.log("Finished sending Data to client: %s" % addr[0])
8.159 + else:
8.160 + lib.log("Client timed out")
8.161 +
8.162 + sys.exit(0)
8.163 +
8.164 +
8.165 + def stop(self):
8.166 + try:
8.167 + os.kill(self.mencoder_pid.pid + 1, signal.SIGKILL)
8.168 + self.mplayer = None
8.169 + except:
8.170 + lib.log("Trying to stop before playing...")
8.171 +
8.172 + if (self.socket != None):
8.173 + lib.log("Closing socket")
8.174 + self.socket.close()
8.175 +
8.176 + lib.log("Trying to stop Mencoder process")
8.177 + if (self.child_pid != None):
8.178 + os.kill(self.child_pid, signal.SIGABRT)
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/gmyth-stream/server/plugins/media/vlc.py Tue Apr 03 16:42:04 2007 +0100
9.3 @@ -0,0 +1,80 @@
9.4 +import os
9.5 +import sys
9.6 +import time
9.7 +import socket
9.8 +import ConfigParser
9.9 +
9.10 +class Media:
9.11 +
9.12 + def __init__(self, config):
9.13 +
9.14 + self.config = config
9.15 + self.pipe = ""
9.16 + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
9.17 +
9.18 + self.path = config.get("Vlc", "path")
9.19 + self.host = config.get("Vlc", "host")
9.20 + self.port = int(config.get("Vlc", "port"))
9.21 + self.pwd = config.get("Vlc", "pwd")
9.22 +
9.23 + # exec VLC
9.24 + pid = os.fork()
9.25 + if (pid == 0):
9.26 + #child
9.27 + print "ESTOU EM CHILD"
9.28 + self.path += " -I telnet -d 1> /dev/null 2> /dev/null &"
9.29 + os.system(self.path)
9.30 + sys.exit(0)
9.31 + else:
9.32 + print "ESTOU EM PARENT 1"
9.33 + time.sleep(3)
9.34 + print "ESTOU EM PARENT 2"
9.35 + self.sock.connect( (self.host, self.port) )
9.36 + self.sock.send("%s\n" % self.pwd)
9.37 +
9.38 +
9.39 + def insert_file(self, filename):
9.40 +
9.41 + self.sock.send("setup output0 input %s\n" % filename)
9.42 +
9.43 +
9.44 +
9.45 + def setup(self, filename, mux, vcodec, vbitrate,\
9.46 + fps, acodec, abitrate, width, height, port):
9.47 +
9.48 + self.filename = filename
9.49 + self.mux = mux
9.50 + self.vcodec = vcodec
9.51 + self.vbitrate = int(vbitrate)
9.52 + self.fps = int(fps)
9.53 + self.acodec = acodec
9.54 + self.abitrate = int(abitrate)
9.55 + self.width = int(width)
9.56 + self.height = int(height)
9.57 +
9.58 + self.port = int(port)
9.59 +
9.60 +
9.61 + self.pipe = "#transcode{vcodec=%s,vb=%d,"\
9.62 + "fps=25.0,scale=1,acodec=mpga,"\
9.63 + "ab=64,channels=1,width=%d,height=%d}"\
9.64 + ":duplicate{dst=std{access=http,"\
9.65 + "mux=mpeg1,dst=:%d}}" % (self.vcodec, self.vbitrate,\
9.66 + self.widht, self.height,\
9.67 + self.port)
9.68 +
9.69 + self.sock.send("setup output0 broadcast %s\n" % self.pipe)
9.70 + self.insert_file(self.filename)
9.71 +
9.72 + def play(self):
9.73 +
9.74 + print "Trying to play: %s" % self.pipe
9.75 + self.sock.send("control output0 play\n")
9.76 +
9.77 +
9.78 + def stop(self):
9.79 +
9.80 + print "Trying to stop: %s" % self.pipe
9.81 + self.sock.send("control output0 stop\n")
9.82 +
9.83 +
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/gmyth-stream/server/stream.conf Tue Apr 03 16:42:04 2007 +0100
10.3 @@ -0,0 +1,23 @@
10.4 +[Comm]
10.5 +engine = tcp
10.6 +port = 12345
10.7 +
10.8 +
10.9 +[Media]
10.10 +engine = mencoder
10.11 +
10.12 +
10.13 +[Vlc]
10.14 +path = /usr/local/bin/vlc
10.15 +host = 127.0.0.1
10.16 +port = 4212
10.17 +pwd = admin
10.18 +
10.19 +
10.20 +[FFmpeg]
10.21 +path = /usr/bin/ffmpeg
10.22 +
10.23 +
10.24 +[Mencoder]
10.25 +path = /usr/local/bin/mencoder
10.26 +fifo_path = /tmp/teste
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/gmyth-stream/server/tests/client_ffmpeg.py Tue Apr 03 16:42:04 2007 +0100
11.3 @@ -0,0 +1,48 @@
11.4 +import os
11.5 +import sys
11.6 +import time
11.7 +import socket
11.8 +
11.9 +
11.10 +if len(sys.argv) < 2:
11.11 + HOST = 'localhost'
11.12 + PORT = 5000
11.13 +elif len(sys.argv) == 2:
11.14 + HOST = sys.argv[1]
11.15 + PORT = 5000
11.16 +else:
11.17 + HOST = sys.argv[1]
11.18 + PORT = int(sys.argv[2])
11.19 +
11.20 +socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
11.21 +socket.settimeout(10)
11.22 +
11.23 +try:
11.24 + socket.connect( (HOST,PORT) )
11.25 +except:
11.26 + print "\n--> Could not connect to ('%s':'%d')\n" % (HOST,PORT)
11.27 + sys.exit(-1)
11.28 +
11.29 +
11.30 +mplayer = os.popen("which mplayer").read().strip()
11.31 +mplayer += " - 1> /dev/null"
11.32 +pin, pout = os.popen2(mplayer)
11.33 +
11.34 +data = socket.recv(1024)
11.35 +i = 0
11.36 +
11.37 +while (data != ""):
11.38 + pin.write(data)
11.39 + data = socket.recv(1024)
11.40 + if (i == 500):
11.41 + socket.send("OK")
11.42 + i += 1
11.43 +
11.44 +pin.close()
11.45 +socket.close()
11.46 +
11.47 +
11.48 +# from select import select
11.49 +# r, w, x = select([pout], []. [], 0)
11.50 +# if pout in r:
11.51 +# pout.read(32)