mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-04 16:42:27 +00:00
docs: make the ten hardest-reading prompting pages readable
Measured across all 136 hand-written pages, the twelve hardest to read were all in prompting/. These ten were untouched — 29% to 40% of their sentences ran over 28 words, against a site median under 15%. media-and-audio 39.7% -> 6.2% 15 semicolons -> 6 visual-specs 37.1% -> 19.0% 11 -> 9 weekly-updates 39.1% -> 0.0% runtimes-and-3d 34.1% -> 17.5% design-systems 34.0% -> 4.3% recreating-references 33.3% -> 7.3% 16 -> 1 storyboards 31.9% -> 5.4% variables-and-templating 30.3% -> 7.3% generated-artwork 29.4% -> 9.1% explainers 29.1% -> 3.3% 12 -> 1 Word counts barely move — 1752 to 1748, 1633 to 1617 — which is the point. The facts and worked examples all survived; the sentences carrying them got shorter. weekly-updates is an archive, so no date, version or fact changed there at all. One anchor came back: capstone#the-full-prompt-verbatim, which these pages link to and which an earlier commit had already moved to #the-prompt-word-for-word. Repointed. Branch total: 0 broken pages, 0 broken anchors.
This commit is contained in:
@@ -1,28 +1,50 @@
|
||||
---
|
||||
title: Media and audio
|
||||
description: "Ask for the voiceover, music, sound, captions, cutouts, and assets a composition needs — with the precise, unambiguous phrasing the media pipeline acts on."
|
||||
description: "Ask for the voiceover, music, sound, captions, cutouts, and assets a composition needs, in phrasing the media pipeline acts on."
|
||||
---
|
||||
|
||||
import { DocsVideo } from "/snippets/docs-video.jsx";
|
||||
|
||||
By now your video moves and reads right; this level gives it a voice. HyperFrames owns media *playback*; a sibling media pipeline resolves everything else — voice, music, sound effects, images, icons, logos, captions, and background removal. You reach all of it by describing what the composition needs, and the agent resolves each need to a frozen local file. The craft here is precision: vague media asks ("add some music," "no sound") are the ones that come back wrong, because the pipeline does exactly what the words say.
|
||||
Your video moves and reads right. This level gives it a voice.
|
||||
|
||||
HyperFrames owns media *playback*. A sibling media pipeline resolves everything
|
||||
else: voice, music, sound effects, images, icons, logos, captions, and
|
||||
background removal. You describe what the composition needs. The agent resolves
|
||||
each need to a frozen local file.
|
||||
|
||||
Precision is the whole craft here. Vague asks come back wrong. "Add some music"
|
||||
and "no sound" are the two that bite most often, because the pipeline does
|
||||
exactly what the words say.
|
||||
|
||||
## Voiceover (TTS)
|
||||
|
||||
Text-to-speech runs locally through Kokoro — no API key needed — with a HeyGen TTS upsell behind it. Describe the content and the agent picks a fitting voice, or name the voice, tone, and speed directly:
|
||||
The agent picks a voice engine in a fixed order. HeyGen Starfish goes first if
|
||||
your HeyGen account is configured. ElevenLabs is next if that key is set.
|
||||
Otherwise the local Kokoro model runs, and it needs no API key.
|
||||
|
||||
Describe the content and let the agent pick a fitting voice. Or name the voice,
|
||||
tone, and speed yourself:
|
||||
|
||||
> Generate narration for this script with a professional female voice.
|
||||
|
||||
> Add TTS voiceover, British male voice, at 1.1× speed.
|
||||
|
||||
The [Vocabulary](/prompting/vocabulary#text-to-speech-voices) table maps content types to Kokoro voices (for example `af_heart` / `af_nova` for a product demo, `am_adam` / `bf_emma` for a tutorial, `af_sky` / `am_michael` for marketing). Name one directly if you already know it; otherwise describe the read and let the agent choose.
|
||||
The [Vocabulary](/prompting/vocabulary#text-to-speech-voices) table maps content
|
||||
types to Kokoro voices. `af_heart` and `af_nova` suit a product demo. `am_adam`
|
||||
and `bf_emma` suit a tutorial. `af_sky` and `am_michael` suit marketing. Name a
|
||||
voice directly if you already know it. Otherwise describe the read and let the
|
||||
agent choose.
|
||||
|
||||
- ❌ `add a voice`
|
||||
- ✅ `warm, unhurried female narration of the quoted script` — tone and pace are what actually change the delivery
|
||||
|
||||
## Background music
|
||||
|
||||
Music resolves from a large catalog by mood, and it should almost always sit *under* the narration, not compete with it. Give the mood **and** a loudness target — the pipeline can duck and normalize to a level, so an explicit target lands a mix instead of a guess:
|
||||
Music resolves from a large catalog by mood. It should almost always sit *under*
|
||||
the narration rather than compete with it.
|
||||
|
||||
Give the mood **and** a loudness target. The pipeline can duck and normalize to
|
||||
a level, so an explicit target lands a mix instead of a guess.
|
||||
|
||||
> Add subtle electronic BGM, kept under −18 dB so it stays beneath the voiceover.
|
||||
|
||||
@@ -32,12 +54,15 @@ Music resolves from a large catalog by mood, and it should almost always sit *un
|
||||
- ✅ `subtle background music, ducked ~12 dB under the voice` — a mix instruction the pipeline can execute
|
||||
|
||||
<Tip>
|
||||
A stated loudness target ("under −18 dB," "ducked under the voice") is the difference between music that supports the piece and music that buries it. When there's narration, always say the bed goes under it.
|
||||
A stated loudness target ("under −18 dB," "ducked under the voice") is the
|
||||
difference between music that supports the piece and music that buries it.
|
||||
When there's narration, always say the bed goes under it.
|
||||
</Tip>
|
||||
|
||||
## Sound effects
|
||||
|
||||
SFX resolve from a small bundled library plus the catalog. Cue them to specific moments — a transition, a stamp-in, an impact — rather than sprinkling them:
|
||||
SFX resolve from a bundled 19-file library plus the catalog. Cue them to
|
||||
specific moments — a transition, a stamp-in, an impact. Don't sprinkle them.
|
||||
|
||||
> Add a whoosh on each of the three scene transitions.
|
||||
|
||||
@@ -45,56 +70,114 @@ SFX resolve from a small bundled library plus the catalog. Cue them to specific
|
||||
|
||||
## Pace reveals to the narration
|
||||
|
||||
Once a video has a voice, the voice is the clock — the next instruction that matters is telling the agent that on-screen elements land **on their spoken cues** — the stat appears as the narrator says it, not at some independent time the builder eyeballed. Without this, narration and visuals drift into two parallel tracks that happen to share a file:
|
||||
Once a video has a voice, the voice is the clock. Say that on-screen elements
|
||||
land **on their spoken cues**. The stat appears as the narrator says it, not at
|
||||
some independent time the builder eyeballed. Skip this and narration and visuals
|
||||
drift into two parallel tracks that happen to share a file.
|
||||
|
||||
> VO-paced reveals: each scene's elements land on their spoken cues; secondary elements keep resolving while the narrator is mid-thought; the scene is complete just as the narration moves on.
|
||||
|
||||
The capstone film applies exactly this rule to every region — its Direction block reads:
|
||||
The capstone film applies exactly this rule to every region. Its Direction block
|
||||
reads:
|
||||
|
||||
> VO-paced reveals: each region's elements land on their spoken cues as the camera arrives; secondary elements keep resolving while the camera is present; the region is complete just as the camera accelerates away.
|
||||
|
||||
Two practical notes: the agent gets word timings for free (the narration is transcribed with per-word timestamps, the same machinery behind [captions](#captions-and-transcription)), so "on its spoken cue" is a real, executable instruction — and the inverse rule matters just as much: the narration never waits for the visuals. Pace the camera and reveals to the voice, not the voice to the animation.
|
||||
Two practical notes.
|
||||
|
||||
The agent gets word timings for free. Narration is transcribed with per-word
|
||||
timestamps — the same machinery behind
|
||||
[captions](#captions-and-transcription). So "on its spoken cue" is a real,
|
||||
executable instruction.
|
||||
|
||||
The inverse rule matters just as much. The narration never waits for the
|
||||
visuals. Pace the camera and the reveals to the voice, not the voice to the
|
||||
animation.
|
||||
|
||||
## Captions and transcription
|
||||
|
||||
Captions come from word-level timestamps. When you generate a voiceover, the timing comes with it; for existing footage, transcription produces the timing (Parakeet by default, with a whisper.cpp fallback). Scaffolding a project from a source video can generate captions from its audio directly.
|
||||
Captions come from word-level timestamps. Generate a voiceover and the timing
|
||||
comes with it. For existing footage, transcription produces the timing: Parakeet
|
||||
runs when it's installed, and whisper handles it otherwise. Scaffolding a
|
||||
project from a source video can generate captions from its audio directly.
|
||||
|
||||
> Transcribe the narration and add karaoke-style captions synced to it.
|
||||
|
||||
> Generate captions from `assets/interview.mp4` and style them hype, scale-pop.
|
||||
|
||||
Caption *look* is its own vocabulary (tone, size, per-word emphasis) — see [Captions catalog](/prompting/captions-catalog) for the styles. This page is about producing the timed text; that page is about styling it.
|
||||
Caption *look* is its own vocabulary — tone, size, per-word emphasis. See the
|
||||
[Captions catalog](/prompting/captions-catalog) for the styles. This page is
|
||||
about producing the timed text. That page is about styling it.
|
||||
|
||||
## Background removal (transparent cutouts)
|
||||
|
||||
The `remove-background` command mattes a subject out of a video or image locally and hands you a transparent WebM you can drop into any scene as a `<video>`:
|
||||
The `remove-background` command mattes a subject out of a video or image
|
||||
locally. You get back a transparent WebM you can drop into any scene as a
|
||||
`<video>`.
|
||||
|
||||
> Remove the background from `assets/presenter.mp4` and float the subject over the scene.
|
||||
|
||||
One caveat is load-bearing: the built-in model is **purpose-built for people** — head-and-shoulders or full-body, reasonably stable framing, a background that contrasts with the subject. It returns a mostly-empty mask on **non-human subjects** (products, animals, objects). If you need to cut out a product, say so — the agent should route to a different tool rather than run the person model and get nothing.
|
||||
One caveat is load-bearing. The built-in model (`u2net_human_seg`) is
|
||||
**purpose-built for people**: head-and-shoulders or full-body, reasonably stable
|
||||
framing, a background that contrasts with the subject. On **non-human subjects**
|
||||
— products, animals, objects — it returns a mostly-empty mask.
|
||||
|
||||
So if you need to cut out a product, say so. The agent should route to a
|
||||
different tool instead of running the person model and getting nothing.
|
||||
|
||||
- ❌ `remove the background from this product shot` with the built-in command — the human-matting model can't see it
|
||||
- ✅ `matte the presenter out of assets/talk.mp4` (person) — or, for a product, flag that it's a non-human subject so a different matter is used
|
||||
- ✅ `matte the presenter out of assets/talk.mp4` for a person. For a product, flag that it's a non-human subject so a different matter is used.
|
||||
|
||||
The [Remove background guide](/guides/remove-background) covers the person-only caveat, the two-layer plate for text-behind-subject, and alternatives for objects and hair-fine mattes.
|
||||
The [Remove background guide](/guides/remove-background) covers the person-only
|
||||
caveat, the two-layer plate for text-behind-subject, and alternatives for
|
||||
objects and hair-fine mattes.
|
||||
|
||||
## Video-in-video and picture-in-picture
|
||||
|
||||
Layering footage — a talking head over a scene, a subject in front of a headline, PiP inset — is a compositing prompt. Two grounded rules keep it frame-accurate, and the agent applies them for you, but naming the layout you want helps:
|
||||
Layering footage is a compositing prompt: a talking head over a scene, a subject
|
||||
in front of a headline, a PiP inset. The agent applies the frame-accuracy rules
|
||||
for you. Naming the layout you want still helps.
|
||||
|
||||
> Put the transparent presenter cutout in the bottom-right, over the chart scene.
|
||||
|
||||
> Layer the headline *behind* the presenter so their silhouette occludes the text.
|
||||
|
||||
<Note>
|
||||
Two mechanics the workflow skills handle automatically (from the [Remove background guide](/guides/remove-background#compositing-patterns-and-pitfalls)): a cutout that reveals into view is wrapped in a non-timed `<div>` and the *wrapper* is animated (the framework forces `opacity: 1` on timed clips, so animating the video directly does nothing); and both the base video and the cutout mount at `data-start="0"` so their decoders stay in sync at the cut. You rarely need to say this — but it's why "late-mounting" a PiP clip can land a frame off.
|
||||
Two mechanics the workflow skills handle automatically, from the [Remove
|
||||
background guide](/guides/remove-background#compositing-patterns-and-pitfalls):
|
||||
|
||||
- A cutout that reveals into view goes inside a non-timed `<div>`, and the
|
||||
*wrapper* is what gets animated. HyperFrames owns clip visibility, so
|
||||
animating the media element directly fights the clip lifecycle.
|
||||
- The base video and the cutout both mount at `data-start="0"`, so their
|
||||
decoders stay in sync at the cut.
|
||||
|
||||
You rarely need to say either one. They're why "late-mounting" a PiP clip can
|
||||
land a frame off.
|
||||
</Note>
|
||||
|
||||
## Bring any footage
|
||||
|
||||
You don't need to pre-convert supplied footage before naming it in a prompt. If a clip's codec doesn't play back cleanly in a browser — HEVC (H.265) is the common case, straight off an iPhone or a screen recorder — the framework probes the asset and builds a bounded H.264 proxy automatically, cached under `.transcode-cache/`. `preview`, `play`, Studio, and published player pages use the proxy for playback; a render always decodes the original file, so nothing about final quality or color is touched. `hyperframes lint` also flags the asset at info level (`hevc_preview_codec`) so you know a proxy is in play, and it's optional — `--no-proxy` per command, or `media.autoProxy: false` in `hyperframes.json` project-wide. The same mechanism covers alpha-channel sources too (ProRes 4444, alpha WebM proxy to VP9+Opus WebM instead of being refused), so a transparent cutout in a hostile codec isn't a blocker either.
|
||||
You don't need to pre-convert supplied footage before naming it in a prompt.
|
||||
|
||||
None of this changes how you phrase the ask: name the footage by path like any other supplied asset, and describe the composition you want built from it.
|
||||
Some codecs don't play back cleanly in a browser. HEVC (H.265) is the common
|
||||
case, straight off an iPhone or a screen recorder. The framework probes the
|
||||
asset and builds a bounded H.264 proxy automatically, cached under
|
||||
`.transcode-cache/`.
|
||||
|
||||
`preview`, `play`, Studio, and published player pages use that proxy for
|
||||
playback. A render always decodes the original file, so nothing about final
|
||||
quality or color is touched.
|
||||
|
||||
`hyperframes lint` also flags the asset at info level (`hevc_preview_codec`) so
|
||||
you know a proxy is in play. Proxying is optional. Pass `--no-proxy` per
|
||||
command, or set `media.autoProxy: false` in `hyperframes.json` project-wide.
|
||||
|
||||
The same mechanism covers alpha-channel sources. ProRes 4444 and alpha WebM get
|
||||
a VP8 + Opus WebM proxy instead of being refused, so a transparent cutout in a
|
||||
hostile codec isn't a blocker either.
|
||||
|
||||
None of this changes how you phrase the ask. Name the footage by path like any
|
||||
other supplied asset, and describe the composition you want built from it.
|
||||
|
||||
> Build a short picture-in-picture piece from `source-hevc.mp4` — inset it bottom-right over a full-bleed background scene, with a soft rounded border.
|
||||
|
||||
@@ -103,42 +186,53 @@ None of this changes how you phrase the ask: name the footage by path like any o
|
||||
src="https://static.heygen.ai/hyperframes-oss/docs/images/prompting/proxy-footage.mp4#t=0.1"
|
||||
loop
|
||||
/>
|
||||
*Rendered from the prompt above, unedited — the source clip is a plain H.265/HEVC file; render decoded it directly via FFmpeg, while preview would have used the automatic H.264 proxy.*
|
||||
*Rendered from the prompt above, unedited. The source clip is a plain H.265/HEVC
|
||||
file. The render decoded it directly via FFmpeg. Preview would have used the
|
||||
automatic H.264 proxy.*
|
||||
|
||||
See the [Rendering guide](/guides/rendering#input-video-codecs) for the mechanics — proxy generation, caching, and which codecs it covers.
|
||||
See the [Rendering guide](/guides/rendering#input-video-codecs) for the
|
||||
mechanics — proxy generation, caching, and which codecs it covers.
|
||||
|
||||
## The supplied-assets rule
|
||||
|
||||
For any asset you already have, an explicit path is the instruction that removes the most ambiguity. The agent will search when you describe an asset, but a path removes every ambiguity about *which* file — and for your own brand assets, it's the only way to guarantee the right one:
|
||||
For any asset you already have, an explicit path removes the most ambiguity. The
|
||||
agent will search when you only describe an asset. A path settles *which* file.
|
||||
|
||||
- ❌ `use my logo`
|
||||
- ✅ `use assets/logo.svg`
|
||||
|
||||
This matters even when resolution would otherwise work: brand and entity assets should point at *your* file, not a resolved lookalike. (Third-party logos are a separate case — the pipeline pulls official marks from a logo cascade and never hand-redraws them, so "add the LinkedIn logo" is fine; "add my company's logo" needs a path.)
|
||||
This matters even when a search would have worked. Brand and entity assets
|
||||
should point at *your* file, not a resolved lookalike.
|
||||
|
||||
Third-party logos are a separate case. The pipeline pulls official marks from a
|
||||
logo cascade and never redraws them by hand. So "add the LinkedIn logo" is fine.
|
||||
"Add my company's logo" needs a path.
|
||||
|
||||
## Say what "no sound" actually means
|
||||
|
||||
The most common audio mistake is a negative that means less than you think. "No narration" removes the voiceover — it does **not** silence music or sound effects. If you want genuine silence, say so:
|
||||
The most common audio mistake is a negative that means less than you think. "No
|
||||
narration" removes the voiceover. It does **not** silence music or sound
|
||||
effects. If you want genuine silence, say so:
|
||||
|
||||
- ❌ `no narration` when you mean a completely silent video — music and SFX can still be added
|
||||
- ✅ `no audio at all` — the unambiguous way to ask for silence
|
||||
|
||||
This mirrors the negatives discipline in [Anatomy](/prompting/anatomy): close the gap explicitly, because the engine acts on the literal words.
|
||||
This mirrors the negatives discipline in [Anatomy](/prompting/anatomy). Close
|
||||
the gap explicitly, because the engine acts on the literal words.
|
||||
|
||||
## Related
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Vocabulary" href="/prompting/vocabulary">Voice names, caption tones, and audio-reactive mappings</Card>
|
||||
<Card title="Captions catalog" href="/prompting/captions-catalog">Styling the timed text this page produces</Card>
|
||||
<Card title="Remove background guide" href="/guides/remove-background">The matting command, its person-only caveat, and alternatives</Card>
|
||||
<Card title="Video components" href="/guides/video-components">Installable overlays, captions, and effects</Card>
|
||||
</CardGroup>
|
||||
## The capstone thread
|
||||
|
||||
<Note>
|
||||
**Capstone thread** — the [Level 7 film](/prompting/capstone)'s Material region runs this chapter's entire pipeline on one clip: generated footage → HEVC auto-proxy → background removal mid-scene → word-synced captions from the clip's own transcription, with the clip's audio ducking the BGM (cut from the film, below).
|
||||
**Capstone thread** — the [Level 7 film](/prompting/capstone)'s Material region
|
||||
runs this chapter's entire pipeline on one clip: generated footage → HEVC
|
||||
auto-proxy → background removal mid-scene → word-synced captions from the clip's
|
||||
own transcription, with the clip's audio ducking the BGM (cut from the film,
|
||||
below).
|
||||
</Note>
|
||||
|
||||
This is the clause in the [full capstone prompt](/prompting/capstone#the-prompt-word-for-word) that buys the piece — prompt language you can lift for your own video:
|
||||
This is the clause in the [full capstone
|
||||
prompt](/prompting/capstone#the-prompt-word-for-word) that buys the piece. It's
|
||||
prompt language you can lift for your own video:
|
||||
|
||||
> […] a real talking-head clip (generate a short clip of a person speaking one neutral line via the media pipeline's avatar video generation […] **transcode it to HEVC `hvc1`** so the automatic proxy subsystem carries preview) sits as a clip on the wire. The order of operations IS the story: as the camera arrives and BEFORE the person speaks, the framework mattes the footage — **the background peels away via background removal** […] THEN they speak, and the main **keywords of their own line — derived from the clip's transcription — land word-synced** […] The clip's own audio ducks the BGM briefly; the VO resumes as the camera pulls away.
|
||||
|
||||
@@ -149,4 +243,12 @@ This is the clause in the [full capstone prompt](/prompting/capstone#the-prompt-
|
||||
/>
|
||||
*That clause, rendered — the region cut from the finished film.*
|
||||
|
||||
*Next: [Design systems and brand](/prompting/design-systems) — pointing the agent at a source of brand truth instead of describing a vibe.*
|
||||
*Next: [Design systems and brand](/prompting/design-systems) — pointing the
|
||||
agent at a source of brand truth instead of describing a vibe.*
|
||||
|
||||
## Related topics
|
||||
|
||||
- [Vocabulary](/prompting/vocabulary) — voice names, caption tones, and audio-reactive mappings
|
||||
- [Captions catalog](/prompting/captions-catalog) — styling the timed text this page produces
|
||||
- [Remove a background](/guides/remove-background) — the matting command, its person-only caveat, and alternatives
|
||||
- [Use images and video](/guides/video-components) — installable overlays, captions, and effects
|
||||
|
||||
Reference in New Issue
Block a user