DUNGEONS-34: implement Webka local streaming app

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
2026-09-06 16:23:09 +05:00
parent 5540b9a1f4
commit 7c737c1011
36 changed files with 21596 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
{
"nav": {
"main": "Main navigation",
"host": "Host studio",
"watch": "Watch",
"accounts": "Accounts",
"settings": "Settings"
},
"common": {
"close": "Close",
"logout": "Sign out",
"skip": "Skip to content",
"working": "Working…",
"loading": "Loading…",
"cancel": "Cancel",
"save": "Save changes",
"refresh": "Refresh"
},
"login": {
"local": "Your network. Your space.",
"headline": "A little closer.",
"headlineAccent": "Wherever you are.",
"description": "Turn a device into a live window. Share your camera or screen, privately on your local network.",
"privacy": "No cloud. Just a connection.",
"title": "Welcome back",
"subtitle": "Sign in to this host to join the stream.",
"setupTitle": "Make yourself at home",
"setupDescription": "Create the administrator account for this host.",
"usernamePlaceholder": "Your username",
"passwordPlaceholder": "Your password",
"setupToken": "Setup token",
"tokenHint": "Use the token in the setup-token file created by the local server.",
"create": "Create host account",
"signin": "Sign in",
"hostAccounts": "Accounts belong to this host only",
"localUtility": "A local streaming utility"
},
"host": {
"eyebrow": "Your local workspace",
"title": "Host studio",
"subtitle": "A live window into your world. You’re in control.",
"start": "Go live",
"stop": "Stop hosting",
"previewTitle": "Your view starts here",
"previewHint": "Choose a source below, then go live when you’re ready.",
"enableCamera": "Enable preview",
"private": "Private stream",
"broadcasting": "Broadcasting to your network",
"previewOnly": "Only you can see this preview",
"audioOff": "Video only · No audio",
"videoSource": "Video source",
"switchAnytime": "Switch anytime",
"rearHint": "Enable the camera first to discover available lenses.",
"uptime": "Time live",
"viewers": "Viewers",
"quality": "Send quality",
"connectDevice": "Connect a device",
"scanHint": "Scan to open the stream on another device.",
"qrAlt": "QR code for the local watch address",
"localAddress": "Local address",
"copy": "Copy address",
"copied": "Address copied",
"sameNetwork": "Connect to the same Wi-Fi",
"connected": "Connected viewers",
"noViewers": "A quiet room, for now",
"inviteHint": "Share the link to invite your first viewer.",
"kick": "Disconnect",
"manageAccess": "Manage access",
"footer": "Local by design. Your stream stays on your network."
},
"sources": {
"front": "Front camera",
"back": "Back camera",
"screen": "Screen"
},
"stream": {
"offline": "Offline",
"connecting": "Connecting",
"reconnecting": "Reconnecting",
"waiting": "Waiting for host",
"live": "Live"
},
"quality": {
"auto": "Adaptive",
"high": "High · 4 Mbps",
"low": "Low · 600 Kbps"
},
"watch": {
"fullscreen": "Toggle fullscreen",
"disconnect": "Disconnect",
"reconnect": "Reconnect",
"waitingTitle": "Ready when they are",
"waitingHint": "The host isn’t live yet. The stream will appear here automatically.",
"connectingTitle": "Bringing you closer",
"connectingHint": "Connecting to the host on your local network."
},
"accounts": {
"eyebrow": "Who’s welcome",
"title": "Accounts & security",
"subtitle": "A private space, with access on your terms.",
"add": "Add viewer",
"protected": "Every connection starts with permission",
"protectedHint": "Sign-in is required. Passwords are hashed. Access can be revoked anytime.",
"localAccounts": "Local accounts",
"account": "Account",
"role": "Role",
"lastLogin": "Last sign-in",
"sessions": "Sessions",
"actions": "Actions",
"you": "You",
"admin": "Host / Admin",
"viewer": "Viewer",
"username": "Username",
"password": "Password",
"usernameHint": "3–40 characters: Latin letters, numbers, dots, underscores or hyphens.",
"passwordHint": "At least 12 characters, including a letter and a number.",
"never": "Not yet",
"reset": "Reset password",
"delete": "Delete account",
"saved": "Access settings updated.",
"activeSessions": "Active sessions",
"sessionHint": "Sessions expire after 30 minutes of inactivity or 12 hours.",
"current": "This session",
"lastActive": "Last active",
"revoke": "Revoke",
"resetHint": "All sessions for {name} will be signed out immediately.",
"deleteHint": "Delete {name}? This removes the account and immediately disconnects all its sessions."
},
"general": {
"eyebrow": "Make it yours",
"title": "Settings",
"subtitle": "Small details. Your kind of space.",
"appearance": "Appearance",
"dark": "Dark glass",
"light": "Light glass",
"accent": "Accent color",
"accentHint": "A little personality for your controls.",
"language": "Language",
"displayLanguage": "Display language",
"languageHint": "Used throughout Webka on this browser.",
"privacy": "Privacy & connection",
"loginRequired": "Require sign-in",
"loginHint": "Only accounts created on this host can watch.",
"alwaysOn": "Always on",
"localOnly": "Local network only",
"localHint": "No cloud relay, analytics, or external media services.",
"savedLocally": "Your preferences are saved in this browser."
},
"colors": {
"lime": "Lime",
"blue": "Blue",
"violet": "Violet",
"peach": "Peach"
},
"errors": {
"server": "Couldn’t complete the request. Check that the local server is running and try again.",
"unauthorized": "Your credentials are incorrect or your session has expired. Please sign in again.",
"forbidden": "This action requires a host account.",
"origin": "This address does not match the server’s configured address. Open the configured local URL.",
"setupToken": "The setup token is incorrect.",
"alreadySetup": "This host already has an administrator. Sign in instead.",
"username": "Use 3–40 Latin letters, numbers, dots, underscores or hyphens.",
"password": "Use at least 12 characters, with a letter and a number.",
"rateLimited": "Too many attempts. Wait a minute and try again.",
"duplicate": "That username is already taken.",
"protectedAccount": "The host account cannot be deleted.",
"notFound": "This account no longer exists.",
"hostBusy": "This session is already connected or another host is live. Close the other tab and try again.",
"secureContext": "Camera and screen access need HTTPS, or localhost on the server device. Open the secure host address.",
"NotAllowedError": "Access was cancelled or denied. Allow camera or screen access in your browser and try again.",
"NotFoundError": "No matching camera was found on this device.",
"NotReadableError": "The camera is busy. Close other apps using it and try again.",
"OverconstrainedError": "This camera source is unavailable. Try the front camera.",
"clipboard": "Couldn’t copy automatically. Select and copy the address above.",
"fullscreen": "Fullscreen isn’t available in this browser."
}
}

