|
\ |
|
import argparse, asyncio, websockets, wave, json, sys |
|
|
|
def read_wav_pcm16(path, chunk_ms=20): |
|
with wave.open(path, 'rb') as wf: |
|
assert wf.getsampwidth() == 2, "Expect 16-bit PCM WAV" |
|
sr = wf.getframerate() |
|
assert sr == 16000, f"Expect 16kHz, got {sr}" |
|
ch = wf.getnchannels() |
|
assert ch == 1, f"Expect mono, got {ch}" |
|
|
|
frames_per_chunk = int(sr * (chunk_ms/1000.0)) |
|
while True: |
|
data = wf.readframes(frames_per_chunk) |
|
if not data: |
|
break |
|
yield data |
|
|
|
async def main(): |
|
ap = argparse.ArgumentParser() |
|
ap.add_argument("--url", default="ws://localhost:8080/ws/amd") |
|
ap.add_argument("--wav", required=True) |
|
ap.add_argument("--chunk_ms", type=int, default=20) |
|
args = ap.parse_args() |
|
|
|
async with websockets.connect(args.url, max_size=2**23) as ws: |
|
async def receiver(): |
|
try: |
|
async for msg in ws: |
|
print("SERVER:", msg) |
|
except Exception as e: |
|
print("Receiver ended:", e, file=sys.stderr) |
|
|
|
recv_task = asyncio.create_task(receiver()) |
|
|
|
for chunk in read_wav_pcm16(args.wav, args.chunk_ms): |
|
await ws.send(chunk) |
|
await asyncio.sleep(args.chunk_ms/1000.0) |
|
|
|
await ws.send(json.dumps({"type":"flush"})) |
|
await asyncio.sleep(1.0) |
|
await ws.close() |
|
await recv_task |
|
|
|
if __name__ == "__main__": |
|
asyncio.run(main()) |
|
|