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
|
||||
- _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
|
||||
- Provide backend setup instructions (local and Docker)
|
||||
- Provide frontend setup instructions
|
||||
|
||||
635
README.md
635
README.md
@@ -17,91 +17,638 @@ A full-stack application that converts long-form text into multi-voice audiobook
|
||||
- **Backend**: Python + FastAPI + Kokoro TTS
|
||||
- **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
|
||||
|
||||
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
|
||||
|
||||
- Python 3.10+
|
||||
- Node.js 20.19+ or 22.12+
|
||||
- espeak-ng (system dependency)
|
||||
- Python 3.10 or higher
|
||||
- espeak-ng (system dependency for grapheme-to-phoneme conversion)
|
||||
- Docker (optional, for containerized deployment)
|
||||
|
||||
### Backend Setup
|
||||
### Local Development
|
||||
|
||||
1. Install espeak-ng:
|
||||
#### 1. Install espeak-ng
|
||||
|
||||
**macOS:**
|
||||
```bash
|
||||
# macOS
|
||||
brew install espeak-ng
|
||||
```
|
||||
|
||||
# Linux (Ubuntu/Debian)
|
||||
**Linux (Ubuntu/Debian):**
|
||||
```bash
|
||||
sudo apt-get update
|
||||
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
|
||||
cd backend
|
||||
|
||||
# Create virtual environment
|
||||
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
|
||||
```
|
||||
|
||||
3. Run the backend:
|
||||
```bash
|
||||
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
||||
```
|
||||
#### 3. Configure environment variables
|
||||
|
||||
### Frontend Setup
|
||||
|
||||
1. Install dependencies:
|
||||
```bash
|
||||
cd frontend
|
||||
npm install
|
||||
```
|
||||
|
||||
2. Configure environment:
|
||||
```bash
|
||||
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
|
||||
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]")
|
||||
2. **Assign Voices**: Select a Kokoro voice for each detected role
|
||||
3. **Configure**: Choose language and playback speed
|
||||
4. **Generate**: Create your multi-voice audiobook
|
||||
5. **Listen & Download**: Play or save the generated audio
|
||||
```bash
|
||||
# Build for production
|
||||
npm run build
|
||||
|
||||
# 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
|
||||
|
||||
```
|
||||
.
|
||||
├── backend/ # FastAPI backend
|
||||
│ ├── main.py # API endpoints
|
||||
│ ├── services/ # Business logic
|
||||
│ ├── requirements.txt # Python dependencies
|
||||
│ └── README.md
|
||||
├── frontend/ # React frontend
|
||||
├── backend/ # FastAPI backend
|
||||
│ ├── services/
|
||||
│ │ ├── role_detector.py # Role detection logic
|
||||
│ │ └── tts_service.py # TTS synthesis logic
|
||||
│ ├── main.py # API endpoints
|
||||
│ ├── requirements.txt # Python dependencies
|
||||
│ ├── Dockerfile # Docker configuration
|
||||
│ ├── docker-compose.yml # Docker Compose setup
|
||||
│ ├── .env.example # Environment template
|
||||
│ ├── test_*.py # Test files
|
||||
│ └── README.md # Backend documentation
|
||||
├── frontend/ # React frontend
|
||||
│ ├── src/
|
||||
│ │ ├── api/ # API client
|
||||
│ │ ├── components/ # React components
|
||||
│ │ └── App.tsx # Main app
|
||||
│ ├── package.json
|
||||
│ └── README.md
|
||||
└── README.md # This file
|
||||
│ │ ├── api/
|
||||
│ │ │ └── tts.ts # API client
|
||||
│ │ ├── components/
|
||||
│ │ │ ├── TextInputSection.tsx
|
||||
│ │ │ ├── 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
|
||||
```
|
||||
|
||||
## 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)
|
||||
- [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)
|
||||
- [Kokoro TTS Library](https://github.com/hexgrad/kokoro)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
# 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
|
||||
- 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:**
|
||||
```bash
|
||||
@@ -22,44 +30,453 @@ sudo apt-get update
|
||||
sudo apt-get install espeak-ng
|
||||
```
|
||||
|
||||
### Python Environment Setup
|
||||
|
||||
1. Create a virtual environment:
|
||||
**Linux (Fedora/RHEL):**
|
||||
```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
|
||||
```
|
||||
|
||||
2. Activate the virtual environment:
|
||||
```bash
|
||||
# macOS/Linux
|
||||
# Activate virtual environment
|
||||
# macOS/Linux:
|
||||
source venv/bin/activate
|
||||
|
||||
# Windows
|
||||
# Windows:
|
||||
venv\Scripts\activate
|
||||
```
|
||||
|
||||
3. Install dependencies:
|
||||
```bash
|
||||
# Upgrade pip
|
||||
pip install --upgrade pip
|
||||
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
4. Create environment file:
|
||||
### 3. Environment Configuration
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
## Running the Server
|
||||
Edit `.env` if needed:
|
||||
```bash
|
||||
PORT=8000
|
||||
LOG_LEVEL=info
|
||||
```
|
||||
|
||||
### 4. Run the Server
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
- `GET /api/health` - Health check endpoint
|
||||
- `POST /api/tts/roles` - Detect roles in text
|
||||
- `POST /api/tts` - Generate audiobook
|
||||
### GET /api/health
|
||||
|
||||
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
|
||||
|
||||
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+
|
||||
- npm or yarn
|
||||
- Backend service running (see [Backend README](../backend/README.md))
|
||||
|
||||
### Installation
|
||||
## Installation
|
||||
|
||||
1. Install dependencies:
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
```
|
||||
|
||||
2. Create environment file:
|
||||
```bash
|
||||
# Create environment file
|
||||
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
|
||||
|
||||
Start the development server:
|
||||
### Start Development Server
|
||||
|
||||
```bash
|
||||
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
|
||||
npm run build
|
||||
```
|
||||
|
||||
Preview production build:
|
||||
Built files will be in `dist/` directory.
|
||||
|
||||
### Preview Production Build
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```
|
||||
src/
|
||||
├── api/ # API client modules
|
||||
├── components/ # React components
|
||||
├── App.tsx # Main application component
|
||||
├── main.tsx # Application entry point
|
||||
└── index.css # Global styles (Tailwind)
|
||||
frontend/
|
||||
├── src/
|
||||
│ ├── api/
|
||||
│ │ └── tts.ts # API client & TypeScript interfaces
|
||||
│ ├── components/
|
||||
│ │ ├── 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