[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