blog-backup/PODCAST_SETUP.md
OpenClaw Bot 9720390e1a Add podcast feature with TTS, RSS feed, and web player
- 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
2026-02-23 20:15:27 -06:00

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)