Add video settings to VoiceCallAudioSettingsDialog
This commit is contained in:
@@ -26,8 +26,10 @@
|
|||||||
|
|
||||||
let audioInputs = $state<MediaDeviceInfo[]>([])
|
let audioInputs = $state<MediaDeviceInfo[]>([])
|
||||||
let audioOutputs = $state<MediaDeviceInfo[]>([])
|
let audioOutputs = $state<MediaDeviceInfo[]>([])
|
||||||
|
let videoInputs = $state<MediaDeviceInfo[]>([])
|
||||||
let selectedInput = $state("")
|
let selectedInput = $state("")
|
||||||
let selectedOutput = $state("")
|
let selectedOutput = $state("")
|
||||||
|
let selectedVideo = $state("")
|
||||||
|
|
||||||
const loadDevices = async () => {
|
const loadDevices = async () => {
|
||||||
if (!navigator.mediaDevices?.enumerateDevices) return
|
if (!navigator.mediaDevices?.enumerateDevices) return
|
||||||
@@ -35,16 +37,25 @@
|
|||||||
const devices = await navigator.mediaDevices.enumerateDevices()
|
const devices = await navigator.mediaDevices.enumerateDevices()
|
||||||
audioInputs = devices.filter(d => d.kind === "audioinput")
|
audioInputs = devices.filter(d => d.kind === "audioinput")
|
||||||
audioOutputs = devices.filter(d => d.kind === "audiooutput")
|
audioOutputs = devices.filter(d => d.kind === "audiooutput")
|
||||||
|
videoInputs = devices.filter(d => d.kind === "videoinput")
|
||||||
} catch {
|
} catch {
|
||||||
audioInputs = []
|
audioInputs = []
|
||||||
audioOutputs = []
|
audioOutputs = []
|
||||||
|
videoInputs = []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
loadDevices()
|
void loadDevices()
|
||||||
navigator.mediaDevices?.addEventListener?.("devicechange", loadDevices)
|
const md = navigator.mediaDevices
|
||||||
return () => navigator.mediaDevices?.removeEventListener?.("devicechange", loadDevices)
|
if (!md?.addEventListener) return
|
||||||
|
const onDeviceChange = () => {
|
||||||
|
void loadDevices()
|
||||||
|
}
|
||||||
|
md.addEventListener("devicechange", onDeviceChange)
|
||||||
|
return () => {
|
||||||
|
md.removeEventListener("devicechange", onDeviceChange)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
@@ -55,6 +66,7 @@
|
|||||||
}
|
}
|
||||||
selectedInput = selectValueForActiveDevice(session, DeviceKind.AudioInput)
|
selectedInput = selectValueForActiveDevice(session, DeviceKind.AudioInput)
|
||||||
selectedOutput = selectValueForActiveDevice(session, DeviceKind.AudioOutput)
|
selectedOutput = selectValueForActiveDevice(session, DeviceKind.AudioOutput)
|
||||||
|
selectedVideo = selectValueForActiveDevice(session, DeviceKind.VideoInput)
|
||||||
})
|
})
|
||||||
|
|
||||||
const onInputChange = () => {
|
const onInputChange = () => {
|
||||||
@@ -65,6 +77,10 @@
|
|||||||
void switchVoiceActiveDevice(DeviceKind.AudioOutput, selectedOutput)
|
void switchVoiceActiveDevice(DeviceKind.AudioOutput, selectedOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onVideoChange = () => {
|
||||||
|
void switchVoiceActiveDevice(DeviceKind.VideoInput, selectedVideo)
|
||||||
|
}
|
||||||
|
|
||||||
const onDone = () => {
|
const onDone = () => {
|
||||||
popModal()
|
popModal()
|
||||||
}
|
}
|
||||||
@@ -76,8 +92,8 @@
|
|||||||
<Modal>
|
<Modal>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<ModalHeader>
|
<ModalHeader>
|
||||||
<ModalTitle>Audio settings</ModalTitle>
|
<ModalTitle>Call settings</ModalTitle>
|
||||||
<ModalSubtitle>Choose microphone and speaker for this call.</ModalSubtitle>
|
<ModalSubtitle>Microphone, speaker, and camera for this call.</ModalSubtitle>
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
<div class="flex flex-col gap-4 pt-2">
|
<div class="flex flex-col gap-4 pt-2">
|
||||||
<FieldInline>
|
<FieldInline>
|
||||||
@@ -120,6 +136,25 @@
|
|||||||
{/snippet}
|
{/snippet}
|
||||||
</FieldInline>
|
</FieldInline>
|
||||||
{/if}
|
{/if}
|
||||||
|
<FieldInline>
|
||||||
|
{#snippet label()}
|
||||||
|
<p>Camera</p>
|
||||||
|
{/snippet}
|
||||||
|
{#snippet input()}
|
||||||
|
<select
|
||||||
|
class="select select-bordered w-full"
|
||||||
|
bind:value={selectedVideo}
|
||||||
|
onchange={onVideoChange}
|
||||||
|
aria-label="Camera">
|
||||||
|
<option value="">Default camera</option>
|
||||||
|
{#each videoInputs as d (d.deviceId)}
|
||||||
|
<option value={d.deviceId}>
|
||||||
|
{d.label || `Camera ${d.deviceId.slice(0, 8)}…`}
|
||||||
|
</option>
|
||||||
|
{/each}
|
||||||
|
</select>
|
||||||
|
{/snippet}
|
||||||
|
</FieldInline>
|
||||||
</div>
|
</div>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<ModalFooter>
|
<ModalFooter>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
pushModal(VoiceRoomJoinDialog, {url: targetRoom.url, h: targetRoom.h})
|
pushModal(VoiceRoomJoinDialog, {url: targetRoom.url, h: targetRoom.h})
|
||||||
}
|
}
|
||||||
|
|
||||||
const openAudioSettings = () => {
|
const openCallSettings = () => {
|
||||||
pushModal(VoiceCallAudioSettingsDialog)
|
pushModal(VoiceCallAudioSettingsDialog)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -128,9 +128,9 @@
|
|||||||
<Icon icon={Monitor} size={4} />
|
<Icon icon={Monitor} size={4} />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
data-tip="Audio settings"
|
data-tip="Call settings"
|
||||||
class="center tooltip tooltip-top btn btn-sm btn-square btn-ghost"
|
class="center tooltip tooltip-top btn btn-sm btn-square btn-ghost"
|
||||||
onclick={openAudioSettings}>
|
onclick={openCallSettings}>
|
||||||
<Icon icon={Settings} size={4} />
|
<Icon icon={Settings} size={4} />
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ const LIVEKIT_DEFAULT_DEVICE_ID = "default"
|
|||||||
export enum DeviceKind {
|
export enum DeviceKind {
|
||||||
AudioInput = "audioinput",
|
AudioInput = "audioinput",
|
||||||
AudioOutput = "audiooutput",
|
AudioOutput = "audiooutput",
|
||||||
|
VideoInput = "videoinput",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const switchVoiceActiveDevice = async (
|
export const switchVoiceActiveDevice = async (
|
||||||
@@ -74,6 +75,9 @@ export const switchVoiceActiveDevice = async (
|
|||||||
case DeviceKind.AudioOutput:
|
case DeviceKind.AudioOutput:
|
||||||
label = "speaker"
|
label = "speaker"
|
||||||
break
|
break
|
||||||
|
case DeviceKind.VideoInput:
|
||||||
|
label = "camera"
|
||||||
|
break
|
||||||
}
|
}
|
||||||
pushToast({theme: "error", message: `Error changing ${label}`})
|
pushToast({theme: "error", message: `Error changing ${label}`})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user