A new Jingle voice chat plugin for Spark

I recently started a project called jitsi-jingle primarily to add Jingle support to an audio-conferencing engine I was developing. It was also an opportunity to provide a replacement for the outdated smack jingle extension library (smackx-jingle) using the Jingle implementation of the active Jitsi project. This however turned out to be more challenging than it sounded as the OSGI dependecies in Jitsi and the internal abstraction model to support multiple protocols like SIP and XMPP made the code extraction difficult. There is a soon to be released libjitsi which should make the task easier, but I am running out of valuable time (I do this stuff in my spare time), so I had to choose another option for my immediate first release.

http://openfire-candy.googlecode.com/files/Image7.jpg

Fortunately, there are alternatives. I had used phono from labs.voxeo.com on the inspired-social project. It has a Java applet which first started life as the IAX applet and is now the backbone to the phono java library. It has an excellent media engine and even supports Jingle internally, but from Javascript. I on the other hand, needed a simple Java Jingle library.

Enter mini-jingle from Thiago Rocha, the original developer of smackx-jingle (while he was at Jivesoftware) and the architect of Jingle Nodes. Project mini-jingle is a simple, but working Jingle implementation minus the media engine which makes it a very good fit with phono-java-audio. By adding support for basic raw RTP UDP packets, the standard PCMU (ulaw) voice codec and the Openfire jingle-nodes plugin, I now have a working Jingle library for Smack that should work most of the time either directly peer to peer or via a Jingle nodes media relay plugin for Openfire. There will always be the exception cases of where UDP packets are completely blocked by a firewall.

In order to test the library and put into practical use, I created a Spark plugin for it as a replacement for the old outdated Jingle plugin for simple voice calls between Spark users. When it is used with the Candy plugin for Openfire, it offers Spark users, group and private audio-conferencing from MUCs with Candy web clients as well. Just click on the telephone icon in the chat room toolbar.

If you intend to use it, pick it up from here and remember to delete the old jingle plugin in both the Spark folder and User data folders. Both won’t work at the same time

3 Likes

BRAVO!

Cant wait to try it out! Great work!

Hello Dele

Great work. It is good to see an update on the project. I tried the plugin with my PC and the PC of a co-worker and we have the icon to Call PC-to-PC but when we press it, nothing happens.

We both are on the same vlan

Here are the steps we did:

1- Removed the old jingle plugins

2- Copied the new jingle file

3- Restart Spark

Do we need anything else? Is jingle node required? Candy?

Thanks

Hi Nick,

Thanks

Check that you are using ver 0.3. You don’t need candy plugin for pc2pc calls. You also don’t need jingle relay nodes if both PCs are on the same LAN. I however found that IPv6 does cause problems on Windows 7, so I forced iPV4 by adding this to my Spark.vmoptions file

-Djava.net.preferIPv4Stack=true

Best thing is to check the Spark log files, especially output.log. On openfire, you should confirm the jingle messages if you run the xmldebugger plugin.

Hello Dele

We are using 0.3 on Windows XP

I see the plugins being loaded correctly in the logs but I see a java exception after I try to call.

Exception in thread “AWT-EventQueue-0” java.lang.NoSuchMethodError: org.jivesoftware.sparkplugin.OutgoingCall.handleOutgoingCall(Lorg/minijingle/xm pp/smack/RawUdpCallManager;Lorg/jivesoftware/spark/ui/ChatRoom;Ljava/lang/String ;)V

at org.jivesoftware.sparkplugin.JitsiJingle.placeCall(JitsiJingle.java:378)

at org.jivesoftware.sparkplugin.JitsiJingle$2.actionPerformed(JitsiJingle.java:334 )

at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)

at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)

at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)

at javax.swing.DefaultButtonModel.setPressed(Unknown Source)

at javax.swing.AbstractButton.doClick(Unknown Source)

at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)

at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)

at java.awt.Component.processMouseEvent(Unknown Source)

at javax.swing.JComponent.processMouseEvent(Unknown Source)

at java.awt.Component.processEvent(Unknown Source)

at java.awt.Container.processEvent(Unknown Source)

at java.awt.Component.dispatchEventImpl(Unknown Source)

at java.awt.Container.dispatchEventImpl(Unknown Source)

at java.awt.Component.dispatchEvent(Unknown Source)

at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)

at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)

at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)

at java.awt.Container.dispatchEventImpl(Unknown Source)

at java.awt.Window.dispatchEventImpl(Unknown Source)

at java.awt.Component.dispatchEvent(Unknown Source)

at java.awt.EventQueue.dispatchEvent(Unknown Source)

at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEvents(Unknown Source)

at java.awt.EventDispatchThread.pumpEvents(Unknown Source)

at java.awt.EventDispatchThread.run(Unknown Source)

Output.log:

Found codec SPEEX 16000 103 20 8589934592

Found codec g722 8000 9 20 4096

