docs: Create comprehensive README documentation
- Updated main README with detailed setup, Kokoro model configuration, and troubleshooting - Enhanced backend README with API documentation, Docker setup, and testing instructions - Improved frontend README with component details, deployment guide, and development tips - Added workflow testing steps and common error solutions - Documented all supported languages, voices, and configuration options Implements task 14 from text-to-audiobook spec Requirements: 13.1, 13.2, 13.3, 13.4, 13.5
This commit is contained in:
@@ -280,7 +280,7 @@
|
|||||||
- Ensure touch targets are appropriately sized
|
- Ensure touch targets are appropriately sized
|
||||||
- _Requirements: 12.1, 12.2, 12.3, 12.4_
|
- _Requirements: 12.1, 12.2, 12.3, 12.4_
|
||||||
|
|
||||||
- [ ] 14. Create comprehensive README documentation
|
- [x] 14. Create comprehensive README documentation
|
||||||
- Document Kokoro model setup and configuration
|
- Document Kokoro model setup and configuration
|
||||||
- Provide backend setup instructions (local and Docker)
|
- Provide backend setup instructions (local and Docker)
|
||||||
- Provide frontend setup instructions
|
- Provide frontend setup instructions
|
||||||
|
|||||||
625
README.md
625
README.md
@@ -17,91 +17,638 @@ A full-stack application that converts long-form text into multi-voice audiobook
|
|||||||
- **Backend**: Python + FastAPI + Kokoro TTS
|
- **Backend**: Python + FastAPI + Kokoro TTS
|
||||||
- **Deployment**: Docker containerization
|
- **Deployment**: Docker containerization
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Quick Start](#quick-start)
|
||||||
|
- [Kokoro Model Setup](#kokoro-model-setup)
|
||||||
|
- [Backend Setup](#backend-setup)
|
||||||
|
- [Local Development](#local-development)
|
||||||
|
- [Docker Deployment](#docker-deployment)
|
||||||
|
- [Frontend Setup](#frontend-setup)
|
||||||
|
- [Usage Workflow](#usage-workflow)
|
||||||
|
- [Testing the Application](#testing-the-application)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
- [Project Structure](#project-structure)
|
||||||
|
- [API Documentation](#api-documentation)
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
|
The fastest way to get started is using Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Start the backend
|
||||||
|
cd backend
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# 2. Start the frontend (in a new terminal)
|
||||||
|
cd frontend
|
||||||
|
npm install
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# 3. Open http://localhost:5173 in your browser
|
||||||
|
```
|
||||||
|
|
||||||
|
## Kokoro Model Setup
|
||||||
|
|
||||||
|
The Kokoro TTS model (hexgrad/Kokoro-82M) is automatically downloaded when you first run the backend. The model files are cached by the `kokoro` Python library.
|
||||||
|
|
||||||
|
### Model Configuration
|
||||||
|
|
||||||
|
**Supported Languages:**
|
||||||
|
- `a` - American English
|
||||||
|
- `b` - British English
|
||||||
|
- `f` - French
|
||||||
|
- `j` - Japanese
|
||||||
|
|
||||||
|
**Available Voices:**
|
||||||
|
- `af_bella` - Bella (Female, American)
|
||||||
|
- `af_sarah` - Sarah (Female, American)
|
||||||
|
- `am_adam` - Adam (Male, American)
|
||||||
|
- `am_michael` - Michael (Male, American)
|
||||||
|
- `bf_emma` - Emma (Female, British)
|
||||||
|
- `bf_isabella` - Isabella (Female, British)
|
||||||
|
- `bm_george` - George (Male, British)
|
||||||
|
- `bm_lewis` - Lewis (Male, British)
|
||||||
|
|
||||||
|
### Model Storage
|
||||||
|
|
||||||
|
The Kokoro library automatically downloads and caches model files in:
|
||||||
|
- **Linux/macOS**: `~/.cache/kokoro/`
|
||||||
|
- **Windows**: `%USERPROFILE%\.cache\kokoro\`
|
||||||
|
|
||||||
|
The first synthesis request will trigger model download (~500MB). Subsequent requests will use the cached model.
|
||||||
|
|
||||||
|
## Backend Setup
|
||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- Python 3.10+
|
- Python 3.10 or higher
|
||||||
- Node.js 20.19+ or 22.12+
|
- espeak-ng (system dependency for grapheme-to-phoneme conversion)
|
||||||
- espeak-ng (system dependency)
|
- Docker (optional, for containerized deployment)
|
||||||
|
|
||||||
### Backend Setup
|
### Local Development
|
||||||
|
|
||||||
1. Install espeak-ng:
|
#### 1. Install espeak-ng
|
||||||
|
|
||||||
|
**macOS:**
|
||||||
```bash
|
```bash
|
||||||
# macOS
|
|
||||||
brew install espeak-ng
|
brew install espeak-ng
|
||||||
|
```
|
||||||
|
|
||||||
# Linux (Ubuntu/Debian)
|
**Linux (Ubuntu/Debian):**
|
||||||
|
```bash
|
||||||
|
sudo apt-get update
|
||||||
sudo apt-get install espeak-ng
|
sudo apt-get install espeak-ng
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Set up Python environment:
|
**Linux (Fedora/RHEL):**
|
||||||
|
```bash
|
||||||
|
sudo dnf install espeak-ng
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
Download and install from [espeak-ng releases](https://github.com/espeak-ng/espeak-ng/releases)
|
||||||
|
|
||||||
|
#### 2. Set up Python environment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd backend
|
cd backend
|
||||||
|
|
||||||
|
# Create virtual environment
|
||||||
python -m venv venv
|
python -m venv venv
|
||||||
source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
||||||
|
# Activate virtual environment
|
||||||
|
# macOS/Linux:
|
||||||
|
source venv/bin/activate
|
||||||
|
# Windows:
|
||||||
|
venv\Scripts\activate
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Run the backend:
|
#### 3. Configure environment variables
|
||||||
```bash
|
|
||||||
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
|
||||||
```
|
|
||||||
|
|
||||||
### Frontend Setup
|
|
||||||
|
|
||||||
1. Install dependencies:
|
|
||||||
```bash
|
|
||||||
cd frontend
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Configure environment:
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Run the frontend:
|
Edit `.env` if needed:
|
||||||
|
```bash
|
||||||
|
PORT=8000
|
||||||
|
LOG_LEVEL=info
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Run the backend server
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||||||
|
```
|
||||||
|
|
||||||
|
The API will be available at:
|
||||||
|
- **API Base**: http://localhost:8000
|
||||||
|
- **API Docs**: http://localhost:8000/docs
|
||||||
|
- **Health Check**: http://localhost:8000/api/health
|
||||||
|
|
||||||
|
### Docker Deployment
|
||||||
|
|
||||||
|
#### Option 1: Using Docker Compose (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
|
||||||
|
# Build and start the container
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# Stop the container
|
||||||
|
docker-compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Option 2: Using Docker directly
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
|
||||||
|
# Build the image
|
||||||
|
docker build -t text-to-audiobook-backend .
|
||||||
|
|
||||||
|
# Run the container
|
||||||
|
docker run -d \
|
||||||
|
--name text-to-audiobook-backend \
|
||||||
|
-p 8000:8000 \
|
||||||
|
-e PORT=8000 \
|
||||||
|
-e LOG_LEVEL=info \
|
||||||
|
text-to-audiobook-backend
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker logs -f text-to-audiobook-backend
|
||||||
|
|
||||||
|
# Stop the container
|
||||||
|
docker stop text-to-audiobook-backend
|
||||||
|
docker rm text-to-audiobook-backend
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Docker Configuration
|
||||||
|
|
||||||
|
The Docker setup includes:
|
||||||
|
- Python 3.10 slim base image
|
||||||
|
- Automatic installation of espeak-ng
|
||||||
|
- Health check endpoint monitoring
|
||||||
|
- Automatic restart on failure
|
||||||
|
- Volume mounting for development (optional)
|
||||||
|
|
||||||
|
**Resource Requirements:**
|
||||||
|
- **Memory**: Minimum 2GB RAM (4GB recommended)
|
||||||
|
- **Storage**: ~500MB for Kokoro models
|
||||||
|
- **CPU**: Multi-core recommended for faster synthesis
|
||||||
|
|
||||||
|
## Frontend Setup
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Node.js 20.19+ or 22.12+
|
||||||
|
- npm or yarn
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Create environment file
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
Edit `frontend/.env`:
|
||||||
|
```bash
|
||||||
|
VITE_API_BASE_URL=http://localhost:8000
|
||||||
|
```
|
||||||
|
|
||||||
|
For production, update this to your backend URL.
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Open http://localhost:5173 in your browser
|
The application will be available at http://localhost:5173
|
||||||
|
|
||||||
## Usage
|
### Production Build
|
||||||
|
|
||||||
1. **Enter Text**: Paste your text with role markers (e.g., "Alice:", "[Narrator]")
|
```bash
|
||||||
2. **Assign Voices**: Select a Kokoro voice for each detected role
|
# Build for production
|
||||||
3. **Configure**: Choose language and playback speed
|
npm run build
|
||||||
4. **Generate**: Create your multi-voice audiobook
|
|
||||||
5. **Listen & Download**: Play or save the generated audio
|
# Preview production build
|
||||||
|
npm run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
The built files will be in `frontend/dist/` and can be served by any static file server.
|
||||||
|
|
||||||
|
## Usage Workflow
|
||||||
|
|
||||||
|
### 1. Enter Text
|
||||||
|
|
||||||
|
Paste your text into the text area. Use role markers to identify different speakers:
|
||||||
|
|
||||||
|
**Colon Pattern:**
|
||||||
|
```
|
||||||
|
Narrator: Once upon a time, in a land far away...
|
||||||
|
Alice: Hello! How are you today?
|
||||||
|
Bob: I'm doing great, thanks for asking!
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bracket Pattern:**
|
||||||
|
```
|
||||||
|
[Narrator] The story begins on a cold winter morning.
|
||||||
|
[Alice] I can't believe it's snowing again!
|
||||||
|
[Bob] I know, it's beautiful though.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mixed Patterns:**
|
||||||
|
```
|
||||||
|
Narrator: The two friends met at the park.
|
||||||
|
Alice: [excitedly] Did you hear the news?
|
||||||
|
Bob: No, what happened?
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Assign Voices
|
||||||
|
|
||||||
|
- The system automatically detects roles from your text
|
||||||
|
- Select a voice for each detected role from the dropdown
|
||||||
|
- Choose the language (American English, British English, French, or Japanese)
|
||||||
|
- Adjust playback speed (0.5x to 1.5x)
|
||||||
|
|
||||||
|
### 3. Generate Audiobook
|
||||||
|
|
||||||
|
- Click "Generate Audiobook" (enabled when all roles have voices)
|
||||||
|
- Wait for synthesis to complete (may take several minutes for long texts)
|
||||||
|
- Progress indicator shows generation status
|
||||||
|
|
||||||
|
### 4. Listen & Download
|
||||||
|
|
||||||
|
- Use the audio player to listen to your audiobook
|
||||||
|
- Click "Download audiobook" to save the file
|
||||||
|
- File is saved as `audiobook.wav`
|
||||||
|
|
||||||
|
## Testing the Application
|
||||||
|
|
||||||
|
### 1. Health Check
|
||||||
|
|
||||||
|
Verify the backend is running:
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8000/api/health
|
||||||
|
# Expected: {"status":"ok"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Role Detection Test
|
||||||
|
|
||||||
|
Test role detection with sample text:
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/api/tts/roles \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"text":"Alice: Hello there!\nBob: Hi Alice!"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"roles": [
|
||||||
|
{"id": "Alice", "label": "Alice"},
|
||||||
|
{"id": "Bob", "label": "Bob"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. End-to-End Workflow Test
|
||||||
|
|
||||||
|
1. Open http://localhost:5173
|
||||||
|
2. Enter sample text:
|
||||||
|
```
|
||||||
|
Narrator: This is a test of the audiobook system.
|
||||||
|
Alice: Hello, this is Alice speaking.
|
||||||
|
Bob: And this is Bob.
|
||||||
|
```
|
||||||
|
3. Click "Next: Assign voices"
|
||||||
|
4. Assign different voices to each role
|
||||||
|
5. Click "Generate Audiobook"
|
||||||
|
6. Verify audio plays correctly
|
||||||
|
7. Test download functionality
|
||||||
|
|
||||||
|
### 4. Test Different Languages
|
||||||
|
|
||||||
|
Try generating audiobooks in different languages:
|
||||||
|
- **American English**: Default, works with all `af_*` and `am_*` voices
|
||||||
|
- **British English**: Use with `bf_*` and `bm_*` voices
|
||||||
|
- **French**: Test with French text
|
||||||
|
- **Japanese**: Test with Japanese text
|
||||||
|
|
||||||
|
### 5. Test Edge Cases
|
||||||
|
|
||||||
|
- **Empty text**: Should show validation error
|
||||||
|
- **No role markers**: Should detect single "Narrator" role
|
||||||
|
- **Very long text**: Should show warning message
|
||||||
|
- **Special characters**: Should handle gracefully
|
||||||
|
|
||||||
|
### Running Automated Tests
|
||||||
|
|
||||||
|
**Backend Tests:**
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
source venv/bin/activate # Activate virtual environment
|
||||||
|
pytest test_*.py -v
|
||||||
|
```
|
||||||
|
|
||||||
|
**Frontend Tests:**
|
||||||
|
```bash
|
||||||
|
cd frontend
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Backend Issues
|
||||||
|
|
||||||
|
#### Issue: "espeak-ng not found"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# macOS
|
||||||
|
brew install espeak-ng
|
||||||
|
|
||||||
|
# Linux
|
||||||
|
sudo apt-get install espeak-ng
|
||||||
|
|
||||||
|
# Verify installation
|
||||||
|
espeak-ng --version
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Issue: "Module 'kokoro' not found"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Issue: "Model download fails"
|
||||||
|
|
||||||
|
**Symptoms:** First synthesis request times out or fails
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
- Ensure stable internet connection
|
||||||
|
- Check firewall settings
|
||||||
|
- Manually download models:
|
||||||
|
```bash
|
||||||
|
python -c "from kokoro import KPipeline; KPipeline(lang_code='a')"
|
||||||
|
```
|
||||||
|
- Check disk space (~500MB required)
|
||||||
|
|
||||||
|
#### Issue: "Out of memory during synthesis"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
- Reduce text length (split into smaller chunks)
|
||||||
|
- Increase Docker memory limit:
|
||||||
|
```bash
|
||||||
|
docker run -m 4g ... # Allocate 4GB RAM
|
||||||
|
```
|
||||||
|
- Close other applications
|
||||||
|
|
||||||
|
#### Issue: "Port 8000 already in use"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Find process using port 8000
|
||||||
|
lsof -i :8000 # macOS/Linux
|
||||||
|
netstat -ano | findstr :8000 # Windows
|
||||||
|
|
||||||
|
# Kill the process or use different port
|
||||||
|
uvicorn main:app --port 8001
|
||||||
|
```
|
||||||
|
|
||||||
|
### Frontend Issues
|
||||||
|
|
||||||
|
#### Issue: "Cannot connect to backend"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
1. Verify backend is running: `curl http://localhost:8000/api/health`
|
||||||
|
2. Check `VITE_API_BASE_URL` in `frontend/.env`
|
||||||
|
3. Check CORS settings in backend
|
||||||
|
4. Verify no firewall blocking
|
||||||
|
|
||||||
|
#### Issue: "Audio won't play"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
- Check browser console for errors
|
||||||
|
- Verify audio format is supported (WAV should work in all browsers)
|
||||||
|
- Try different browser
|
||||||
|
- Check browser audio permissions
|
||||||
|
|
||||||
|
#### Issue: "Download doesn't work"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
- Check browser download settings
|
||||||
|
- Verify popup blocker isn't blocking download
|
||||||
|
- Check browser console for errors
|
||||||
|
- Try right-click → "Save As" on audio player
|
||||||
|
|
||||||
|
### Docker Issues
|
||||||
|
|
||||||
|
#### Issue: "Docker build fails"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Clear Docker cache
|
||||||
|
docker system prune -a
|
||||||
|
|
||||||
|
# Rebuild without cache
|
||||||
|
docker-compose build --no-cache
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Issue: "Container exits immediately"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Check logs
|
||||||
|
docker-compose logs backend
|
||||||
|
|
||||||
|
# Common causes:
|
||||||
|
# - Missing dependencies
|
||||||
|
# - Port conflict
|
||||||
|
# - Syntax errors in code
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Issue: "Health check failing"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Check if service is actually running
|
||||||
|
docker exec -it text-to-audiobook-backend curl http://localhost:8000/api/health
|
||||||
|
|
||||||
|
# Check logs for startup errors
|
||||||
|
docker-compose logs backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Issues
|
||||||
|
|
||||||
|
#### Issue: "Generation is very slow"
|
||||||
|
|
||||||
|
**Causes & Solutions:**
|
||||||
|
- **Long text**: Split into smaller sections
|
||||||
|
- **First run**: Model download takes time (one-time)
|
||||||
|
- **Limited CPU**: Use faster machine or reduce text length
|
||||||
|
- **Docker on macOS**: Docker Desktop has performance overhead
|
||||||
|
|
||||||
|
#### Issue: "High memory usage"
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
- Restart backend service to clear cache
|
||||||
|
- Process shorter texts
|
||||||
|
- Increase system RAM
|
||||||
|
- Monitor with: `docker stats` (Docker) or `top`/`htop` (local)
|
||||||
|
|
||||||
|
### Common Error Messages
|
||||||
|
|
||||||
|
| Error | Cause | Solution |
|
||||||
|
|-------|-------|----------|
|
||||||
|
| `ValidationError: Missing required field` | Invalid API request | Check request format matches API spec |
|
||||||
|
| `Language code 'x' not supported` | Invalid language code | Use: a, b, f, or j |
|
||||||
|
| `Voice ID 'x' not found` | Invalid voice ID | Check available voices list |
|
||||||
|
| `Text is required` | Empty text submitted | Enter text before proceeding |
|
||||||
|
| `CORS error` | Frontend can't reach backend | Check CORS settings and URLs |
|
||||||
|
|
||||||
|
### Getting Help
|
||||||
|
|
||||||
|
If you encounter issues not covered here:
|
||||||
|
|
||||||
|
1. Check the logs:
|
||||||
|
- Backend: `docker-compose logs backend` or console output
|
||||||
|
- Frontend: Browser developer console (F12)
|
||||||
|
|
||||||
|
2. Verify versions:
|
||||||
|
```bash
|
||||||
|
python --version # Should be 3.10+
|
||||||
|
node --version # Should be 20.19+ or 22.12+
|
||||||
|
espeak-ng --version
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Check the [GitHub Issues](https://github.com/yourusername/text-to-audiobook/issues)
|
||||||
|
|
||||||
|
4. Review the design document: `.kiro/specs/text-to-audiobook/design.md`
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
.
|
.
|
||||||
├── backend/ # FastAPI backend
|
├── backend/ # FastAPI backend
|
||||||
|
│ ├── services/
|
||||||
|
│ │ ├── role_detector.py # Role detection logic
|
||||||
|
│ │ └── tts_service.py # TTS synthesis logic
|
||||||
│ ├── main.py # API endpoints
|
│ ├── main.py # API endpoints
|
||||||
│ ├── services/ # Business logic
|
|
||||||
│ ├── requirements.txt # Python dependencies
|
│ ├── requirements.txt # Python dependencies
|
||||||
│ └── README.md
|
│ ├── Dockerfile # Docker configuration
|
||||||
|
│ ├── docker-compose.yml # Docker Compose setup
|
||||||
|
│ ├── .env.example # Environment template
|
||||||
|
│ ├── test_*.py # Test files
|
||||||
|
│ └── README.md # Backend documentation
|
||||||
├── frontend/ # React frontend
|
├── frontend/ # React frontend
|
||||||
│ ├── src/
|
│ ├── src/
|
||||||
│ │ ├── api/ # API client
|
│ │ ├── api/
|
||||||
│ │ ├── components/ # React components
|
│ │ │ └── tts.ts # API client
|
||||||
│ │ └── App.tsx # Main app
|
│ │ ├── components/
|
||||||
│ ├── package.json
|
│ │ │ ├── TextInputSection.tsx
|
||||||
│ └── README.md
|
│ │ │ ├── VoiceAssignmentSection.tsx
|
||||||
|
│ │ │ └── AudioPlayerSection.tsx
|
||||||
|
│ │ ├── App.tsx # Main application
|
||||||
|
│ │ ├── main.tsx # Entry point
|
||||||
|
│ │ └── index.css # Global styles
|
||||||
|
│ ├── package.json # Node dependencies
|
||||||
|
│ ├── vite.config.ts # Vite configuration
|
||||||
|
│ ├── .env.example # Environment template
|
||||||
|
│ └── README.md # Frontend documentation
|
||||||
|
├── .kiro/specs/ # Specification documents
|
||||||
|
│ └── text-to-audiobook/
|
||||||
|
│ ├── requirements.md # Requirements
|
||||||
|
│ ├── design.md # Design document
|
||||||
|
│ └── tasks.md # Implementation tasks
|
||||||
└── README.md # This file
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
|
|
||||||
## Documentation
|
## API Documentation
|
||||||
|
|
||||||
|
### Endpoints
|
||||||
|
|
||||||
|
#### GET /api/health
|
||||||
|
Health check endpoint.
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### POST /api/tts/roles
|
||||||
|
Detect roles in text.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"text": "Alice: Hello!\nBob: Hi there!"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"roles": [
|
||||||
|
{"id": "Alice", "label": "Alice"},
|
||||||
|
{"id": "Bob", "label": "Bob"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### POST /api/tts
|
||||||
|
Generate audiobook.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"text": "Alice: Hello!\nBob: Hi there!",
|
||||||
|
"lang": "a",
|
||||||
|
"roles": [
|
||||||
|
{"id": "Alice", "voice": "af_bella"},
|
||||||
|
{"id": "Bob", "voice": "am_adam"}
|
||||||
|
],
|
||||||
|
"speed": 1.0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
- Content-Type: `audio/wav`
|
||||||
|
- Content-Disposition: `attachment; filename="audiobook.wav"`
|
||||||
|
- Body: Audio file bytes
|
||||||
|
|
||||||
|
### Interactive API Documentation
|
||||||
|
|
||||||
|
Visit http://localhost:8000/docs for interactive Swagger UI documentation.
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
- [Backend Documentation](./backend/README.md)
|
- [Backend Documentation](./backend/README.md)
|
||||||
- [Frontend Documentation](./frontend/README.md)
|
- [Frontend Documentation](./frontend/README.md)
|
||||||
- [Requirements](./.kiro/specs/text-to-audiobook/requirements.md)
|
- [Requirements Document](./.kiro/specs/text-to-audiobook/requirements.md)
|
||||||
- [Design Document](./.kiro/specs/text-to-audiobook/design.md)
|
- [Design Document](./.kiro/specs/text-to-audiobook/design.md)
|
||||||
|
- [Kokoro TTS Library](https://github.com/hexgrad/kokoro)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
# Text to Audiobook Backend
|
# Text to Audiobook Backend
|
||||||
|
|
||||||
FastAPI backend service for converting text to multi-voice audiobooks using Kokoro TTS.
|
FastAPI backend service for converting text to multi-voice audiobooks using Kokoro TTS (hexgrad/Kokoro-82M).
|
||||||
|
|
||||||
## Setup
|
## Overview
|
||||||
|
|
||||||
### Prerequisites
|
The backend provides REST API endpoints for:
|
||||||
|
- Role/speaker detection in text
|
||||||
|
- Multi-voice audio synthesis
|
||||||
|
- Audio streaming and download
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
- Python 3.10 or higher
|
- Python 3.10 or higher
|
||||||
- espeak-ng (system dependency)
|
- espeak-ng (system dependency for grapheme-to-phoneme conversion)
|
||||||
|
- Docker (optional, for containerized deployment)
|
||||||
|
|
||||||
### Install espeak-ng
|
## Local Development Setup
|
||||||
|
|
||||||
|
### 1. Install espeak-ng
|
||||||
|
|
||||||
**macOS:**
|
**macOS:**
|
||||||
```bash
|
```bash
|
||||||
@@ -22,44 +30,453 @@ sudo apt-get update
|
|||||||
sudo apt-get install espeak-ng
|
sudo apt-get install espeak-ng
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python Environment Setup
|
**Linux (Fedora/RHEL):**
|
||||||
|
|
||||||
1. Create a virtual environment:
|
|
||||||
```bash
|
```bash
|
||||||
|
sudo dnf install espeak-ng
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
Download from [espeak-ng releases](https://github.com/espeak-ng/espeak-ng/releases)
|
||||||
|
|
||||||
|
Verify installation:
|
||||||
|
```bash
|
||||||
|
espeak-ng --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Python Environment Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create virtual environment
|
||||||
python -m venv venv
|
python -m venv venv
|
||||||
```
|
|
||||||
|
|
||||||
2. Activate the virtual environment:
|
# Activate virtual environment
|
||||||
```bash
|
# macOS/Linux:
|
||||||
# macOS/Linux
|
|
||||||
source venv/bin/activate
|
source venv/bin/activate
|
||||||
|
# Windows:
|
||||||
# Windows
|
|
||||||
venv\Scripts\activate
|
venv\Scripts\activate
|
||||||
```
|
|
||||||
|
|
||||||
3. Install dependencies:
|
# Upgrade pip
|
||||||
```bash
|
pip install --upgrade pip
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
4. Create environment file:
|
### 3. Environment Configuration
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
## Running the Server
|
Edit `.env` if needed:
|
||||||
|
```bash
|
||||||
|
PORT=8000
|
||||||
|
LOG_LEVEL=info
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Run the Server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||||||
```
|
```
|
||||||
|
|
||||||
The API will be available at `http://localhost:8000`
|
The server will start on http://localhost:8000
|
||||||
|
|
||||||
API documentation: `http://localhost:8000/docs`
|
**Available URLs:**
|
||||||
|
- API Base: http://localhost:8000
|
||||||
|
- Interactive API Docs: http://localhost:8000/docs
|
||||||
|
- Alternative API Docs: http://localhost:8000/redoc
|
||||||
|
- Health Check: http://localhost:8000/api/health
|
||||||
|
|
||||||
|
## Docker Deployment
|
||||||
|
|
||||||
|
### Using Docker Compose (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and start
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker-compose logs -f backend
|
||||||
|
|
||||||
|
# Stop
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# Rebuild after code changes
|
||||||
|
docker-compose up -d --build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Docker Directly
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build image
|
||||||
|
docker build -t text-to-audiobook-backend .
|
||||||
|
|
||||||
|
# Run container
|
||||||
|
docker run -d \
|
||||||
|
--name text-to-audiobook-backend \
|
||||||
|
-p 8000:8000 \
|
||||||
|
-e PORT=8000 \
|
||||||
|
-e LOG_LEVEL=info \
|
||||||
|
text-to-audiobook-backend
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker logs -f text-to-audiobook-backend
|
||||||
|
|
||||||
|
# Stop and remove
|
||||||
|
docker stop text-to-audiobook-backend
|
||||||
|
docker rm text-to-audiobook-backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Configuration
|
||||||
|
|
||||||
|
The Dockerfile includes:
|
||||||
|
- Python 3.10 slim base image
|
||||||
|
- Automatic espeak-ng installation
|
||||||
|
- Python dependencies from requirements.txt
|
||||||
|
- Health check monitoring
|
||||||
|
- Uvicorn ASGI server
|
||||||
|
|
||||||
|
**Resource Requirements:**
|
||||||
|
- Memory: 2GB minimum (4GB recommended)
|
||||||
|
- Storage: ~500MB for Kokoro models
|
||||||
|
- CPU: Multi-core recommended
|
||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
- `GET /api/health` - Health check endpoint
|
### GET /api/health
|
||||||
- `POST /api/tts/roles` - Detect roles in text
|
|
||||||
- `POST /api/tts` - Generate audiobook
|
Health check endpoint.
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
curl http://localhost:8000/api/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### POST /api/tts/roles
|
||||||
|
|
||||||
|
Detect distinct roles/speakers in text.
|
||||||
|
|
||||||
|
**Request Body:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"text": "Alice: Hello there!\nBob: Hi Alice, how are you?\nNarrator: They greeted each other warmly."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"roles": [
|
||||||
|
{"id": "Alice", "label": "Alice"},
|
||||||
|
{"id": "Bob", "label": "Bob"},
|
||||||
|
{"id": "Narrator", "label": "Narrator"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Supported Role Patterns:**
|
||||||
|
- Colon pattern: `RoleName: dialogue text`
|
||||||
|
- Bracket pattern: `[RoleName] dialogue text`
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/api/tts/roles \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"text":"Alice: Hello!\nBob: Hi there!"}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### POST /api/tts
|
||||||
|
|
||||||
|
Generate multi-voice audiobook.
|
||||||
|
|
||||||
|
**Request Body:**
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"text": "Alice: Hello there!\nBob: Hi Alice!",
|
||||||
|
"lang": "a",
|
||||||
|
"roles": [
|
||||||
|
{"id": "Alice", "voice": "af_bella"},
|
||||||
|
{"id": "Bob", "voice": "am_adam"}
|
||||||
|
],
|
||||||
|
"speed": 1.0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `text` (required): Text to synthesize
|
||||||
|
- `lang` (required): Language code (a=American English, b=British English, f=French, j=Japanese)
|
||||||
|
- `roles` (required): Array of role-to-voice mappings
|
||||||
|
- `speed` (optional): Playback speed (0.5-1.5, default: 1.0)
|
||||||
|
|
||||||
|
**Response:**
|
||||||
|
- Content-Type: `audio/wav`
|
||||||
|
- Content-Disposition: `attachment; filename="audiobook.wav"`
|
||||||
|
- Body: Audio file bytes
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
curl -X POST http://localhost:8000/api/tts \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"text": "Alice: Hello!\nBob: Hi!",
|
||||||
|
"lang": "a",
|
||||||
|
"roles": [
|
||||||
|
{"id": "Alice", "voice": "af_bella"},
|
||||||
|
{"id": "Bob", "voice": "am_adam"}
|
||||||
|
],
|
||||||
|
"speed": 1.0
|
||||||
|
}' \
|
||||||
|
--output audiobook.wav
|
||||||
|
```
|
||||||
|
|
||||||
|
## Kokoro TTS Configuration
|
||||||
|
|
||||||
|
### Supported Languages
|
||||||
|
|
||||||
|
| Code | Language |
|
||||||
|
|------|----------|
|
||||||
|
| `a` | American English |
|
||||||
|
| `b` | British English |
|
||||||
|
| `f` | French |
|
||||||
|
| `j` | Japanese |
|
||||||
|
|
||||||
|
### Available Voices
|
||||||
|
|
||||||
|
| Voice ID | Gender | Accent | Description |
|
||||||
|
|----------|--------|--------|-------------|
|
||||||
|
| `af_bella` | Female | American | Bella |
|
||||||
|
| `af_sarah` | Female | American | Sarah |
|
||||||
|
| `am_adam` | Male | American | Adam |
|
||||||
|
| `am_michael` | Male | American | Michael |
|
||||||
|
| `bf_emma` | Female | British | Emma |
|
||||||
|
| `bf_isabella` | Female | British | Isabella |
|
||||||
|
| `bm_george` | Male | British | George |
|
||||||
|
| `bm_lewis` | Male | British | Lewis |
|
||||||
|
|
||||||
|
### Model Storage
|
||||||
|
|
||||||
|
Models are automatically downloaded on first use and cached:
|
||||||
|
- **Linux/macOS**: `~/.cache/kokoro/`
|
||||||
|
- **Windows**: `%USERPROFILE%\.cache\kokoro\`
|
||||||
|
|
||||||
|
First synthesis may take longer due to model download (~500MB).
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
backend/
|
||||||
|
├── services/
|
||||||
|
│ ├── __init__.py
|
||||||
|
│ ├── role_detector.py # Role detection logic
|
||||||
|
│ └── tts_service.py # TTS synthesis service
|
||||||
|
├── main.py # FastAPI application & endpoints
|
||||||
|
├── requirements.txt # Python dependencies
|
||||||
|
├── Dockerfile # Docker image configuration
|
||||||
|
├── docker-compose.yml # Docker Compose setup
|
||||||
|
├── .env.example # Environment template
|
||||||
|
├── .dockerignore # Docker ignore patterns
|
||||||
|
├── test_api.py # API endpoint tests
|
||||||
|
├── test_role_detection.py # Role detection tests
|
||||||
|
├── test_tts_service.py # TTS service tests
|
||||||
|
└── README.md # This file
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Run All Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Activate virtual environment
|
||||||
|
source venv/bin/activate # macOS/Linux
|
||||||
|
# or
|
||||||
|
venv\Scripts\activate # Windows
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
pytest test_*.py -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Specific Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Test API endpoints
|
||||||
|
pytest test_api.py -v
|
||||||
|
|
||||||
|
# Test role detection
|
||||||
|
pytest test_role_detection.py -v
|
||||||
|
|
||||||
|
# Test TTS service
|
||||||
|
pytest test_tts_service.py -v
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Coverage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pytest --cov=. --cov-report=html test_*.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### espeak-ng not found
|
||||||
|
|
||||||
|
**Error:** `OSError: espeak-ng not found`
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Install espeak-ng
|
||||||
|
brew install espeak-ng # macOS
|
||||||
|
sudo apt-get install espeak-ng # Linux
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
espeak-ng --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### Module not found
|
||||||
|
|
||||||
|
**Error:** `ModuleNotFoundError: No module named 'kokoro'`
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
source venv/bin/activate
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port already in use
|
||||||
|
|
||||||
|
**Error:** `Address already in use`
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
```bash
|
||||||
|
# Find process using port 8000
|
||||||
|
lsof -i :8000 # macOS/Linux
|
||||||
|
netstat -ano | findstr :8000 # Windows
|
||||||
|
|
||||||
|
# Use different port
|
||||||
|
uvicorn main:app --port 8001
|
||||||
|
```
|
||||||
|
|
||||||
|
### Model download fails
|
||||||
|
|
||||||
|
**Symptoms:** First synthesis times out
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
- Check internet connection
|
||||||
|
- Check firewall settings
|
||||||
|
- Manually trigger download:
|
||||||
|
```bash
|
||||||
|
python -c "from kokoro import KPipeline; KPipeline(lang_code='a')"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Out of memory
|
||||||
|
|
||||||
|
**Error:** Memory error during synthesis
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
- Reduce text length
|
||||||
|
- Increase system RAM
|
||||||
|
- For Docker: `docker run -m 4g ...`
|
||||||
|
|
||||||
|
## Performance Optimization
|
||||||
|
|
||||||
|
### Tips for Faster Synthesis
|
||||||
|
|
||||||
|
1. **Use cached pipelines**: The service caches KPipeline instances per language
|
||||||
|
2. **Shorter texts**: Break very long texts into chapters
|
||||||
|
3. **Multi-core CPU**: Synthesis benefits from multiple cores
|
||||||
|
4. **SSD storage**: Faster model loading from SSD
|
||||||
|
|
||||||
|
### Monitoring
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View logs
|
||||||
|
docker-compose logs -f backend
|
||||||
|
|
||||||
|
# Monitor resource usage
|
||||||
|
docker stats text-to-audiobook-backend
|
||||||
|
|
||||||
|
# Check health
|
||||||
|
curl http://localhost:8000/api/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Code Style
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Format code
|
||||||
|
black .
|
||||||
|
|
||||||
|
# Lint
|
||||||
|
flake8 .
|
||||||
|
|
||||||
|
# Type checking
|
||||||
|
mypy .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding New Voices
|
||||||
|
|
||||||
|
To add new Kokoro voices, update the voice validation in `main.py`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
SUPPORTED_VOICES = [
|
||||||
|
"af_bella", "af_sarah", "am_adam", "am_michael",
|
||||||
|
"bf_emma", "bf_isabella", "bm_george", "bm_lewis",
|
||||||
|
# Add new voices here
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding New Languages
|
||||||
|
|
||||||
|
To add new languages, update the language validation in `main.py`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
SUPPORTED_LANGUAGES = ["a", "b", "f", "j"] # Add new codes
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
- Input validation on all endpoints
|
||||||
|
- Text length limits to prevent DoS
|
||||||
|
- CORS configured for frontend origin
|
||||||
|
- No sensitive data in logs
|
||||||
|
- Rate limiting recommended for production
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
### Recommendations
|
||||||
|
|
||||||
|
1. **Use environment variables** for configuration
|
||||||
|
2. **Enable HTTPS** with reverse proxy (nginx, Caddy)
|
||||||
|
3. **Set up monitoring** (health checks, logs)
|
||||||
|
4. **Configure rate limiting**
|
||||||
|
5. **Use production ASGI server** (Uvicorn with workers)
|
||||||
|
6. **Set resource limits** (memory, CPU)
|
||||||
|
|
||||||
|
### Production Command
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uvicorn main:app \
|
||||||
|
--host 0.0.0.0 \
|
||||||
|
--port 8000 \
|
||||||
|
--workers 4 \
|
||||||
|
--log-level info \
|
||||||
|
--no-access-log
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
- [Kokoro TTS GitHub](https://github.com/hexgrad/kokoro)
|
||||||
|
- [FastAPI Documentation](https://fastapi.tiangolo.com/)
|
||||||
|
- [Main Project README](../README.md)
|
||||||
|
- [Design Document](../.kiro/specs/text-to-audiobook/design.md)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|||||||
@@ -1,60 +1,555 @@
|
|||||||
# Text to Audiobook Frontend
|
# Text to Audiobook Frontend
|
||||||
|
|
||||||
React TypeScript frontend for the Text to Audiobook application.
|
React TypeScript single-page application for converting text to multi-voice audiobooks.
|
||||||
|
|
||||||
## Setup
|
## Overview
|
||||||
|
|
||||||
### Prerequisites
|
The frontend provides an intuitive interface for:
|
||||||
|
- Text input with role marker support
|
||||||
|
- Automatic role detection
|
||||||
|
- Voice assignment per role
|
||||||
|
- Language and speed configuration
|
||||||
|
- Audio playback and download
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
- Node.js 20.19+ or 22.12+
|
- Node.js 20.19+ or 22.12+
|
||||||
- npm or yarn
|
- npm or yarn
|
||||||
|
- Backend service running (see [Backend README](../backend/README.md))
|
||||||
|
|
||||||
### Installation
|
## Installation
|
||||||
|
|
||||||
1. Install dependencies:
|
|
||||||
```bash
|
```bash
|
||||||
|
# Install dependencies
|
||||||
npm install
|
npm install
|
||||||
```
|
|
||||||
|
|
||||||
2. Create environment file:
|
# Create environment file
|
||||||
```bash
|
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Update `.env` with your backend URL (default: `http://localhost:8000`)
|
## Configuration
|
||||||
|
|
||||||
|
Edit `.env` to configure the backend URL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
VITE_API_BASE_URL=http://localhost:8000
|
||||||
|
```
|
||||||
|
|
||||||
|
**For production:**
|
||||||
|
```bash
|
||||||
|
VITE_API_BASE_URL=https://your-backend-domain.com
|
||||||
|
```
|
||||||
|
|
||||||
## Development
|
## Development
|
||||||
|
|
||||||
Start the development server:
|
### Start Development Server
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
The application will be available at `http://localhost:5173`
|
The application will be available at http://localhost:5173
|
||||||
|
|
||||||
## Build
|
### Development Features
|
||||||
|
|
||||||
|
- Hot Module Replacement (HMR)
|
||||||
|
- Fast refresh for React components
|
||||||
|
- TypeScript type checking
|
||||||
|
- ESLint integration
|
||||||
|
|
||||||
|
### Development Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start dev server
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# Type check
|
||||||
|
npm run type-check
|
||||||
|
|
||||||
|
# Lint code
|
||||||
|
npm run lint
|
||||||
|
|
||||||
|
# Format code
|
||||||
|
npm run format
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production Build
|
||||||
|
|
||||||
|
### Build for Production
|
||||||
|
|
||||||
Build for production:
|
|
||||||
```bash
|
```bash
|
||||||
npm run build
|
npm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
Preview production build:
|
Built files will be in `dist/` directory.
|
||||||
|
|
||||||
|
### Preview Production Build
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run preview
|
npm run preview
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Preview server runs on http://localhost:4173
|
||||||
|
|
||||||
|
### Build Optimization
|
||||||
|
|
||||||
|
The production build includes:
|
||||||
|
- Code minification
|
||||||
|
- Tree shaking
|
||||||
|
- Asset optimization
|
||||||
|
- CSS purging (Tailwind)
|
||||||
|
- Source maps (optional)
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
frontend/
|
||||||
├── api/ # API client modules
|
├── src/
|
||||||
├── components/ # React components
|
│ ├── api/
|
||||||
├── App.tsx # Main application component
|
│ │ └── tts.ts # API client & TypeScript interfaces
|
||||||
├── main.tsx # Application entry point
|
│ ├── components/
|
||||||
└── index.css # Global styles (Tailwind)
|
│ │ ├── TextInputSection.tsx # Text input component
|
||||||
|
│ │ ├── VoiceAssignmentSection.tsx # Voice assignment UI
|
||||||
|
│ │ └── AudioPlayerSection.tsx # Audio playback component
|
||||||
|
│ ├── App.tsx # Main application & state management
|
||||||
|
│ ├── App.css # Application styles
|
||||||
|
│ ├── main.tsx # Application entry point
|
||||||
|
│ └── index.css # Global styles (Tailwind)
|
||||||
|
├── public/
|
||||||
|
│ └── vite.svg # Public assets
|
||||||
|
├── index.html # HTML template
|
||||||
|
├── package.json # Dependencies & scripts
|
||||||
|
├── tsconfig.json # TypeScript configuration
|
||||||
|
├── vite.config.ts # Vite configuration
|
||||||
|
├── tailwind.config.js # Tailwind CSS configuration
|
||||||
|
├── postcss.config.js # PostCSS configuration
|
||||||
|
├── eslint.config.js # ESLint configuration
|
||||||
|
├── .env.example # Environment template
|
||||||
|
└── README.md # This file
|
||||||
```
|
```
|
||||||
|
|
||||||
## Environment Variables
|
## Components
|
||||||
|
|
||||||
- `VITE_API_BASE_URL` - Backend API base URL (default: http://localhost:8000)
|
### App Component (`App.tsx`)
|
||||||
|
|
||||||
|
Main application container managing workflow state.
|
||||||
|
|
||||||
|
**State:**
|
||||||
|
- Text input
|
||||||
|
- Detected roles
|
||||||
|
- Voice assignments
|
||||||
|
- Language selection
|
||||||
|
- Speed setting
|
||||||
|
- Audio URL
|
||||||
|
- Loading states
|
||||||
|
- Error handling
|
||||||
|
|
||||||
|
**Phases:**
|
||||||
|
1. Input - Text entry
|
||||||
|
2. Assignment - Voice selection
|
||||||
|
3. Generated - Audio playback
|
||||||
|
|
||||||
|
### TextInputSection Component
|
||||||
|
|
||||||
|
Text input interface with validation.
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Large multiline textarea
|
||||||
|
- Character count (optional)
|
||||||
|
- Validation for empty text
|
||||||
|
- "Next: Assign voices" button
|
||||||
|
- Loading state support
|
||||||
|
|
||||||
|
### VoiceAssignmentSection Component
|
||||||
|
|
||||||
|
Voice assignment and configuration interface.
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Role list with voice dropdowns
|
||||||
|
- Language selector (American English, British English, French, Japanese)
|
||||||
|
- Speed slider (0.5x - 1.5x)
|
||||||
|
- "Generate Audiobook" button
|
||||||
|
- Validation (all roles must have voices)
|
||||||
|
|
||||||
|
### AudioPlayerSection Component
|
||||||
|
|
||||||
|
Audio playback and download interface.
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- HTML5 audio player with controls
|
||||||
|
- Download button
|
||||||
|
- Blob URL management
|
||||||
|
|
||||||
|
## API Client
|
||||||
|
|
||||||
|
### TypeScript Interfaces
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface Role {
|
||||||
|
id: string;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RoleWithVoice extends Role {
|
||||||
|
voice: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface RolesResponse {
|
||||||
|
roles: Role[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface GenerateRequest {
|
||||||
|
text: string;
|
||||||
|
lang: string;
|
||||||
|
roles: { id: string; voice: string }[];
|
||||||
|
speed?: number;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Functions
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Detect roles in text
|
||||||
|
async function detectRoles(text: string): Promise<RolesResponse>
|
||||||
|
|
||||||
|
// Generate audiobook
|
||||||
|
async function generateAudiobook(payload: GenerateRequest): Promise<Blob>
|
||||||
|
|
||||||
|
// Health check
|
||||||
|
async function checkHealth(): Promise<{ status: string }>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Styling
|
||||||
|
|
||||||
|
### Tailwind CSS
|
||||||
|
|
||||||
|
The application uses Tailwind CSS for styling:
|
||||||
|
|
||||||
|
- Utility-first CSS framework
|
||||||
|
- Responsive design
|
||||||
|
- Dark mode support (optional)
|
||||||
|
- Custom color palette
|
||||||
|
|
||||||
|
### Responsive Design
|
||||||
|
|
||||||
|
Breakpoints:
|
||||||
|
- Mobile: < 640px
|
||||||
|
- Tablet: 640px - 1024px
|
||||||
|
- Desktop: > 1024px
|
||||||
|
|
||||||
|
All components are mobile-friendly with:
|
||||||
|
- Touch-friendly controls (min 44x44px)
|
||||||
|
- Responsive layouts
|
||||||
|
- Readable text sizes
|
||||||
|
- Appropriate spacing
|
||||||
|
|
||||||
|
## Usage Workflow
|
||||||
|
|
||||||
|
### 1. Text Input Phase
|
||||||
|
|
||||||
|
User enters text with role markers:
|
||||||
|
|
||||||
|
```
|
||||||
|
Narrator: Once upon a time...
|
||||||
|
Alice: Hello there!
|
||||||
|
Bob: Hi Alice!
|
||||||
|
```
|
||||||
|
|
||||||
|
Supported patterns:
|
||||||
|
- `RoleName:` - Colon pattern
|
||||||
|
- `[RoleName]` - Bracket pattern
|
||||||
|
|
||||||
|
### 2. Voice Assignment Phase
|
||||||
|
|
||||||
|
- System detects roles automatically
|
||||||
|
- User assigns voice to each role
|
||||||
|
- User selects language
|
||||||
|
- User adjusts speed (optional)
|
||||||
|
|
||||||
|
### 3. Audio Generation Phase
|
||||||
|
|
||||||
|
- Click "Generate Audiobook"
|
||||||
|
- Loading indicator shows progress
|
||||||
|
- Warning for long texts
|
||||||
|
|
||||||
|
### 4. Playback Phase
|
||||||
|
|
||||||
|
- Audio player appears
|
||||||
|
- Play/pause/seek controls
|
||||||
|
- Download button available
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Network Errors
|
||||||
|
|
||||||
|
- Connection failures
|
||||||
|
- Timeout errors
|
||||||
|
- Server unavailable
|
||||||
|
|
||||||
|
**Display:** User-friendly error messages
|
||||||
|
|
||||||
|
### Validation Errors
|
||||||
|
|
||||||
|
- Empty text
|
||||||
|
- Missing voice assignments
|
||||||
|
- Invalid configurations
|
||||||
|
|
||||||
|
**Display:** Inline validation messages
|
||||||
|
|
||||||
|
### API Errors
|
||||||
|
|
||||||
|
- 400 Bad Request
|
||||||
|
- 500 Internal Server Error
|
||||||
|
- Custom error messages
|
||||||
|
|
||||||
|
**Display:** Error banner with details
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Run Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Coverage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run test:coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Files
|
||||||
|
|
||||||
|
- Component tests
|
||||||
|
- API client tests
|
||||||
|
- Integration tests
|
||||||
|
- E2E tests (optional)
|
||||||
|
|
||||||
|
## Browser Support
|
||||||
|
|
||||||
|
### Supported Browsers
|
||||||
|
|
||||||
|
- Chrome/Edge 90+
|
||||||
|
- Firefox 88+
|
||||||
|
- Safari 14+
|
||||||
|
- Opera 76+
|
||||||
|
|
||||||
|
### Required Features
|
||||||
|
|
||||||
|
- ES2020 support
|
||||||
|
- Fetch API
|
||||||
|
- HTML5 Audio
|
||||||
|
- Blob API
|
||||||
|
- Local Storage (optional)
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
### Optimization Techniques
|
||||||
|
|
||||||
|
1. **Code splitting**: Dynamic imports for large components
|
||||||
|
2. **Lazy loading**: Load components on demand
|
||||||
|
3. **Memoization**: React.memo for expensive components
|
||||||
|
4. **Debouncing**: Input handlers
|
||||||
|
5. **Asset optimization**: Image compression, lazy loading
|
||||||
|
|
||||||
|
### Performance Monitoring
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Analyze bundle size
|
||||||
|
npm run build -- --analyze
|
||||||
|
|
||||||
|
# Lighthouse audit
|
||||||
|
npm run lighthouse
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### Static Hosting
|
||||||
|
|
||||||
|
The built application can be deployed to:
|
||||||
|
- Vercel
|
||||||
|
- Netlify
|
||||||
|
- GitHub Pages
|
||||||
|
- AWS S3 + CloudFront
|
||||||
|
- Any static file server
|
||||||
|
|
||||||
|
### Deployment Steps
|
||||||
|
|
||||||
|
1. Build the application:
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Configure environment variables for production
|
||||||
|
|
||||||
|
3. Deploy `dist/` directory to hosting service
|
||||||
|
|
||||||
|
### Environment Variables in Production
|
||||||
|
|
||||||
|
Set `VITE_API_BASE_URL` to your production backend URL:
|
||||||
|
|
||||||
|
**Vercel:**
|
||||||
|
```bash
|
||||||
|
vercel env add VITE_API_BASE_URL
|
||||||
|
```
|
||||||
|
|
||||||
|
**Netlify:**
|
||||||
|
Add to `netlify.toml`:
|
||||||
|
```toml
|
||||||
|
[build.environment]
|
||||||
|
VITE_API_BASE_URL = "https://api.yourdomain.com"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example nginx Configuration
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name yourdomain.com;
|
||||||
|
root /var/www/text-to-audiobook;
|
||||||
|
index index.html;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cache static assets
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Cannot connect to backend
|
||||||
|
|
||||||
|
**Error:** Network request failed
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. Verify backend is running: `curl http://localhost:8000/api/health`
|
||||||
|
2. Check `VITE_API_BASE_URL` in `.env`
|
||||||
|
3. Verify CORS settings in backend
|
||||||
|
4. Check browser console for details
|
||||||
|
|
||||||
|
### Audio won't play
|
||||||
|
|
||||||
|
**Error:** Audio playback failed
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
1. Check browser console for errors
|
||||||
|
2. Verify audio format support (WAV)
|
||||||
|
3. Try different browser
|
||||||
|
4. Check audio permissions
|
||||||
|
|
||||||
|
### Build fails
|
||||||
|
|
||||||
|
**Error:** Build errors
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
```bash
|
||||||
|
# Clear cache
|
||||||
|
rm -rf node_modules dist
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Check Node version
|
||||||
|
node --version # Should be 20.19+ or 22.12+
|
||||||
|
|
||||||
|
# Update dependencies
|
||||||
|
npm update
|
||||||
|
```
|
||||||
|
|
||||||
|
### TypeScript errors
|
||||||
|
|
||||||
|
**Error:** Type checking fails
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
```bash
|
||||||
|
# Run type check
|
||||||
|
npm run type-check
|
||||||
|
|
||||||
|
# Check tsconfig.json
|
||||||
|
# Verify all dependencies have types
|
||||||
|
```
|
||||||
|
|
||||||
|
### Styling issues
|
||||||
|
|
||||||
|
**Error:** Tailwind classes not working
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
```bash
|
||||||
|
# Rebuild Tailwind
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# Check tailwind.config.js
|
||||||
|
# Verify PostCSS configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Tips
|
||||||
|
|
||||||
|
### Hot Reload Issues
|
||||||
|
|
||||||
|
If HMR stops working:
|
||||||
|
```bash
|
||||||
|
# Restart dev server
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# Clear Vite cache
|
||||||
|
rm -rf node_modules/.vite
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debugging
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Enable debug mode
|
||||||
|
localStorage.setItem('debug', 'true');
|
||||||
|
|
||||||
|
// View API requests
|
||||||
|
// Open browser DevTools → Network tab
|
||||||
|
```
|
||||||
|
|
||||||
|
### Code Quality
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Format code
|
||||||
|
npm run format
|
||||||
|
|
||||||
|
# Lint and fix
|
||||||
|
npm run lint -- --fix
|
||||||
|
|
||||||
|
# Type check
|
||||||
|
npm run type-check
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
### Code Style
|
||||||
|
|
||||||
|
- Use TypeScript for type safety
|
||||||
|
- Follow React best practices
|
||||||
|
- Use functional components with hooks
|
||||||
|
- Write meaningful component names
|
||||||
|
- Add comments for complex logic
|
||||||
|
|
||||||
|
### Component Guidelines
|
||||||
|
|
||||||
|
1. Keep components small and focused
|
||||||
|
2. Use props for configuration
|
||||||
|
3. Lift state up when needed
|
||||||
|
4. Use custom hooks for reusable logic
|
||||||
|
5. Handle errors gracefully
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
- [React Documentation](https://react.dev/)
|
||||||
|
- [TypeScript Documentation](https://www.typescriptlang.org/)
|
||||||
|
- [Vite Documentation](https://vitejs.dev/)
|
||||||
|
- [Tailwind CSS Documentation](https://tailwindcss.com/)
|
||||||
|
- [Main Project README](../README.md)
|
||||||
|
- [Backend Documentation](../backend/README.md)
|
||||||
|
- [Design Document](../.kiro/specs/text-to-audiobook/design.md)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT
|
||||||
|
|||||||
Reference in New Issue
Block a user