One-key formula: AI images, TTS narration, auto music, subtitles, and self-review pipeline

Prove that adding one API key (OPENAI_API_KEY) to the zero-key foundation
produces dramatically better videos for ~$0.69 each. Two compositions built:
The Abyss (deep ocean visual essay) and VOID (neural interface product ad).

New tools:
- audio_probe: ffprobe wrapper with probe_duration() helper
- composition_validator: pre-render checks (asset existence, audio-video sync)
- pixabay_music: royalty-free music scraper (no API key needed)
- freesound_music: Freesound API search + download

Remotion upgrades:
- BackgroundImageLayer: AI images behind data scenes with ken-burns + dark overlay
- Gradient support: all 9 components changed from backgroundColor to background CSS
- CaptionOverlay: word spacing fix, WhisperX word-level subtitles
- HeroTitle: reduced overlay opacity so background images show through

Process codified in agent skills:
- compose-director: audio acquisition flow (present user with voice/music/subtitle
  options), mandatory pre-render validation, post-render self-review (extract
  frames + transcribe + inspect + present findings to user)
- scene-director: narration duration budgeting (word budget from video duration)
- remotion skill: pre-render validation section
- TTS tool: now returns audio_duration_seconds in result

README updated with VOID product ad video embed.
This commit is contained in:
calesthio
2026-03-30 16:54:13 -07:00
parent 4ef335ac0b
commit 8cac647193
21 changed files with 1329 additions and 112 deletions
@@ -111,7 +111,7 @@ export const CalloutBox: React.FC<CalloutBoxProps> = ({
return (
<AbsoluteFill
style={{
backgroundColor: containerBackgroundColor,
background: containerBackgroundColor,
justifyContent: "center",
alignItems: "center",
}}
@@ -107,7 +107,7 @@ const PageRenderer: React.FC<{
: "0 2px 4px rgba(0,0,0,0.5)",
}}
>
{w.word}
{w.word}{i < page.words.length - 1 ? " " : ""}
</span>
);
})}
@@ -134,7 +134,7 @@ export const ComparisonCard: React.FC<ComparisonCardProps> = ({
return (
<AbsoluteFill
style={{
backgroundColor,
background: backgroundColor,
justifyContent: "center",
alignItems: "center",
}}
@@ -24,7 +24,7 @@ export const HeroTitle: React.FC<HeroTitleProps> = ({ title, subtitle }) => {
justifyContent: "center",
alignItems: "center",
background:
"radial-gradient(ellipse at center, rgba(15,23,42,0.85) 0%, rgba(15,23,42,0.95) 100%)",
"radial-gradient(ellipse at center, rgba(15,23,42,0.35) 0%, rgba(15,23,42,0.55) 100%)",
}}
>
<div style={{ textAlign: "center", maxWidth: "85%" }}>
@@ -129,7 +129,7 @@ export const ProgressBar: React.FC<ProgressBarProps> = ({
return (
<AbsoluteFill
style={{
backgroundColor,
background: backgroundColor,
justifyContent: "center",
alignItems: "center",
}}
@@ -41,7 +41,7 @@ export const StatCard: React.FC<StatCardProps> = ({
style={{
justifyContent: "center",
alignItems: "center",
backgroundColor,
background: backgroundColor,
}}
>
<div style={{ textAlign: "center" }}>
@@ -30,7 +30,7 @@ export const TextCard: React.FC<TextCardProps> = ({
style={{
justifyContent: "center",
alignItems: "center",
backgroundColor,
background: backgroundColor,
}}
>
<div
@@ -73,7 +73,7 @@ export const BarChart: React.FC<BarChartProps> = ({
return (
<AbsoluteFill
style={{
backgroundColor,
background: backgroundColor,
justifyContent: "flex-start",
alignItems: "center",
padding: 40,
@@ -78,7 +78,7 @@ export const KPIGrid: React.FC<KPIGridProps> = ({
return (
<AbsoluteFill
style={{
backgroundColor,
background: backgroundColor,
justifyContent: "flex-start",
alignItems: "center",
fontFamily,
@@ -101,7 +101,7 @@ export const LineChart: React.FC<LineChartProps> = ({
return (
<AbsoluteFill
style={{
backgroundColor,
background: backgroundColor,
justifyContent: "flex-start",
alignItems: "center",
padding: 40,
@@ -91,7 +91,7 @@ export const PieChart: React.FC<PieChartProps> = ({
return (
<AbsoluteFill
style={{
backgroundColor,
background: backgroundColor,
justifyContent: "flex-start",
alignItems: "center",
padding: 40,