[telepathy-ashes/master] still not getting any sound out of echo bot

David Laban "David Labanalsuren" at gmail.com
Thu Sep 17 03:10:00 PDT 2009


---
 ashes/tools/echo_bot.py |  133 +++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 124 insertions(+), 9 deletions(-)

diff --git a/ashes/tools/echo_bot.py b/ashes/tools/echo_bot.py
index 6a65b07..c78738c 100644
--- a/ashes/tools/echo_bot.py
+++ b/ashes/tools/echo_bot.py
@@ -4,11 +4,13 @@ import pdb
 import shiny
 
 import gobject
+import gst
 import dbus
 import dbus.mainloop.glib
 import telepathy
 from telepathy.constants import HANDLE_TYPE_CONTACT
 import tpfarsight
+import farsight
 
 from helper_functions import get_connections, green, red
 
@@ -168,6 +170,14 @@ class ChannelDispatcher(ConnectionListener):
             return class_
         return decorate
     
+    def __init__(self, connection, contact_regexp='.*'):
+        # FIXME: This should really be done only if there is a handler for this type.
+        # It should also probably be done in some kind of setup function rather than 
+        # __init__ because I don't know what state the connection is in here.
+        super(ChannelDispatcher, self).__init__(connection, contact_regexp)
+        self.connection[telepathy.CONN_INTERFACE_CAPABILITIES].AdvertiseCapabilities(
+            [(telepathy.CHANNEL_TYPE_STREAMED_MEDIA, 0xff)], [])
+    
     def NewChannel(self, object_path, channel_type, handle_type, handle, suppress_handler):
         """
         Callback for Connection.NewChannel. Currently doesn't do anything.
@@ -336,6 +346,7 @@ class ChannelListener(ObjectListener):
                 signal_names = self._signal_names[channel_type]
                 for signal_name in signal_names:
                     self.connect_to_signal(channel_type, signal_name)
+        
 
 
 
@@ -379,16 +390,120 @@ class MediaChannelEchoer(ChannelListener):
                                             self.connection.object_path,      
                                             channel.object_path)
         
-        self.tfchannel.connect ("session-created", self.session_created)
-        self.tfchannel.connect ("stream-created", self.stream_created)
-        self.tfchannel.connect ("stream-get-codec-config", self.stream_get_codec_config)
+        
+        
+        self.fschannel = None
+        self.pipeline = gst.Pipeline()
+        self.pipeline.get_bus().add_watch(self.async_handler)
+        
+        self.tfchannel.connect("session-created", self.session_created)
+        self.tfchannel.connect("stream-created", self.stream_created)
+        self.tfchannel.connect("stream-get-codec-config", self.stream_get_codec_config)
+        
+        
+        gobject.timeout_add(1000, self.accept_incoming_members)
+    
+    def accept_incoming_members(self):
+        print green('Accepting incoming group members')
+        pending = self.channel[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].GetLocalPendingMembers()
+        self.channel[telepathy.interfaces.CHANNEL_INTERFACE_GROUP].AddMembers(pending, "")
     
-    def session_created(self, *args):
-        print 'session_created(%s)' % ', '.join(map(str, args))
-    def stream_created(self, *args):
-        print 'stream_created(%s)' % ', '.join(map(str, args))
-    def stream_get_codec_config(self, *args):
-        print 'stream-get-codec-config(%s)' % ', '.join(map(str, args))
+    #The following functions are copied from the call.py example and documented.
+    def async_handler(self, bus, message):
+        """
+        Gets registered with self.pipeline.get_bus().add_watch(self.async_handler)
+        and forwards gst bus messages to self.tfchannel.
+        """
+        if self.tfchannel != None:
+            self.tfchannel.bus_message(message)
+        return True    
+    
+    def src_pad_added(self, stream, pad, codec):
+        """
+        Connects up incoming media to the speakers/screen.
+        Actually just hacked it to throw away all incoming data.
+        """
+        type = stream.get_property ("media-type")
+        if type == farsight.MEDIA_TYPE_AUDIO:
+            sink = gst.parse_bin_from_description("audioconvert ! audioresample ! audioconvert ! autoaudiosink", True)
+        elif type == farsight.MEDIA_TYPE_VIDEO:
+            sink = gst.parse_bin_from_description("ffmpegcolorspace ! videoscale ! autovideosink", True)
+        
+        self.pipeline.add(sink)
+        pad.link(sink.get_pad("sink"))
+        sink.set_state(gst.STATE_PLAYING)
+    
+    def stream_created(self, channel, stream):
+        """
+        connects (audio|video)testsrc to the input of the stream, and sets up
+        self.src_pad_added to handle incoming media pads.
+        Note that there is a delay before adding the audio. 
+        This is to avoid a race condition in gabble.
+        """
+        stream.connect("src-pad-added", self.src_pad_added)
+        gobject.timeout_add(1000, self.do_test_sound, stream)
+        
+    
+    def do_test_sound(self, stream):
+        print '#'*500
+        print green('Sending test sound/video')
+        srcpad = stream.get_property("sink-pad")
+
+        type = stream.get_property ("media-type")
+
+        if type == farsight.MEDIA_TYPE_AUDIO:
+            src = gst.element_factory_make("audiotestsrc")
+            src.set_property("is-live", True)
+        elif type == farsight.MEDIA_TYPE_VIDEO:
+            src = gst.element_factory_make("videotestsrc")
+            src.set_property("is-live", True)
+
+        self.pipeline.add(src)
+        src.get_pad("src").link(srcpad)
+        src.set_state(gst.STATE_PLAYING)    
+
+    def session_created(self, channel, conference, participant):
+        """
+        #todo: work out why we add conference to the pipeline.
+        """
+        self.pipeline.add(conference)
+        self.pipeline.set_state(gst.STATE_PLAYING)  
+        
+        
+    def stream_get_codec_config(self, channel, stream_id, media_type, direction):
+        """
+        Called by tfchannel to query which video codecs we want.
+        """
+        print "got codec config"
+        if media_type == farsight.MEDIA_TYPE_VIDEO:
+            codecs = [ farsight.Codec(farsight.CODEC_ID_ANY, "H264",
+                farsight.MEDIA_TYPE_VIDEO, 0) ]
+            if self.conn.GetProtocol() == "sip" :
+                codecs += [ farsight.Codec(farsight.CODEC_ID_DISABLE, "THEORA",
+                                        farsight.MEDIA_TYPE_VIDEO, 0) ]
+            else:
+                codecs += [ farsight.Codec(farsight.CODEC_ID_ANY, "THEORA",
+                                        farsight.MEDIA_TYPE_VIDEO, 0) ]
+            codecs += [
+                farsight.Codec(farsight.CODEC_ID_ANY, "H263",
+                                        farsight.MEDIA_TYPE_VIDEO, 0),
+                farsight.Codec(farsight.CODEC_ID_DISABLE, "DV",
+                                        farsight.MEDIA_TYPE_VIDEO, 0),
+                farsight.Codec(farsight.CODEC_ID_ANY, "JPEG",
+                                        farsight.MEDIA_TYPE_VIDEO, 0),
+                farsight.Codec(farsight.CODEC_ID_ANY, "MPV",
+                                        farsight.MEDIA_TYPE_VIDEO, 0),
+            ]
+
+            return codecs
+        else:
+            return None
+    #def session_created(self, *args):
+    #    print green('session_created(%s)' % ', '.join(map(str, args)))
+    #def stream_created(self, channel, stream):
+    #    print green('stream_created(%s)' % ', '.join(map(str, [channel, stream])))
+    #def stream_get_codec_config(self, *args):
+    #    print green('stream-get-codec-config(%s)' % ', '.join(map(str, args)))
 
 # These global variables are just lists of all the connections and channels
 # so that a) we don't handle things twice and b) nothing gets accidentally
-- 
1.5.6.5



More information about the telepathy-commits mailing list