This commit is contained in:
Andras Schmelczer 2026-06-28 11:59:44 +01:00
parent f1601257c7
commit c2070693fb
68 changed files with 2305 additions and 212 deletions

View file

@ -8,10 +8,10 @@
# language variants there; this script renders every emitted slug.
#
# Two targets:
# local (default) assumes the docker-compose stack on host.docker.internal,
# bootstraps a recorder admin user automatically.
# prod points at https://perfect-postcode.co.uk and skips the
# bootstrap step; you supply real account credentials.
# local (default): assumes the docker-compose stack on host.docker.internal,
# bootstraps a recorder admin user automatically.
# prod: points at https://perfect-postcode.co.uk and skips the
# bootstrap step; you supply real account credentials.
#
# Usage:
# ./render.sh # local stack, English homepage landscape + portrait
@ -27,10 +27,10 @@
# APP_URL=http://localhost:3001 ./render.sh # override frontend URL
#
# Cred env vars (read for both targets, but prod has no fallback defaults):
# LOGIN_EMAIL, LOGIN_PASSWORD the dashboard account to record as
# (same email/password you'd type into
# the login modal)
# PB_ADMIN_EMAIL, PB_ADMIN_PASSWORD PocketBase superuser, only used by
# LOGIN_EMAIL, LOGIN_PASSWORD: the dashboard account to record as
# (same email/password you'd type into
# the login modal)
# PB_ADMIN_EMAIL, PB_ADMIN_PASSWORD: PocketBase superuser, only used by
# --target local to bootstrap the
# recorder user; ignored on --prod
@ -80,7 +80,7 @@ else
fi
export PB_BOOTSTRAP_ADMIN
export LOGIN_EMAIL LOGIN_PASSWORD
# Per-target storage state switching targets must not reuse a stale token.
# Per-target storage state: switching targets must not reuse a stale token.
# config.ts reads AUTH_STATE_FILE for AUTH_STATE_PATH.
export AUTH_STATE_FILE="${AUTH_STATE_FILE:-auth.${TARGET}.json}"
AUTH_TTL_HOURS="${AUTH_TTL_HOURS:-24}" # re-auth if cache older than this
@ -306,7 +306,7 @@ if [ "$DO_AUDIO" = "1" ]; then
export UV_HTTP_TIMEOUT="${UV_HTTP_TIMEOUT:-600}"
# Pull in the flash-attn prebuilt wheel (defined as the `gpu` extra) when
# the host actually has a GPU. The wheel is bound to torch 2.6 + cu12 +
# cp312 — see tts/pyproject.toml.
# cp312. See tts/pyproject.toml.
uv_sync_extras=()
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi -L >/dev/null 2>&1; then
uv_sync_extras+=(--extra gpu)
@ -331,7 +331,7 @@ if [ "$DO_AUDIO" = "1" ]; then
# Voice consistency: every ad in this set declares the same AD_VOICE
# (instruct/seed/temperature/topP/referenceText). Even with seed-locked
# VoiceDesign, independent invocations across processes can produce
# mildly different reference waveforms different enough that a
# mildly different reference waveforms, different enough that a
# listener notices the timbre shift across ads. To avoid that, we
# mint the reference WAV ONCE (from the first storyboard) and reuse
# it across the rest of the storyboards by copying _reference.wav +
@ -342,7 +342,7 @@ if [ "$DO_AUDIO" = "1" ]; then
# We copy ONLY the reference, never the cue wavs or index.json. Copying
# the whole audio dir (as an earlier version did) overwrote each later
# storyboard's cached index.json with the FIRST storyboard's, which
# forced a full re-synth on every run and in multi-voice sets (the
# forced a full re-synth on every run, and in multi-voice sets (the
# localized homepage demos: en/de/zh/hi) it clobbered correct localized
# audio. With a reference-only copy: same-voice sets reuse the reference
# (meta matches); different-voice sets re-mint their own (meta mismatch),
@ -364,7 +364,7 @@ if [ "$DO_AUDIO" = "1" ]; then
if [ -z "$shared_ref_wav" ] && [ -f "output/$sb/audio/_reference.wav" ]; then
shared_ref_wav="output/$sb/audio/_reference.wav"
shared_ref_meta="output/$sb/audio/_reference.meta.json"
say "Locked voice reference to $shared_ref_wav reusing for the rest of the set"
say "Locked voice reference to $shared_ref_wav; reusing for the rest of the set"
fi
done
fi
@ -422,7 +422,7 @@ for sb in "${STORYBOARDS[@]}"; do
if [ "$DO_ENCODE" = "1" ] && [ "$DO_AUDIO" = "1" ]; then
if [ ! -s "output/$sb/narration.json" ]; then
fail "[$sb] narration.json missing recorder did not log cues"
fail "[$sb] narration.json missing: recorder did not log cues"
fi
say "[$sb] Muxing narration into output/$sb/recording.mp4"
uv run --project tts python tts/mux.py --storyboard "$sb" --replace \