View File

@@ -0,0 +1,177 @@
{
"nav": {
"main": "Navegación principal",
"host": "Estudio",
"watch": "Ver",
"accounts": "Cuentas",
"settings": "Ajustes"
},
"common": {
"close": "Cerrar",
"logout": "Cerrar sesión",
"skip": "Ir al contenido",
"working": "Procesando…",
"loading": "Cargando…",
"cancel": "Cancelar",
"save": "Guardar cambios",
"refresh": "Actualizar"
},
"login": {
"local": "Tu red. Tu espacio.",
"headline": "Un poco más cerca.",
"headlineAccent": "Estés donde estés.",
"description": "Convierte un dispositivo en una ventana en directo. Comparte tu cámara o pantalla en tu red local.",
"privacy": "Sin nube. Solo una conexión.",
"title": "Te damos la bienvenida",
"subtitle": "Inicia sesión en este servidor para ver la transmisión.",
"setupTitle": "Este es tu espacio",
"setupDescription": "Crea la cuenta de administrador de este servidor.",
"usernamePlaceholder": "Tu nombre de usuario",
"passwordPlaceholder": "Tu contraseña",
"setupToken": "Código de configuración",
"tokenHint": "Usa el código del archivo setup-token creado por el servidor local.",
"create": "Crear cuenta",
"signin": "Iniciar sesión",
"hostAccounts": "Las cuentas pertenecen solo a este servidor",
"localUtility": "Transmisiones locales"
},
"host": {
"eyebrow": "Tu espacio local",
"title": "Estudio de emisión",
"subtitle": "Una ventana a tu mundo. Tú tienes el control.",
"start": "Emitir en directo",
"stop": "Dejar de emitir",
"previewTitle": "Tu vista empieza aquí",
"previewHint": "Elige una fuente y empieza a emitir cuando quieras.",
"enableCamera": "Activar vista previa",
"private": "Emisión privada",
"broadcasting": "Emitiendo en tu red",
"previewOnly": "Solo tú puedes ver esta vista previa",
"audioOff": "Solo vídeo · Sin audio",
"videoSource": "Fuente de vídeo",
"switchAnytime": "Cambia cuando quieras",
"rearHint": "Activa la cámara para detectar las lentes disponibles.",
"uptime": "Tiempo en directo",
"viewers": "Espectadores",
"quality": "Calidad de envío",
"connectDevice": "Conectar un dispositivo",
"scanHint": "Escanea para abrir la emisión en otro dispositivo.",
"qrAlt": "Código QR de la dirección local",
"localAddress": "Dirección local",
"copy": "Copiar dirección",
"copied": "Dirección copiada",
"sameNetwork": "Conéctate a la misma red Wi-Fi",
"connected": "Espectadores conectados",
"noViewers": "Por ahora, todo tranquilo",
"inviteHint": "Comparte el enlace para invitar a alguien.",
"kick": "Desconectar",
"manageAccess": "Gestionar acceso",
"footer": "Diseñado para tu red. Tu emisión se queda en ella."
},
"sources": {
"front": "Cámara frontal",
"back": "Cámara trasera",
"screen": "Pantalla"
},
"stream": {
"offline": "Desconectado",
"connecting": "Conectando",
"reconnecting": "Reconectando",
"waiting": "Esperando al anfitrión",
"live": "En directo"
},
"quality": {
"auto": "Adaptable",
"high": "Alta · 4 Mbps",
"low": "Baja · 600 Kbps"
},
"watch": {
"fullscreen": "Alternar pantalla completa",
"disconnect": "Desconectar",
"reconnect": "Reconectar",
"waitingTitle": "Todo listo para empezar",
"waitingHint": "El anfitrión aún no está emitiendo. El vídeo aparecerá automáticamente.",
"connectingTitle": "Conectando contigo",
"connectingHint": "Conectando al servidor de tu red local."
},
"accounts": {
"eyebrow": "Quién puede entrar",
"title": "Cuentas y seguridad",
"subtitle": "Un espacio privado, con acceso a tu manera.",
"add": "Añadir espectador",
"protected": "Cada conexión empieza con un permiso",
"protectedHint": "El inicio de sesión es obligatorio. Las contraseñas se almacenan con hash. Puedes revocar el acceso.",
"localAccounts": "Cuentas locales",
"account": "Cuenta",
"role": "Rol",
"lastLogin": "Último acceso",
"sessions": "Sesiones",
"actions": "Acciones",
"you": "Tú",
"admin": "Administrador",
"viewer": "Espectador",
"username": "Nombre de usuario",
"password": "Contraseña",
"usernameHint": "3–40 caracteres: letras latinas, números, puntos, guiones o guiones bajos.",
"passwordHint": "Al menos 12 caracteres, con una letra y un número.",
"never": "Todavía no",
"reset": "Restablecer contraseña",
"delete": "Eliminar cuenta",
"saved": "Ajustes de acceso actualizados.",
"activeSessions": "Sesiones activas",
"sessionHint": "Las sesiones caducan tras 30 minutos de inactividad o 12 horas.",
"current": "Esta sesión",
"lastActive": "Última actividad",
"revoke": "Revocar",
"resetHint": "Se cerrarán todas las sesiones de {name} de inmediato.",
"deleteHint": "¿Eliminar a {name}? Se borrará la cuenta y se desconectarán todas sus sesiones."
},
"general": {
"eyebrow": "A tu gusto",
"title": "Ajustes",
"subtitle": "Pequeños detalles para tu espacio.",
"appearance": "Apariencia",
"dark": "Cristal oscuro",
"light": "Cristal claro",
"accent": "Color de acento",
"accentHint": "Dale personalidad a los controles.",
"language": "Idioma",
"displayLanguage": "Idioma de la interfaz",
"languageHint": "Se usa en toda la aplicación en este navegador.",
"privacy": "Privacidad y conexión",
"loginRequired": "Exigir inicio de sesión",
"loginHint": "Solo las cuentas de este servidor pueden ver la emisión.",
"alwaysOn": "Siempre activo",
"localOnly": "Solo red local",
"localHint": "Sin retransmisión en la nube, analítica ni servicios multimedia externos.",
"savedLocally": "Tus preferencias se guardan en este navegador."
},
"colors": {
"lime": "Lima",
"blue": "Azul",
"violet": "Violeta",
"peach": "Melocotón"
},
"errors": {
"server": "No se pudo completar la solicitud. Comprueba que el servidor local esté en marcha.",
"unauthorized": "Las credenciales no son correctas o la sesión ha caducado. Vuelve a iniciar sesión.",
"forbidden": "Esta acción requiere una cuenta de administrador.",
"origin": "Esta dirección no coincide con la del servidor. Abre la URL local configurada.",
"setupToken": "El código de configuración no es correcto.",
"alreadySetup": "Este servidor ya tiene un administrador. Inicia sesión.",
"username": "Usa 3–40 letras latinas, números, puntos o guiones.",
"password": "Usa al menos 12 caracteres, con una letra y un número.",
"rateLimited": "Demasiados intentos. Espera un minuto.",
"duplicate": "Ese nombre de usuario ya existe.",
"protectedAccount": "No se puede eliminar la cuenta del administrador.",
"notFound": "Esta cuenta ya no existe.",
"hostBusy": "Esta sesión ya está conectada u otro anfitrión está emitiendo. Cierra la otra pestaña.",
"secureContext": "La cámara y la pantalla necesitan HTTPS o localhost en el servidor. Abre la dirección segura.",
"NotAllowedError": "Se canceló o denegó el acceso. Permite el acceso a la cámara o pantalla.",
"NotFoundError": "No se encontró una cámara compatible.",
"NotReadableError": "La cámara está ocupada. Cierra las otras aplicaciones que la usan.",
"OverconstrainedError": "Esta fuente no está disponible. Prueba la cámara frontal.",
"clipboard": "No se pudo copiar automáticamente. Selecciona y copia la dirección.",
"fullscreen": "La pantalla completa no está disponible en este navegador."
}
}

