Ep13 publish, MLX whisper, voicemail system, hero redesign, massive topic expansion

- Switch whisper transcription from faster-whisper (CPU) to lightning-whisper-mlx (GPU)
- Fix word_timestamps hanging, use ffprobe for accurate duration
- Add Cloudflare Pages Worker for SignalWire voicemail fallback when server offline
- Add voicemail sync on startup, delete tracking, save feature
- Add /feed RSS proxy to _worker.js (was broken by worker taking over routing)
- Redesign website hero section: ghost buttons, compact phone, plain text links
- Rewrite caller prompts for faster point-getting and host-following
- Expand TOPIC_CALLIN from ~250 to 547 entries across 34 categories
- Add new categories: biology, psychology, engineering, math, geology, animals,
  work, money, books, movies, relationships, health, language, true crime,
  drunk/high/unhinged callers
- Remove bad Inworld voices (Pixie, Dominus), reduce repeat caller frequency
- Add audio monitor device routing, uvicorn --reload-dir fix
- Publish episode 13

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 01:56:47 -07:00
parent 8d3d67a177
commit 3164a70e48
23 changed files with 2944 additions and 512 deletions

View File

@@ -60,7 +60,7 @@ PODCAST_ID = 1
PODCAST_HANDLE = "LukeAtTheRoost"
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")
WHISPER_MODEL = "large-v3"
WHISPER_MODEL = "distil-large-v3"
# Postiz (social media posting)
POSTIZ_URL = "https://social.lukeattheroost.com"
@@ -189,35 +189,41 @@ TRANSCRIPT:
def transcribe_audio(audio_path: str) -> dict:
"""Transcribe audio using faster-whisper with timestamps."""
print(f"[1/5] Transcribing {audio_path}...")
"""Transcribe audio using Lightning Whisper MLX (Apple Silicon GPU)."""
print(f"[1/5] Transcribing {audio_path} (MLX GPU)...")
try:
from faster_whisper import WhisperModel
from lightning_whisper_mlx import LightningWhisperMLX
except ImportError:
print("Error: faster-whisper not installed. Run: pip install faster-whisper")
print("Error: lightning-whisper-mlx not installed. Run: pip install lightning-whisper-mlx")
sys.exit(1)
model = WhisperModel(WHISPER_MODEL, compute_type="int8")
segments, info = model.transcribe(audio_path, word_timestamps=True)
probe = subprocess.run(
["ffprobe", "-v", "quiet", "-show_entries", "format=duration", "-of", "csv=p=0", audio_path],
capture_output=True, text=True
)
duration = int(float(probe.stdout.strip())) if probe.returncode == 0 else 0
whisper = LightningWhisperMLX(model=WHISPER_MODEL, batch_size=12, quant=None)
result = whisper.transcribe(audio_path=audio_path, language="en")
transcript_segments = []
full_text = []
for segment in segments:
for segment in result.get("segments", []):
start_ms, end_ms, text = segment[0], segment[1], segment[2]
transcript_segments.append({
"start": segment.start,
"end": segment.end,
"text": segment.text.strip()
"start": start_ms / 1000.0,
"end": end_ms / 1000.0,
"text": text.strip()
})
full_text.append(segment.text.strip())
print(f" Transcribed {info.duration:.1f} seconds of audio")
full_text.append(text.strip())
print(f" Transcribed {duration} seconds of audio ({len(transcript_segments)} segments)")
return {
"segments": transcript_segments,
"full_text": " ".join(full_text),
"duration": int(info.duration)
"duration": duration
}