1.1 --- a/gmyth-stream/server/plugins/media/gstreamer.py Tue Apr 03 16:42:04 2007 +0100
1.2 +++ b/gmyth-stream/server/plugins/media/gstreamer.py Wed Apr 11 19:34:21 2007 +0100
1.3 @@ -1,82 +1,105 @@
1.4 +#vim:ts=4:sw=4:et
1.5 import pygst
1.6 pygst.require("0.10")
1.7 import gst
1.8 import gobject
1.9 import socket
1.10 +from threading import Thread
1.11
1.12 class Media:
1.13 + class StreamListener(Thread):
1.14 + def __init__ (self, stream_data):
1.15 + Thread.__init__(self)
1.16 + self.stream = stream_data
1.17 + print "Thread Created"
1.18 +
1.19 + def run (self):
1.20 + #Create socket
1.21 + print "Waiting connection"
1.22 + self.stream.Socket.listen(1)
1.23 + self.stream.Connection, self.stream.Addr = self.stream.Socket.accept ()
1.24 + print "Connection requested"
1.25 + self.stream.Sink.set_property ("fd", self.stream.Connection.fileno())
1.26 + self.stream.Pipe.set_state(gst.STATE_PLAYING)
1.27 + print "PLAYING"
1.28 +
1.29 +
1.30 class StreamData:
1.31 stream_count = 0
1.32 -
1.33 - def __init__ (self, pipe, abin, vbin, sink):
1.34
1.35 - self.stream_count += 1
1.36 - self.Id = self.stream_count
1.37 - self.Pipe = pipe
1.38 - self.Abin = abin
1.39 - self.Vbin = vbin
1.40 - self.Sink = sink
1.41 - self.Loop = gobject.MainLoop()
1.42 - self.ACaps = ""
1.43 - self.VCaps = ""
1.44 - self.Ready = False
1.45 -
1.46 + def __init__ (self, pipe, abin, vbin, sink):
1.47 + self.stream_count += 1
1.48 + self.Id = self.stream_count
1.49 + self.Pipe = pipe
1.50 + self.Abin = abin
1.51 + self.Vbin = vbin
1.52 + self.Sink = sink
1.53 + self.Loop = gobject.MainLoop()
1.54 + self.ACaps = ""
1.55 + self.VCaps = ""
1.56 + self.Ready = False
1.57 + self.Socket = None
1.58 + self.Connection = None
1.59 + self.Addr = None
1.60
1.61 def __init__(self, config):
1.62 # set gstreamer basic options
1.63 self.config = config
1.64 - self.pipe = None
1.65 self.streams = []
1.66 - self.socket = None
1.67 - self.connection = None
1.68 - self.addr = None
1.69 + self.socket = None
1.70 + self.connection = None
1.71 + self.addr = None
1.72 + self.ready = False
1.73
1.74
1.75 - def setup(self, filename, mux, vcodec, vbitrate,
1.76 + def setup(self, uri, mux, vcodec, vbitrate,
1.77 fps, acodec, abitrate, width, height, port, options):
1.78
1.79 ## Pipelines
1.80 - self.pipe = gst.Pipeline ()
1.81 - uri = "file://" + filename
1.82 + pipe = gst.Pipeline ()
1.83 print "Opening Uri:" + uri
1.84 src = gst.element_make_from_uri (gst.URI_SRC, uri, "src")
1.85 if (src is None):
1.86 + print "Fail to create src element"
1.87 return None
1.88 -
1.89 +
1.90 decode = gst.element_factory_make ("decodebin", "decode")
1.91 if (decode is None):
1.92 + print "Fail to create decodebin"
1.93 return None
1.94
1.95 - mux = gst.element_factory_make ("avimux", "mux")
1.96 + mux = gst.element_factory_make ("avimux", "mux")
1.97 if (mux is None):
1.98 + print "Fail to create mux"
1.99 return None
1.100
1.101 sink = gst.element_factory_make ("fdsink", "sink")
1.102 if (sink is None):
1.103 + print "Fail to create fdsink"
1.104 return None
1.105
1.106 - #Create socket
1.107 - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1.108 - self.socket.bind(('', int (port)))
1.109 -
1.110 - #video encode
1.111 +
1.112 + #video encode
1.113 #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
1.114 vbin = gst.Bin ()
1.115 vqueue = gst.element_factory_make ("queue", "vqueue")
1.116 vscale = gst.element_factory_make ("videoscale", "vscale")
1.117 + colorspace = gst.element_factory_make ("ffmpegcolorspace", "")
1.118 vrate = gst.element_factory_make ("videorate", "vrate")
1.119 vencode = gst.element_factory_make ("ffenc_h263p", "vencode")
1.120
1.121 +
1.122 if (None in [vbin, vqueue, vscale, vrate, vencode]):
1.123 print "Fail to create video encode elements."
1.124 return None
1.125
1.126 + '''
1.127 vscale_pad = vscale.get_pad("sink")
1.128 if (vscale_pad is None):
1.129 print "Fail to get vscale sink pad."
1.130 return None
1.131
1.132 - vscale_caps = gst.caps_from_string ("video/x-raw-yuv, width=%s, height=%s" % (width, height))
1.133 + vscale_caps = gst.caps_from_string ("video/x-raw-yuv,width=%d,height=(int)%d" % (int(width), int(height)))
1.134 if (vscale_caps is None):
1.135 print "Fail to create video caps"
1.136 return None
1.137 @@ -84,21 +107,32 @@
1.138 if (not vscale_pad.set_caps (vscale_caps)):
1.139 print "Fail to set video output caps"
1.140 return None
1.141 -
1.142 - vbin.add (vqueue, vscale, vrate, vencode)
1.143 - if (not gst.element_link_many (vqueue, vscale, vrate, vencode)):
1.144 + '''
1.145 +
1.146 + vbin.add (vqueue, vscale, colorspace, vrate, vencode)
1.147 + if (not vqueue.link (vscale)):
1.148 print "Fail to link video elements"
1.149 return None
1.150 -
1.151 +
1.152 + if (not vscale.link (colorspace, \
1.153 + gst.caps_from_string ("video/x-raw-yuv,width=%d,height=(int)%d" % (int(width), int(height))))):
1.154 + print "Fail to link video elements"
1.155 + return None
1.156 +
1.157 + if (not gst.element_link_many (colorspace, vrate, vencode)):
1.158 + print "Fail to link video elements"
1.159 + return None
1.160 +
1.161 vbin.add_pad (gst.GhostPad ("sink", vqueue.get_pad ("sink")))
1.162 - vbin.add_pad (gst.GhostPad ("src", vencode.get_pad ("src")))
1.163 + vbin.add_pad (gst.GhostPad ("src", vencode.get_pad ("src")))
1.164
1.165 #audio encode
1.166 #audio/x-raw-int ! queue ! audioconvert ! faac ! rtpmp4gpay ! udpsink name=upd_audio host=224.0.0.1 port=5002
1.167 abin = gst.Bin ()
1.168 aqueue = gst.element_factory_make ("queue", "vqueue")
1.169 aconvert = gst.element_factory_make ("audioconvert", "aconvert")
1.170 - aencode = gst.element_factory_make ("ffenc_ac3", "aencode")
1.171 + #aencode = gst.element_factory_make ("ffenc_ac3", "aencode")
1.172 + aencode = gst.element_factory_make ("lame", "aencode")
1.173
1.174 if (None in [abin, aqueue, aconvert, aencode]):
1.175 print "Fail to create video encode elements."
1.176 @@ -108,81 +142,66 @@
1.177 if (not gst.element_link_many (aqueue, aconvert, aencode)):
1.178 print "Fail to link video elements"
1.179 return None
1.180 -
1.181 +
1.182 abin.add_pad (gst.GhostPad ("sink", aqueue.get_pad ("sink")))
1.183 abin.add_pad (gst.GhostPad ("src", aencode.get_pad ("src")))
1.184
1.185 #Finish Pipeline
1.186
1.187 - self.pipe.add (src, decode, abin, vbin, mux, sink)
1.188 - gst.element_link_many (src, decode)
1.189 + pipe.add (src, decode, abin, vbin, mux, sink)
1.190 + gst.element_link_many (src, decode)
1.191 gst.element_link_many (mux, sink)
1.192
1.193 #Linking decode with mux
1.194 mux_audio = mux.get_pad ("audio_0")
1.195 mux_video = mux.get_pad ("video_0")
1.196
1.197 - audio_pad = abin.get_pad ("src")
1.198 + audio_pad = abin.get_pad ("src")
1.199 video_pad = vbin.get_pad ("src")
1.200
1.201 if (audio_pad.link (mux_audio) != gst.PAD_LINK_OK):
1.202 print "Fail to link audio with mux"
1.203 return None
1.204 -
1.205 +
1.206 if (video_pad.link (mux_video) != gst.PAD_LINK_OK):
1.207 print "Fail to link audio with mux"
1.208 return None
1.209
1.210 - stream_data = self.StreamData (self.pipe, abin, vbin, sink)
1.211 + stream_data = self.StreamData (pipe, abin, vbin, sink)
1.212 + bus = pipe.get_bus()
1.213 + bus.add_signal_watch()
1.214 + bus.connect ("message", self.__on_bus_message, stream_data)
1.215
1.216 - bus = self.pipe.get_bus()
1.217 - bus.add_signal_watch()
1.218 - bus.connect("message", self.__on_bus_message, stream_data)
1.219 -
1.220 - decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
1.221 - decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
1.222 + decode.connect("new-decoded-pad", self.__on_decode_new_pad, stream_data)
1.223 + decode.connect("unknown-type", self.__on_decode_unknown_type, stream_data)
1.224
1.225 -
1.226 - self.pipe.set_state (gst.STATE_PAUSED)
1.227 + pipe.set_state (gst.STATE_PAUSED)
1.228 print "Running Pipe"
1.229 - stream_data.Loop.run ()
1.230 + stream_data.Loop.run ()
1.231 print "End run"
1.232
1.233 - a_caps = stream_data.ACaps
1.234 - v_caps = stream_data.VCaps
1.235 - stream_id = stream_data.Id
1.236 +
1.237 + #Create socket
1.238 + stream_data.Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1.239 + print "Bind on port %d" % port
1.240 + stream_data.Socket.bind(('', int (port)))
1.241
1.242 self.streams.append (stream_data)
1.243 + return True
1.244
1.245 - def play(self):
1.246 -
1.247 - print "Trying to play pipeline: %s" % self.pipe
1.248 - try:
1.249 - if (self.pipe):
1.250 - print "Waiting for connection"
1.251 - self.socket.listen(1)
1.252 - print "Connection Requested"
1.253 - #Create socket
1.254 - self.connection, self.addr = self.socket.accept ()
1.255 -
1.256 - stream_data = self.streams[0]
1.257 - stream_data.Sink.set_property ("fd", self.connection.fileno());
1.258 - print "Connected"
1.259 -
1.260 - self.pipe.set_state(gst.STATE_PLAYING)
1.261 - except gobject.GError, e:
1.262 - print "Error: " + str(e)
1.263 -
1.264 + def play(self):
1.265 + stream = self.streams[0]
1.266 + current = self.StreamListener(stream)
1.267 + current.start ()
1.268 + print "Saindo"
1.269 + return True
1.270
1.271 def stop(self):
1.272 + stream = self.streams[0]
1.273 + stream.Pipe.set_state(gst.STATE_NULL)
1.274 + stream.Connection.close ()
1.275 + return True
1.276
1.277 - print "Trying to stop pipeline: %s" % self.pipe
1.278 - try:
1.279 - if (self.pipeline):
1.280 - self.connection.close ()
1.281 - self.pipeline.set_state(gst.STATE_NULL)
1.282 - except gobject.GError, e:
1.283 - print "Error: " + str(e)
1.284
1.285 def __on_bus_message (self, bus, message, stream_data):
1.286
1.287 @@ -196,30 +215,30 @@
1.288 (newstate == gst.STATE_PAUSED) and \
1.289 (pending == gst.STATE_VOID_PENDING) and \
1.290 (stream_data.Ready == False)):
1.291 - state_changed_status, current_state, pending_state = stream_data.Pipe.get_state ()
1.292 - if ((current_state == gst.STATE_PAUSED) and \
1.293 + state_changed_status, current_state, pending_state = stream_data.Pipe.get_state ()
1.294 + if ((current_state == gst.STATE_PAUSED) and \
1.295 (pending_state == gst.STATE_VOID_PENDING)):
1.296 print "Pipe paused"
1.297 stream_data.Loop.quit ()
1.298 stream_data.Ready = True
1.299 elif (t == gst.MESSAGE_ERROR):
1.300 err, debug = message.parse_error()
1.301 - print "Error: %s" % err, debug
1.302 + print "Error: %s" % err, debug
1.303 stream_data.Loop.quit ()
1.304 stream_data.Ready = False
1.305
1.306 return True
1.307 -
1.308 +
1.309 def __on_decode_unknown_type (self, decode, pad, caps, stream_data):
1.310
1.311 print "Unknown Type"
1.312 return None
1.313
1.314 def __on_decode_new_pad (self, decode, pad, arg1, stream_data):
1.315 -
1.316 +
1.317 caps = pad.get_caps().to_string()
1.318 print "New pad " + caps
1.319 - if (caps.rfind ("audio") != -1):
1.320 + if (caps.rfind ("audio") != -1):
1.321 apad = stream_data.Abin.get_pad ("sink")
1.322 if (pad.link (apad) != gst.PAD_LINK_OK):
1.323 print "Error on link audio pad"
1.324 @@ -232,4 +251,3 @@
1.325 else:
1.326 print "Invalid caps"
1.327
1.328 -