Hello Ryan,
First, I am sorry it took me so long to answer your mail! I
know how
frustrating this could be so I apologize.
I've been reading through your blog and saw that you've
become very
well acquainted with our architecture, which is quite
impressive since
there is no documentation whatsoever on call management.
more inline:
Ryan Ricard wrote:
> I have a basic skeleton of the Mailbox service
implemented as a new OSGI
> bundle, and I'm attempting to get it to play an
outgoing message through
> a SendStream. The problem is I haven't found a way of
getting at the
> CallSession or RTPManager to create a new Sendstream.
Is there a way to
> get the CallSession associated with a particular Call
object? >
The bad news is that there is none. SendStream-s are a
JMF-specific
concept so they shouldn't be used outside the service
implementation.
The good news, however, is that your approach is right and
all we need
to do is devise a way for you to feed your pre-recorded data
to the
media service, and tell it which call it is supposed to go
to. We'll get
to this in a minute.
> I notice
> that CallSipImpl has a getMediaCallSession() method,
but when I try to
> cast a Call object to a CallSipImpl, I get a
NoClassDefFoundError at
> runtime, presumably because CallSipImpl is not one of
the import
> packages in my bundle's manifest.
Everything that ends with Impl ... or rather, all the stuff
located
under the net.java.sip.communicator.impl package (and its
sub-packages)
is not to be used by anyone else but the bundle that it
belongs to. You
only have the "right" to use functionality
(interfaces or classes)
defined under the net.java.sip.communicator.service package
tree.
So, not only is CallSipImpl not imported by your manifest
(which is
indeed part of the reason why you can't use it) but it's not
even
exported by the sip provider since it is an implementation
specific class.
Think of it this way. If you decided to export the
impl.protocol.sip
package in the sip provider bundle and use the CallSipImpl
class, all
the code where you reference this class will be SIP specific
and will
not work for say Jabber the day when we implement jingle.
> Is there another way of getting at the
> CallSession associated with a particular call?
>
> Also, what is the preferred method of obtaining the
currently active
> CallManager object?
do you mean
net.java.sip.communicator.*impl*.gui.main.call.CallManager
;) ?
The preferred method is not to obtain a currently active
instance since
it is an implementation specific class and any code using it
would break
the day we decide to switch to another UI implementation or
modify the
one we're using now.
> Sorry if I'm being less than clear. I wrote up a bit
more about my
> current situation on the project blog
> <http://sc-avmailbox.blogspot.c
om/2007/05/education-but-not-much-in-way-of.html>,
> so that might be more enlightening
You are very clear and as I said - you're headed in the
right direction.
We only need to figure out what is the best way of extending
the
architecture of SIP Communicator so that it would allow what
you are
trying to achieve.
Here's how things currently happen. Whenever an incoming
call is
received, the protocol provider would create a Call and a
CallParticipant. It will then fire the corresponding events
so that the
GUI would alert the user of the incoming call. When the user
clicks on
the answer buttonm, the GUI would call the
answerCallParticipant()
method. It is at this point (i.e. when
answerCallParticipant() is
invoked) that the SIP provider would actually create and
initialize the
media CallSession. It is also at this point that the send
streams would
be crated and initialized, though not started (that would
only happen
when the call state changes to CONNECTED).
In the voice mail case it would be your plugin that would be
calling the
answerCallParticipant() method so all you need to do is make
sure that
before you invoke it you tell the media service that for
that particular
call it should use your own data source and not the default
one
(microphone and webcam).
The media service does not allow this currently so you have
authorization to add whatever's missing.
Now we only need to figure out the best way for you to tell
the media
service where to look for data. I guess we'd most probably
need a method
which would look sth like:
MediaService
{
...
/**
* We could use this one to set a data source globally
- for all
* sessions. The thing is that if we use it for a
mailbox plugin
* You have to remember to put back the default data
source after
* you are done with the current call.
*
* param dataSource
* and I guess you could set back the default
dataSource
* by passing a null pointer here ... or
something like
* this.
*/
public void setDefaultDataSource( DataSource
dataSource );
<or>
/**
* ... we could also specify a media file (or better
yet - a URL)
* containing recorded audio video data and let the
media service
* create a data source from it.
*
* param dataSourceFile
* again, you should preview the possibility
to disable a
* source that we have previously set ( again
- passing a
* null pointer seems like a good way to go.
*/
public void setDefaultDataSource( URL dataSourceFile
);
<or>
/**
* It might also be a good idea to allow specifying a
custom data
* source for one call only. This could be useful if a
user would
* not take an incoming call (e.g. from an ex
girfriend) and
* receive a new, more important one (e.g. from the
super sexy
* neighbor) that he would want to answer while the
mailbox message
* is still being played on the first one.
*
* param call would be the call that we'd like dSource
to be used
* for. We'll be using the default data
source for all
* other calls.
* param dataSource the dataSource containing your
message media.
*/
public void setDataSourceForCall( Call call,
DataSource dSource );
<or>
/**
* ... ok I think you got the point, so I guess I
don't need to
* go into details for this one.
*/
public void setDataSourceForCall( Call call, URL
dataSourceFile );
...
.... oooor .... maybe we can (should?) have all of the
above?
}
The tricky part is that the DataSource interface that I've
been passing
as a param in the above methods MUST NOT be the JMF
DataSource interface
since it is specific to the current implementation of the
media service
but would not work with an FFMPEG one for example, so we'd
need to
define one of our own that users of the service would have
to implement
....
I am wondering whether this is really necessary though since
it adds
quite a lot of complexity while passing a URL around is
quite enough. I
don't see what media source would possibly not be
representable by a
URL. (So I guess I'd vote for only keeping methods 2 and 4
but I left
them all as it would mainly be your call).
OK, I think that's all I have to say on this. Hope I am
making sense
(don't hesitate to ask if I am not!)
Cheers
Emil
------------------------------------------------------------
---------
To unsubscribe, e-mail: dev-unsubscribe sip-communicator.dev.java.net
For additional commands, e-mail: dev-help sip-communicator.dev.java.net
|