# TTSFM v3.4.x Dual-Image Implementation

## Overview

Starting with v3.4.0-alpha1, TTSFM provides two Docker image variants to balance functionality and image size:

1. **Full variant** (`dbcccc/ttsfm:latest`, `dbcccc/ttsfm:v3.4.0-alpha1`)
   - Includes ffmpeg for advanced audio processing
   - Supports all features including speed adjustment and format conversion

2. **Slim variant** (`dbcccc/ttsfm:v3.4.0-alpha1-slim`)
   - Minimal image without ffmpeg
   - Basic TTS functionality only

## Implementation Details

### 1. Dockerfile Changes

The Dockerfile now accepts a `VARIANT` build argument:

```dockerfile
ARG VARIANT=full  # Can be 'full' or 'slim'
```

- **Full variant**: Installs ffmpeg in the runtime stage
- **Slim variant**: Skips ffmpeg installation

### 2. GitHub Actions Workflow

`.github/workflows/docker-build.yml` now builds both variants:

- **Full image tags**: `vX.X.X`, `latest`
- **Slim image tags**: `vX.X.X-slim`

Both variants are built for `linux/amd64` and `linux/arm64` platforms on release.

### 3. Runtime Feature Detection

`ttsfm/audio.py` now includes runtime detection:

```python
import shutil
FFMPEG_AVAILABLE = shutil.which("ffmpeg") is not None
```

Functions that require ffmpeg provide helpful error messages when it's not available.

### 4. Speed Adjustment Feature

New module `ttsfm/audio_processing.py` provides:

- `adjust_audio_speed()`: Adjust playback speed using ffmpeg (0.25x - 4.0x)
- `convert_audio_format()`: Convert between audio formats using ffmpeg

Both sync (`TTSClient`) and async (`AsyncTTSClient`) clients now support the `speed` parameter:

```python
response = client.generate_speech(
    text="Hello!",
    voice=Voice.ALLOY,
    speed=1.5,  # 1.5x faster
)
```

Speed adjustment is applied post-generation using ffmpeg's `atempo` filter.

## Feature Matrix

| Feature | Full Image | Slim Image | Python Package |
|---------|-----------|------------|----------------|
| Basic TTS (MP3/WAV) | ✅ | ✅ | ✅ |
| WAV auto-combine | ✅ | ✅ (simple) | ✅ (simple) |
| MP3 auto-combine | ✅ | ❌ | ✅ (with pydub) |
| Speed adjustment | ✅ | ❌ | ✅ (with ffmpeg) |
| Format conversion | ✅ | ❌ | ✅ (with ffmpeg) |

## Usage Examples

### Full Image (Recommended)

```bash
# Pull and run full image
docker run -p 8000:8000 dbcccc/ttsfm:latest

# Use speed adjustment
curl -X POST http://localhost:8000/v1/audio/speech \
  -H "Content-Type: application/json" \
  -d '{"input":"Hello!","voice":"alloy","speed":1.5}' \
  --output fast.mp3
```

### Slim Image (Minimal)

```bash
# Pull and run slim image
docker run -p 8000:8000 dbcccc/ttsfm:v3.4.0-alpha1-slim

# Basic TTS works fine
curl -X POST http://localhost:8000/v1/audio/speech \
  -H "Content-Type: application/json" \
  -d '{"input":"Hello!","voice":"alloy"}' \
  --output speech.mp3

# Speed parameter will be ignored (no error, just logged warning)
```

### Python Package

```python
from ttsfm import TTSClient, Voice

client = TTSClient()

# Speed adjustment requires ffmpeg installed on system
response = client.generate_speech(
    text="This will be faster!",
    voice=Voice.NOVA,
    speed=1.5,
)
response.save_to_file("fast.mp3")
```

## Error Handling

When ffmpeg-dependent features are used without ffmpeg:

```python
# Graceful degradation with helpful error messages
RuntimeError: "Speed adjustment requires ffmpeg. 
Use the full Docker image (dbcccc/ttsfm:latest) instead of the slim variant."
```

## Migration Guide

### From v3.3.x to v3.4.x

**No breaking changes** - existing code continues to work:

1. **Docker users**:
   - `dbcccc/ttsfm:latest` now includes speed adjustment
   - Use `dbcccc/ttsfm:v3.4.0-alpha1-slim` for minimal image

2. **Python package users**:
   - Speed parameter now functional (requires ffmpeg)
   - Install ffmpeg: `apt-get install ffmpeg` (Linux) or `brew install ffmpeg` (Mac)

3. **API users**:
   - Speed parameter now works in `/v1/audio/speech` endpoint
   - Response metadata includes `speed_applied: true/false`

## Technical Notes

### Speed Adjustment Implementation

- Uses ffmpeg's `atempo` filter for speed adjustment
- Supports 0.25x to 4.0x range (OpenAI TTS API compatible)
- Chains multiple `atempo` filters for speeds outside 0.5-2.0 range
- Adjusts estimated duration based on speed multiplier
- Runs in thread pool for async client to avoid blocking

### Build Optimization

- Shared builder stage for both variants
- Separate cache scopes (`scope=full`, `scope=slim`) for efficient caching
- Multi-platform builds only on release (saves CI time)

## Future Enhancements

Potential additions for future versions:

1. **Additional format support**: Real AAC, FLAC, OPUS output (currently mapped to WAV)
2. **Audio effects**: Pitch adjustment, noise reduction
3. **Streaming support**: Real-time audio streaming with speed adjustment
4. **Ultra-slim variant**: Alpine-based image (~50MB) with no Python web server

## References

- [OpenAI TTS API Documentation](https://platform.openai.com/docs/guides/text-to-speech)
- [ffmpeg atempo filter](https://ffmpeg.org/ffmpeg-filters.html#atempo)
- [Docker multi-stage builds](https://docs.docker.com/build/building/multi-stage/)

