comparison dictation/webrtc_smoke.py @ 275:78699f810817

Add Qwen3-VL and WebRTC dictation services Add Bazel targets for the CUDA-backed Qwen3-VL server and a local WebRTC faster-whisper dictation service. Co-authored-by: Copilot <[email protected]> Copilot-Session: e3d8cb06-6c95-4ae0-9757-651d3796ab00
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 10:58:47 -0700
parents
children
comparison
equal deleted inserted replaced
274:c9be578316a6 275:78699f810817
1 from __future__ import annotations
2
3 import argparse
4 import asyncio
5 import json
6
7 from aiortc import RTCPeerConnection, RTCSessionDescription
8 from aiortc.contrib.media import MediaPlayer
9 import httpx
10
11
12 async def run(server_url: str, audio_path: str, timeout: float) -> None:
13 peer = RTCPeerConnection()
14 channel = peer.createDataChannel("transcripts")
15 player = MediaPlayer(audio_path)
16 if player.audio is None:
17 raise RuntimeError("Input file does not contain an audio track")
18 peer.addTrack(player.audio)
19 final_received = asyncio.Event()
20 session_id = None
21
22 @channel.on("message")
23 def on_message(message):
24 event = json.loads(message)
25 print(json.dumps(event, ensure_ascii=False), flush=True)
26 if event.get("type") == "transcript.final":
27 final_received.set()
28
29 try:
30 offer = await peer.createOffer()
31 await peer.setLocalDescription(offer)
32 async with httpx.AsyncClient(timeout=timeout) as client:
33 response = await client.post(
34 f"{server_url}/api/webrtc/offer",
35 json={
36 "sdp": peer.localDescription.sdp,
37 "type": peer.localDescription.type,
38 },
39 )
40 response.raise_for_status()
41 answer = response.json()
42 session_id = answer["sessionId"]
43 await peer.setRemoteDescription(
44 RTCSessionDescription(
45 sdp=answer["sdp"],
46 type=answer["type"],
47 )
48 )
49 await asyncio.wait_for(final_received.wait(), timeout=timeout)
50 await client.post(
51 f"{server_url}/api/webrtc/session/{session_id}/close"
52 )
53 finally:
54 await peer.close()
55
56
57 def main() -> None:
58 parser = argparse.ArgumentParser()
59 parser.add_argument("audio")
60 parser.add_argument(
61 "--server",
62 default="http://127.0.0.1:8090",
63 )
64 parser.add_argument("--timeout", type=float, default=60.0)
65 args = parser.parse_args()
66 asyncio.run(run(args.server.rstrip("/"), args.audio, args.timeout))
67
68
69 if __name__ == "__main__":
70 main()