ginger's thoughts

Silvia's blog

Video Conferencing in HTML5: WebRTC via Socket.io

Posted in code,Digital Media,open codecs,Open Source,standards,Videos,WebRTC by silvia on the February 6th, 2013

Six months ago I experimented with Web sockets for WebRTC and the early implementations of PeerConnection in Chrome. Last week I gave a presentation about WebRTC at Linux.conf.au, so it was time to update that codebase.

I decided to use socket.io for the signalling following the idea of Luc, which made the server code even smaller and reduced it to a mere reflector:

 var app = require('http').createServer().listen(1337);
 var io = require('socket.io').listen(app);

 io.sockets.on('connection', function(socket) {
         socket.on('message', function(message) {
         socket.broadcast.emit('message', message);
     });
 });

Then I turned to the client code. I was surprised to see the massive changes that PeerConnection has gone through. Check out my slide deck to see the different components that are now necessary to create a PeerConnection.

I was particularly surprised to see the SDP object now fully exposed to JavaScript and thus the ability to manipulate it directly rather than through some API. This allows Web developers to manipulate the type of session that they are asking the browsers to set up. I can imaging e.g. if they have support for a video codec in JavaScript that the browser does not provide built-in, they can add that codec to the set of choices to be offered to the peer. While it is flexible, I am concerned if this might create more problems than it solves. I guess we’ll have to wait and see.

I was also surprised by the need to use ICE, even though in my experiment I got away with an empty list of ICE servers – the ICE messages just got exchanged through the socket.io server. I am not sure whether this is a bug, but I was very happy about it because it meant I could run the whole demo on a completely separate network from the Internet.

The most exciting news since my talk is that Mozilla and Google have managed to get a PeerConnection working between Firefox and Chrome – this is the first cross-browser video conference call without a plugin! The code differences are minor.

Since the specification of the WebRTC API and of the MediaStream API are now official Working Drafts at the W3C, I expect other browsers will follow. I am also looking forward to the possibilities of:

The best places to learn about the latest possibilities of WebRTC are webrtc.org and the W3C WebRTC WG. code.google.com has open source code that continues to be updated to the latest released and interoperable features in browsers.

The video of my talk is in the process of being published. There is a MP4 version on the Linux Australia mirror server, but I expect it will be published properly soon. I will update the blog post when that happens.

38 Responses to 'Video Conferencing in HTML5: WebRTC via Socket.io'

