EN
React - list available audio and video input devices (e.g. web cameras and microphones)
3 points
In this short article, we would like to show how using React in simple way list available input audio and input video devices (web cameras and microphones).
In this section, you can find reusable logic that lists available input devices.
Devices are ordered by importance. It means the most recommended or default devices should be listed as first.
xxxxxxxxxx
1
// import React from 'react';
2
3
const listDevices = async () => {
4
const devices = await navigator.mediaDevices?.enumerateDevices?.();
5
if (devices) {
6
const video = [];
7
const audio = [];
8
for (const device of devices) {
9
switch (device.kind) {
10
case 'videoinput':
11
video.push(device);
12
break;
13
case 'audioinput':
14
audio.push(device);
15
break;
16
}
17
}
18
return { video, audio };
19
} else {
20
throw new Error('No support for multimedia devices.');
21
}
22
};
23
24
25
// Usage example:
26
27
const App = () => {
28
const [error, setError] = React.useState(null);
29
const [devices, setDevices] = React.useState(null);
30
React.useEffect(() => {
31
const promise = listDevices(); // <--- lists available input audio and input video devices
32
promise
33
.then((devices) => setDevices(devices))
34
.catch((error) => setError(error));
35
;
36
}, []);
37
return (
38
<div>
39
{error && (<div>{error}</div>)}
40
{devices && (
41
<>
42
{devices.video.length === 0 && (<div>Video devices: not detected!</div>)}
43
{devices.video.length > 0 && (
44
<>
45
<div>Video devices:</div>
46
<ul>
47
{devices.video.map((videoDevice) => (
48
<li key={videoDevice.deviceId}>
49
<div>deviceId: {videoDevice.deviceId}</div>
50
<div>kind: {videoDevice.kind}</div>
51
<div>label: {videoDevice.label}</div>
52
<div>groupId: {videoDevice.groupId}</div>
53
</li>
54
))}
55
</ul>
56
</>
57
)}
58
{devices.audio.length === 0 && (<div>Audio devices: not detected!</div>)}
59
{devices.audio.length > 0 && (
60
<>
61
<div>Audio devices:</div>
62
<ul>
63
{devices.video.map((audioDevice) => (
64
<li key={audioDevice.deviceId}>
65
<div>deviceId: {audioDevice.deviceId}</div>
66
<div>kind: {audioDevice.kind}</div>
67
<div>label: {audioDevice.label}</div>
68
<div>groupId: {audioDevice.groupId}</div>
69
</li>
70
))}
71
</ul>
72
</>
73
)}
74
</>
75
)}
76
</div>
77
);
78
};
79
80
// export default App;
81
82
const root = document.querySelector('#root');
83
ReactDOM.render(<App />, root);
In this example, we present listing available audio and video input devices with the possibility of choosing them in the select box.
xxxxxxxxxx
1
// import React from 'react';
2
3
const listDevices = async () => {
4
const devices = await navigator.mediaDevices?.enumerateDevices?.();
5
if (devices) {
6
const video = [];
7
const audio = [];
8
for (const device of devices) {
9
switch (device.kind) {
10
case 'videoinput':
11
video.push(device);
12
break;
13
case 'audioinput':
14
audio.push(device);
15
break;
16
}
17
}
18
return { video, audio };
19
} else {
20
throw new Error('No support for multimedia devices.');
21
}
22
};
23
24
25
// Usage example:
26
27
const fieldStyle = {
28
display: 'flex'
29
};
30
31
const labelStyle = {
32
flex: '0 110px'
33
};
34
35
const selectStyle = {
36
flex: 'auto'
37
};
38
39
const App = () => {
40
const [error, setError] = React.useState(null);
41
const [devices, setDevices] = React.useState(null);
42
React.useEffect(() => {
43
const promise = listDevices(); // <--- lists available input audio and input video devices
44
promise
45
.then((devices) => setDevices(devices))
46
.catch((error) => setError(error));
47
;
48
}, []);
49
const handleVideoDeviceChange = (e) => {
50
const device = devices.video[e.target.value];
51
console.log(`Video device change:\n label: ${device.label}\n deviceId: ${device.deviceId}\n groupId: ${device.groupId}`);
52
};
53
const handleAudioDeviceChange = (e) => {
54
const device = devices.audio[e.target.value];
55
console.log(`Audio device change:\n label: ${device.label}\n deviceId: ${device.deviceId}\n groupId: ${device.groupId}`);
56
};
57
return (
58
<div>
59
{error && (<div>{error}</div>)}
60
{devices && (
61
<>
62
<label style={fieldStyle}>
63
<span style={labelStyle}>Video device: </span>
64
<select style={selectStyle} disabled={devices.video.length === 0} onChange={handleVideoDeviceChange}>
65
{devices.video.map((device, index) => (
66
<option key={device.deviceId} value={index}>
67
{device.label || device.deviceId || device.groupId}
68
</option>
69
))}
70
</select>
71
</label>
72
<label style={fieldStyle}>
73
<span style={labelStyle}>Audio device: </span>
74
<select style={selectStyle} disabled={devices.audio.length === 0} onChange={handleAudioDeviceChange}>
75
{devices.audio.map((device, index) => (
76
<option key={device.deviceId} value={index}>
77
{device.label || device.deviceId || device.groupId}
78
</option>
79
))}
80
</select>
81
</label>
82
</>
83
)}
84
</div>
85
);
86
};
87
88
// export default App;
89
90
const root = document.querySelector('#root');
91
ReactDOM.render(<App />, root);