mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 23:03:09 +00:00
chore(skills): rename compose-video → hyperframes-compose, captions → hyperframes-captions
Namespace skill names with `hyperframes-` prefix for clearer identity in OSS contexts where users may have other skills installed. Updates skill directories, SKILL.md frontmatter, CLAUDE.md, README.md, CLI build script, init command, and project template. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
---
|
||||
name: hyperframes-captions
|
||||
description: Build tone-adaptive captions from whisper transcripts. Detects script energy (hype, corporate, tutorial, storytelling, social) and applies matching typography, color, and animation. Supports per-word styling for brand names, ALL CAPS, numbers, and CTAs. Use when adding captions or subtitles to a HyperFrames composition.
|
||||
---
|
||||
|
||||
# Captions
|
||||
|
||||
Analyze the spoken content to determine caption style. If the user specifies a style, use that. Otherwise, detect tone from the transcript.
|
||||
|
||||
## Transcript Source
|
||||
|
||||
The project's `transcript.json` contains word-level timestamps from whisper.cpp (`--output-json-full` with `--dtw`):
|
||||
|
||||
```json
|
||||
{
|
||||
"transcription": [
|
||||
{
|
||||
"offsets": { "from": 0, "to": 5000 },
|
||||
"text": " Hello world.",
|
||||
"tokens": [
|
||||
{ "text": " Hello", "offsets": { "from": 0, "to": 1000 }, "p": 0.98 },
|
||||
{ "text": " world", "offsets": { "from": 1000, "to": 2000 }, "p": 0.95 }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Normalize tokens into a word array before grouping:
|
||||
|
||||
```js
|
||||
const words = [];
|
||||
for (const segment of transcript.transcription) {
|
||||
for (const token of segment.tokens || []) {
|
||||
const text = token.text.trim();
|
||||
if (!text) continue;
|
||||
words.push({
|
||||
text,
|
||||
start: token.offsets.from / 1000,
|
||||
end: token.offsets.to / 1000,
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If no `transcript.json` exists, check for `.srt` or `.vtt` files. If no transcript is available, ask the user to provide one or run `hyperframes transcribe` (when available).
|
||||
|
||||
## Style Detection (Default — When No Style Is Specified)
|
||||
|
||||
Read the full transcript before choosing a style. The style comes from the content, not a template.
|
||||
|
||||
### Four Dimensions
|
||||
|
||||
**1. Visual feel** — the overall aesthetic personality:
|
||||
|
||||
- Corporate/professional scripts → clean, minimal, restrained
|
||||
- Energetic/marketing scripts → bold, punchy, high-impact
|
||||
- Storytelling/narrative scripts → elegant, warm, cinematic
|
||||
- Technical/educational scripts → precise, high-contrast, structured
|
||||
- Social media/casual scripts → playful, dynamic, friendly
|
||||
|
||||
**2. Color palette** — driven by the content's mood:
|
||||
|
||||
- Dark backgrounds with bright accents for high energy
|
||||
- Muted/neutral tones for professional or calm content
|
||||
- High contrast (white on black, black on white) for clarity
|
||||
- One accent color for emphasis — not multiple
|
||||
|
||||
**3. Font mood** — typography character, not specific font names:
|
||||
|
||||
- Heavy/condensed for impact and energy
|
||||
- Clean sans-serif for modern and professional
|
||||
- Rounded for friendly and approachable
|
||||
- Serif for elegance and storytelling
|
||||
|
||||
**4. Animation character** — how words enter and exit:
|
||||
|
||||
- Scale-pop/slam for punchy energy
|
||||
- Gentle fade/slide for calm or professional
|
||||
- Word-by-word reveal for emphasis
|
||||
- Typewriter for technical or narrative pacing
|
||||
|
||||
## Per-Word Styling
|
||||
|
||||
Scan the script for words that deserve distinct visual treatment. Not every word is equal — some carry the message.
|
||||
|
||||
### What to Detect
|
||||
|
||||
- **Brand names / product names** — larger size, unique color, distinct entrance
|
||||
- **ALL CAPS words** — the author emphasized them intentionally. Scale boost, flash, or accent color.
|
||||
- **Numbers / statistics** — bold weight, accent color. Numbers are the payload in data-driven content.
|
||||
- **Emotional keywords** — "incredible", "insane", "amazing", "revolutionary" → exaggerated animation (overshoot, bounce)
|
||||
- **Proper nouns** — names of people, places, events → distinct accent or italic
|
||||
- **Call-to-action phrases** — "sign up", "get started", "try it now" → highlight, underline, or color pop
|
||||
|
||||
### How to Apply
|
||||
|
||||
For each detected word, specify:
|
||||
|
||||
- Font size multiplier (e.g., 1.3x for emphasis, 1.5x for hero moments)
|
||||
- Color override (specific hex value)
|
||||
- Weight/style change (bolder, italic)
|
||||
- Animation variant (overshoot entrance, glow pulse, scale pop)
|
||||
|
||||
## Script-to-Style Mapping
|
||||
|
||||
| Script tone | Font mood | Animation | Color | Size |
|
||||
| -------------------- | ------------------------------------- | --------------------------------------- | -------------------------------------------- | -------------------- |
|
||||
| Hype/launch | Heavy condensed, 800-900 weight | Scale-pop, back.out(1.7), fast 0.1-0.2s | Bright accent on dark (cyan, yellow, lime) | Large 72-96px |
|
||||
| Corporate/pitch | Clean sans-serif, 600-700 weight | Fade + slide-up, power3.out, 0.3s | White/neutral on dark, single muted accent | Medium 56-72px |
|
||||
| Tutorial/educational | Mono or clean sans, 500-600 weight | Typewriter or gentle fade, 0.4-0.5s | High contrast, minimal color | Medium 48-64px |
|
||||
| Storytelling/brand | Serif or elegant sans, 400-500 weight | Slow fade, power2.out, 0.5-0.6s | Warm muted tones, low opacity (0.85-0.9) | Smaller 44-56px |
|
||||
| Social/casual | Rounded sans, 700-800 weight | Bounce, elastic.out, word-by-word | Playful colors, colored backgrounds on pills | Medium-large 56-80px |
|
||||
|
||||
## Word Grouping by Tone
|
||||
|
||||
Group size affects pacing. Fast content needs fast caption turnover.
|
||||
|
||||
- **High energy:** 2-3 words per group. Quick turnover matches rapid delivery.
|
||||
- **Conversational:** 3-5 words per group. Natural phrase length.
|
||||
- **Measured/calm:** 4-6 words per group. Longer groups match slower pace.
|
||||
|
||||
Break groups on sentence boundaries (`.` `?` `!`), pauses (>150ms gap), or max word count — whichever comes first.
|
||||
|
||||
## Positioning
|
||||
|
||||
- **Landscape (1920x1080):** Bottom 80-120px, centered
|
||||
- **Portrait (1080x1920):** Lower middle ~600-700px from bottom, centered
|
||||
- Never cover the subject's face
|
||||
- Use `position: absolute` — never relative (causes overflow)
|
||||
- One caption group visible at a time
|
||||
|
||||
## Constraints
|
||||
|
||||
- **Deterministic.** No `Math.random()`, no `Date.now()`.
|
||||
- **Sync to transcript timestamps.** Words appear when spoken.
|
||||
- **One group visible at a time.** No overlapping caption groups.
|
||||
- **Check project root** for font files before defaulting to Google Fonts.
|
||||
Reference in New Issue
Block a user