Found codec SPEEX 8000 102 20 512

Found codec PCMU 8000 0 20 4

Found codec PCMA 8000 8 20 8

Found codec GSM 8000 3 20 2

Found codec telephone-event 8000 101 0 0

windows xp

makeCall: XXXXX@XXXXXX/Spark 2.6.3

Fetching xmpp server jingle node relay channel

Found jingle relay node channel xx.xx.xxx.xx 31824 31826

makeCall: XXXXX@XXXXXX/Spark 2.6.3

Fetching xmpp server jingle node relay channel

Found jingle relay node channel xx.xx.xx.xx 49770 49772

Nothing else

Very strange error

Exception in thread “AWT-EventQueue-0” java.lang.NoSuchMethodError: org.jivesoftware.sparkplugin.OutgoingCall.handleOutgoingCall(Lorg/minijingle/xm pp/smack/RawUdpCallManager;Lorg/jivesoftware/spark/ui/ChatRoom;Ljava/lang/Strin g ;)V

No clues **
**

Which version of java do you use?

The one bundled with Spark 2.6.3

hello, someone can help me to use this plugin?

I try to use, but it dont work. I dont know what plugins i can have in my serv. Here is my list of plugins on server openfire:

broadcast 1.8.2

client Control 1.1.0

Clustering Plugin 1.2.0

Countent Filter 1.6.1

Email Listener 1.0.2

Fastpath Service 4.2.0

Jingle Nodes Plugin 0.0.3

Monitoring Service 1.2.0

MotD 1.0.4

Packet Filter 3.0.1

Presence Service 1.5.0

Registration 1.5.0

Search 1.5.1

Subscription 1.2.2

User Import Export 2.3.0

User Service 1.3.2

On client, i try to use 2.5.8, 2.6.0, 2.6.3. When i open windows contact, dont have icon to call.

thanks

This looks like the same error Nick had.

Unfortunately, I can’t reproduce it. Are you sure you removed the old jingle.jar and folder from both Spark program and user data folders.

On my xp pc, that is C:\Program Files\Spark\plugins and C:\Documents and Settings\xxxxxxx\Application Data\Spark\plugins. It will be different for Windows 7 64 bit

That did the trick Dele!!

After removing the jingle folder in the user data folder it started working. Might be something useful to add in the installation procedure as not all of us are familiar with the way spark save things in the user profile.

Thanks again!!

You are welcome

Hey Dele,

Congrats for your ongoing efforts on this!

In case you haven’t noticed, I’ve just posted a note about our libjitsi releast, that we believe could fit this project very well:

http://community.igniterealtime.org/blogs/ignite/2012/03/17/jitsi-jingle-and-ope nfirejs#comment-7599

Drop us a note if you have any questions!

Cheers,

Emil

Hi Dele,

I want to use ICE-UDP transport, Is there anyway I can change transport method?

Now that libjitsi is implemented, is there a plan to port jitsi-jingle to use libjitsi? Is it better to use libjitsi instead of jitsi-jingle?

I started on migrating the jitsi-jingle Spark plugin code to use libjitsi when it first went into beta, but I stopped when I discovered it would require changes to Spark beyond the plugin.

Giving Spark a new audio/video using libjitsi would be best done by the Spark development team who can incorporate the Spark code base change required to make it work.

If jitsi-jingle plugin works for you, then keep on using it as I plan to add webrtc support as soo as it become stable.

Looking at this some more, I have some concerns:

  • I can’t figure out how to use this in spark (I’ve never used spark before, it seems you need to understand the plugin structure). This doesn’t bother me too much, it just means I can’t give it a quick test.

  • More importantly, It seems to depend on minijingle. MiniJingle says “Currently there is no goal for now to support ICE” which is, to me, a very important goal. Do I understand correctly that this plugin won’t do ICE?

  • Are there some “getting started” docs for programmers that I’m missing? For example, what steps do I take to setup an A/V chat between two users who are already connected via smack? It would be great if I could, for example, use a library like https://github.com/sarxos/webcam-capture.

Note that both ICE and platform specific video capture and rendering are supported by libjitsi

Thanks Emil. From the libjitsi sample code and doc page it looks like Video capture and RTP (as well as codecs) are supported, but I did not get any sense that ICE was supported. Indeed, I downloaded the source, and I see that ice4j is in there. It seems like libjitsi is what I want, assuming I have an easy way to setup a jingle session as well.

In response to my original comment, after taking a closer look at the source of jitsi-jingle, it seems to me that jitsi-jingle is really a wrapper around minijingle for the purpose of making a spark plugin (for spark end users), not for the purpose of replacing smackx-jingle (for developers).

It will be up to the using application to implement the actual signalling and control ice4j but you could then use the resulting connection with libjitsi.

This is what we do with Jitsi so you may want to have a look there.

(Also, questions on the subject are welcome on the Jitsi dev list).

Cheers,

Emil