Transform voice memos into structured, actionable markdown notes using Gemini AI
A powerful web application that converts voice recordings (iPhone, Android, or any device) into beautifully formatted markdown documents. Built with FastAPI, Google's Gemini AI, and Docker for seamless deployment.
- Multi-format Support: MP3, M4A, WAV, OGG, FLAC, WebM, AAC
- Intelligent Compression: Reduces file size up to 10x using FFmpeg (Opus codec)
- Compress-Only Mode: Just compress audio without transcription
- Audio Player: Built-in player on recording pages for playback
- Gemini 3 Flash Preview: Latest model for fast, accurate transcription
- Hindi/Hinglish Support: Excellent code-switching between Hindi and English
- Speaker Identification: Distinguishes and labels multiple speakers
- Timestamped Output: Automatic timestamps every 1-2 minutes
- Key Rotation: Add multiple Gemini keys with automatic failover
- Load Balancing: Capacity-aware distribution across keys (5 RPM per key)
- Race Condition Prevention: Key locking for parallel processing
- Queue Visibility: See your position in the processing queue
- Upload β Audio file received and validated
- Compress β FFmpeg reduces file size (Opus codec @ 32kbps)
- Transcribe β Gemini AI generates verbatim transcript
- Analyze β Structured breakdown with topics, action items, insights
- Dark Mode: Beautiful dark theme for comfortable viewing
- Real-time Progress: Step-by-step processing status with visual indicators
- Drag & Drop: Easy file upload interface
- Download Options: Export transcripts and breakdowns as markdown
For each audio file, generates two markdown files:
| File | Contents |
|---|---|
*_transcript.md |
Raw verbatim transcription with timestamps and speaker labels |
*_breakdown.md |
Structured breakdown with topics, action items, key insights |
- Summary: Quick overview of the recording
- Topics Discussed: Main subjects covered with details
- Action Items: Tasks and follow-ups mentioned
- Key Insights: Important takeaways and decisions
- Questions/Open Items: Unresolved points for follow-up
# Clone the repository
git clone https://github.com/yourusername/voice-to-notes.git
cd voice-to-notes
# Run first-time setup
./setup.sh
# Start the application
docker-compose up -d
# Open in browser
open http://localhost:9123# Create virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Install FFmpeg (for audio compression)
brew install ffmpeg # macOS
# or: apt-get install ffmpeg # Ubuntu
# Run the app
uvicorn app.main:app --reload --port 8000
# Open in browser
open http://localhost:8000- Open the app at
http://localhost:9123 - Click "API Keys" in the navigation
- Add your Gemini API key from AI Studio
- (Optional) Add multiple keys for higher throughput
- 5 RPM (requests per minute) per key
- 250K TPM (tokens per minute) per key
- Adding 2 keys = 10 RPM = ~5 parallel recordings
- Upload: Drag & drop or select your audio file
- Choose Mode:
- Process - Full transcription + breakdown
- Compress Only - Just reduce file size
- Wait: Processing takes 1-5 minutes depending on length
- View: See the structured breakdown and raw transcript
- Download: Export as markdown files
- Long recordings: Handles files up to ~2 hours
- Multiple speakers: Automatically distinguishes voices
- Background noise: Works well, but quieter is better
- File size: 50MB+ typically compresses to 2-5MB
- Capacity Tracking: Monitors requests per minute per key
- Load Balancing: Distributes load across available keys
- Auto-Failover: Switches to next key on quota exhaustion
- Key Locking: Prevents race conditions in parallel processing
- See your position in the processing queue
- Estimated wait time displayed
- API capacity status visible during processing
Before starting the application for the first time, run the setup script:
./setup.shThis will:
- Create the data directory structure (default:
~/voice-notes-data) - Set up your
.envfile with required configuration - Explain where data lives and what's safe to do
Data is stored outside the project folder for maximum safety:
volumes:
- ${DATA_DIR:-~/voice-notes-data}:/app/data # SQLite DBs + uploads
- ${GDRIVE_MOUNT_PATH}:/data/gdrive # Google Drive mountNo Docker named volumes are used β everything is bind-mounted. This means docker-compose down -v is completely safe and won't delete your data.
| Variable | Description | Default |
|---|---|---|
DATA_DIR |
Host path for persistent data | ~/voice-notes-data |
GDRIVE_MOUNT_PATH |
Path to Google Drive folder | Required |
GEMINI_API_KEYS |
Comma-separated API keys | Required |
DATABASE_URL |
Database connection string | sqlite:///./data/voice_notes.db |
docker-compose logs -fdocker-compose up --build -dBy default, all your voice notes data is stored in:
~/voice-notes-data/
βββ voice_notes.db # Main database (recordings, API keys, settings)
βββ engine/
β βββ registry.db # Processing registry (watcher tracking)
βββ uploads/ # Uploaded audio files
βββ backups/ # Database backups (created by backup.sh)
This location is outside your project folder, which means:
- β
Your data survives
rm -rf voice-to-notes(deleting project folder) - β
Your data survives
git clean -fdx(cleaning git repo) - β Your data survives switching branches, re-cloning the repo
- β You can safely develop, test, and experiment without risking data loss
These operations will NOT delete your data:
β
docker-compose down # Stop containers
β
docker-compose down -v # Stop and remove volumes (no named volumes exist)
β
docker system prune # Clean up Docker resources
β
docker volume prune # Remove unused volumes (none are named)
β
rm -rf voice-to-notes # Delete project folder
β
git clean -fdx # Clean git working directory
β
git checkout different-branch # Switch branches
β
git clone (on another machine) # Re-clone repositoryOnly these operations can delete your data:
β rm -rf ~/voice-notes-data # Delete data directory
β rm ~/voice-notes-data/*.db # Delete databases
β docker exec voice-to-notes rm -rf /app/data # Delete from inside containerTo use a different data directory:
-
Set
DATA_DIRin your.envfile:DATA_DIR=/path/to/your/data
-
Or export as environment variable:
export DATA_DIR=/path/to/your/data docker-compose up -d
Run the backup script regularly to create hot backups (safe while app is running):
./backup.shThis creates timestamped backups in ~/voice-notes-data/backups/ and automatically keeps only the last 5 backups to prevent disk space issues.
Backup files:
voice_notes_YYYYMMDD_HHMMSS.db- Main database backupregistry_YYYYMMDD_HHMMSS.db- Registry database backup
# 1. Stop the application
docker-compose down
# 2. Copy the backup file
cp ~/voice-notes-data/backups/voice_notes_20260216_143000.db ~/voice-notes-data/voice_notes.db
# 3. Start the application
docker-compose up -dTo move your data to a new machine:
# On old machine
tar -czf voice-notes-backup.tar.gz ~/voice-notes-data
# Copy to new machine, then:
tar -xzf voice-notes-backup.tar.gz -C ~/
# Clone repo on new machine
git clone https://github.com/yourusername/voice-to-notes.git
cd voice-to-notes
# Start the application
docker-compose up -dBoth databases use SQLite with WAL mode for:
- β Crash safety: Survives unclean Docker shutdowns
- β Better concurrency: Multiple readers + single writer
- β Hot backups: Safe to backup while app is running
- β No maintenance: No vacuum, reindex, or optimization needed
voice-to-notes/
βββ app/
β βββ __init__.py
β βββ main.py # FastAPI routes & endpoints
β βββ database.py # SQLAlchemy models (Recording, APIKey, Settings)
β βββ api_keys.py # Key rotation & load balancing logic
β βββ processor.py # Audio compression & AI transcription
β βββ templates/
β βββ index.html # Dashboard with recording list
β βββ recording.html # Recording detail view
β βββ keys.html # API key management
β βββ storage.html # Storage management
βββ data/ # SQLite DB + uploads (Docker volume)
βββ transcribe.py # Standalone CLI tool
βββ Dockerfile
βββ docker-compose.yml
βββ requirements.txt
βββ TIMELINE.md # Project development story
βββ README.md
- Backend: FastAPI (Python 3.11)
- AI: Google Gemini 3 Flash Preview
- Database: SQLite (PostgreSQL optional)
- Audio: FFmpeg with Opus codec
- Frontend: Jinja2 templates + Alpine.js + Tailwind CSS
- Temperature 1.0: Google's recommendation to prevent AI looping
- Opus @ 32kbps: Optimal balance of compression and quality
- 15-second key locks: Prevents parallel processing race conditions
- 90-second rate limit waits: Handles free tier limits gracefully
Gemini 3 Flash Preview pricing (approximate):
- Audio processing: ~$0.00025 per second
- Text generation: Generous free tier limits
- Typical 30-min recording: ~$0.45
Free tier is sufficient for personal use.
Add a key via: http://localhost:9123/keys
- Wait 60 seconds for rate limit reset
- Add more API keys for higher throughput
brew install ffmpeg # macOS
apt-get install ffmpeg # Ubuntu# View logs
docker-compose logs -f
# Rebuild
docker-compose up --build -d
# Reset everything
docker-compose down -v
docker-compose up --build -dFixed with temperature=1.0 (Google's strong recommendation)
MIT License - see LICENSE for details.
- Google Gemini AI for powerful multimodal AI
- FastAPI for the excellent web framework
- FFmpeg for audio processing
- Tailwind CSS for beautiful styling
Made with β€οΈ for turning thoughts into organized notes.