From 002fbadbc0cb9a69ac76f5643fccba9eca814eaf Mon Sep 17 00:00:00 2001 From: xdzqyyds <139134069+xdzqyyds@users.noreply.github.com> Date: Thu, 21 Nov 2024 20:04:26 +0800 Subject: [PATCH] Speaker button (#22) * speaker button * npx eslint --fix * finish speaker button * use atom to finish speaker button * Fixed an alert that did not allow trailing Spaces * Delete a blank line from player.tsx * add disable/enable function * el.muted = !SpeakerStatus --- webapp/components/device.tsx | 52 +++++++++++++++++++++++++++++ webapp/components/player/player.tsx | 12 ++++++- webapp/components/svg/speaker.tsx | 7 ++++ webapp/store/atom.ts | 5 +++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 webapp/components/svg/speaker.tsx diff --git a/webapp/components/device.tsx b/webapp/components/device.tsx index 5e1ebc9..fad64e9 100644 --- a/webapp/components/device.tsx +++ b/webapp/components/device.tsx @@ -1,12 +1,15 @@ import useWhipClient from './use/whip' +import { useAtom } from 'jotai' import { useEffect, useState } from 'react' import { Device, deviceNone, deviceScreen, } from '../lib/device' +import { deviceSpeakerAtom, SpeakerStatusAtom } from './../store/atom' import Loading from './svg/loading' +import SvgSpeaker from './svg/speaker' import SvgAudio from './svg/audio' import SvgVideo from './svg/video' import { SvgPresentCancel, SvgPresentToAll } from './svg/present' @@ -24,10 +27,14 @@ export default function DeviceBar(props: { streamId: string }) { const [permissionAudio, setPermissionAudio] = useState('') const [permissionVideo, setPermissionVideo] = useState('') + const [loadingSpeaker, setLoadingSpeaker] = useState(false) const [loadingAudio, setLoadingAudio] = useState(false) const [loadingVideo, setLoadingVideo] = useState(false) const [loadingScreen, setLoadingScreen] = useState(false) + const [currentDeviceSpeaker, setCurrentDeviceSpeaker] = useAtom(deviceSpeakerAtom) + const [SpeakerStatus, setSpeakerStatus] = useAtom(SpeakerStatusAtom) + const { userStatus, currentDeviceAudio, @@ -38,6 +45,7 @@ export default function DeviceBar(props: { streamId: string }) { toggleEnableVideo, } = useWhipClient(props.streamId) + const [deviceSpeaker, setDeviceSpeaker] = useState([deviceNone]) const [deviceAudio, setDeviceAudio] = useState([deviceNone]) const [deviceVideo, setDeviceVideo] = useState([deviceNone]) @@ -82,9 +90,15 @@ export default function DeviceBar(props: { streamId: string }) { const devices = (await navigator.mediaDevices.enumerateDevices()).filter(i => !!i.deviceId) + const speakers = devices.filter(i => i.kind === 'audiooutput').map(toDevice) const audios = devices.filter(i => i.kind === 'audioinput').map(toDevice) const videos = devices.filter(i => i.kind === 'videoinput').map(toDevice) + if (currentDeviceSpeaker === deviceNone.deviceId) { + const device = speakers[0] + if (device) setCurrentDeviceSpeaker(device.deviceId) + } + if (currentDeviceAudio === deviceNone.deviceId) { const device = audios[0] if (device) await setCurrentDeviceAudio(device.deviceId) @@ -95,6 +109,7 @@ export default function DeviceBar(props: { streamId: string }) { if (device) await setCurrentDeviceVideo(device.deviceId) } + setDeviceSpeaker([...speakers]) setDeviceAudio([...audios]) setDeviceVideo([...videos, deviceScreen]) } @@ -130,6 +145,12 @@ export default function DeviceBar(props: { streamId: string }) { return () => { navigator.mediaDevices.removeEventListener('devicechange', updateDeviceList) } }, []) + const onChangedDeviceSpeaker = async (current: string) => { + setLoadingSpeaker(true) + setCurrentDeviceSpeaker(current) + setLoadingSpeaker(false) + } + const onChangedDeviceAudio = async (current: string) => { setLoadingAudio(true) await setCurrentDeviceAudio(current) @@ -151,6 +172,37 @@ export default function DeviceBar(props: { streamId: string }) { return (
+
+ +
+
+ {SpeakerStatus + ?
+ :
+ } +
+ +
+