Join multi-user chat with node-xmpp-client


XEP-0045 defines the XMPP protocol extensions required to join multi-user chat rooms, and receive and post messages. In this post, I use the node-xmpp-client library to join a multi-user chat room. Messages sent to the chat room are received but are not parsed.

node-xmpp-client can be installed using npm, as follows

npm i node-xmpp-client

Here’s a script that creates a new XMPP client, and sends a presence stanza to the XMPP server, to join a chat room

var Client = require("node-xmpp-client")

var jid = "user@domain"
var password = "password"
var room = "room@domain/nickname"

var client = new Client({
    jid: jid,
    password: password,
    preferred: "PLAIN"
})

client.on("online", function() {
    console.log("online")
    console.log("joining chat room")
    var stanza = new Client.Stanza("presence", {from: jid, to: room})
    client.send(stanza)
})

client.on("stanza", function(stanza) {
    console.log("Incoming stanza: ", stanza.toString())
})

client.on("error", function(e) {
    console.log(e);
})

process.on("SIGINT", function(code) {
    console.log("leaving chat room")
    var stanza = new Client.Stanza("presence", {from: jid, to: room, type: "unavailable"})
    client.send(stanza)

    setTimeout(function() {
        process.exit()
    }, 1000);
})

If you don’t specify a unique nickname, the XMPP server will likely reject the request to join the room. Modify the above script appropriately, save, and invoke node to execute it

node muc.js

If you get any errors, try setting the DEBUG environment variable as follows, and try again

export DEBUG=*

Build FreeSWITCH from source on Ubuntu 12.04


FreeSWITCH has a fairly detailed Wiki page on download and installation. This post cuts to the chaff.

Execute the following commands from terminal in the order specified. You should be fine doing it in your home folder.

sudo apt-get install git-core build-essential autoconf automake libtool libncurses5 libncurses5-dev make libjpeg-dev pkg-config unixodbc unixodbc-dev zlib1g-dev libcurl4-openssl-dev libexpat1-dev libssl-dev libtiff4-dev libx11-dev unixodbc-dev zlib1g-dev libzrtpcpp-dev libasound2-dev libogg-dev libvorbis-dev libperl-dev libgdbm-dev libdb-dev python-dev uuid-dev bison autoconf g++ libncurses-dev speex libspeexdsp-dev libedit-dev libpcre3-dev

git clone https://freeswitch.org/stash/scm/fs/freeswitch.git

cd freeswitch

./bootstrap.sh

./configure

make

sudo make install cd-sounds-install cd-moh-install

Configuration files are located under /usr/local/freeswitch/conf, if you want to edit any.

Execute FreeSWITCH as superuser thus

sudo /usr/local/freeswitch/bin/freeswitch -nc

Remove -nc option to run in console mode.

To stop FreeSWITCH

sudo /usr/local/freeswitch/bin/freeswitch -stop

If you get “libspandsp.a: No such file or directoryerror when executing make after a make clean, execute the following commands and resume make.

cd libs/spandsp
make clean
make
cd ../..

To ensure a clean build, use git clean -f -x instead of make clean.

Kudos: Henrique Borges, Vitória Vasconcelos

VoIP calls from the browser using WebRTC and FreeSWITCH


There was a time when making phone calls from the browser would have meant installing a native extension. Thanks to WebRTC, we can now make phone calls from the browser. This post is my recent experiment with doing exactly that, using readily available open source components.

Let’s start by installing FreeSWITCH (FS). I am assuming a Windows based setup but Linux or Mac should also work. Once you have FS installed (I’m on 1.5.8b+git~20131213T181356Z~87751f9eaf~64bit) and sanity-tested, you’ll need to enable websocket support. This can be done by editing the configuration file <FS folder>\conf\sip_profiles\internal.xml so the the following line is uncommented

    <param name="ws-binding"  value=":5066"/>

You can also use secure websockets, I’ll leave that setup for a future exercise. At this point, restart the FreeSWITCH service.

The next step is to find a suitable browser-based SIP client. Luckily, there is exactly such a client provided by jsSIP, and you don’t even have to install it. Fire up your browser (I’m using the latest version of Chrome) and access that URL. Assuming that your IP address is 10.211.55.3, this is the information you can provide

Name: Your Name
SIP URI: sip:1000@10.211.55.3
SIP Password: 1234
WS URI: ws://10.211.55.3:5066

Hit ENTER and you’ll be taken to the dialer. Dial 9195 to make a call, FS will relay your voice back to you, after a five second delay. You’ll need to allow the browser to use your microphone.

sipML5 is another nice alternative to jsSIP. You’ll need to edit the WebSocket Server URL in expert mode.

Happy RTCing!

FFmpeg on Windows


A quick post to document how audio and video can be captured on Windows using FFmpeg into different container formats like MKV, MP4 and WebM.

List DirectShow devices

The following command lists the names of audio and video devices currently installed

ffmpeg -list_devices true -f dshow -i dummy

Capture from webcam and microphone

With container format mkv the default video codec is H.264 and audio codec is Vorbis. With the mp4 container format (change output.mkv to output.mp4) the video codec is H.264 and audio code is MPEG AAC. With the webm container format the video codec is the Google/On2 VP8 and audio codec is Vorbis.

ffmpeg -f dshow -i video="video device name":audio="audio device name" -r 25 -s 320x240 output.mkv

I added the -s (video size) and -r (video frame rate) options because with mkv and mp4 I was getting lots of dropped frames.

References
ffmpeg directshow

Video streaming using jpeg encoding


Here’s an example of a GStreamer pipeline that produces a less CPU intensive and low latency video stream using jpeg encoding. Audio in vorbis is muxed, along with the video, into a matroska stream. I have tested this on Ubuntu 11.04.

gst-launch v4l2src decimate=3 ! video/x-raw-yuv,width=320,height=240 ! jpegenc ! queue2 ! m. alsasrc device=hw:2,0 ! audioconvert ! vorbisenc ! queue2 ! m. matroskamux name=m streamable=true ! tcpclientsink host=localhost port=9002

A server can stream it with a content type of video/x-matroska. Most browsers will not play it directly, but external plugins can be used.

Adjusting attributes of v4l2src and vp8enc elements for video conferencing


Video conferencing is real time in nature. The default encoding parameters of vp8enc element of GStreamer are not always appropriate. Let us start with the following pipeline

gst-launch v4l2src ! video/x-raw-rgb,width=320,height=240 ! ffmpegcolorspace ! vp8enc ! vp8dec ! ffmpegcolorspace ! ximagesink sync=false

The CPU usage, on a PandaBoard with Ubuntu 11.04, is close to 100% (since there are 2 cores, that translates to 50%).

Now, modify the pipeline as follows

gst-launch v4l2src decimate=3 ! video/x-raw-rgb,width=320,height=240 ! ffmpegcolorspace ! vp8enc speed=2 max-latency=2 quality=5.0 max-keyframe-distance=3 threads=5 ! vp8dec ! ffmpegcolorspace ! ximagesink sync=false

Note the decimate attribute of the v4l2src element, and the attributes speed, max-latency, max-keyframe-distance, threads and quality of the vp8enc element. With these changes the CPU usage drops to 40% and the video playback is more real time.

HP sells Visual Collaboration business; Google announces WebRTC


In two unrelated events, HP has sold its Visual Collaboration business to Polycom, and Google has announced the WebRTC initiative. Polycom has also announced an industry wide initiative called The Open Visual Communications Consortium, whereas the approach that Google is taking is to support synergistic initiatives from the W3C, IETF and the WHATWG. Google also released IP they acquired from Global IP Solutions under an open project.