|
|
|
import asyncio |
|
import json |
|
import uuid |
|
|
|
from fastapi import FastAPI, WebSocket, WebSocketDisconnect |
|
from aiortc import RTCPeerConnection, RTCSessionDescription, RTCIceCandidate |
|
|
|
app = FastAPI() |
|
connections = {} |
|
|
|
@app.websocket("/ws/{room_id}/{client_id}") |
|
async def websocket_endpoint(websocket: WebSocket, room_id: str, client_id: str): |
|
await websocket.accept() |
|
pc = RTCPeerConnection() |
|
connections[client_id] = pc |
|
|
|
@pc.on("track") |
|
def on_track(track): |
|
print("Track received") |
|
|
|
try: |
|
while True: |
|
message = await websocket.receive_text() |
|
data = json.loads(message) |
|
if data["type"] == "offer": |
|
offer = RTCSessionDescription(sdp=data["sdp"], type=data["type"]) |
|
await pc.setRemoteDescription(offer) |
|
answer = await pc.createAnswer() |
|
await pc.setLocalDescription(answer) |
|
await websocket.send_text(json.dumps({"type": "answer", "sdp": pc.localDescription.sdp})) |
|
elif data["type"] == "answer": |
|
answer = RTCSessionDescription(sdp=data["sdp"], type=data["type"]) |
|
await pc.setRemoteDescription(answer) |
|
elif data["type"] == "candidate": |
|
candidate = RTCIceCandidate( |
|
component=data["candidate"]["component"], |
|
foundation=data["candidate"]["foundation"], |
|
ip=data["candidate"]["ip"], |
|
port=data["candidate"]["port"], |
|
priority=data["candidate"]["priority"], |
|
protocol=data["candidate"]["protocol"], |
|
type=data["candidate"]["type"], |
|
sdpMid=data["candidate"]["sdpMid"], |
|
sdpMLineIndex=data["candidate"]["sdpMLineIndex"], |
|
usernameFragment=data["candidate"]["usernameFragment"], |
|
) |
|
await pc.addIceCandidate(candidate) |
|
else: |
|
print(f"Received unknown message: {data}") |
|
|
|
except WebSocketDisconnect: |
|
await pc.close() |
|
del connections[client_id] |
|
print(f"Client {client_id} disconnected from room {room_id}") |