uchill/backend/apps/video/jitsi_service.py

190 lines
7.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Сервис для работы с 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