summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.com>2016-11-14 16:33:00 -0500
committerOlivier CrĂȘte <olivier.crete@collabora.com>2016-11-15 17:38:54 -0500
commitfd046ba80f47bf1e568b5fa41ba903c8002deba8 (patch)
treea275ce6dbe38f598788e84ef397c276e4b30965c
parent2038d9e9aed63e663e3a1a3fec12f1a7c22a2d9f (diff)
downloadtelepathy-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.py149
-rw-r--r--examples/python/callhandler.py107
-rw-r--r--examples/python/constants.py8
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