- Multi-provider TTS service (OpenAI, Piper, macOS say) - Supabase Storage integration for audio files - RSS 2.0 feed with iTunes extensions for podcast distribution - Web audio player at /podcast page - Integration with daily digest workflow - Manual TTS generation script - Complete documentation in PODCAST_SETUP.md
319 lines
8.4 KiB
Markdown
319 lines
8.4 KiB
Markdown
# Podcast Setup Guide
|
|
|
|
This guide covers setting up and using the podcast feature for the Daily Digest blog.
|
|
|
|
## Overview
|
|
|
|
The podcast feature automatically converts Daily Digest blog posts into audio format using Text-to-Speech (TTS) and provides:
|
|
|
|
- 🎧 **Web Player** - Listen directly on the blog
|
|
- 📱 **RSS Feed** - Subscribe in any podcast app (Apple Podcasts, Spotify, etc.)
|
|
- 🔄 **Auto-generation** - TTS runs automatically when new posts are created
|
|
- 💾 **Audio Storage** - Files stored in Supabase Storage (free tier)
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
|
│ Daily │────▶│ TTS API │────▶│ Supabase │
|
|
│ Digest │ │ (OpenAI/ │ │ Storage │
|
|
│ Post │ │ Piper) │ │ │
|
|
└─────────────┘ └─────────────┘ └──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ RSS Feed │
|
|
│ (/api/ │
|
|
│ podcast/ │
|
|
│ rss) │
|
|
└──────┬──────┘
|
|
│
|
|
▼
|
|
┌─────────────┐
|
|
│ Podcast │
|
|
│ Apps │
|
|
│ (Apple, │
|
|
│ Spotify) │
|
|
└─────────────┘
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
### 1. Configure Environment Variables
|
|
|
|
Add to your `.env.local` and `.env.production`:
|
|
|
|
```bash
|
|
# Enable TTS generation
|
|
ENABLE_TTS=true
|
|
|
|
# Choose TTS Provider: "openai" (paid, best quality) or "macsay" (free, macOS only)
|
|
TTS_PROVIDER=openai
|
|
|
|
# For OpenAI TTS (recommended)
|
|
OPENAI_API_KEY=sk-your-key-here
|
|
TTS_VOICE=alloy # Options: alloy, echo, fable, onyx, nova, shimmer
|
|
```
|
|
|
|
### 2. Update Database Schema
|
|
|
|
Run this SQL in your Supabase SQL Editor to add audio columns:
|
|
|
|
```sql
|
|
-- Add audio URL column
|
|
ALTER TABLE blog_messages
|
|
ADD COLUMN IF NOT EXISTS audio_url TEXT;
|
|
|
|
-- Add audio duration column
|
|
ALTER TABLE blog_messages
|
|
ADD COLUMN IF NOT EXISTS audio_duration INTEGER;
|
|
|
|
-- Create index for faster RSS feed queries
|
|
CREATE INDEX IF NOT EXISTS idx_blog_messages_audio
|
|
ON blog_messages(audio_url)
|
|
WHERE audio_url IS NOT NULL;
|
|
```
|
|
|
|
### 3. Create Supabase Storage Bucket
|
|
|
|
The app will automatically create the `podcast-audio` bucket on first use, or you can create it manually:
|
|
|
|
1. Go to Supabase Dashboard → Storage
|
|
2. Click "New Bucket"
|
|
3. Name: `podcast-audio`
|
|
4. Check "Public bucket"
|
|
5. Click "Create"
|
|
|
|
### 4. Deploy
|
|
|
|
```bash
|
|
npm run build
|
|
vercel --prod
|
|
```
|
|
|
|
### 5. Subscribe to the Podcast
|
|
|
|
The RSS feed is available at:
|
|
```
|
|
https://blog-backup-two.vercel.app/api/podcast/rss
|
|
```
|
|
|
|
**Apple Podcasts:**
|
|
1. Open Podcasts app
|
|
2. Tap Library → Edit → Add a Show by URL
|
|
3. Paste the RSS URL
|
|
|
|
**Spotify:**
|
|
1. Go to Spotify for Podcasters
|
|
2. Submit RSS feed
|
|
|
|
**Other Apps:**
|
|
Just paste the RSS URL into any podcast app.
|
|
|
|
## TTS Providers
|
|
|
|
### Option 1: OpenAI TTS (Recommended)
|
|
|
|
**Cost:** ~$2-4/month for daily 5-minute episodes
|
|
|
|
**Pros:**
|
|
- Excellent voice quality
|
|
- Multiple voices available
|
|
- Simple API integration
|
|
- Fast processing
|
|
|
|
**Cons:**
|
|
- Paid service
|
|
- Requires API key
|
|
|
|
**Setup:**
|
|
```bash
|
|
TTS_PROVIDER=openai
|
|
OPENAI_API_KEY=sk-your-key-here
|
|
TTS_VOICE=alloy # or echo, fable, onyx, nova, shimmer
|
|
```
|
|
|
|
### Option 2: macOS `say` Command (Free)
|
|
|
|
**Cost:** $0
|
|
|
|
**Pros:**
|
|
- Free, built into macOS
|
|
- No API key needed
|
|
- Works offline
|
|
|
|
**Cons:**
|
|
- Lower voice quality
|
|
- macOS only
|
|
- Limited to macOS deployment
|
|
|
|
**Setup:**
|
|
```bash
|
|
TTS_PROVIDER=macsay
|
|
TTS_VOICE=Samantha # or Alex, Victoria, etc.
|
|
```
|
|
|
|
### Option 3: Piper TTS (Free, Local)
|
|
|
|
**Cost:** $0
|
|
|
|
**Pros:**
|
|
- Free and open source
|
|
- High quality neural voices
|
|
- Runs locally (privacy)
|
|
- No rate limits
|
|
|
|
**Cons:**
|
|
- Requires downloading voice models (~100MB)
|
|
- More complex setup
|
|
- Requires local execution
|
|
|
|
**Setup:**
|
|
1. Install Piper:
|
|
```bash
|
|
brew install piper-tts # or download from GitHub
|
|
```
|
|
|
|
2. Download voice model:
|
|
```bash
|
|
mkdir -p models
|
|
cd models
|
|
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/lessac/medium/en_US-lessac-medium.onnx
|
|
wget https://huggingface.co/rhasspy/piper-voices/resolve/v1.0.0/en/en_US/lessac/medium/en_US-lessac-medium.onnx.json
|
|
```
|
|
|
|
3. Configure:
|
|
```bash
|
|
TTS_PROVIDER=piper
|
|
PIPER_MODEL_PATH=./models/en_US-lessac-medium.onnx
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Automatic Generation
|
|
|
|
When `ENABLE_TTS=true`, audio is automatically generated when a new digest is posted via the `/api/digest` endpoint.
|
|
|
|
### Manual Generation
|
|
|
|
Generate audio for a specific post:
|
|
```bash
|
|
npm run generate-tts -- <post_id>
|
|
```
|
|
|
|
Generate audio for all posts missing audio:
|
|
```bash
|
|
npm run generate-tts:all
|
|
```
|
|
|
|
Force regeneration (overwrite existing):
|
|
```bash
|
|
npm run generate-tts -- <post_id> --force
|
|
```
|
|
|
|
## API Endpoints
|
|
|
|
### GET /api/podcast/rss
|
|
|
|
Returns the podcast RSS feed in XML format with iTunes extensions.
|
|
|
|
**Headers:**
|
|
- `Accept: application/xml`
|
|
|
|
**Response:** RSS 2.0 XML feed
|
|
|
|
### POST /api/digest (Updated)
|
|
|
|
Now accepts an optional `generateAudio` parameter:
|
|
|
|
```json
|
|
{
|
|
"date": "2026-02-23",
|
|
"content": "# Daily Digest\n\nToday's news...",
|
|
"tags": ["daily-digest", "ai"],
|
|
"generateAudio": true // Optional, defaults to true
|
|
}
|
|
```
|
|
|
|
## Database Schema
|
|
|
|
The `blog_messages` table now includes:
|
|
|
|
| Column | Type | Description |
|
|
|--------|------|-------------|
|
|
| `audio_url` | TEXT | Public URL to the audio file in Supabase Storage |
|
|
| `audio_duration` | INTEGER | Estimated duration in seconds |
|
|
|
|
## File Structure
|
|
|
|
```
|
|
src/
|
|
├── app/
|
|
│ ├── api/
|
|
│ │ ├── digest/route.ts # Updated with TTS trigger
|
|
│ │ └── podcast/
|
|
│ │ └── rss/route.ts # RSS feed endpoint
|
|
│ ├── podcast/
|
|
│ │ └── page.tsx # Podcast web player page
|
|
│ └── page.tsx # Updated with audio player
|
|
├── lib/
|
|
│ ├── tts.ts # TTS service abstraction
|
|
│ ├── storage.ts # Supabase storage helpers
|
|
│ └── podcast.ts # RSS generation utilities
|
|
└── scripts/
|
|
└── generate-tts.ts # Manual TTS generation script
|
|
```
|
|
|
|
## Cost Analysis
|
|
|
|
### OpenAI TTS (Daily Digest ~5 min)
|
|
- Characters per day: ~4,000
|
|
- Cost: $0.015 per 1,000 chars (tts-1)
|
|
- Monthly cost: ~$1.80
|
|
- HD voice (tts-1-hd): ~$3.60/month
|
|
|
|
### Supabase Storage
|
|
- Free tier: 1 GB storage
|
|
- Audio files: ~5 MB per episode
|
|
- Monthly storage: ~150 MB (30 episodes)
|
|
- Well within free tier
|
|
|
|
### Total Monthly Cost
|
|
- **OpenAI TTS:** ~$2-4/month
|
|
- **Supabase Storage:** $0 (free tier)
|
|
- **RSS Hosting:** $0 (Next.js API route)
|
|
- **Total:** ~$2-4/month
|
|
|
|
## Troubleshooting
|
|
|
|
### TTS not generating
|
|
1. Check `ENABLE_TTS=true` in environment variables
|
|
2. Check `TTS_PROVIDER` is set correctly
|
|
3. For OpenAI: Verify `OPENAI_API_KEY` is valid
|
|
4. Check Vercel logs for errors
|
|
|
|
### Audio not playing
|
|
1. Check Supabase Storage bucket is public
|
|
2. Verify `audio_url` in database is not null
|
|
3. Check browser console for CORS errors
|
|
|
|
### RSS feed not updating
|
|
1. RSS is cached for 5 minutes (`max-age=300`)
|
|
2. Check that posts have `audio_url` set
|
|
3. Verify RSS URL is accessible: `/api/podcast/rss`
|
|
|
|
## Future Enhancements
|
|
|
|
- [ ] Background job queue for TTS generation (using Inngest/Upstash)
|
|
- [ ] Voice selection per post
|
|
- [ ] Chapter markers in audio
|
|
- [ ] Transcript generation
|
|
- [ ] Podcast analytics
|
|
|
|
## Resources
|
|
|
|
- [OpenAI TTS Documentation](https://platform.openai.com/docs/guides/text-to-speech)
|
|
- [Piper TTS GitHub](https://github.com/rhasspy/piper)
|
|
- [Apple Podcasts RSS Requirements](https://help.apple.com/itc/podcasts_connect/#/itcb54333f1)
|
|
- [Podcast RSS 2.0 Spec](https://cyber.harvard.edu/rss/rss.html)
|