From 40a68b7a16ce68e946575a47ba36960c2e1bb409 Mon Sep 17 00:00:00 2001 From: winter_NaN <124137506+WinterJack002@users.noreply.github.com> Date: Tue, 5 Nov 2024 20:24:41 +0800 Subject: [PATCH] fix(web): obtain media device label (#10) * fix(web): obtain media device label * correct code issues Signed-off-by: winter_NaN * fix firefox lable issues sec. * deal with device lable and coding format * refactor device and fix device change * fix code format * fix deviceNone --------- Signed-off-by: winter_NaN Co-authored-by: winter_NaN Co-authored-by: a-wing <1@233.email> --- .github/CLA.md | 3 ++- webapp/components/device.tsx | 22 ++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/.github/CLA.md b/.github/CLA.md index e47d791..7b51949 100644 --- a/.github/CLA.md +++ b/.github/CLA.md @@ -44,4 +44,5 @@ Example: --> - Metal A-wing, @a-wing, 2024/10/23 -- Hongcha Zhang, @hongcha98, 2024/10/24 \ No newline at end of file +- Hongcha Zhang, @hongcha98, 2024/10/24 +- Winter Zhang, @WinterJack002, 2024/10/26 diff --git a/webapp/components/device.tsx b/webapp/components/device.tsx index 02ec08a..6795ff4 100644 --- a/webapp/components/device.tsx +++ b/webapp/components/device.tsx @@ -11,6 +11,15 @@ import SvgAudio from './svg/audio' import SvgVideo from './svg/video' import { SvgPresentCancel, SvgPresentToAll } from './svg/present' +function toDevice(info: MediaDeviceInfo): Device { + const deviceId = info.deviceId; + let label = info.label; + if (label.length <= 0) { + label = `${info.kind} (${deviceId.substring(0, 8)})`; + } + return { deviceId, label }; +} + export default function DeviceBar(props: { streamId: string }) { const [permissionAudio, setPermissionAudio] = useState("") const [permissionVideo, setPermissionVideo] = useState("") @@ -48,18 +57,23 @@ export default function DeviceBar(props: { streamId: string }) { // NOTE: // Chrome: audio_capture, video_capture // Safari: microphone, camera - if (status.name === "audio_capture" || "microphone") { + if (status.name === "audio_capture" || status.name === "microphone") { setPermissionAudio(status.state) } - if (status.name === "video_capture" || "camera") { + if (status.name === "video_capture" || status.name === "camera") { setPermissionVideo(status.state) } }) const updateDeviceList = async () => { + // to obtain non-empty device label, there needs to be an active media stream or persistent permission + // https://developer.mozilla.org/en-US/docs/Web/API/MediaDeviceInfo/label#value + await navigator.mediaDevices.getUserMedia({ audio: true, video: true }); + const devices = (await navigator.mediaDevices.enumerateDevices()).filter(i => !!i.deviceId) - const audios: Device[] = devices.filter(i => i.kind === 'audioinput') - const videos: Device[] = devices.filter(i => i.kind === 'videoinput') + + const audios = devices.filter(i => i.kind === 'audioinput').map(toDevice) + const videos = devices.filter(i => i.kind === 'videoinput').map(toDevice) if (currentDeviceAudio === deviceNone.deviceId) { let device = audios[0]