first commit
This commit is contained in:
commit
efa5080897
127 changed files with 18610 additions and 0 deletions
76
backend/app/voice/bonvoice_media.py
Normal file
76
backend/app/voice/bonvoice_media.py
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
"""Bonvoice media — raw frame relay only (no PCM processing on the API)."""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from collections.abc import Awaitable, Callable
|
||||
from typing import Any
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import WebSocket, WebSocketDisconnect
|
||||
|
||||
from .presence import console_presence
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
OnEndCallback = Callable[[], Awaitable[None]]
|
||||
|
||||
|
||||
def parse_event(raw: str) -> dict[str, Any] | None:
|
||||
try:
|
||||
payload = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
return payload if isinstance(payload, dict) else None
|
||||
|
||||
|
||||
def extract_start_metadata(message: dict[str, Any]) -> dict[str, Any]:
|
||||
data = message.get("data") or message.get("start") or {}
|
||||
stream_id = data.get("stream_id") if data.get("stream_id") is not None else message.get("stream_id")
|
||||
return {
|
||||
"stream_id": stream_id,
|
||||
"stream_id_str": str(stream_id) if stream_id is not None else "",
|
||||
"call_id": str(data.get("call_id") or message.get("call_id") or ""),
|
||||
"from": str(data.get("from") or message.get("from") or ""),
|
||||
"to": str(data.get("to") or message.get("to") or ""),
|
||||
}
|
||||
|
||||
|
||||
async def run_console_raw_relay(
|
||||
provider: WebSocket,
|
||||
user_id: UUID,
|
||||
console_ws: WebSocket,
|
||||
*,
|
||||
initial_frames: list[str] | None = None,
|
||||
on_end: OnEndCallback | None = None,
|
||||
) -> None:
|
||||
"""Console test bridge — forward raw JSON frames both ways (no server audio processing)."""
|
||||
stop = asyncio.Event()
|
||||
relay_queue = await console_presence.start_relay(user_id)
|
||||
|
||||
for raw in initial_frames or []:
|
||||
await console_ws.send_text(raw)
|
||||
|
||||
async def console_to_provider() -> None:
|
||||
try:
|
||||
while not stop.is_set():
|
||||
raw = await relay_queue.get()
|
||||
await provider.send_text(raw)
|
||||
except (WebSocketDisconnect, RuntimeError):
|
||||
stop.set()
|
||||
|
||||
async def provider_to_console() -> None:
|
||||
try:
|
||||
while not stop.is_set():
|
||||
raw = await provider.receive_text()
|
||||
await console_ws.send_text(raw)
|
||||
except (WebSocketDisconnect, RuntimeError):
|
||||
stop.set()
|
||||
|
||||
try:
|
||||
await asyncio.gather(console_to_provider(), provider_to_console())
|
||||
finally:
|
||||
stop.set()
|
||||
await console_presence.stop_relay(user_id)
|
||||
if on_end:
|
||||
await on_end()
|
||||
Loading…
Add table
Add a link
Reference in a new issue