Reels: portrait canvas with blurred fill, fade transitions, warmer TTS

Fixes the "image is tiny" problem: a 1920x1080 landscape reel letterboxes
to a ~25%-height band on a portrait phone. Switch to a portrait 1080x1920
canvas and fill it per photo with a blurred, zoomed copy of the image
behind the sharp fitted photo — so the frame is always full regardless of
the photo's orientation, with no black bars and no cropping of the subject.

Add a quick 0.35s fade in/out baked into each segment so concatenated
photos dip smoothly instead of hard-cutting (fade-out lands in the
narration's silent tail, so speech isn't clipped). Drop the unused
Ken Burns branch — motion can return deliberately later.

Warm up the narration a touch: thread Chatterbox's `exaggeration` through
synthesize_serialized and default reels to 0.7 (tunable via
REEL_TTS_EXAGGERATION). Bump RENDER_VERSION so existing landscape reels
re-render.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cameron CordesandClaude Fable 5 committed 2026-06-12 23:10:26 -04:00
1 parent 42453d5786
commit 7715a7a905
3 files changed
+101 -66

No files matched your search

+5 -1
View File
@@ -486,11 +486,15 @@ pub async fn synthesize_serialized(
text: &str,
voice: Option<&str>,
format: &str,
exaggeration: Option<f32>,
) -> anyhow::Result<Vec<u8>> {
let prepared = prepare_for_tts(text);
if prepared.is_empty() {
anyhow::bail!("nothing to synthesize after cleanup");
}
// Clamp to Chatterbox's documented range, matching the HTTP handlers
// (which clamp before forwarding; this path bypasses them).
let exaggeration = exaggeration.map(|x| x.clamp(0.25, 2.0));
// Queue rather than fast-fail (mirrors create_speech_job_handler).
let _permit = TTS_PERMIT
.acquire()
@@ -500,7 +504,7 @@ pub async fn synthesize_serialized(
// starts (see ai::gpu).
let _gpu = crate::ai::gpu::tts_lease().await;
client
.text_to_speech(&prepared, voice, format, None, None, None)
.text_to_speech(&prepared, voice, format, exaggeration, None, None)
.await
}