[Telepathy-commits] [multi-jingle/master] Rename test client to multi-jingle-client.py

Sjoerd Simons sjoerd.simons at collabora.co.uk
Fri Dec 19 11:44:48 PST 2008


---
 README                 |   10 +-
 mingle-client.py       |  457 ------------------------------------------------
 multi-jingle-client.py |  457 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 462 insertions(+), 462 deletions(-)
 delete mode 100644 mingle-client.py
 create mode 100644 multi-jingle-client.py

diff --git a/README b/README
index 42dce55..3bea2b3 100644
--- a/README
+++ b/README
@@ -22,14 +22,14 @@ shows a list of people that are online on the given account
 Simple program to make jingle calls. Logs in as JID with password PASSWORD and
 will then  listen for incoming jingle calls. Calls  REMOTEJID if given.
 
-- mingle-client.py <JID> <PASSWORD> <CONFERENCEJID>
+- multi-jingle-client.py <JID> <PASSWORD> <CONFERENCEJID>
 
 Simple demonstration program for mingle. Logs in as JID with password PASSWORD
 and will join/start a mingle conference at CONFERENCEJID (e.g.
 mingle at conference.jabber.org)
 
 
-To use either mingle-client.py or jingle-call.py with a webcam the VIDEO_DEVICE
-environment variable needs to be set (e.g. VIDEO_DEVICE=/dev/video0). To use an
-audiotestsrc for audio input instead of a microphone set TESTAUDIO in the
-environment.
+To use either multi-jingle-client.py or jingle-call.py with a webcam the
+VIDEO_DEVICE environment variable needs to be set (e.g.
+VIDEO_DEVICE=/dev/video0). To use an audiotestsrc for audio input instead of a
+microphone set TESTAUDIO in the environment.
diff --git a/mingle-client.py b/mingle-client.py
deleted file mode 100644
index 9ba4716..0000000
--- a/mingle-client.py
+++ /dev/null
@@ -1,457 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-
-from twisted.internet import glib2reactor
-glib2reactor.install()
-
-from twisted.internet import reactor, defer
-from twisted.words.protocols.jabber.jid import JID
-from twisted.words.xish import domish, xpath
-
-import jingle
-import ns
-import util
-from client import create_client
-from jingle import make_sid
-import farsight
-import threading
-
-try:
-    import pygtk
-    pygtk.require("2.0")
-
-    import gtk, gtk.glade, gobject, gtk.gdk
-    import gobject
-except ImportError, e:
-    raise SystemExit("PyGTK couldn't be found ! (%s)" % (e[0]))
-
-try:
-    import pygst
-    pygst.require('0.10')
-
-    import gst
-except ImportError, e:
-    raise SystemExit("Gst-Python couldn't be found! (%s)" % (e[0]))
-
-
-class VideoSink(gtk.DrawingArea):
-    def __init__(self, pipeline):
-        gtk.DrawingArea.__init__(self)
-        self.set_double_buffered(False)
-        self.set_size_request (320, 240)
-        self.vsink = None
-        self.sink = bin = gst.Bin()
-
-        bin.connect ("element-added", self.element_added_cb)
-
-        colorspace = gst.element_factory_make("ffmpegcolorspace")
-        videoscale = gst.element_factory_make("videoscale")
-        vsink = gst.element_factory_make("gconfvideosink")
-
-        bin.add(colorspace)
-        bin.add(videoscale)
-        bin.add(vsink)
-
-        colorspace.link(videoscale)
-        videoscale.link(vsink)
-
-        bin.add_pad(gst.GhostPad("sink", colorspace.get_pad("sink")))
-
-        bus = pipeline.get_bus()
-        bus.enable_sync_message_emission()
-        bus.connect("sync-message", self.sync_handler)
-
-        self.exposedc = threading.Condition()
-        self.exposed = False
-
-        self.connect ("expose-event", self.expose_event)
-
-    def element_added_cb (self, bin, element):
-        if isinstance(element, gst.Bin):
-            element.connect ("element-added", self.element_added_cb)
-            for e in element.elements():
-                self.element_added_cb (element, e)
-
-        if isinstance(element, gst.interfaces.XOverlay):
-            self.vsink = element
-            try:
-                self.sink.set_property("force-aspect-ratio", True)
-            except Exception:
-                pass
-
-    def expose_event(self, *args):
-        if not self.exposed:
-            self.exposedc.acquire()
-            self.exposed = True
-            self.exposedc.notify()
-            self.exposedc.release()
-
-    def sync_handler(self, bus, message):
-        if message.src == self.vsink and \
-            message.type == gst.MESSAGE_ELEMENT and \
-            message.structure.has_name("prepare-xwindow-id"):
-
-            self.exposedc.acquire()
-            while not self.exposed:
-                self.exposedc.wait()
-            gtk.gdk.threads_enter()
-            self.vsink.set_xwindow_id (self.window.xid)
-            gtk.gdk.threads_leave()
-            self.exposedc.release()
-
-            return gst.BUS_DROP
-
-        return gst.BUS_PASS
-
-
-class UI(gtk.Window):
-    WIDTH = 340
-    HEIGHT = 260
-    def __init__(self, jid, conference):
-        gtk.Window.__init__(self)
-        self.connect('destroy', lambda x: reactor.stop())
-        self.hbox = gtk.HBox()
-        self.add(self.hbox)
-        self.outputs = {}
-
-        self.label = gtk.Label("Waiting for other participants...")
-        self.label.set_size_request(self.WIDTH, self.HEIGHT)
-
-        self.preview_frame = gtk.Frame("Local Preview")
-        self.preview_frame.set_size_request(self.WIDTH, self.HEIGHT)
-
-        self.hbox.pack_start(self.preview_frame, False, False, 3)
-        self.hbox.add(self.label)
-        self.conference = conference
-        self.set_title(jid.userhost())
-
-        self.show_all()
-
-    def add_video_preview (self, session):
-        gtk.gdk.threads_enter()
-
-        pad = session.source.tee.get_pad("src%d")
-
-        vsink = VideoSink(self.conference)
-        session.source.add(vsink.sink)
-
-        #vsink.sink.set_property("sync", False)
-
-        pad.link(vsink.sink.get_pad("sink"))
-        vsink.sink.set_state(gst.STATE_PLAYING)
-
-        self.preview_frame.add(vsink)
-        vsink.show_all()
-
-        gtk.gdk.threads_leave()
-
-    def add_output(self, name):
-        gtk.gdk.threads_enter()
-        if self.label:
-            self.hbox.remove(self.label)
-            self.label = None
-
-        assert not self.outputs.has_key(name)
-
-        frame = gtk.Frame(name)
-        frame.set_border_width(3)
-        label = gtk.Label("Waiting for video streams...")
-        label.set_size_request(320, 240)
-        frame.add(label)
-
-        self.outputs[name] = frame
-
-        self.hbox.pack_start(frame, False, False, 3)
-        frame.show_all()
-
-        gtk.gdk.threads_leave()
-
-    def remove_output (self, name):
-        frame = self.outputs.pop(name)
-        self.hbox.remove(frame)
-        if len(self.outputs) == 0:
-            self.label = gtk.Label("Waiting for other participants...")
-            self.hbox.add(self.label)
-            self.hbox.show_all()
-
-        self.resize(self.WIDTH, self.HEIGHT)
-
-    def add_video_output(self, name, stream, pad):
-        gtk.gdk.threads_enter()
-
-        frame = self.outputs[name]
-
-        if type(frame.get_child()) == gtk.Label:
-            frame.remove(frame.get_child())
-
-        vsink = VideoSink(self.conference)
-        frame.add(vsink)
-        frame.show_all()
-
-        stream.add_sink (vsink.sink)
-
-        self.conference.add(vsink.sink)
-        pad.link(vsink.sink.get_pad("sink"))
-        vsink.sink.set_state(gst.STATE_PLAYING)
-
-        gtk.gdk.threads_leave()
-
-class Muc:
-    PREPARING = 0
-    JOINING = 1
-    PRESENT = 2
-
-    def __init__(self, client, jid):
-        self.jid = jid
-        self.client = client
-        self.state = Muc.PREPARING
-        self.members = []
-        self.conference = jingle.JingleConference()
-        self.jingle_sessions = {}
-        self.mingle_presences = {}
-
-        self.my_jid = JID('%s/%s' % (self.jid.userhost(),
-            self.client.jid.user))
-
-        transports = jingle.get_available_transports()
-        client.features.update([
-         ns.JINGLE,
-         ns.JINGLE_RTP,
-        ] + transports)
-
-        client.send_presence()
-
-        self.conference.streamAdded.addCallback(False, self.new_stream)
-        self.ui = UI(client.jid, self.conference)
-
-        client.add_iq_handler('set', ns.JINGLE, 'jingle',
-            self.jingle_iq_received)
-
-        self.client.resourceOffline.addCallback(False, self.resource_offline)
-
-    def resource_offline(self, contact):
-        if self.jingle_sessions.has_key(contact):
-            self.jingle_sessions.pop(contact).terminate()
-            self.ui.remove_output(contact.jid.full())
-
-    def jingle_iq_received(self, iq):
-        j = xpath.queryForNodes('/iq/jingle', iq)[0]
-        if j['action'] != 'session-initiate':
-            return None
-
-        jid = JID(iq['from'])
-        contact = self.client.get_contact (jid)
-
-        session = jingle.JingleSession(self.client, self.conference)
-        self.jingle_sessions[contact] = session
-
-        self.ui.add_output (jid.full())
-        return session.handle_session_initiate (iq,
-            self.client.get_contact (jid))
-
-    def new_stream(self, participant, stream):
-        if stream.session.type == farsight.MEDIA_TYPE_VIDEO:
-            stream.src_pad_hook  = lambda stream, fsstream, pad, codec: \
-                self.new_video_output(participant, stream, pad, codec)
-
-    def new_video_output(self, participant, stream, pad, codec):
-        self.ui.add_video_output(participant.cname, stream, pad)
-
-    def join(self):
-        self.state = Muc.JOINING
-        self.client.stream.addObserver('/presence', self.presence)
-        self.update_presence()
-
-    def presence_(self, stanza):
-        from_jid = JID(stanza['from'])
-        mingle = util.elem_find_child(stanza, ns.MINGLE, 'mingle')
-
-        if mingle is None:
-            return
-
-        self.mingle_presences[from_jid] = stanza
-
-    def update_presence(self, mingle = None):
-        join = domish.Element((None, 'presence'))
-        join['to'] = self.my_jid.full()
-        self.client.presence_add_caps(join)
-
-        if (mingle != None):
-            join.addChild(mingle)
-
-        self.client.stream.send(join)
-
-    def got_codecs(self, results):
-        print "Got codecs!!!!"
-        mingle = domish.Element((ns.MINGLE, 'mingle'))
-        for (result, sessioninfo) in results:
-            c = mingle.addElement ('content')
-            desc = c.addElement ((ns.JINGLE_RTP, "description"))
-
-            c['name'] = sessioninfo[0]
-
-            fssession = sessioninfo[1]
-            if fssession.type == farsight.MEDIA_TYPE_VIDEO:
-                desc['media'] = "video"
-            elif fssession.type == farsight.MEDIA_TYPE_AUDIO:
-                desc['media'] = "audio"
-
-            for codec in sessioninfo[2]:
-                pt = desc.addElement("payload-type")
-
-                pt['id'] = str(codec.id)
-                pt['name'] = codec.encoding_name
-                pt['clockrate'] = str(codec.clock_rate)
-                if codec.channels > 0:
-                    pt['channels'] = str(codec.channels)
-
-                for (name, value) in codec.optional_params:
-                    param = pt.addElement('parameter')
-                    param['name'] = name
-                    param['value'] = value
-
-        self.update_presence(mingle)
-
-        # call the lot using the existing conference
-
-    def participants_done (self, *args):
-        deferreds = []
-
-        for (name, session) in self.conference.sessions.iteritems():
-            print "Adding.. %s" % name
-
-            d = session.get_codecs()
-            d.addCallback (lambda result, n=name, s=session: (n, s, result))
-            deferreds.append(d)
-
-        dlist = defer.DeferredList(deferreds)
-        dlist.addCallback(self.got_codecs)
-
-        for jid in self.mingle_presences.iterkeys():
-            print "Calling: %s" % jid.full()
-            self.ui.add_output (jid.full())
-            session = jingle.JingleSession (self.client, self.conference)
-            contact = self.client.get_contact (jid)
-            self.jingle_sessions[contact] = session
-            session.initiate(contact)
-
-    def participant_got_stream (self, stream, session, description):
-        payloads = xpath.queryForNodes(
-            '/description/payload-type', description)
-
-        codecs = []
-        for p in payloads:
-            codec = farsight.Codec(int(p["id"]),
-                                    p["name"],
-                                    session.type,
-                                    int(p["clockrate"]))
-            params = xpath.queryForNodes("/payload-type/parameter", p)
-            if params !=None:
-                optional_params = []
-
-                for param in params:
-                    optional_params.append(
-                        (str(param['name']), str(param['value'])))
-                codec.optional_params = optional_params
-
-            codecs.append(codec)
-
-        stream.set_remote_codecs(codecs)
-
-    def add_participant (self, jid, stanza):
-        contact = self.client.get_contact (jid)
-
-        deferreds = []
-        contents = xpath.queryForNodes ('/presence/mingle/content', stanza)
-
-        for c in contents:
-            description = xpath.queryForNodes ('/content/description', c)[0]
-            if description['media'] == "audio":
-                type = farsight.MEDIA_TYPE_AUDIO
-            elif description['media'] == "video":
-                type = farsight.MEDIA_TYPE_VIDEO
-
-            session = self.conference.get_session( c['name'], type)
-            d = self.conference.get_stream(session, contact)
-            deferreds.append(d)
-            d.addCallback (self.participant_got_stream, session, description)
-
-        dlist = defer.DeferredList(deferreds)
-        return dlist
-
-    def joined (self):
-        print 'joined the room'
-        deferreds = []
-
-        if len(self.conference.sessions) == 0:
-            # Trigger voice and video streams
-            self.conference.get_session("video", farsight.MEDIA_TYPE_VIDEO)
-            self.conference.get_session("audio", farsight.MEDIA_TYPE_AUDIO)
-
-
-        session = self.conference.get_session("video",
-            farsight.MEDIA_TYPE_VIDEO)
-        self.ui.add_video_preview(session)
-
-
-        for (jid, stanza) in self.mingle_presences.iteritems():
-            deferreds.append (self.add_participant(jid, stanza))
-
-        dlist = defer.DeferredList(deferreds)
-        dlist.addCallback(self.participants_done)
-
-    def presence(self, stanza):
-        global state
-        from_jid = JID(stanza['from'])
-
-        if from_jid.userhost() != self.jid.userhost():
-            return
-
-        if self.state == Muc.JOINING:
-            if from_jid == self.my_jid:
-                self.state = Muc.PRESENT
-                self.joined()
-            else:
-                print '%s is in room' % from_jid.resource
-                self.presence_(stanza)
-        else:
-            if from_jid == self.my_jid:
-                return
-            elif stanza.getAttribute('type') == 'unavailable':
-                print '%s left room' % from_jid.resource
-            else:
-                print '%s has joined room' % from_jid.resource
-
-
-
-def run(jid, password, muc_jid, peers):
-
-    def authd(client):
-        muc = Muc(client, muc_jid)
-        muc.join()
-
-    client = create_client(jid, password)
-
-    client.authenticated.addCallback(authd)
-    client.done.addBoth(lambda *args: reactor.stop())
-
-    reactor.run()
-
-def main(argv):
-    if len(argv) != 4:
-        return 1
-
-    jid_str, password, muc_str = argv[1:]
-    muc_jid = JID(muc_str)
-    #peers = map(JID, argv[3:])
-    #print (jid, password, peers)
-    run(jid_str, password, muc_jid, [])
-    return 0
-
-if __name__ == '__main__':
-    gobject.threads_init()
-    gtk.gdk.threads_init()
-
-    sys.exit(main(sys.argv))
-
diff --git a/multi-jingle-client.py b/multi-jingle-client.py
new file mode 100644
index 0000000..9ba4716
--- /dev/null
+++ b/multi-jingle-client.py
@@ -0,0 +1,457 @@
+#!/usr/bin/env python
+
+import sys
+
+from twisted.internet import glib2reactor
+glib2reactor.install()
+
+from twisted.internet import reactor, defer
+from twisted.words.protocols.jabber.jid import JID
+from twisted.words.xish import domish, xpath
+
+import jingle
+import ns
+import util
+from client import create_client
+from jingle import make_sid
+import farsight
+import threading
+
+try:
+    import pygtk
+    pygtk.require("2.0")
+
+    import gtk, gtk.glade, gobject, gtk.gdk
+    import gobject
+except ImportError, e:
+    raise SystemExit("PyGTK couldn't be found ! (%s)" % (e[0]))
+
+try:
+    import pygst
+    pygst.require('0.10')
+
+    import gst
+except ImportError, e:
+    raise SystemExit("Gst-Python couldn't be found! (%s)" % (e[0]))
+
+
+class VideoSink(gtk.DrawingArea):
+    def __init__(self, pipeline):
+        gtk.DrawingArea.__init__(self)
+        self.set_double_buffered(False)
+        self.set_size_request (320, 240)
+        self.vsink = None
+        self.sink = bin = gst.Bin()
+
+        bin.connect ("element-added", self.element_added_cb)
+
+        colorspace = gst.element_factory_make("ffmpegcolorspace")
+        videoscale = gst.element_factory_make("videoscale")
+        vsink = gst.element_factory_make("gconfvideosink")
+
+        bin.add(colorspace)
+        bin.add(videoscale)
+        bin.add(vsink)
+
+        colorspace.link(videoscale)
+        videoscale.link(vsink)
+
+        bin.add_pad(gst.GhostPad("sink", colorspace.get_pad("sink")))
+
+        bus = pipeline.get_bus()
+        bus.enable_sync_message_emission()
+        bus.connect("sync-message", self.sync_handler)
+
+        self.exposedc = threading.Condition()
+        self.exposed = False
+
+        self.connect ("expose-event", self.expose_event)
+
+    def element_added_cb (self, bin, element):
+        if isinstance(element, gst.Bin):
+            element.connect ("element-added", self.element_added_cb)
+            for e in element.elements():
+                self.element_added_cb (element, e)
+
+        if isinstance(element, gst.interfaces.XOverlay):
+            self.vsink = element
+            try:
+                self.sink.set_property("force-aspect-ratio", True)
+            except Exception:
+                pass
+
+    def expose_event(self, *args):
+        if not self.exposed:
+            self.exposedc.acquire()
+            self.exposed = True
+            self.exposedc.notify()
+            self.exposedc.release()
+
+    def sync_handler(self, bus, message):
+        if message.src == self.vsink and \
+            message.type == gst.MESSAGE_ELEMENT and \
+            message.structure.has_name("prepare-xwindow-id"):
+
+            self.exposedc.acquire()
+            while not self.exposed:
+                self.exposedc.wait()
+            gtk.gdk.threads_enter()
+            self.vsink.set_xwindow_id (self.window.xid)
+            gtk.gdk.threads_leave()
+            self.exposedc.release()
+
+            return gst.BUS_DROP
+
+        return gst.BUS_PASS
+
+
+class UI(gtk.Window):
+    WIDTH = 340
+    HEIGHT = 260
+    def __init__(self, jid, conference):
+        gtk.Window.__init__(self)
+        self.connect('destroy', lambda x: reactor.stop())
+        self.hbox = gtk.HBox()
+        self.add(self.hbox)
+        self.outputs = {}
+
+        self.label = gtk.Label("Waiting for other participants...")
+        self.label.set_size_request(self.WIDTH, self.HEIGHT)
+
+        self.preview_frame = gtk.Frame("Local Preview")
+        self.preview_frame.set_size_request(self.WIDTH, self.HEIGHT)
+
+        self.hbox.pack_start(self.preview_frame, False, False, 3)
+        self.hbox.add(self.label)
+        self.conference = conference
+        self.set_title(jid.userhost())
+
+        self.show_all()
+
+    def add_video_preview (self, session):
+        gtk.gdk.threads_enter()
+
+        pad = session.source.tee.get_pad("src%d")
+
+        vsink = VideoSink(self.conference)
+        session.source.add(vsink.sink)
+
+        #vsink.sink.set_property("sync", False)
+
+        pad.link(vsink.sink.get_pad("sink"))
+        vsink.sink.set_state(gst.STATE_PLAYING)
+
+        self.preview_frame.add(vsink)
+        vsink.show_all()
+
+        gtk.gdk.threads_leave()
+
+    def add_output(self, name):
+        gtk.gdk.threads_enter()
+        if self.label:
+            self.hbox.remove(self.label)
+            self.label = None
+
+        assert not self.outputs.has_key(name)
+
+        frame = gtk.Frame(name)
+        frame.set_border_width(3)
+        label = gtk.Label("Waiting for video streams...")
+        label.set_size_request(320, 240)
+        frame.add(label)
+
+        self.outputs[name] = frame
+
+        self.hbox.pack_start(frame, False, False, 3)
+        frame.show_all()
+
+        gtk.gdk.threads_leave()
+
+    def remove_output (self, name):
+        frame = self.outputs.pop(name)
+        self.hbox.remove(frame)
+        if len(self.outputs) == 0:
+            self.label = gtk.Label("Waiting for other participants...")
+            self.hbox.add(self.label)
+            self.hbox.show_all()
+
+        self.resize(self.WIDTH, self.HEIGHT)
+
+    def add_video_output(self, name, stream, pad):
+        gtk.gdk.threads_enter()
+
+        frame = self.outputs[name]
+
+        if type(frame.get_child()) == gtk.Label:
+            frame.remove(frame.get_child())
+
+        vsink = VideoSink(self.conference)
+        frame.add(vsink)
+        frame.show_all()
+
+        stream.add_sink (vsink.sink)
+
+        self.conference.add(vsink.sink)
+        pad.link(vsink.sink.get_pad("sink"))
+        vsink.sink.set_state(gst.STATE_PLAYING)
+
+        gtk.gdk.threads_leave()
+
+class Muc:
+    PREPARING = 0
+    JOINING = 1
+    PRESENT = 2
+
+    def __init__(self, client, jid):
+        self.jid = jid
+        self.client = client
+        self.state = Muc.PREPARING
+        self.members = []
+        self.conference = jingle.JingleConference()
+        self.jingle_sessions = {}
+        self.mingle_presences = {}
+
+        self.my_jid = JID('%s/%s' % (self.jid.userhost(),
+            self.client.jid.user))
+
+        transports = jingle.get_available_transports()
+        client.features.update([
+         ns.JINGLE,
+         ns.JINGLE_RTP,
+        ] + transports)
+
+        client.send_presence()
+
+        self.conference.streamAdded.addCallback(False, self.new_stream)
+        self.ui = UI(client.jid, self.conference)
+
+        client.add_iq_handler('set', ns.JINGLE, 'jingle',
+            self.jingle_iq_received)
+
+        self.client.resourceOffline.addCallback(False, self.resource_offline)
+
+    def resource_offline(self, contact):
+        if self.jingle_sessions.has_key(contact):
+            self.jingle_sessions.pop(contact).terminate()
+            self.ui.remove_output(contact.jid.full())
+
+    def jingle_iq_received(self, iq):
+        j = xpath.queryForNodes('/iq/jingle', iq)[0]
+        if j['action'] != 'session-initiate':
+            return None
+
+        jid = JID(iq['from'])
+        contact = self.client.get_contact (jid)
+
+        session = jingle.JingleSession(self.client, self.conference)
+        self.jingle_sessions[contact] = session
+
+        self.ui.add_output (jid.full())
+        return session.handle_session_initiate (iq,
+            self.client.get_contact (jid))
+
+    def new_stream(self, participant, stream):
+        if stream.session.type == farsight.MEDIA_TYPE_VIDEO:
+            stream.src_pad_hook  = lambda stream, fsstream, pad, codec: \
+                self.new_video_output(participant, stream, pad, codec)
+
+    def new_video_output(self, participant, stream, pad, codec):
+        self.ui.add_video_output(participant.cname, stream, pad)
+
+    def join(self):
+        self.state = Muc.JOINING
+        self.client.stream.addObserver('/presence', self.presence)
+        self.update_presence()
+
+    def presence_(self, stanza):
+        from_jid = JID(stanza['from'])
+        mingle = util.elem_find_child(stanza, ns.MINGLE, 'mingle')
+
+        if mingle is None:
+            return
+
+        self.mingle_presences[from_jid] = stanza
+
+    def update_presence(self, mingle = None):
+        join = domish.Element((None, 'presence'))
+        join['to'] = self.my_jid.full()
+        self.client.presence_add_caps(join)
+
+        if (mingle != None):
+            join.addChild(mingle)
+
+        self.client.stream.send(join)
+
+    def got_codecs(self, results):
+        print "Got codecs!!!!"
+        mingle = domish.Element((ns.MINGLE, 'mingle'))
+        for (result, sessioninfo) in results:
+            c = mingle.addElement ('content')
+            desc = c.addElement ((ns.JINGLE_RTP, "description"))
+
+            c['name'] = sessioninfo[0]
+
+            fssession = sessioninfo[1]
+            if fssession.type == farsight.MEDIA_TYPE_VIDEO:
+                desc['media'] = "video"
+            elif fssession.type == farsight.MEDIA_TYPE_AUDIO:
+                desc['media'] = "audio"
+
+            for codec in sessioninfo[2]:
+                pt = desc.addElement("payload-type")
+
+                pt['id'] = str(codec.id)
+                pt['name'] = codec.encoding_name
+                pt['clockrate'] = str(codec.clock_rate)
+                if codec.channels > 0:
+                    pt['channels'] = str(codec.channels)
+
+                for (name, value) in codec.optional_params:
+                    param = pt.addElement('parameter')
+                    param['name'] = name
+                    param['value'] = value
+
+        self.update_presence(mingle)
+
+        # call the lot using the existing conference
+
+    def participants_done (self, *args):
+        deferreds = []
+
+        for (name, session) in self.conference.sessions.iteritems():
+            print "Adding.. %s" % name
+
+            d = session.get_codecs()
+            d.addCallback (lambda result, n=name, s=session: (n, s, result))
+            deferreds.append(d)
+
+        dlist = defer.DeferredList(deferreds)
+        dlist.addCallback(self.got_codecs)
+
+        for jid in self.mingle_presences.iterkeys():
+            print "Calling: %s" % jid.full()
+            self.ui.add_output (jid.full())
+            session = jingle.JingleSession (self.client, self.conference)
+            contact = self.client.get_contact (jid)
+            self.jingle_sessions[contact] = session
+            session.initiate(contact)
+
+    def participant_got_stream (self, stream, session, description):
+        payloads = xpath.queryForNodes(
+            '/description/payload-type', description)
+
+        codecs = []
+        for p in payloads:
+            codec = farsight.Codec(int(p["id"]),
+                                    p["name"],
+                                    session.type,
+                                    int(p["clockrate"]))
+            params = xpath.queryForNodes("/payload-type/parameter", p)
+            if params !=None:
+                optional_params = []
+
+                for param in params:
+                    optional_params.append(
+                        (str(param['name']), str(param['value'])))
+                codec.optional_params = optional_params
+
+            codecs.append(codec)
+
+        stream.set_remote_codecs(codecs)
+
+    def add_participant (self, jid, stanza):
+        contact = self.client.get_contact (jid)
+
+        deferreds = []
+        contents = xpath.queryForNodes ('/presence/mingle/content', stanza)
+
+        for c in contents:
+            description = xpath.queryForNodes ('/content/description', c)[0]
+            if description['media'] == "audio":
+                type = farsight.MEDIA_TYPE_AUDIO
+            elif description['media'] == "video":
+                type = farsight.MEDIA_TYPE_VIDEO
+
+            session = self.conference.get_session( c['name'], type)
+            d = self.conference.get_stream(session, contact)
+            deferreds.append(d)
+            d.addCallback (self.participant_got_stream, session, description)
+
+        dlist = defer.DeferredList(deferreds)
+        return dlist
+
+    def joined (self):
+        print 'joined the room'
+        deferreds = []
+
+        if len(self.conference.sessions) == 0:
+            # Trigger voice and video streams
+            self.conference.get_session("video", farsight.MEDIA_TYPE_VIDEO)
+            self.conference.get_session("audio", farsight.MEDIA_TYPE_AUDIO)
+
+
+        session = self.conference.get_session("video",
+            farsight.MEDIA_TYPE_VIDEO)
+        self.ui.add_video_preview(session)
+
+
+        for (jid, stanza) in self.mingle_presences.iteritems():
+            deferreds.append (self.add_participant(jid, stanza))
+
+        dlist = defer.DeferredList(deferreds)
+        dlist.addCallback(self.participants_done)
+
+    def presence(self, stanza):
+        global state
+        from_jid = JID(stanza['from'])
+
+        if from_jid.userhost() != self.jid.userhost():
+            return
+
+        if self.state == Muc.JOINING:
+            if from_jid == self.my_jid:
+                self.state = Muc.PRESENT
+                self.joined()
+            else:
+                print '%s is in room' % from_jid.resource
+                self.presence_(stanza)
+        else:
+            if from_jid == self.my_jid:
+                return
+            elif stanza.getAttribute('type') == 'unavailable':
+                print '%s left room' % from_jid.resource
+            else:
+                print '%s has joined room' % from_jid.resource
+
+
+
+def run(jid, password, muc_jid, peers):
+
+    def authd(client):
+        muc = Muc(client, muc_jid)
+        muc.join()
+
+    client = create_client(jid, password)
+
+    client.authenticated.addCallback(authd)
+    client.done.addBoth(lambda *args: reactor.stop())
+
+    reactor.run()
+
+def main(argv):
+    if len(argv) != 4:
+        return 1
+
+    jid_str, password, muc_str = argv[1:]
+    muc_jid = JID(muc_str)
+    #peers = map(JID, argv[3:])
+    #print (jid, password, peers)
+    run(jid_str, password, muc_jid, [])
+    return 0
+
+if __name__ == '__main__':
+    gobject.threads_init()
+    gtk.gdk.threads_init()
+
+    sys.exit(main(sys.argv))
+
-- 
1.5.6.5



More information about the Telepathy-commits mailing list