[Telepathy-commits] [mingle/master] get the descriptions from the muc presence and feed those into the fsconference before calling other participants

Sjoerd Simons sjoerd at luon.net
Tue Nov 4 11:40:08 PST 2008


---
 mingle-client.py |  146 ++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 125 insertions(+), 21 deletions(-)

diff --git a/mingle-client.py b/mingle-client.py
index 5450aae..cb387e7 100644
--- a/mingle-client.py
+++ b/mingle-client.py
@@ -4,15 +4,16 @@ import sys
 from twisted.internet import glib2reactor
 glib2reactor.install()
 
-from twisted.internet import reactor
+from twisted.internet import reactor, defer
 from twisted.words.protocols.jabber.jid import JID
-from twisted.words.xish import domish
+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
 
 class Muc:
     PREPARING = 0
@@ -24,41 +25,142 @@ class Muc:
         self.client = client
         self.state = Muc.PREPARING
         self.members = []
+        self.conference = jingle.JingleConference()
+        self.mingle_presences = {}
 
         self.my_jid = JID('%s/%s' % (self.jid.userhost(),
             self.client.jid.user))
 
     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
+
+        # Store others mingle descriptions, we can't send disco request untill
+        # after joining the muc
 
+        #print "initiating session with %s" % from_
+        #from_jid = JID(from_)
+        #contact = self.client.contacts[from_jid.userhost()][from_jid.resource]
+
+        #d = contact.get_capabilities()
+        #d.addCallback(self.got_caps, contact, stanza)
+
+    def update_presence(self, mingle = None):
         join = domish.Element((None, 'presence'))
         join['to'] = self.my_jid.full()
-        x = join.addElement((ns.MUC_USER, 'x'))
-        mingle = join.addElement((ns.MINGLE, 'mingle'))
         self.client.presence_add_caps(join)
 
-        self.client.stream.addObserver('/presence', self.presence)
+        if (mingle != None):
+            join.addChild(mingle)
+
         self.client.stream.send(join)
 
-    def got_caps(self, caps, contact):
-        print "Got caps for %s: %s" % (contact.jid.full(), str(caps))
-        session = jingle.get_session_for_capabilities(self.client, caps)
-        if session != None:
+    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['rate'] = str(codec.clock_rate)
+                if codec.channels > 0:
+                    pt['channels'] = str(codec.channels)
+
+        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: (name, session, 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()
+            session = jingle.JingleSession (self.client, self.conference)
+            contact = self.client.get_contact (jid)
             session.initiate(contact)
 
-    def presence_(self, stanza):
-        from_ = stanza['from']
-        mingle = util.elem_find_child(stanza, ns.MINGLE, 'mingle')
 
-        if mingle is None:
-            return
+    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["rate"]))
+            codecs.append(codec)
 
-        print "initiating session with %s" % from_
-        from_jid = JID(from_)
-        contact = self.client.contacts[from_jid.userhost()][from_jid.resource]
+        stream.set_remote_codecs(codecs)
 
-        d = contact.get_capabilities()
-        d.addCallback(self.got_caps, contact)
+    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)
+
+        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
@@ -70,12 +172,14 @@ class Muc:
         if self.state == Muc.JOINING:
             if from_jid == self.my_jid:
                 self.state = Muc.PRESENT
-                print 'joined room'
+                self.joined()
             else:
                 print '%s is in room' % from_jid.resource
                 self.presence_(stanza)
         else:
-            if stanza.getAttribute('type') == 'unavailable':
+            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
-- 
1.5.6.5




More information about the Telepathy-commits mailing list