View File

@@ -0,0 +1,177 @@
{
"nav": {
"main": "Основная навигация",
"host": "Студия",
"watch": "Просмотр",
"accounts": "Аккаунты",
"settings": "Настройки"
},
"common": {
"close": "Закрыть",
"logout": "Выйти",
"skip": "К содержимому",
"working": "Подождите…",
"loading": "Загрузка…",
"cancel": "Отмена",
"save": "Сохранить",
"refresh": "Обновить"
},
"login": {
"local": "Ваша сеть. Ваше пространство.",
"headline": "Немного ближе.",
"headlineAccent": "Где бы вы ни были.",
"description": "Превратите устройство в окно прямого эфира. Делитесь камерой или экраном в своей локальной сети.",
"privacy": "Без облака. Только связь.",
"title": "С возвращением",
"subtitle": "Войдите на этот сервер для просмотра.",
"setupTitle": "Добро пожаловать домой",
"setupDescription": "Создайте аккаунт администратора этого сервера.",
"usernamePlaceholder": "Имя пользователя",
"passwordPlaceholder": "Пароль",
"setupToken": "Код первоначальной настройки",
"tokenHint": "Введите код из файла setup-token, созданного локальным сервером.",
"create": "Создать аккаунт",
"signin": "Войти",
"hostAccounts": "Аккаунты доступны только на этом сервере",
"localUtility": "Локальные трансляции"
},
"host": {
"eyebrow": "Ваше локальное пространство",
"title": "Студия трансляций",
"subtitle": "Окно в ваш мир. Всё под вашим контролем.",
"start": "Начать эфир",
"stop": "Остановить",
"previewTitle": "Здесь начинается ваш эфир",
"previewHint": "Выберите источник и начните эфир, когда будете готовы.",
"enableCamera": "Включить предпросмотр",
"private": "Приватный эфир",
"broadcasting": "Эфир в вашей сети",
"previewOnly": "Предпросмотр виден только вам",
"audioOff": "Только видео · Без звука",
"videoSource": "Источник видео",
"switchAnytime": "Меняйте в любой момент",
"rearHint": "Включите камеру, чтобы найти доступные объективы.",
"uptime": "Время эфира",
"viewers": "Зрители",
"quality": "Качество передачи",
"connectDevice": "Подключить устройство",
"scanHint": "Отсканируйте код на другом устройстве.",
"qrAlt": "QR-код адреса просмотра",
"localAddress": "Локальный адрес",
"copy": "Копировать адрес",
"copied": "Адрес скопирован",
"sameNetwork": "Подключитесь к той же Wi-Fi сети",
"connected": "Подключённые зрители",
"noViewers": "Пока здесь тихо",
"inviteHint": "Поделитесь ссылкой с первым зрителем.",
"kick": "Отключить",
"manageAccess": "Управление доступом",
"footer": "Локально по замыслу. Эфир остаётся в вашей сети."
},
"sources": {
"front": "Передняя камера",
"back": "Задняя камера",
"screen": "Экран"
},
"stream": {
"offline": "Не в эфире",
"connecting": "Подключение",
"reconnecting": "Переподключение",
"waiting": "Ожидание эфира",
"live": "В эфире"
},
"quality": {
"auto": "Автоматически",
"high": "Высокое · 4 Мбит/с",
"low": "Низкое · 600 Кбит/с"
},
"watch": {
"fullscreen": "Полноэкранный режим",
"disconnect": "Отключиться",
"reconnect": "Подключиться снова",
"waitingTitle": "Готовы к началу эфира",
"waitingHint": "Эфир ещё не начался. Видео появится здесь автоматически.",
"connectingTitle": "Устанавливаем связь",
"connectingHint": "Подключаемся к серверу в вашей локальной сети."
},
"accounts": {
"eyebrow": "Кому открыт доступ",
"title": "Аккаунты и безопасность",
"subtitle": "Личное пространство с доступом на ваших условиях.",
"add": "Добавить зрителя",
"protected": "Каждое подключение — с разрешения",
"protectedHint": "Вход обязателен. Пароли хешируются. Доступ можно отозвать в любой момент.",
"localAccounts": "Локальные аккаунты",
"account": "Аккаунт",
"role": "Роль",
"lastLogin": "Последний вход",
"sessions": "Сеансы",
"actions": "Действия",
"you": "Вы",
"admin": "Владелец",
"viewer": "Зритель",
"username": "Имя пользователя",
"password": "Пароль",
"usernameHint": "3–40 символов: латинские буквы, цифры, точки, подчёркивания или дефисы.",
"passwordHint": "Не менее 12 символов, включая букву и цифру.",
"never": "Ещё не входил",
"reset": "Сменить пароль",
"delete": "Удалить аккаунт",
"saved": "Настройки доступа обновлены.",
"activeSessions": "Активные сеансы",
"sessionHint": "Сеансы истекают через 30 минут бездействия или через 12 часов.",
"current": "Этот сеанс",
"lastActive": "Последняя активность",
"revoke": "Отозвать",
"resetHint": "Все сеансы пользователя {name} будут завершены.",
"deleteHint": "Удалить {name}? Аккаунт будет удалён, все его сеансы завершатся."
},
"general": {
"eyebrow": "На ваш вкус",
"title": "Настройки",
"subtitle": "Маленькие детали вашего пространства.",
"appearance": "Внешний вид",
"dark": "Тёмное стекло",
"light": "Светлое стекло",
"accent": "Цвет акцента",
"accentHint": "Добавьте индивидуальности элементам управления.",
"language": "Язык",
"displayLanguage": "Язык интерфейса",
"languageHint": "Используется во всём приложении в этом браузере.",
"privacy": "Приватность и подключение",
"loginRequired": "Обязательный вход",
"loginHint": "Просмотр доступен только аккаунтам этого сервера.",
"alwaysOn": "Всегда включено",
"localOnly": "Только локальная сеть",
"localHint": "Без облачных ретрансляторов, аналитики и внешних медиасервисов.",
"savedLocally": "Предпочтения сохраняются в этом браузере."
},
"colors": {
"lime": "Лайм",
"blue": "Голубой",
"violet": "Фиолетовый",
"peach": "Персиковый"
},
"errors": {
"server": "Не удалось выполнить запрос. Проверьте, что локальный сервер запущен.",
"unauthorized": "Неверные данные для входа или сеанс истёк. Войдите снова.",
"forbidden": "Для этого действия нужен аккаунт владельца.",
"origin": "Адрес не совпадает с настройкой сервера. Откройте настроенный локальный URL.",
"setupToken": "Неверный код первоначальной настройки.",
"alreadySetup": "Администратор уже создан. Войдите в аккаунт.",
"username": "Используйте 3–40 латинских букв, цифр, точек, подчёркиваний или дефисов.",
"password": "Используйте не менее 12 символов, включая букву и цифру.",
"rateLimited": "Слишком много попыток. Подождите минуту.",
"duplicate": "Это имя пользователя уже занято.",
"protectedAccount": "Аккаунт владельца нельзя удалить.",
"notFound": "Этот аккаунт больше не существует.",
"hostBusy": "Этот сеанс уже подключён или другой владелец ведёт эфир. Закройте другую вкладку.",
"secureContext": "Для доступа к камере и экрану нужен HTTPS или localhost на устройстве сервера. Откройте защищённый адрес.",
"NotAllowedError": "Доступ отменён или запрещён. Разрешите камеру или экран в браузере.",
"NotFoundError": "На устройстве не найдена подходящая камера.",
"NotReadableError": "Камера занята. Закройте другие использующие её приложения.",
"OverconstrainedError": "Этот источник недоступен. Попробуйте переднюю камеру.",
"clipboard": "Не удалось скопировать автоматически. Выделите и скопируйте адрес выше.",
"fullscreen": "Полноэкранный режим недоступен в этом браузере."
}
}