Tutorial: WebRTC with HTML5 and Javascript

Updated: 7/24/2012

WebRTC is a new technology that brings real-time communication capabilities to your browser without the need for plugins. In this tutorial you'll learn how to set up a webcam stream and copy images from it to an HTML5 canvas element.

The first thing you need to know about this technology is that it is not readily available just yet. To get this to work, you'll need to download the developer build of Google Chrome, called Canary. Once Canary is installed, open it up and type "about:flags" in the address bar. Find the MediaStream option and click Enable; you'll need to close and reopen the browser for this change to take effect.

Note: this flag no longer exists in the latest version of Canary, MediaStream is enabled by default.

To test if it's working (and to preview what we will be building here), use Canary and head here to see if the stream comes through. Note that you will be prompted to allow access to your camera.

With MediaStream enabled, we can now move onto the code. We'll begin by laying out a simple HTML file.

<!DOCTYPE html>

<html>

    <head>
        <title>webRTC Test</title>
    </head>

    <script type="text/javascript">

    </script>

    <body onload="init();" style="background-color:#ababab;" >
        <div style="width:352px; height:625px; margin:0 auto; background-color:#fff;" >
            <div>
	            <video id="camFeed" width="320" height="240" autoplay>
		        </video>
	        </div>

            <div>
                <canvas id="photo" width="320" height="240">
                </canvas>
            </div>

            <div style="margin:0 auto; width:82px;">
                <input type="button" value="Take Photo" onclick="takePhoto();">
            </div>
        </div>

    </body>
</html>

As you can see, we've got a fairly standard HTML document here. At the top we've got an empty script block which we'll be filling out in just a bit. I've just inlined the css styles for this example because there isn't much to it. When the body tag loads, it will call a function, init, which we haven't written just yet. The init function will be responsible for determining if the user's browser supports webRTC or not.

Within the body we've got a simple wrapper div that holds all the content. Inside there we have another div that contains a video tag. The video tag is where the webcam feed will be rendered.

Following the div containing the video tag is another div. This one holds a canvas element. This canvas element is where we will display the photo that gets taken. It is important to note that I set the width and height attributes of this tag directly and not through css. This is because HTML5 will actually scale and stretch a canvas element when the width and height are set using css. Some people think this is a nice feature; I just think it's stupid, but that's how it is.

After closing the div containing the canvas element, we create one more div. This one holds a standard button that when clicked will call a javascript function, takePhoto. This method will be responsible for rendering the photo in the canvas element.

It is now time to get to the javascript. Add the following code inside the empty script block we created above.

function init()
{
    if(navigator.webkitGetUserMedia)
    {
        navigator.webkitGetUserMedia({video:true}, onSuccess, onFail);
    }
    else
    {
        alert('webRTC not available');
    }
}
		
function onSuccess(stream)
{
    document.getElementById('camFeed').src = webkitURL.createObjectURL(stream);
}
		
function onFail()
{
    alert('could not connect stream');
}

There really isn't a whole lot to it. In the init function we first check to see that the browser supports webRTC. If not, we throw up an alert letting the user know that it is not supported. If it is, we use a call to webkitGetUserMedia to get things going. We tell it we're using video and then give it a function to call upon successful stream creation and another to call if it fails.

Note that the webkit vendor prefix may or may not be necessary depending on the browser (Opera, for example). Once standardized, the method should become just: getUserMedia. However, it isn't there yet and because we're using Canary, we need it.

In the onFail function, we just send an alert to the user letting them know that something went wrong and we were unable to connect a stream to the video tag. In onSuccess, we receive a stream as an argument. We then create an object URL for the stream and apply it to the src property of our video tag.

We're just about done now. All that's left to do is write the takePhoto function to copy an image to the canvas element. Add the following method just after the onFail function we created above.

function takePhoto() 
{
    var c = document.getElementById('photo');
    var v = document.getElementById('camFeed');
    c.getContext('2d').drawImage(v, 0, 0, 320, 240);
}

