Video Conferencing in HTML5: WebRTC via Web Sockets

A bit over a week ago I gave a presentation at Web Directions Code 2012 in Melbourne. Maxine and John asked me to speak about something related to HTML5 video, so I went for the new shiny: WebRTC – real-time communication in the browser.

Presentation slides

I only had 20 min, so I had to make it tight. I wanted to show off video conferencing without special plugins in Google Chrome in just a few lines of code, as is the promise of WebRTC. To a large extent, I achieved this. But I made some interesting discoveries along the way. Demos are in the slide deck.

UPDATE: Opera 12 has been released with WebRTC support.

Housekeeping: if you want to replicate what I have done, you need to install a Google Chrome Web Browser 19+. Then make sure you go to chrome://flags and activate the MediaStream and PeerConnection experiment(s). Restart your browser and now you can experiment with this feature. Big warning up-front: it’s not production-ready, since there are still changes happening to the spec and there is no compatible implementation by another browser yet.

Here is a brief summary of the steps involved to set up video conferencing in your browser:

  1. Set up a video element each for the local and the remote video stream.
  2. Grab the local camera and stream it to the first video element.
  3. (*) Establish a connection to another person running the same Web page.
  4. Send the local camera stream on that peer connection.
  5. Accept the remote camera stream into the second video element.

Now, the most difficult part of all of this – believe it or not – is the signalling part that is required to build the peer connection (marked with (*)). Initially I wanted to run completely without a server and just enter the remote’s IP address to establish the connection. This is, however, not a functionality that the PeerConnection object provides [might this be something to add to the spec?].

So, you need a server known to both parties that can provide for the handshake to set up the connection. All the examples that I have seen, such as https://apprtc.appspot.com/, use a channel management server on Google’s appengine. I wanted it all working with HTML5 technology, so I decided to use a Web Socket server instead.

I implemented my Web Socket server using node.js (code of websocket server). The video conferencing demo is in the slide deck in an iframe – you can also use the stand-alone html page. Works like a treat.

While it is still using Google’s STUN server to get through NAT, the messaging for setting up the connection is running completely through the Web Socket server. The messages that get exchanged are plain SDP message packets with a session ID. There are OFFER, ANSWER, and OK packets exchanged for each streaming direction. You can see some of it in the below image:

WebRTC demo

I’m not running a public WebSocket server, so you won’t be able to see this part of the presentation working. But the local loopback video should work.

At the conference, it all went without a hitch (while the wireless played along). I believe you have to host the WebSocket server on the same machine as the Web page, otherwise it won’t work for security reasons.

A whole new world of opportunities lies out there when we get the ability to set up video conferencing on every Web page – scary and exciting at the same time!

85 thoughts on “Video Conferencing in HTML5: WebRTC via Web Sockets

  1. Thank you,silvia.
    Although change some things, but almost the same process.
    I have made a new example,
    But I don’t know when to create PeerConnection send data do? What is the use?Data is like the as written.
    {“type”:”candidate”,”label”:”0″,”candidate”:”a=candidate:880637118 2 udp 2130714367 124.193.126.14 12495 typ host generation 0rn”}

  2. Hi,

    i’m experimenting your code Silvia but nothing works out.
    The server is running and it gets the peers connections but when it’s time to connect, nothing happens. All doors from router are open and firewall from computers don’t interfere.
    The code changes that i have made are the name of the PeerConnection object so it works with the actual implementation.
    So any idea?

    Thks

  3. The latest Chrome browser supports webkitPeerConnection00 which has different implementation than webkitPeerConnection in this example.

    We need to adapt the new ICE callback mechanism.

  4. Thank you.. I’ve made it working with both WebkitRTCPeerConnection & WebkitPeerConnection00 by adjusting the codes.

    Note: to have the best and most stable result, both clients should use the same Chrome version.

  5. @Tri Nugroho : Could you share the updated code for the WebkitRTCPeerConnection 🙂 Could save me some time understanding the changes in the API.

  6. First of all forgive my newbee question, I am trying to run locally the stand alone page When i try to start the websocket server i get the following error, I have apache running, tried some tests on node.js that worked so I am not sure what I m missing.
    ~/www$ node websocket-server.js
    module.js:340
    throw err; ^
    Error: Cannot find module ‘websocket’
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:362:17)
    at require (module.js:378:17)
    at Object. (/home/jordip/www/websocket-server.js:1:85)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)

  7. sudo npm link websocket, soleved this error, nevermind, i am trying to run it locally and on a android on bowser or opera12 mobile it says stream is not running yet (on bowser when i do start video a small blue interrogation button shows up), I am sure its my fault or its lack of suppot.

    thanks for the tutorial

  8. I am trying to implement one demo it is working properly on lan but when i am trying on iternet chat is working but video is not working it display black screen only plz tell me i am new one and it is argent. thank you in advance.

  9. @Silvia rtc.SERVER = {iceServers:[{url:”stun:stun.l.google.com:19302″}]};
    I used this line any changes plz tell me? And i have to setup my own ICE server or i can use google url?

  10. @Silvia so this lines rtc.SERVER = {iceServers:[{url:”stun:stun.l.google.com:19302″}]}; are perfect so the problem is may be hosting related and ICE Servers are TCP or UDP?

Leave a Reply

Your email address will not be published. Required fields are marked *