-
Notifications
You must be signed in to change notification settings - Fork 228
Expand file tree
/
Copy pathAudioOutputSelect.tsx
More file actions
88 lines (76 loc) · 2.34 KB
/
AudioOutputSelect.tsx
File metadata and controls
88 lines (76 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import type React from 'react';
import { useEffect, useState } from 'react';
import { logAndNotifyError } from '../../lib/utils';
import * as Setting from '../Setting/Setting';
type Props = {
value: string;
onChange: (deviceID: string) => void;
} & Setting.InputProps;
export default function AudioOutputSelect(props: Props) {
const { label, description, id } = props;
const selectProps = { label, description, id };
const [devices, setDevices] = useState<MediaDeviceInfo[] | null>(null);
const [hasError, setHasError] = useState(false);
useEffect(() => {
const refreshDevices = async () => {
try {
// This will display a popup to users asking them to give microphone access,
// which is lame because we only need outputs.
// Does not work on macOS/linux for now.
await navigator.mediaDevices.getUserMedia({
audio: true,
});
const devices = await navigator.mediaDevices.enumerateDevices();
const audioDevices = devices.filter(
(device) => device.kind === 'audiooutput' && device.deviceId !== '',
);
setDevices(audioDevices);
} catch (err) {
setDevices([]);
setHasError(true);
logAndNotifyError(err);
}
};
refreshDevices();
}, []);
const setAudioOutputDevice = (e: React.ChangeEvent<HTMLSelectElement>) => {
props.onChange(e.currentTarget.value);
};
if (!devices) {
return (
<Setting.Select {...selectProps} disabled key="selectDisabled">
<option>loading devices...</option>
</Setting.Select>
);
}
if (hasError) {
return (
<Setting.Select {...selectProps} disabled key="selectDisabled">
<option>Could not get audio output devices</option>
</Setting.Select>
);
}
if (devices.length === 0) {
return (
<Setting.Select {...selectProps} disabled key="selectDisabled">
<option>no audio output devices found</option>
</Setting.Select>
);
}
return (
<Setting.Select
{...selectProps}
key="devicesOk" // avoid default value problems
value={props.value}
onChange={setAudioOutputDevice}
>
{devices.map((device) => {
return (
<option key={device.deviceId} value={device.deviceId}>
{device.label}
</option>
);
})}
</Setting.Select>
);
}