Languages
[Edit]
EN

JavaScript - play web camera video on canvas element (webcam usage example)

6 points
Created by:
cory
1486

In this short article, you can see how to stream video from web camera to canvas element using JavaScript.

Example preview:

Example camera streaming to canvas element using JavaScript.
Example camera streaming to canvas element using JavaScript.

Practical example

Note: it is important to be sure the web camera is connected properly and not used by any other application.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<body>
  <canvas id="my-canvas" width="640" height="480"></canvas>
  <script>

    function playStream(canvas, stream) {
        var video = document.createElement('video');
        video.addEventListener('loadedmetadata', function() {
            const context = canvas.getContext('2d');
            var drawFrame = function() {
                context.drawImage(video, 0, 0);
                window.requestAnimationFrame(drawFrame);
            };
            drawFrame();
        });
        video.autoplay = true;
        video.srcObject = stream;
    }
    
    function playCamera(canvas, preferedWidth, preferedHeight) {
        var devices = navigator.mediaDevices;
        if (devices && 'getUserMedia' in devices) {
            var constraints = {
                video: {
                    width: preferedWidth,
                    height: preferedHeight
                }
                // you can use microphone adding `audio: true` property here
            };
            var promise = devices.getUserMedia(constraints);
            promise
                .then(function(stream) {
                    playStream(canvas, stream);
                })
                .catch(function(error) {
                    console.error(error.name + ': ' + error.message);
                });
        } else {
            console.error('Camera API is not supported.');
        }
    }
    
    
    // Usage example:
    
    var canvas = document.querySelector('#my-canvas');
    
    playCamera(canvas, canvas.width, canvas.height);

  </script>
</body>
</html>

Hint: used solutions in the above example were introduced in the major web browsers around 2016.

 

Giving premissions

When a web camera is accessed from JavaScript you should see notification to permit using it. Just let use it by desired website and remove permissions when it is not needed.

Giving permissions to use web camera under Google Chrome web browser.
Giving permissions to use web camera under Google Chrome web browser.

Reusable logic

In this section, you can find reusable class that plays indicated stream on canvas element.

// Possible player states:
//
const PLAYER_WAITING = 1;
const PLAYER_STARTING = 2;
const PLAYER_WORKING = 3;
const PLAYER_STOPPING = 4;


function findStream(preferedWidth, preferedHeight, callback) {
    const devices = navigator.mediaDevices;
    if (devices && 'getUserMedia' in devices) {
        const constraints = {
            video: {
                width: preferedWidth,
                height: preferedHeight
            }
            // you can use microphone adding `audio: true` property here
        };
        const promise = devices.getUserMedia(constraints);
        promise
            .then(function(stream) {
                callback(stream, null);
            })
            .catch(function(error) {
                callback(null, `${error.name}: ${error.message}`);
            });
    } else {
        callback(null, 'Camera API is not supported.');
    }
}
    
function StreamPlayer(canvas, callback) {
    let _state = PLAYER_WAITING;
    if (callback) {
        callback(_state, null);
    }
    const _context = canvas.getContext('2d');
    const _video = document.createElement('video');
    _video.addEventListener('loadedmetadata', function() {
        switch (_state) {
            case PLAYER_STARTING:
                _state = PLAYER_WORKING;
                if (callback) {
                    callback(_state, null);
                }
                const drawFrame = function() {
                    switch (_state) {
                        case PLAYER_WORKING:
                            _context.drawImage(_video, 0, 0);
                            window.requestAnimationFrame(drawFrame);
                            break;
                        case PLAYER_STOPPING:
                            _state = PLAYER_WAITING;
                            if (callback) {
                                callback(_state, null);
                            }
                            break;
                    }
                };
                drawFrame();
                break;
            case PLAYER_STOPPING:
                _state = PLAYER_WAITING;
                if (callback) {
                    callback(_state, null);
                }
                break;
        }
    });
    _video.autoplay = true;
    const playStream = function(stream) {
        if (_state === PLAYER_WAITING) {
            _state = PLAYER_STARTING;
            _video.srcObject = stream;
            if (callback) {
                callback(_state, null);
            }
        }
    };
    const stopStream = function() {
        if (_state === PLAYER_STARTING || _state === PLAYER_WORKING) {
            _state = PLAYER_STOPPING;
            _video.srcObject = null;
            if (callback) {
                callback(_state, null);
            }
        }
    };

    // Plays indicated stream.
    // e.g.
    //     const canvas = document.querySelector('#my-canvas');
    //     const player = new StreamPlayer(canvas, function(state, error) {
    //         console.log(`state: ${state}  error: ${error}`);
    //     });
    //     player.play$2(stream);  // use `devices.getUserMedia()` method to get stream
    //
    this.play$1 = playStream;

    // Plays detected web camera.
    // e.g.
    //     const canvas = document.querySelector('#my-canvas');
    //     const player = new StreamPlayer(canvas, function(state, error) {
    //         console.log(`state: ${state}  error: ${error}`);
    //     });
    //     player.play$2();
    //
    this.play$2 = function() {
        if (_state === PLAYER_WAITING) {
            findStream(canvas.width, canvas.height, function(stream, error) {
                if (error) {
                    stopStream();
                    if (callback) {
                        callback(0, error);
                    }
                } else {
                    playStream(stream);
                }
            });
        }
    };

    // Stops web camera streaming.
    //
    this.stop = stopStream;
}



// Usage example 1:

const canvas = document.querySelector('#my-canvas');

const player = new StreamPlayer(canvas, function(state, error) {
    console.log(`state: ${state}  error: '${error}'`);
});
               
player.play$2();  // to stop:  player.stop();



// Usage example 2:

const canvas = document.querySelector('#my-canvas');

const player = new StreamPlayer(canvas, function(state, error) {
    console.log(`state: ${state}  error: '${error}'`);
});

findStream(canvas.width, canvas.height, function(stream, error) {
    if (error) {
        console.log(`error: ${error}`);
    } else {
        player.play$1(stream);  // to stop:  player.stop();
    }
});

// Where: findStream() uses `devices.getUserMedia()` method to find web camera and access stream

 

See also

  1. JavaScript - play web camera video on video element

  2. JavaScript - list available audio and video input devices

  3. JavaScript - capture video from device camera using input HTML element (mobile devices only)

References

  1. MediaDevices.getUserMedia() - MDN Docs
  2. HTMLMediaElement.srcObject - MDN Docs

  3. <video>: The Video Embed element - MDN Docs

Alternative titles

  1. JavaScript - stream web camera video to canvas element
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join