diff --git a/src/frontend/src/features/rooms/components/Conference.tsx b/src/frontend/src/features/rooms/components/Conference.tsx
index 3ee174c7..e7b82d3e 100644
--- a/src/frontend/src/features/rooms/components/Conference.tsx
+++ b/src/frontend/src/features/rooms/components/Conference.tsx
@@ -2,7 +2,12 @@ import { useEffect, useMemo, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useTranslation } from 'react-i18next'
import { LiveKitRoom } from '@livekit/components-react'
-import { DisconnectReason, Room, RoomOptions } from 'livekit-client'
+import {
+ DisconnectReason,
+ MediaDeviceFailure,
+ Room,
+ RoomOptions,
+} from 'livekit-client'
import { keys } from '@/api/queryKeys'
import { queryClient } from '@/api/queryClient'
import { Screen } from '@/layout/Screen'
@@ -18,6 +23,7 @@ import { css } from '@/styled-system/css'
import { BackgroundProcessorFactory } from '../livekit/components/blur'
import { LocalUserChoices } from '@/stores/userChoices'
import { navigateTo } from '@/navigation/navigateTo'
+import { MediaDeviceErrorAlert } from './MediaDeviceErrorAlert'
export const Conference = ({
roomId,
@@ -86,6 +92,13 @@ export const Conference = ({
const room = useMemo(() => new Room(roomOptions), [roomOptions])
const [showInviteDialog, setShowInviteDialog] = useState(mode === 'create')
+ const [mediaDeviceError, setMediaDeviceError] = useState<{
+ error: MediaDeviceFailure | null
+ kind: MediaDeviceKind | null
+ }>({
+ error: null,
+ kind: null,
+ })
const { t } = useTranslation('rooms')
if (isCreateError) {
@@ -132,6 +145,11 @@ export const Conference = ({
navigateTo('feedback', { duplicateIdentity: true })
}
}}
+ onMediaDeviceFailure={(e, kind) => {
+ if (e == MediaDeviceFailure.DeviceInUse && !!kind) {
+ setMediaDeviceError({ error: e, kind })
+ }
+ }}
>
{showInviteDialog && (
@@ -142,6 +160,10 @@ export const Conference = ({
onClose={() => setShowInviteDialog(false)}
/>
)}
+ setMediaDeviceError({ error: null, kind: null })}
+ />
diff --git a/src/frontend/src/features/rooms/components/MediaDeviceErrorAlert.tsx b/src/frontend/src/features/rooms/components/MediaDeviceErrorAlert.tsx
new file mode 100644
index 00000000..bc240869
--- /dev/null
+++ b/src/frontend/src/features/rooms/components/MediaDeviceErrorAlert.tsx
@@ -0,0 +1,33 @@
+import { MediaDeviceFailure } from 'livekit-client'
+import { useTranslation } from 'react-i18next'
+import { Button, Dialog, P } from '@/primitives'
+
+export type MediaDeviceErrorAlertProps = {
+ error?: MediaDeviceFailure | null
+ kind?: MediaDeviceKind | null
+ onClose: () => void
+}
+
+export const MediaDeviceErrorAlert = ({
+ error,
+ kind,
+ onClose,
+}: MediaDeviceErrorAlertProps) => {
+ const { t } = useTranslation('rooms', { keyPrefix: 'mediaErrorDialog' })
+
+ if (!error || !kind) return
+
+ return (
+
+ )
+}
diff --git a/src/frontend/src/locales/de/rooms.json b/src/frontend/src/locales/de/rooms.json
index 3deed51a..4db7930d 100644
--- a/src/frontend/src/locales/de/rooms.json
+++ b/src/frontend/src/locales/de/rooms.json
@@ -60,6 +60,19 @@
"description": "Teilen Sie diesen Link mit Personen, die Sie zum Meeting einladen möchten.",
"permissions": "Personen mit diesem Link benötigen keine Erlaubnis, um diesem Meeting beizutreten."
},
+ "mediaErrorDialog": {
+ "DeviceInUse": {
+ "title": {
+ "audioinput": "Mikrofon konnte nicht aktiviert werden",
+ "videoinput": "Kamera konnte nicht aktiviert werden"
+ },
+ "body": {
+ "audioinput": "Ihr Mikrofon wird bereits in einem anderen Tab oder von einer anderen Anwendung verwendet, was die Aktivierung in diesem Videoanruf verhindert. Wenn Sie möchten, schließen Sie den anderen Tab oder die Anwendung, um es hier zu verwenden.",
+ "videoinput": "Ihre Kamera wird bereits in einem anderen Tab oder von einer anderen Anwendung verwendet, was die Aktivierung in diesem Videoanruf verhindert. Wenn Sie möchten, schließen Sie den anderen Tab oder die Anwendung, um sie hier zu verwenden."
+ }
+ },
+ "close": "OK"
+ },
"error": {
"createRoom": {
"heading": "Authentifizierung erforderlich",
diff --git a/src/frontend/src/locales/en/rooms.json b/src/frontend/src/locales/en/rooms.json
index ee5f22eb..1b5c4c3e 100644
--- a/src/frontend/src/locales/en/rooms.json
+++ b/src/frontend/src/locales/en/rooms.json
@@ -60,6 +60,19 @@
"description": "Share this link with people you want to invite to the meeting.",
"permissions": "People with this link do not need your permission to join this meeting."
},
+ "mediaErrorDialog": {
+ "DeviceInUse": {
+ "title": {
+ "audioinput": "Microphone Activation Failed",
+ "videoinput": "Camera Activation Failed"
+ },
+ "body": {
+ "audioinput": "Your microphone is already in use by another tab or application, which prevents it from being activated in this video call. If you wish, close the other tab or application to use it here.",
+ "videoinput": "Your camera is already in use by another tab or application, which prevents it from being activated in this video call. If you wish, close the other tab or application to use it here."
+ }
+ },
+ "close": "OK"
+ },
"error": {
"createRoom": {
"heading": "Authentication Required",
diff --git a/src/frontend/src/locales/fr/rooms.json b/src/frontend/src/locales/fr/rooms.json
index aa92064c..a3d5a077 100644
--- a/src/frontend/src/locales/fr/rooms.json
+++ b/src/frontend/src/locales/fr/rooms.json
@@ -60,6 +60,19 @@
"description": "Partagez ce lien avec les personnes que vous souhaitez inviter à la réunion.",
"permissions": "Les personnes disposant de ce lien n'ont pas besoin de votre autorisation pour rejoindre cette réunion."
},
+ "mediaErrorDialog": {
+ "DeviceInUse": {
+ "title": {
+ "audioinput": "Activation microphone impossible",
+ "videoinput": "Activation caméra impossible"
+ },
+ "body": {
+ "audioinput": "Votre microphone est déjà utilisé dans un autre onglet ou une autre application, ce qui empêche son activation dans cette visioconférence. Si vous le souhaitez, fermez l'autre onglet ou application pour l'utiliser ici.",
+ "videoinput": "Votre caméra est déjà utilisée dans un autre onglet ou une autre application, ce qui empêche son activation dans cette visioconférence. Si vous le souhaitez, fermez l'autre onglet ou application pour l'utiliser ici."
+ }
+ },
+ "close": "OK"
+ },
"error": {
"createRoom": {
"heading": "Authentification requise",
diff --git a/src/frontend/src/locales/nl/rooms.json b/src/frontend/src/locales/nl/rooms.json
index 1a085d75..56d9bc0a 100644
--- a/src/frontend/src/locales/nl/rooms.json
+++ b/src/frontend/src/locales/nl/rooms.json
@@ -60,6 +60,19 @@
"description": "Deel deze link met mensen die u wilt uitnodigen voor de vergadering.",
"permissions": "Mensen met deze link hebben uw toestemming niet nodig om deel te nemen aan deze vergadering."
},
+ "mediaErrorDialog": {
+ "DeviceInUse": {
+ "title": {
+ "audioinput": "Microfoon activeren mislukt",
+ "videoinput": "Camera activeren mislukt"
+ },
+ "body": {
+ "audioinput": "Je microfoon wordt al gebruikt door een ander tabblad of een andere toepassing, waardoor deze niet geactiveerd kan worden in dit videogesprek. Sluit indien gewenst het andere tabblad of de toepassing om je microfoon hier te gebruiken.",
+ "videoinput": "Je camera wordt al gebruikt door een ander tabblad of een andere toepassing, waardoor deze niet geactiveerd kan worden in dit videogesprek. Sluit indien gewenst het andere tabblad of de toepassing om je camera hier te gebruiken."
+ }
+ },
+ "close": "OK"
+ },
"error": {
"createRoom": {
"heading": "Verificatie vereist",