""" Сервис для работы с Jitsi Meet. Генерация JWT токенов, создание комнат, управление участниками. """ import jwt import uuid from datetime import datetime, timedelta from django.conf import settings from typing import Dict, Optional class JitsiService: """Сервис для интеграции с Jitsi Meet.""" @staticmethod def generate_room_name() -> str: """ Генерация уникального имени комнаты. Returns: str: Уникальное имя комнаты """ return str(uuid.uuid4()) @staticmethod def generate_jwt_token( room_name: str, user_id: int, user_name: str, user_email: str, is_moderator: bool = False, avatar_url: Optional[str] = None, expires_in_minutes: int = 120 ) -> str: """ Генерация JWT токена для аутентификации в Jitsi Meet. Args: room_name: Имя комнаты user_id: ID пользователя user_name: Имя пользователя user_email: Email пользователя is_moderator: Является ли пользователь модератором avatar_url: URL аватара пользователя expires_in_minutes: Время жизни токена в минутах Returns: str: JWT токен """ # Получаем настройки из environment app_id = getattr(settings, 'JITSI_APP_ID', 'platform') app_secret = getattr(settings, 'JITSI_APP_SECRET', 'secret') # Время создания и истечения токена now = datetime.utcnow() exp = now + timedelta(minutes=expires_in_minutes) # Payload токена payload = { # Стандартные JWT claims 'iss': app_id, 'aud': app_id, 'sub': getattr(settings, 'JITSI_XMPP_DOMAIN', 'meet.jitsi'), 'room': room_name, 'exp': int(exp.timestamp()), 'iat': int(now.timestamp()), 'nbf': int(now.timestamp()), # Контекст пользователя 'context': { 'user': { 'id': str(user_id), 'name': user_name, 'email': user_email, 'avatar': avatar_url or '', 'moderator': is_moderator, }, 'group': getattr(settings, 'JITSI_APP_NAME', 'Платформа'), }, # Права доступа 'moderator': is_moderator, } # Генерация токена token = jwt.encode( payload, app_secret, algorithm='HS256' ) return token @staticmethod def get_room_url( room_name: str, jwt_token: Optional[str] = None, config_overrides: Optional[Dict] = None ) -> str: """ Получение URL комнаты Jitsi Meet. Args: room_name: Имя комнаты jwt_token: JWT токен (опционально) config_overrides: Переопределение конфигурации (опционально) Returns: str: URL комнаты """ jitsi_url = getattr(settings, 'JITSI_PUBLIC_URL', 'http://127.0.0.1:8443') # Базовый URL url = f"{jitsi_url}/{room_name}" # Добавляем параметры params = [] if jwt_token: params.append(f"jwt={jwt_token}") if config_overrides: # Добавляем config overrides как URL параметры for key, value in config_overrides.items(): if isinstance(value, bool): value = 'true' if value else 'false' params.append(f"config.{key}={value}") if params: url += '?' + '&'.join(params) return url @staticmethod def get_default_config_overrides(user_role: str = 'client') -> Dict: """ Получение стандартных переопределений конфигурации. Args: user_role: Роль пользователя (mentor, client, parent) Returns: Dict: Переопределения конфигурации """ # Базовые настройки для всех config = { 'startWithAudioMuted': False, 'startWithVideoMuted': False, 'prejoinPageEnabled': False, # Отключаем prejoin 'disableDeepLinking': True, # Отключаем deep linking 'enableWelcomePage': False, # Отключаем welcome page 'enableClosePage': False, # Отключаем close page 'defaultLanguage': 'ru', 'disableThirdPartyRequests': True, 'enableNoisyMicDetection': True, # Настройки для использования GPU (аппаратное ускорение) 'p2p.enabled': False, # Отключаем P2P для работы через сервер с GPU 'resolution': 720, # Разрешение видео 'maxReceiveFrameRate': 30, # Максимальный FPS 'maxReceiveResolution': 720, # Максимальное разрешение приема 'videoQuality.adaptiveLastN': 4, # Адаптивное качество 'videoQuality.persist': True, # Сохранять настройки качества # Приоритет H.264 кодека для лучшей поддержки GPU 'codecPreferences': 'H264', # H.264 лучше поддерживает GPU ускорение # Дополнительные настройки производительности 'enableLayerSuspension': True, # Приостановка слоев для экономии ресурсов 'enableRemb': True, # REMB (Receiver Estimated Maximum Bitrate) для адаптивного битрейта 'enableTcc': True, # TCC (Transport-CC) для лучшего контроля качества } # Настройки для клиентов (студентов) if user_role == 'client': config.update({ 'disableModeratorIndicator': True, 'enableForcedReload': False, }) # Настройки для менторов (модераторы) elif user_role == 'mentor': config.update({ 'disableModeratorIndicator': False, 'enableForcedReload': True, }) return config