Subscribe to comments with RSS or TrackBack to 'Video Conferencing in HTML5: WebRTC via Socket.io'.


  1. on February 9th, 2013 at 6:23 am

    Hi,
    I am actually looking for video conferencing using HTML5. One to one is easy to implement using WebRTC. Is it possible to get atleast 1:N webcam video ( to simulate teaching on net ) ?
    1 –> teacher
    N –> Students who should be able to see teacher

    Cheers,
    Siddhartha

  2. Luigi said,

    on February 12th, 2013 at 5:33 am

    I am trying to run your demo on an online node.js server. If I try to estabilish a videochat within my network it works, but when I try to videochat with a friend in another network I see only a black screen for the receiver. Did you try a similar scenario? I think that thare are some problems with the NAT.

  3. silvia said,

    on February 12th, 2013 at 7:36 am

    Yes, for outside the network you need to use an ICE server. Try https://apprtc.appspot.com/ with your friend. If it works, you can add the ICE server into the peer connection setup.

  4. silvia said,

    on February 12th, 2013 at 7:40 am

    @Siddartha you can probably send your local video to many peers – just set up one PeerConnection per connect request.

  5. Luigi said,

    on February 13th, 2013 at 12:39 am

    @Silvia should I only put the address of the ICE server in this?
    var pc_config = {
    “iceServers” : ["stun.l.google.com:19302"]
    };

  6. Luigi said,

    on February 13th, 2013 at 3:07 am

    @Silvia I tried the apprtc.appspot.com with my friends using chromium and it doesn’t work; however it works in my local network.
    I tried to add an ICE server in your code but it doesn’t work for me (the ip address is from apprtc example)
    var pc_config = {
    “iceServers” : [{"url":"stun:23.21.150.121"}]
    };

    I can see the ICE messages in the console and I can also see the address of my remote friend, but I can’t see the remote video

  7. silvia said,

    on February 13th, 2013 at 2:02 pm

    @Luigi your friend must be using a modern version of Chrome, too (preferably a beta version). Try to get apprtc working first.

  8. Laks said,

    on February 15th, 2013 at 8:49 am

    I am able to successfully create webrtc video conference between two clients. But the remote videos on both the clients freeze after ~10 sec. Please suggest ways to overcome this problem.

  9. silvia said,

    on February 15th, 2013 at 10:55 am

    @Laks register a bug on chrome and provide details on how this is happening

  10. Neha said,

    on March 4th, 2013 at 8:40 pm

    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.

  11. John McLear said,

    on March 7th, 2013 at 11:48 am

    With regards to:

    io.sockets.on(‘connection’, function(socket) {
    socket.on(‘message’, function(message) {
    socket.broadcast.emit(‘message’, message);
    });
    });

    Is it a privacy/security issue to blindly broadcast all new connection messages to all other clients? I’m not sure what data is exposed but it seems kinda dangerous to me?

    Also something minor but your indentation is quirky, prolly just a typo :)

  12. silvia said,

    on March 8th, 2013 at 4:35 pm

    @John – sure is – that example was a quick and dirty hack to get the signalling working – I would not recommend using this in anger or in production!

  13. Tomas said,

    on March 14th, 2013 at 2:18 am

    Have you tried to interface between Firefox and Chrome? I have followed the guide on the WebRTC website to implement interoperability between the two with no avail. The code I am working from is: https://github.com/tomasbasham/SocialVidRTC/blob/master/javascript/main.js
    Do you have any insight?

  14. ray said,

    on March 16th, 2013 at 5:19 am

    I am getting this error.

    Uncaught TypeError: Cannot call method ‘createOffer’ of null

    I believe its the sessiondescription of function setLocalAndSendMessage is causing the error.

    Please if you have any suggestions

  15. silvia said,

    on March 16th, 2013 at 12:55 pm

    @ray what browser are you running?

  16. silvia said,

    on March 16th, 2013 at 12:56 pm

    @Tomas I’ve not been very successful with Firefox either, but apparently apprtc.appspot.com supports both.

  17. ray said,

    on March 16th, 2013 at 3:12 pm

    Im using the latest version of chrome.

  18. silvia said,

    on March 16th, 2013 at 3:37 pm

    @ray you’re trying to call createOffer() with a null function – did you define setLocalAndSendMessage() after createOffer()?

  19. ray said,

    on March 16th, 2013 at 3:48 pm

    First i have placed the “setLocalAndSendMessage()”, then “errorCallBack()” and followed by “mediaconstraint”

    Only after that
    peerConn.createOffer(setLocalAndSendMessage,
    errorCallback,
    mediaConstraints);

    Am i missing something ?

  20. silvia said,

    on March 16th, 2013 at 3:52 pm

    @ray s setLocalAndSendMessage(sessionDescription) setting the SDP for local and sending it to remote: peerConn.setLocalDescription(sessionDescription); ?
    Put a console.log into setLocalAndSendMessage on the sessionDescription so you can see what it contains.

  21. ray said,

    on March 16th, 2013 at 4:40 pm

    sessionDescription error
    console.log(“error check:” + peerConn.setLocalDescription.sessionDescription);

    Uncaught TypeError: Cannot read property ‘setLocalDescription’ of null

    And yes setLocalAndSendMessage(sessionDescription) is setting the SDP for both local and remote.

  22. ray said,

    on March 16th, 2013 at 5:04 pm

    Should my signaling channel be open before the call for createOffer() ?

  23. silvia said,

    on March 16th, 2013 at 5:17 pm

    @ray how much javascript programming have you done before? Your console.log should be inside the setLocalAndSendMessage function and should just print sessionDescription, not the function call. It also seems your peerConn object has not been set up yet. And yes, the first thing you need to do is opening the signalling channel.

  24. ray said,

    on March 16th, 2013 at 5:33 pm

    I have placed a logg once the channel is open.
    I get the createOffer error before the channel is open logg. Is there a way to first open the connection ?

    And thanks for all the replies. :D I know you have many other things to do. Much appreciated !

  25. silvia said,

    on March 16th, 2013 at 5:38 pm

    @ray your code sounds pretty messed up – I’m sorry I can’t help you more without seeing the code and blog comments are not the best way to get help. Ask on stackoverflow and put your code into a snippet sharer, see http://www.sitepoint.com/top-5-places-to-share-code-quickly/ .

  26. Akane Tech said,

    on March 21st, 2013 at 8:56 am

    It works like a charm. Thanks a lot silvia

    I made a small change, instead of using Node js, I used Java Websockets.

  27. silvia said,

    on March 21st, 2013 at 9:36 am

    @Akane Excellent! :-)

  28. hila said,

    on April 19th, 2013 at 1:56 am

    hi!

    i was trying your code. i installed nodejs and i am able to run the server(reflector.js).how ever i could not figure it out how the client side can be implemented in nodejs. i want it to give html page.
    i was trying it on local host first.
    can you please tell me how to integrate the client side with the server?

  29. silvia said,

    on April 19th, 2013 at 12:40 pm

    The client page that I am using is simply a HTML page. I didn’t serve it through the node server, but through a separate server – I’m using apache but any web server will do. If you want to use node to also serve the static page, you need to adapt reflector.js e.g. http://stackoverflow.com/questions/6084360/node-js-as-a-simple-web-server but listen on port 80 for that server.

  30. matt said,

    on May 6th, 2013 at 5:48 am

    hi silvia
    thanks so much for your post ! This helped me a lot to set up my first working example with webRTC. It feels like this is now a good starting point to begin to implement own ideas.

    cheers

  31. sola said,

    on May 13th, 2013 at 9:45 am

    hallo silvia,

    we have been trying running your code on this link : https://googledrive.com/host/0B_SthAHTAe0gTThIX1F0MU1HR00/index.html deploying the io server code on https://www.nodejitsu.com/‎ ‘s hosting platform ,but failing with errors ” Uncaught ReferenceError: io is not defined ”
    and ” Failed to load resource “, even being unable to see local video .
    any help then ? thanks a lot .

  32. silvia said,

    on May 13th, 2013 at 10:06 am

    @sola – that is a socket.io error. You should google for that. It means that your code cannot load the socket.io javascript library. You’re trying to load it from http://165.225.130.239:80/socket.io/socket.io.js , but it’s not there.

  33. hila said,

    on May 14th, 2013 at 9:24 pm

    HI silvia,
    Thanks a lot for your support. Your blog is very helpful.
    we successfully implemented your code and we are trying to learn by writing our own video conferencing application. I am new for java script and html. When we deploy your code(the one using socket.io) the video experienced a delay. Is it how it is expected to be or we have done something wrong in the deployment?
    Is there any drawbacks of signaling mechanism using web socket(socket.io) in comparison with the signaling mechanism using XHR and channel API?

  34. silvia said,

    on May 16th, 2013 at 9:12 am

    @hila Any delays in the video have nothing to do with the signaling mechanism, because the video will flow directly from browser to browser once the connection is set up. Thus, it depends on the direct connection between the two browsers and the available bandwidth and processing power of the end points. You can test that by setting up the connection and then taking down the signalling server – your video should continue streaming.

  35. suhail said,

    on May 19th, 2013 at 10:01 pm

    hi
    i am new to webRTC. i read your post i got many things clear, but i could not get the source code. where i can get source code with proper instructions to run.
    cheers

  36. silvia said,

    on May 20th, 2013 at 8:17 am

    @suhail The source code is in the presentations. The presentations are HTML5.

  37. suhail said,

    on May 21st, 2013 at 3:30 am

    @Siddartha any proress you can share on 1 to N broadcast.
    cheers

  38. sola said,

    on May 23rd, 2013 at 8:45 am

    Hallo Silvia,

    am trying to impliment 3-party chat locally by slightly modifying your code.
    In doing so,I am able to see three videos on two tabs,whereas on the third one, only the local video; the other two being “black screen” . Seeing the console,I can only suspect that it might be a code-ordering problem if it should work this way.On the code,i simply added only a third video element, and include another event listening line for the second remote video :{
    peerConn.addEventListener(“addstream”, onRemoteStreamAdded1, false);
    peerConn.addEventListener(“addstream”, onRemoteStreamAdded2, false);
    peerConn.addEventListener(“removestream”, onRemoteStreamRemoved1, false);
    peerConn.addEventListener(“removestream”, onRemoteStreamRemoved2, false); }
    thanks a lot.

Leave a Reply