Spaces:
Sleeping
Sleeping
| import asyncio | |
| import websockets | |
| import sounddevice as sd | |
| import numpy as np | |
| import json | |
| import sys | |
| # Audio recording settings | |
| SAMPLING_RATE = 16000 | |
| CHANNELS = 1 | |
| BLOCK_SIZE = 1024 # 1024 samples at 16kHz = 64ms of audio | |
| async def stream_mic(): | |
| uri = "ws://localhost:8000/stream" | |
| print(f"Connecting to server at {uri}...") | |
| try: | |
| async with websockets.connect(uri) as websocket: | |
| print("Connected successfully! Start speaking...") | |
| loop = asyncio.get_running_loop() | |
| audio_queue = asyncio.Queue() | |
| def callback(indata, frames, time, status): | |
| if status: | |
| print(f"\n[Warning] Input status: {status}", file=sys.stderr, flush=True) | |
| # indata has shape (BLOCK_SIZE, CHANNELS) | |
| # Convert float32 array in [-1.0, 1.0] to 16-bit PCM bytes | |
| # Server expects 16-bit PCM (int16) scaled to float32 | |
| audio_int16 = (indata.flatten() * 32767).astype(np.int16) | |
| audio_bytes = audio_int16.tobytes() | |
| # Put in queue in thread-safe manner | |
| loop.call_soon_threadsafe(audio_queue.put_nowait, audio_bytes) | |
| # Define the input stream | |
| stream = sd.InputStream( | |
| samplerate=SAMPLING_RATE, | |
| channels=CHANNELS, | |
| blocksize=BLOCK_SIZE, | |
| dtype='float32', | |
| callback=callback | |
| ) | |
| async def send_audio(): | |
| with stream: | |
| print("Microphone stream is live. Press Ctrl+C to stop.") | |
| while True: | |
| data = await audio_queue.get() | |
| await websocket.send(data) | |
| async def receive_transcripts(): | |
| try: | |
| async for message in websocket: | |
| data = json.loads(message) | |
| if "text" in data: | |
| print(f"[Live Transcript]: {data['text']}", flush=True) | |
| except websockets.exceptions.ConnectionClosed: | |
| print("\nConnection closed by server.") | |
| # Run sending and receiving concurrently | |
| await asyncio.gather(send_audio(), receive_transcripts()) | |
| except Exception as e: | |
| print(f"\nError: {e}") | |
| if __name__ == "__main__": | |
| try: | |
| asyncio.run(stream_mic()) | |
| except KeyboardInterrupt: | |
| print("\nStopped microphone stream.") | |