Add persistent caller voices, Discord, REC/on-air linking, SEO fixes, ep9

- Returning callers now keep their voice across sessions (stored in regulars.json)
- Backfilled voice assignments for all 11 existing regulars
- Discord button on homepage + link in all page footers
- REC and On-Air buttons now toggle together (both directions)
- Fixed host mic double-stream bug (stem_mic vs host_stream conflict)
- SEO: JSON-LD structured data on episode + how-it-works pages
- SEO: noscript fallbacks, RSS links, twitter meta tags
- Episode 9 transcript and sitemap update

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-12 00:24:37 -07:00
parent 953c501f75
commit 75f15ba2d2
13 changed files with 604 additions and 53 deletions

View File

@@ -522,6 +522,13 @@ class AudioService:
print("[Audio] No input device configured for host streaming")
return
# Close stem_mic if active — this stream's callback handles stem recording too
if self._stem_mic_stream is not None:
self._stem_mic_stream.stop()
self._stem_mic_stream.close()
self._stem_mic_stream = None
print("[Audio] Closed stem_mic (host stream takes over)")
self._host_send_callback = send_callback
def _start():
@@ -960,9 +967,12 @@ class AudioService:
def start_stem_mic(self):
"""Start a persistent mic capture stream for stem recording.
Runs independently of push-to-talk and host streaming."""
Skips if _host_stream is already active (it writes to the host stem too)."""
if self._stem_mic_stream is not None:
return
if self._host_stream is not None:
print("[StemRecorder] Host stream already capturing mic, skipping stem_mic")
return
if self.input_device is None:
print("[StemRecorder] No input device configured, skipping host mic capture")
return

View File

@@ -51,7 +51,7 @@ class RegularCallerService:
def add_regular(self, name: str, gender: str, age: int, job: str,
location: str, personality_traits: list[str],
first_call_summary: str) -> dict:
first_call_summary: str, voice: str = None) -> dict:
"""Promote a first-time caller to regular"""
# Retire oldest if at cap
if len(self._regulars) >= MAX_REGULARS:
@@ -67,6 +67,7 @@ class RegularCallerService:
"job": job,
"location": location,
"personality_traits": personality_traits,
"voice": voice,
"call_history": [
{"summary": first_call_summary, "timestamp": time.time()}
],