EN
JavaScript - play web camera video on canvas element (webcam usage example)
6 points
In this short article, you can see how to stream video from web camera to canvas element using JavaScript.
Example preview:

Note: it is important to be sure the web camera is connected properly and not used by any other application.
xxxxxxxxxx
1
2
<html>
3
<body>
4
<canvas id="my-canvas" width="640" height="480"></canvas>
5
<script>
6
7
function playStream(canvas, stream) {
8
var video = document.createElement('video');
9
video.addEventListener('loadedmetadata', function() {
10
const context = canvas.getContext('2d');
11
var drawFrame = function() {
12
context.drawImage(video, 0, 0);
13
window.requestAnimationFrame(drawFrame);
14
};
15
drawFrame();
16
});
17
video.autoplay = true;
18
video.srcObject = stream;
19
}
20
21
function playCamera(canvas, preferedWidth, preferedHeight) {
22
var devices = navigator.mediaDevices;
23
if (devices && 'getUserMedia' in devices) {
24
var constraints = {
25
video: {
26
width: preferedWidth,
27
height: preferedHeight
28
}
29
// you can use microphone adding `audio: true` property here
30
};
31
var promise = devices.getUserMedia(constraints);
32
promise
33
.then(function(stream) {
34
playStream(canvas, stream);
35
})
36
.catch(function(error) {
37
console.error(error.name + ': ' + error.message);
38
});
39
} else {
40
console.error('Camera API is not supported.');
41
}
42
}
43
44
45
// Usage example:
46
47
var canvas = document.querySelector('#my-canvas');
48
49
playCamera(canvas, canvas.width, canvas.height);
50
51
</script>
52
</body>
53
</html>
Hint: used solutions in the above example were introduced in the major web browsers around 2016.
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.

In this section, you can find reusable class that plays indicated stream on canvas element.
xxxxxxxxxx
1
// Possible player states:
2
//
3
const PLAYER_WAITING = 1;
4
const PLAYER_STARTING = 2;
5
const PLAYER_WORKING = 3;
6
const PLAYER_STOPPING = 4;
7
8
9
function findStream(preferedWidth, preferedHeight, callback) {
10
const devices = navigator.mediaDevices;
11
if (devices && 'getUserMedia' in devices) {
12
const constraints = {
13
video: {
14
width: preferedWidth,
15
height: preferedHeight
16
}
17
// you can use microphone adding `audio: true` property here
18
};
19
const promise = devices.getUserMedia(constraints);
20
promise
21
.then(function(stream) {
22
callback(stream, null);
23
})
24
.catch(function(error) {
25
callback(null, `${error.name}: ${error.message}`);
26
});
27
} else {
28
callback(null, 'Camera API is not supported.');
29
}
30
}
31
32
function StreamPlayer(canvas, callback) {
33
let _state = PLAYER_WAITING;
34
if (callback) {
35
callback(_state, null);
36
}
37
const _context = canvas.getContext('2d');
38
const _video = document.createElement('video');
39
_video.addEventListener('loadedmetadata', function() {
40
switch (_state) {
41
case PLAYER_STARTING:
42
_state = PLAYER_WORKING;
43
if (callback) {
44
callback(_state, null);
45
}
46
const drawFrame = function() {
47
switch (_state) {
48
case PLAYER_WORKING:
49
_context.drawImage(_video, 0, 0);
50
window.requestAnimationFrame(drawFrame);
51
break;
52
case PLAYER_STOPPING:
53
_state = PLAYER_WAITING;
54
if (callback) {
55
callback(_state, null);
56
}
57
break;
58
}
59
};
60
drawFrame();
61
break;
62
case PLAYER_STOPPING:
63
_state = PLAYER_WAITING;
64
if (callback) {
65
callback(_state, null);
66
}
67
break;
68
}
69
});
70
_video.autoplay = true;
71
const playStream = function(stream) {
72
if (_state === PLAYER_WAITING) {
73
_state = PLAYER_STARTING;
74
_video.srcObject = stream;
75
if (callback) {
76
callback(_state, null);
77
}
78
}
79
};
80
const stopStream = function() {
81
if (_state === PLAYER_STARTING || _state === PLAYER_WORKING) {
82
_state = PLAYER_STOPPING;
83
_video.srcObject = null;
84
if (callback) {
85
callback(_state, null);
86
}
87
}
88
};
89
90
// Plays indicated stream.
91
// e.g.
92
// const canvas = document.querySelector('#my-canvas');
93
// const player = new StreamPlayer(canvas, function(state, error) {
94
// console.log(`state: ${state} error: ${error}`);
95
// });
96
// player.play$2(stream); // use `devices.getUserMedia()` method to get stream
97
//
98
this.play$1 = playStream;
99
100
// Plays detected web camera.
101
// e.g.
102
// const canvas = document.querySelector('#my-canvas');
103
// const player = new StreamPlayer(canvas, function(state, error) {
104
// console.log(`state: ${state} error: ${error}`);
105
// });
106
// player.play$2();
107
//
108
this.play$2 = function() {
109
if (_state === PLAYER_WAITING) {
110
findStream(canvas.width, canvas.height, function(stream, error) {
111
if (error) {
112
stopStream();
113
if (callback) {
114
callback(0, error);
115
}
116
} else {
117
playStream(stream);
118
}
119
});
120
}
121
};
122
123
// Stops web camera streaming.
124
//
125
this.stop = stopStream;
126
}
127
128
129
130
// Usage example 1:
131
132
const canvas = document.querySelector('#my-canvas');
133
134
const player = new StreamPlayer(canvas, function(state, error) {
135
console.log(`state: ${state} error: '${error}'`);
136
});
137
138
player.play$2(); // to stop: player.stop();
139
140
141
142
// Usage example 2:
143
144
const canvas = document.querySelector('#my-canvas');
145
146
const player = new StreamPlayer(canvas, function(state, error) {
147
console.log(`state: ${state} error: '${error}'`);
148
});
149
150
findStream(canvas.width, canvas.height, function(stream, error) {
151
if (error) {
152
console.log(`error: ${error}`);
153
} else {
154
player.play$1(stream); // to stop: player.stop();
155
}
156
});
157
158
// Where: findStream() uses `devices.getUserMedia()` method to find web camera and access stream