Add WebRTC TURN configuration and related enhancements
- Introduce a new `.env.example` file for environment variable setup, including `PUBLIC_IP`, `TURN_SECRET`, and `TURN_URLS` for WebRTC TURN server configuration. - Update `docker-compose.yaml` to support TURN server deployment with necessary environment variables and commands. - Enhance backend configuration and routes to include WebRTC ICE server settings, allowing for STUN/TURN server integration. - Implement a new service for managing WebRTC ICE server configurations, providing credentials for TURN when configured. - Modify frontend API to fetch ICE server configurations dynamically, improving support for cross-network voice preview.
This commit is contained in:
60
backend/services/webrtc_ice.py
Normal file
60
backend/services/webrtc_ice.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""WebRTC ICE server config: STUN + optional TURN for cross-network voice preview."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import time
|
||||
|
||||
import config
|
||||
|
||||
STUN_URL = "stun:stun.l.google.com:19302"
|
||||
|
||||
|
||||
def _turn_credentials() -> tuple[str, str] | None:
|
||||
"""Return (username, credential) for TURN, or None when TURN is not configured."""
|
||||
if not config.TURN_URLS:
|
||||
return None
|
||||
if config.TURN_SECRET:
|
||||
expiry = int(time.time()) + config.TURN_CREDENTIAL_TTL
|
||||
username = f"{expiry}:ai-video"
|
||||
credential = base64.b64encode(
|
||||
hmac.new(
|
||||
config.TURN_SECRET.encode("utf-8"),
|
||||
username.encode("utf-8"),
|
||||
hashlib.sha1,
|
||||
).digest()
|
||||
).decode("utf-8")
|
||||
return username, credential
|
||||
if config.TURN_USERNAME and config.TURN_PASSWORD:
|
||||
return config.TURN_USERNAME, config.TURN_PASSWORD
|
||||
return None
|
||||
|
||||
|
||||
def client_ice_servers() -> list[dict]:
|
||||
"""ICE servers for browser RTCPeerConnection (JSON-serializable)."""
|
||||
servers: list[dict] = [{"urls": STUN_URL}]
|
||||
creds = _turn_credentials()
|
||||
if not creds:
|
||||
return servers
|
||||
username, credential = creds
|
||||
for url in config.TURN_URLS:
|
||||
servers.append({"urls": url, "username": username, "credential": credential})
|
||||
return servers
|
||||
|
||||
|
||||
def aiortc_ice_servers() -> list:
|
||||
"""ICE servers for backend SmallWebRTCConnection / aiortc."""
|
||||
from aiortc import RTCIceServer
|
||||
|
||||
servers = [RTCIceServer(urls=STUN_URL)]
|
||||
creds = _turn_credentials()
|
||||
if not creds:
|
||||
return servers
|
||||
username, credential = creds
|
||||
for url in config.TURN_URLS:
|
||||
servers.append(
|
||||
RTCIceServer(urls=url, username=username, credential=credential)
|
||||
)
|
||||
return servers
|
||||
Reference in New Issue
Block a user