πŸŽ™οΈ ESP32 Real-Time Audio Transcriber

A real-time speech-to-text system that captures audio from an ESP32 + INMP441 microphone, streams it to a cloud-hosted FastAPI server, transcribes it via Deepgram Nova-3, and generates conversational AI responses using Google Gemini 2.5 Flash β€” all viewable in a sleek live web dashboard.


πŸ“Έ Product Images

Product Image 1    Product Image 2

ESP32 + INMP441 assembly housed in a custom 3D printed case

πŸŽ₯ Demo Video

β–Ά Watch the product demo video


✨ Features

  • Real-time transcription β€” Live interim + final transcripts powered by Deepgram Nova-3
  • AI conversation β€” Press Q or click Ask Gemini to get a conversational response from Gemini 2.5 Flash with multi-turn context
  • WiFi captive portal β€” No hardcoded credentials; configure WiFi via phone/laptop on first boot
  • One-click deploy β€” Server deploys to Railway with zero configuration
  • Live status dashboard β€” Monitor WebSocket, Deepgram, ESP32, and Gemini connection states in real time
  • Debug panel β€” Built-in debug log overlay for troubleshooting

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        WSS (binary audio)        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       WSS        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   ESP32 +   β”‚ ──────────────────────────────▢   β”‚  FastAPI Server  β”‚ ──────────────▢  β”‚ Deepgram  β”‚
β”‚   INMP441   β”‚                                   β”‚  (Railway)       β”‚ ◀──────────────  β”‚ Nova-3    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                   β”‚                  β”‚   transcripts    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                  β”‚                  β”‚
                                                  β”‚                  β”‚       REST        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”        WSS (text events)          β”‚                  β”‚ ──────────────▢  β”‚  Gemini   β”‚
β”‚   Browser   β”‚ ◀──────────────────────────────   β”‚                  β”‚ ◀──────────────  β”‚  2.5 Flashβ”‚
β”‚   Dashboard β”‚ ──────────────────────────────▢   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   AI response    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        "PROCESS" / "CLEAR"

πŸ“ Project Structure

audio_transcriber/
β”œβ”€β”€ server.py                        # FastAPI server (transcription + LLM + web UI)
β”œβ”€β”€ esp32_firmware/
β”‚   └── esp32_firmware.ino           # Arduino sketch for ESP32 + INMP441
β”œβ”€β”€ requirements.txt                 # Python dependencies
β”œβ”€β”€ Procfile                         # Railway process definition
β”œβ”€β”€ runtime.txt                      # Python version for Railway
β”œβ”€β”€ .gitignore                       # Ignored files (venv, cache, etc.)
└── README.md                        # This file

πŸ”§ Hardware Requirements

Component Description
ESP32 Dev Board Any ESP32-WROOM-32 based board
INMP441 I2S MEMS microphone module
Jumper wires 5 connections (see wiring below)
USB cable For flashing and serial monitor

Wiring Diagram

ESP32 Pin INMP441 Pin Function
GPIO 26 SCK Bit Clock
GPIO 32 WS Word Select (LRCLK)
GPIO 33 SD Serial Data Out
3.3V VDD Power
GND GND + L/R Ground (L/R β†’ GND for left channel)

πŸš€ Getting Started

1. Deploy the Server to Railway

  1. Push this repository to GitHub
  2. Go to railway.app β†’ New Project β†’ Deploy from GitHub Repo
  3. Railway auto-detects the Procfile and runtime.txt β€” no extra config needed
  4. Note your deployed URL (e.g. audio-transcriber.up.railway.app)

2. Flash the ESP32 Firmware

  1. Open esp32_firmware/esp32_firmware.ino in Arduino IDE
  2. Install the required libraries via Library Manager:
    • WiFiManager by tzapu (β‰₯ 2.0)
    • WebSockets by Markus Sattler (β‰₯ 2.4)
  3. Update SERVER_HOST in the sketch if your Railway URL differs:
    const char* SERVER_HOST = "your-app-name.up.railway.app";
    
  4. Select board: ESP32 Dev Module
  5. Flash and open the Serial Monitor at 115200 baud

3. Connect to WiFi

  1. On first boot, the ESP32 creates a WiFi AP named Transcriber-Setup
  2. Connect to it from your phone or laptop
  3. Select your home WiFi network and enter the password
  4. The ESP32 saves the credentials and auto-connects on subsequent boots

πŸ’‘ Reset WiFi: Hold the BOOT button (GPIO 0) while powering on to clear saved credentials.

4. View the Dashboard

Open your Railway URL in a browser:

https://audio-transcriber.up.railway.app

You'll see live transcription appear as the ESP32 streams audio.


🧠 Using Gemini AI

Once transcription lines appear:

  1. Press Q on your keyboard or click the ⬑ Ask Gemini button
  2. Gemini reads the buffered transcript and responds in a casual, conversational tone
  3. The conversation supports multi-turn context β€” keep talking and asking
  4. Click Reset Chat to clear the conversation history

βš™οΈ Configuration

Server Environment

Variable Default Description
PORT 8000 HTTP port (auto-set by Railway)

API Keys

API keys are currently embedded in server.py. For production, move them to environment variables:

DEEPGRAM_API_KEY = os.environ.get("DEEPGRAM_API_KEY")
GOOGLE_API_KEY   = os.environ.get("GOOGLE_API_KEY")

ESP32 Firmware

Constant Default Description
SERVER_HOST audio-transcriber.up.railway.app Railway domain
SERVER_PORT 443 HTTPS/WSS port
WS_PATH /ws/audio WebSocket endpoint
SAMPLE_RATE 16000 Audio sample rate (Hz)
I2S_READ_LEN 256 Samples per I2S read cycle

πŸ› οΈ Local Development

# Clone the repo
git clone https://github.com/<your-username>/audio_transcriber.git
cd audio_transcriber

# Create a virtual environment
python -m venv venv
source venv/bin/activate        # Linux/Mac
# venv\Scripts\activate         # Windows

# Install dependencies
pip install -r requirements.txt

# Run the server locally
python server.py
# β†’ Server starts at http://localhost:8000

Update SERVER_HOST in the ESP32 sketch to your local IP for local testing.


πŸ“¦ Dependencies

Python (Server)

Package Purpose
fastapi Async web framework & WebSocket handling
uvicorn ASGI server
websockets Async WebSocket client for Deepgram
langchain-google-genai LangChain integration for Gemini

Arduino (ESP32)

Library Purpose
WiFiManager Captive portal for WiFi provisioning
WebSockets WebSocket client with SSL support

πŸ“ API Endpoints

Endpoint Type Description
GET / HTTP Serves the live transcription dashboard
WS /ws WebSocket Browser ↔ Server (transcripts + LLM events)
WS /ws/audio WebSocket ESP32 β†’ Server (raw 16-bit PCM audio)

Browser WebSocket Messages

Direction Message Description
Browser β†’ Server PROCESS Trigger Gemini on buffered transcript
Browser β†’ Server CLEAR_HISTORY Reset conversation history
Server β†’ Browser __FINAL__:<text> Final transcript line
Server β†’ Browser __INTERIM__:<text> Interim (partial) transcript
Server β†’ Browser __LLM_START__ Gemini processing started
Server β†’ Browser __LLM_TOKEN__:<text> Gemini response text
Server β†’ Browser __LLM_DONE__ Gemini processing complete
Server β†’ Browser __LLM_ERROR__:<msg> Gemini error message
Server β†’ Browser __STATUS__:<state> Connection state change

🀝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is open source and available under the MIT License.


Built with ❀️ using ESP32 · FastAPI · Deepgram · Gemini

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support