It's that easy! We just grab a reference to our canvas tag and also to our video tag. We then get a 2D rendering context from the canvas and call the drawImage function. We tell it what to draw, the video element, where to draw it (0,0) and at what size (320, 240).

That's it; we're done. This works...but probably not if you try running it locally! This is due to a security restriction in Canary. You can push the file to a web server and it should run fine as long as you enabled the MediaStream flag earlier (with Canary). When you navigate to the page you should be prompted to allow access to your camera. Obviously you should allow it if you want to see this working!

If you don't have access to a web server, don't worry, you can still run the file locally too. You just have to run Canary with another flag set: --allow-file-access-from-files. You can do this by opening a command prompt window and navigating to the directory where Canary was installed. On my Windows 7 machine, the command looks like this:

cd C:\Users\USERNAME\AppData\Local\Google\Chrome SxS\Application

Then just launch the canary exe with the following command:

chrome.exe --allow-file-access-from-files

When you open the file locally, you'll know it's not going to work if you see: "null wants to use your camera." If instead you see "file:// wants to use your camera" you're in good shape.

It's worth pointing out that while this functionality is new to Chrome, it was actually available last year in Opera's development browser.

That's all there is to it; I hope you had fun with this tutorial and I encourage you to keep an eye on webRTC in the future. I imagine it should be readily available on all major browsers by the year's end, but we'll have to wait and see.

Bookmark and Share

13 Responses to “Tutorial: WebRTC with HTML5 and Javascript”

  1. Joan says:

    wow, this one is good! gonna use for my own side project, BIG thanks :)

  2. amar says:

    null wants to use your camera what is that means plz help me at this email ASAP….
    Thanks…..

  3. Rhuno says:

    Hey amar, if you have a webcam hooked up and you’re seeing null, you’re probably trying to run it locally and have not set the correct flags in Canary. This is covered near the end of this tutorial, but what you need to do is launch Canary from the command line with the following option set: –allow-file-access-from-files.

    You can also try uploading your file to a webserver and running it; that should also get around the issue.

  4. Sara says:

    I went to tons of links before this, what was I tihnknig?

  5. Abendstern says:

    Hello,
    I tried this code and i launch Canary from the command line as described above and i could not do it.
    It gave JavaScript error “could not connect to stream”. I need help
    Thanks

  6. Rhuno says:

    Hi Abendstern,

    Are you seeing the error in the javascript console or in an alert popup? You may be hitting the onFail function which means the call to webkitGetUserMedia is not completing successfully. Do you have a webcam hooked up? That is the only way I was able to get this to fail. Also, try it with the regular version of Chrome. Support for GetUserMedia has been added.

  7. Abendstern says:

    Hi Rhuno,
    I solved it, Because of firewall, it could not access the webcam and microphone. It is working now and I am trying to make it multiuser video chat :) Thanks for reply

  8. starlover says:

    Hello,
    What do you know about the acceptance message of the webcam?
    Is there a workaround for that, or an automatic acceptance?
    Greets,
    Starlover

  9. Rhuno says:

    starlover, the acceptance message is there for security purposes; it would be bad if webpages could access your webcam without your knowledge. As far as I know there is no work around.

  10. Russ Mathis says:

    Error: could not connect stream, when clicking “Head hear” link and accepting “http://www.rhuno.com/wants to use your camera”.
    irremediably get “could not connect stream”

    Any ideas? Just installed:”Version 25.0.1347.0 canary”
    OS: Windows 7

    Help

  11. Rhuno says:

    Hey Russ,

    This might sound silly, but double check to make sure your webcam is connected. After seeing your comment, I checked out the page and got the same error, but then I realized my webcam wasn’t plugged in. Once I connected the webcam, everything worked.

    Also, you don’t actually need Canary any more for this. Recent versions of Chrome should already have the media stream enabled by default.

  12. Ahmed galal says:

    Thanks a lot , it is very nice experiment for me !

  13. Eran says:

    Hi

    I have webCam that is using the H264 protocol.
    Do you know suitable solution to this case.
    currently I’m using SilverLight control, I really want to get rid of it :)

Leave a Reply

Subscribe to RSS feed FGS5 Badge