diff options
author | Olivier CrĂȘte <olivier.crete@collabora.com> | 2016-11-14 16:33:00 -0500 |
---|---|---|
committer | Olivier CrĂȘte <olivier.crete@collabora.com> | 2016-11-15 17:38:54 -0500 |
commit | fd046ba80f47bf1e568b5fa41ba903c8002deba8 (patch) | |
tree | a275ce6dbe38f598788e84ef397c276e4b30965c | |
parent | 2038d9e9aed63e663e3a1a3fec12f1a7c22a2d9f (diff) | |
download | telepathy-farstream-fd046ba80f47bf1e568b5fa41ba903c8002deba8.tar.gz |
Port example python call handler to GStreamer 1.0 & TpGLib
Also disable a bunch of codecs, because the
list of audio doesnt needs to fit in one UDP packet
-rw-r--r-- | examples/python/callchannel.py | 149 | ||||
-rw-r--r-- | examples/python/callhandler.py | 107 | ||||
-rw-r--r-- | examples/python/constants.py | 8 |
3 files changed, 99 insertions, 165 deletions
diff --git a/examples/python/callchannel.py b/examples/python/callchannel.py index e60e671..32aa39c 100644 --- a/examples/python/callchannel.py +++ b/examples/python/callchannel.py @@ -17,78 +17,55 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -import dbus -import dbus.glib -from gi.repository import GObject +import gi +gi.require_version('Gst', '1.0') +gi.require_version('TelepathyGLib', '0.12') +gi.require_version('TelepathyFarstream', '0.6') +from gi.repository import GLib, GObject, Gst, TelepathyFarstream, Farstream, TelepathyGLib + import sys -from glib import GError -import pygst -pyGst.require("0.10") -from gi.repository import Gst +Gst.init(sys.argv) -import tpfarstream -import farstream from util import * -import gc - -from telepathy.client.channel import Channel -from telepathy.constants import ( - CONNECTION_HANDLE_TYPE_NONE, CONNECTION_HANDLE_TYPE_CONTACT, - CONNECTION_STATUS_CONNECTED, CONNECTION_STATUS_DISCONNECTED, - MEDIA_STREAM_STATE_CONNECTED - ) -from telepathy.interfaces import ( - CHANNEL_INTERFACE, CONN_INTERFACE, - CONNECTION_INTERFACE_REQUESTS, - CONNECTION_INTERFACE_CONTACT_CAPABILITIES, - CLIENT) - -from constants import * class CallChannel: - def __init__ (self, bus, connection, object_path, properties): - self.bus = bus + def __init__ (self, connection, channel): self.conn = connection + self.channel = channel self.tfchannel = None - self.obj = self.bus.get_object (self.conn.service_name, object_path) - self.obj.connect_to_signal ("CallStateChanged", - self.state_changed_cb, dbus_interface=CHANNEL_TYPE_CALL) + channel.connect ("state-changed", self.state_changed_cb) - self.pipeline = Gst.Pipeline() - self.pipeline.get_bus().add_watch(self.async_handler) + self.pipeline = Gst.Pipeline(None) + self.pipeline.get_bus().add_signal_watch() + self.pipeline.get_bus().connect ("message", self.async_handler) - self.notifier = notifier = farstream.ElementAddedNotifier() + self.notifier = notifier = Farstream.ElementAddedNotifier() notifier.set_properties_from_file("element-properties") notifier.add(self.pipeline) - tpfarstream.tf_channel_new_async (connection.service_name, - connection.object_path, object_path, self.tpfs_created) + TelepathyFarstream.Channel.new_async (channel, self.tpfs_created) - def state_changed_cb(self, state, flags, reason, details): + def state_changed_cb(self, channel, state, flags, reason, details): print "* StateChanged:\n State: %s (%d)\n Flags: %s" % ( call_state_to_s (state), state, call_flags_to_s (flags)) - - print "\tReason: actor: %d reason: %d dbus_reason: '%s'" % ( - reason[0], reason[1], reason[2]) - + print "\tReason: " + reason.message, print '\tDetails:' for key, value in details.iteritems(): print "\t %s: %s" % (key, value) else: print '\t None' - if state == CALL_STATE_ENDED: + if state == TelepathyGLib.CallState.ENDED: self.close() - def accept (self): - self.obj.Accept(dbus_interface=CHANNEL_TYPE_CALL) def close (self): print "Closing the channel" + # close and cleanup - self.obj.Close(dbus_interface=CHANNEL_INTERFACE) + self.channel.close_async() self.pipeline.set_state (Gst.State.NULL) self.pipeline = None @@ -101,53 +78,72 @@ class CallChannel: self.tfchannel.bus_message(message) return True - self.pipeline = Gst.Pipeline() - def tpfs_created (self, source, result): - tfchannel = self.tfchannel = source.new_finish(result) + tfchannel = self.tfchannel = source.new_finish(source, result) tfchannel.connect ("fs-conference-added", self.conference_added) tfchannel.connect ("content-added", self.content_added) def src_pad_added (self, content, handle, stream, pad, codec): type = content.get_property ("media-type") - if type == farstream.MEDIA_TYPE_AUDIO: + if type == Farstream.MediaType.AUDIO: sink = Gst.parse_bin_from_description("audioconvert ! audioresample ! audioconvert ! autoaudiosink", True) - elif type == farstream.MEDIA_TYPE_VIDEO: - sink = Gst.parse_bin_from_description("ffmpegcolorspace ! videoscale ! autovideosink", True) + elif type == Farstream.MediaType.VIDEO: + sink = Gst.parse_bin_from_description("videoconvert ! videoscale ! autovideosink", True) self.pipeline.add(sink) - pad.link(sink.get_pad("sink")) + pad.link(sink.get_static_pad("sink")) sink.set_state(Gst.State.PLAYING) def get_codec_config (self, media_type): - if media_type == farstream.MEDIA_TYPE_VIDEO: - codecs = [ farstream.Codec(farstream.CODEC_ID_ANY, "H264", - farstream.MEDIA_TYPE_VIDEO, 0) ] + if media_type == Farstream.MediaType.VIDEO: + codecs = [ farstream.Codec.new(farstream.CODEC_ID_ANY, "VP8", + Farstream.MediaType.VIDEO, 0), + farstream.Codec.new(farstream.CODEC_ID_ANY, "H264", + Farstream.MediaType.VIDEO, 0) ] if self.conn.GetProtocol() == "sip" : - codecs += [ farstream.Codec(farstream.CODEC_ID_DISABLE, "THEORA", - farstream.MEDIA_TYPE_VIDEO, 0) ] + codecs += [ Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "THEORA", + Farstream.MediaType.VIDEO, 0) ] else: - codecs += [ farstream.Codec(farstream.CODEC_ID_ANY, "THEORA", - farstream.MEDIA_TYPE_VIDEO, 0) ] + codecs += [ Farstream.Codec.new(Farstream.CODEC_ID_ANY, "THEORA", + Farstream.MediaType.VIDEO, 0) ] codecs += [ - farstream.Codec(farstream.CODEC_ID_ANY, "H263", - farstream.MEDIA_TYPE_VIDEO, 0), - farstream.Codec(farstream.CODEC_ID_DISABLE, "DV", - farstream.MEDIA_TYPE_VIDEO, 0), - farstream.Codec(farstream.CODEC_ID_ANY, "JPEG", - farstream.MEDIA_TYPE_VIDEO, 0), - farstream.Codec(farstream.CODEC_ID_ANY, "MPV", - farstream.MEDIA_TYPE_VIDEO, 0), + farstream.Codec.new.new(Farstream.CODEC_ID_ANY, "H263", + Farstream.MediaType.VIDEO, 0), + farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "DV", + Farstream.MediaType.VIDEO, 0), + farstream.Codec.new(Farstream.CODEC_ID_ANY, "JPEG", + Farstream.MediaType.VIDEO, 0), + farstream.Codec.new(Farstream.CODEC_ID_ANY, "MPV", + Farstream.MediaType.VIDEO, 0), ] else: codecs = [ - farstream.Codec(farstream.CODEC_ID_ANY, "SPEEX", - farstream.MEDIA_TYPE_AUDIO, 16000 ), - farstream.Codec(farstream.CODEC_ID_ANY, "SPEEX", - farstream.MEDIA_TYPE_AUDIO, 8000 ) - ] + Farstream.Codec.new(Farstream.CODEC_ID_ANY, "OPUS", + Farstream.MediaType.AUDIO, 0 ), + Farstream.Codec.new(Farstream.CODEC_ID_ANY, "SPEEX", + Farstream.MediaType.AUDIO, 16000 ), + Farstream.Codec.new(Farstream.CODEC_ID_ANY, "SPEEX", + Farstream.MediaType.AUDIO, 8000 ), + Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "G722", + Farstream.MediaType.AUDIO, 0 ), + Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "G726-16", + Farstream.MediaType.AUDIO, 0 ), + Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "L16", + Farstream.MediaType.AUDIO, 0 ), + Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "AMR", + Farstream.MediaType.AUDIO, 0 ), + Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "SIREN", + Farstream.MediaType.AUDIO, 0 ), + Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "MPA", + Farstream.MediaType.AUDIO, 0 ), + Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, "MPA-ROBUST", + Farstream.MediaType.AUDIO, 0 ), + Farstream.Codec.new(Farstream.CODEC_ID_DISABLE, + "X-MP3-DRAFT-00", + Farstream.MediaType.AUDIO, 0 ) + ] return codecs def content_added(self, channel, content): @@ -157,21 +153,20 @@ class CallChannel: prefs = self.get_codec_config (mtype) if prefs != None: try: - content.set_codec_preferences(prefs) - except GError, e: + content.props.fs_session.set_codec_preferences(prefs) + except GLib.GError, e: print e.message content.connect ("src-pad-added", self.src_pad_added) - if mtype == farstream.MEDIA_TYPE_AUDIO: - src = Gst.parse_bin_from_description("audiotestsrc is-live=1 ! " \ - "queue", True) - elif mtype == farstream.MEDIA_TYPE_VIDEO: + if mtype == Farstream.MediaType.AUDIO: + src = Gst.parse_bin_from_description("audiotestsrc is-live=1", True) + elif mtype == Farstream.MediaType.VIDEO: src = Gst.parse_bin_from_description("videotestsrc is-live=1 ! " \ "capsfilter caps=video/x-raw-yuv,width=320,height=240", True) self.pipeline.add(src) - src.get_pad("src").link(sinkpad) + src.get_static_pad("src").link(sinkpad) src.set_state(Gst.State.PLAYING) def conference_added (self, channel, conference): diff --git a/examples/python/callhandler.py b/examples/python/callhandler.py index f4f6973..2d20e33 100644 --- a/examples/python/callhandler.py +++ b/examples/python/callhandler.py @@ -15,102 +15,39 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -from gi.repository import GObject -# Need gio so GAsyncInitialbe is known -from gi.repository import Gio - -import dbus -from dbus.mainloop.glib import DBusGMainLoop -DBusGMainLoop(set_as_default=True) +import gi +gi.require_version('TelepathyGLib', '0.12') +from gi.repository import GObject, Gio, TelepathyGLib from constants import * -from telepathy.interfaces import CHANNEL_INTERFACE, CLIENT, CLIENT_HANDLER -from telepathy.constants import CONNECTION_HANDLE_TYPE_CONTACT, CONNECTION_HANDLE_TYPE_ROOM -import telepathy from callchannel import CallChannel -class CallHandler(dbus.service.Object, telepathy.server.DBusProperties): - def __init__(self, bus, bus_name = None): - self.bus = bus - if bus_name == None: - self.bus_name = "org.freedesktop.Telepathy.Client.CallDemo" \ - + bus.get_unique_name().replace(":", "_").replace(".","_") - else: - self.bus_name = bus_name - self.path = "/" + self.bus_name.replace(".", "/") - self._interfaces = set([CLIENT, CLIENT_HANDLER]) - self._prop_getters = {} - self._prop_setters = {} - - dbus.service.Object.__init__(self, bus, self.path) - telepathy.server.DBusProperties.__init__(self) - - self._name = dbus.service.BusName (self.bus_name, bus) - - self._implement_property_get (CLIENT, - { "Interfaces": self._get_interfaces } ) - self._implement_property_get (CLIENT_HANDLER, - { "HandlerChannelFilter": self._get_filters } ) - self._implement_property_get (CLIENT_HANDLER, - { "Capabilities": self._get_capabilities } ) - - def _get_interfaces(self): - return dbus.Array(self._interfaces, signature='s') - - def _get_filters(self): - return dbus.Array ([ - { CHANNEL_INTERFACE + ".ChannelType": CHANNEL_TYPE_CALL, - CHANNEL_INTERFACE + ".TargetHandleType": - CONNECTION_HANDLE_TYPE_CONTACT, - CALL_INITIAL_AUDIO: True, - }, - { CHANNEL_INTERFACE + ".ChannelType": CHANNEL_TYPE_CALL, - CHANNEL_INTERFACE + ".TargetHandleType": - CONNECTION_HANDLE_TYPE_CONTACT, - CALL_INITIAL_VIDEO: True, - }, - { CHANNEL_INTERFACE + ".ChannelType": CHANNEL_TYPE_CALL, - CHANNEL_INTERFACE + ".TargetHandleType": - CONNECTION_HANDLE_TYPE_ROOM, - CALL_INITIAL_AUDIO: True, - }, - { CHANNEL_INTERFACE + ".ChannelType": CHANNEL_TYPE_CALL, - CHANNEL_INTERFACE + ".TargetHandleType": - CONNECTION_HANDLE_TYPE_ROOM, - CALL_INITIAL_VIDEO: True, - } - ], - signature='a{sv}') - - def _get_capabilities(self): - return dbus.Array ([ - CHANNEL_TYPE_CALL + '/gtalk-p2p', - CHANNEL_TYPE_CALL + '/ice-udp', - CHANNEL_TYPE_CALL + '/video/h264', - ], signature='s') +class CallHandler: + def __init__(self, bus_name = 'CallDemo'): + TelepathyGLib.debug_set_flags("all") + am = TelepathyGLib.AccountManager.dup() + self.handler = handler = TelepathyGLib.SimpleHandler.new_with_am( + am, True, False, bus_name, True, self.handle_channels_cb) - def do_handle_call_channel (self, requests, bus, conn, channel, properties): - cchannel = CallChannel(self.bus, conn, channel, properties) - cchannel.accept() + handler.add_handler_filter({ + TelepathyGLib.PROP_CHANNEL_CHANNEL_TYPE: TelepathyGLib.IFACE_CHANNEL_TYPE_CALL, - @dbus.service.method(dbus_interface=CLIENT_HANDLER, - in_signature='ooa(oa{sv})aota{sv}', - async_callbacks= ('_success', '_error')) - def HandleChannels(self, account, connection, channels, - requests, time, info, _success, _error): + TelepathyGLib.PROP_CHANNEL_TARGET_HANDLE_TYPE: int(TelepathyGLib.HandleType.CONTACT) + }) + self.bus_name = handler.get_bus_name() - conn = telepathy.client.Connection (connection[1:].replace('/','.'), - connection) - # Assume there can be only one - (channel, properties) = channels[0] + handler.register() - _success() - self.do_handle_call_channel (requests, - self.bus, conn, channel, properties); + def handle_channels_cb (self, handler, account, conn, channels, + requests_satisfied, user_action_time, context): + assert len(channels) == 1 + cchannel = CallChannel(conn, channels[0]) + context.accept() + channels[0].accept_async(None) if __name__ == '__main__': GObject.threads_init() loop = GObject.MainLoop() - CallHandler(dbus.SessionBus()) + CallHandler() loop.run() diff --git a/examples/python/constants.py b/examples/python/constants.py index 43af8ba..49be3b9 100644 --- a/examples/python/constants.py +++ b/examples/python/constants.py @@ -48,9 +48,11 @@ STREAM_TRANSPOR_DUMMY = 0xff CALL_STATE_UNKNOWN = 0 CALL_STATE_PENDING_INITIATOR = 1 -CALL_STATE_PENDING_RECEIVER = 2 -CALL_STATE_ACCEPTED = 3 -CALL_STATE_ENDED = 4 +CALL_STATE_INITIALISING = 2 +CALL_STATE_INITIALISED = 3 +CALL_STATE_ACCEPTED = 4 +CALL_STATE_ACTIVE = 5 +CALL_STATE_ENDED = 6 CALL_FLAG_LOCALLY_RINGING = 1 CALL_FLAG_QUEUED = 2 |