The websockets library defaults to ping_interval=20, ping_timeout=20. go2rtc doesn't respond to these pings, so the upstream WebSocket was being killed after ~50 seconds causing all camera streams to freeze. Disabled ping_interval and ping_timeout on the upstream connection.
71 lines
1.9 KiB
Python
71 lines
1.9 KiB
Python
import asyncio
|
|
import logging
|
|
|
|
import httpx
|
|
import websockets
|
|
from fastapi import APIRouter, Request, WebSocket, WebSocketDisconnect, Response
|
|
|
|
from config import get_config
|
|
|
|
logger = logging.getLogger(__name__)
|
|
router = APIRouter(prefix="/api/go2rtc")
|
|
|
|
|
|
@router.post("/webrtc")
|
|
async def proxy_webrtc(request: Request, src: str):
|
|
"""Proxy WebRTC SDP exchange to go2rtc."""
|
|
config = get_config()
|
|
target = f"{config.go2rtc.url}/api/webrtc?src={src}"
|
|
body = await request.body()
|
|
|
|
async with httpx.AsyncClient() as client:
|
|
resp = await client.post(
|
|
target,
|
|
content=body,
|
|
headers={"Content-Type": "application/sdp"},
|
|
timeout=10.0,
|
|
)
|
|
|
|
return Response(
|
|
content=resp.content,
|
|
status_code=resp.status_code,
|
|
media_type="application/sdp",
|
|
)
|
|
|
|
|
|
@router.websocket("/ws")
|
|
async def proxy_mse_ws(ws: WebSocket, src: str):
|
|
"""Proxy MSE WebSocket to go2rtc."""
|
|
config = get_config()
|
|
go2rtc_ws_url = config.go2rtc.url.replace("http", "ws")
|
|
target = f"{go2rtc_ws_url}/api/ws?src={src}"
|
|
|
|
await ws.accept()
|
|
|
|
try:
|
|
async with websockets.connect(
|
|
target,
|
|
ping_interval=None,
|
|
ping_timeout=None,
|
|
close_timeout=5,
|
|
) as upstream:
|
|
|
|
async def forward_to_client():
|
|
async for msg in upstream:
|
|
if isinstance(msg, bytes):
|
|
await ws.send_bytes(msg)
|
|
else:
|
|
await ws.send_text(msg)
|
|
|
|
async def forward_to_upstream():
|
|
while True:
|
|
data = await ws.receive_text()
|
|
await upstream.send(data)
|
|
|
|
await asyncio.gather(
|
|
forward_to_client(),
|
|
forward_to_upstream(),
|
|
)
|
|
except (WebSocketDisconnect, websockets.ConnectionClosed, Exception):
|
|
pass
|