# 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 -- ``` Generate audio for all posts missing audio: ```bash npm run generate-tts:all ``` Force regeneration (overwrite existing): ```bash npm run generate-tts -- --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)