Jingle: another farsight function wrapped + start using farsight in jingle.py
This commit is contained in:
parent
5fce20024c
commit
394c544571
|
@ -84,6 +84,64 @@ static PyObject* _wrap_farsight_stream_get_local_codecs(PyGObject *self)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
%%
|
%%
|
||||||
|
override farsight_stream_get_native_candidate kwargs
|
||||||
|
static PyObject* _wrap_farsight_stream_get_native_candidate(PyGObject *self,
|
||||||
|
PyObject *args,
|
||||||
|
PyObject *kwargs)
|
||||||
|
{
|
||||||
|
static char* kwlist[] = {"candidate_id", NULL};
|
||||||
|
char* candidate_id;
|
||||||
|
GList* list;
|
||||||
|
FarsightTransportInfo* data;
|
||||||
|
PyObject* ret;
|
||||||
|
PyObject* item;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &candidate_id))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
list = farsight_stream_get_native_candidate(FARSIGHT_STREAM(self->obj), candidate_id);
|
||||||
|
data = list->data;
|
||||||
|
|
||||||
|
ret = PyDict_New();
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "candidate_id", item=PyString_FromString(data->candidate_id));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "component", item=PyInt_FromLong(data->component));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "ip", item=PyString_FromString(data->ip));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "port", item=PyInt_FromLong(data->port));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "proto", item=PyInt_FromLong(data->proto));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "proto_subtype", item=PyString_FromString(data->proto_subtype));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "proto_profile", item=PyString_FromString(data->proto_profile));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "preference", item=PyFloat_FromDouble(data->preference));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "type", item=PyInt_FromLong(data->type));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "username", item=PyString_FromString(data->username));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
PyDict_SetItemString(ret, "password", item=PyString_FromString(data->password));
|
||||||
|
Py_DECREF(item);
|
||||||
|
|
||||||
|
g_list_free(list);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
%%
|
||||||
override farsight_stream_get_native_candidate_list noargs
|
override farsight_stream_get_native_candidate_list noargs
|
||||||
static PyObject* _wrap_farsight_stream_get_native_candidate_list(PyGObject *self)
|
static PyObject* _wrap_farsight_stream_get_native_candidate_list(PyGObject *self)
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,16 @@
|
||||||
import gajim
|
import gajim
|
||||||
import xmpp
|
import xmpp
|
||||||
|
|
||||||
|
# ugly hack
|
||||||
|
import sys, dl, gst
|
||||||
|
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)
|
||||||
|
import farsight
|
||||||
|
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_LOCAL)
|
||||||
|
FARSIGHT_MEDIA_TYPE_AUDIO=0
|
||||||
|
FARSIGHT_STREAM_DIRECTION_BOTH=3
|
||||||
|
FARSIGHT_NETWORK_PROTOCOL_UDP=0
|
||||||
|
FARSIGHT_CANDIDATE_TYPE_LOCAL=0
|
||||||
|
|
||||||
import meta
|
import meta
|
||||||
|
|
||||||
class JingleStates(object):
|
class JingleStates(object):
|
||||||
|
@ -68,6 +78,10 @@ class JingleSession(object):
|
||||||
'iq-error': [],
|
'iq-error': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# for making streams using farsight
|
||||||
|
self.p2psession = farsight.farsight_session_factory_make('rtp')
|
||||||
|
self.p2psession.connect('error', self.on_p2psession_error)
|
||||||
|
|
||||||
''' Middle-level functions to manage contents. Handle local content
|
''' Middle-level functions to manage contents. Handle local content
|
||||||
cache and send change notifications. '''
|
cache and send change notifications. '''
|
||||||
def addContent(self, name, content, initiator='we'):
|
def addContent(self, name, content, initiator='we'):
|
||||||
|
@ -146,10 +160,9 @@ class JingleSession(object):
|
||||||
name = content['name']
|
name = content['name']
|
||||||
|
|
||||||
|
|
||||||
def sessionInitiateCB(self, stanza):
|
def __sessionInitiateCB(self, stanza, jingle, error):
|
||||||
''' We got a jingle session request from other entity,
|
''' We got a jingle session request from other entity,
|
||||||
therefore we are the receiver... Unpack the data. '''
|
therefore we are the receiver... Unpack the data. '''
|
||||||
jingle = stanza.getTag('jingle')
|
|
||||||
self.initiator = jingle['initiator']
|
self.initiator = jingle['initiator']
|
||||||
self.responder = self.ourjid
|
self.responder = self.ourjid
|
||||||
self.jid = self.initiator
|
self.jid = self.initiator
|
||||||
|
@ -173,6 +186,9 @@ class JingleSession(object):
|
||||||
|
|
||||||
self.state = JingleStates.pending
|
self.state = JingleStates.pending
|
||||||
|
|
||||||
|
def on_p2psession_error(self, *anything):
|
||||||
|
print "Farsight session error!"
|
||||||
|
|
||||||
''' Methods that make/send proper pieces of XML. They check if the session
|
''' Methods that make/send proper pieces of XML. They check if the session
|
||||||
is in appropriate state. '''
|
is in appropriate state. '''
|
||||||
def __makeJingle(self, action):
|
def __makeJingle(self, action):
|
||||||
|
@ -358,18 +374,44 @@ class JingleVoiP(object):
|
||||||
__metaclass__=meta.VerboseClassType
|
__metaclass__=meta.VerboseClassType
|
||||||
def __init__(self, session, node=None):
|
def __init__(self, session, node=None):
|
||||||
self.session = session
|
self.session = session
|
||||||
|
self.codecs = None
|
||||||
|
|
||||||
if node is None:
|
#if node is None:
|
||||||
self.audio = JingleAudioSession(self)
|
# self.audio = JingleAudioSession(self)
|
||||||
else:
|
#else:
|
||||||
self.audio = JingleAudioSession(self, node.getTag('content'))
|
# self.audio = JingleAudioSession(self, node.getTag('content'))
|
||||||
self.transport = JingleICEUDPSession(self)
|
#self.transport = JingleICEUDPSession(self)
|
||||||
|
self.setupStream()
|
||||||
|
|
||||||
def toXML(self):
|
def toXML(self):
|
||||||
''' Return proper XML for <content/> element. '''
|
''' Return proper XML for <content/> element. '''
|
||||||
return xmpp.Node('content',
|
return xmpp.Node('content',
|
||||||
attrs={'name': self.name, 'creator': self.creator, 'profile': 'RTP/AVP'},
|
attrs={'name': self.name, 'creator': self.creator, 'profile': 'RTP/AVP'},
|
||||||
payload=[self.audio.toXML(), self.transport.toXML()])
|
payload=[
|
||||||
|
xmpp.Node(xmpp.NS_JINGLE_AUDIO+' description', payload=self.getCodecs()),
|
||||||
|
xmpp.Node(xmpp.NS_JINGLE_ICE_UDP+' transport')
|
||||||
|
])
|
||||||
|
|
||||||
|
def setupStream(self):
|
||||||
|
self.p2pstream = self.session.p2psession.create_stream(FARSIGHT_MEDIA_TYPE_AUDIO, FARSIGHT_STREAM_DIRECTION_BOTH)
|
||||||
|
self.p2pstream.set_property('transmitter', 'libjingle')
|
||||||
|
self.p2pstream.connect('error', self.on_p2pstream_error)
|
||||||
|
self.p2pstream.connect('new-active-candidate-pair', self.on_p2pstream_new_active_candidate_pair)
|
||||||
|
self.p2pstream.connect('codec-changed', self.on_p2pstream_codec_changed)
|
||||||
|
self.p2pstream.connect('native-candidates-prepared', self.on_p2pstream_native_candidates_prepared)
|
||||||
|
self.p2pstream.connect('state-changed', self.on_p2pstream_state_changed)
|
||||||
|
self.p2pstream.connect('new-native-candidate', self.on_p2pstream_new_native_candidate)
|
||||||
|
self.p2pstream.prepare_transports()
|
||||||
|
|
||||||
|
def on_p2pstream_error(self, *whatever): pass
|
||||||
|
def on_p2pstream_new_active_candidate_pair(self, *whatever): pass
|
||||||
|
def on_p2pstream_codec_changed(self, *whatever): pass
|
||||||
|
def on_p2pstream_native_candidates_prepared(self, *whatever): pass
|
||||||
|
def on_p2pstream_state_changed(self, *whatever): pass
|
||||||
|
def on_p2pstream_new_native_candidate(self, *whatever): pass
|
||||||
|
def getCodecs(self):
|
||||||
|
codecs=self.p2pstream.get_local_codecs()
|
||||||
|
return (xmpp.Node('payload', attrs=a) for a in codecs)
|
||||||
|
|
||||||
class ConnectionJingle(object):
|
class ConnectionJingle(object):
|
||||||
''' This object depends on that it is a part of Connection class. '''
|
''' This object depends on that it is a part of Connection class. '''
|
||||||
|
@ -428,5 +470,5 @@ class ConnectionJingle(object):
|
||||||
def startVoiP(self, jid):
|
def startVoiP(self, jid):
|
||||||
jingle = JingleSession(self, weinitiate=True, jid=jid)
|
jingle = JingleSession(self, weinitiate=True, jid=jid)
|
||||||
self.addJingle(jingle)
|
self.addJingle(jingle)
|
||||||
jingle.addContent('voice', JingleVoiP())
|
jingle.addContent('voice', JingleVoiP(jingle))
|
||||||
jingle.startSession()
|
jingle.startSession()
|
||||||
|
|
Loading…
Reference in New Issue