zilmate 1.9.9 → 1.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/ad-creative/SKILL.md +362 -0
- package/.agents/skills/ad-creative/evals/evals.json +90 -0
- package/.agents/skills/ad-creative/references/generative-tools.md +637 -0
- package/.agents/skills/ad-creative/references/platform-specs.md +213 -0
- package/.agents/skills/ai-seo/SKILL.md +489 -0
- package/.agents/skills/ai-seo/evals/evals.json +90 -0
- package/.agents/skills/ai-seo/references/content-patterns.md +285 -0
- package/.agents/skills/ai-seo/references/content-types.md +71 -0
- package/.agents/skills/ai-seo/references/okf.md +104 -0
- package/.agents/skills/ai-seo/references/platform-ranking-factors.md +154 -0
- package/.agents/skills/clerk-backend-api/SKILL.md +426 -0
- package/.agents/skills/clerk-backend-api/evals/evals.json +87 -0
- package/.agents/skills/clerk-backend-api/scripts/api-specs-context.sh +30 -0
- package/.agents/skills/clerk-backend-api/scripts/execute-request.sh +88 -0
- package/.agents/skills/clerk-backend-api/scripts/extract-endpoint-detail.sh +165 -0
- package/.agents/skills/clerk-backend-api/scripts/extract-tag-endpoints.sh +208 -0
- package/.agents/skills/clerk-backend-api/scripts/extract-tags.js +14 -0
- package/.agents/skills/copy-editing/SKILL.md +457 -0
- package/.agents/skills/copy-editing/evals/evals.json +89 -0
- package/.agents/skills/copy-editing/references/checklist.md +66 -0
- package/.agents/skills/copy-editing/references/content-refresh.md +38 -0
- package/.agents/skills/copy-editing/references/plain-english-alternatives.md +394 -0
- package/.agents/skills/hyperframes/SKILL.md +163 -0
- package/.agents/skills/hyperframes-cli/SKILL.md +109 -0
- package/.agents/skills/hyperframes-cli/references/doctor-browser.md +45 -0
- package/.agents/skills/hyperframes-cli/references/init-and-scaffold.md +51 -0
- package/.agents/skills/hyperframes-cli/references/lambda.md +132 -0
- package/.agents/skills/hyperframes-cli/references/lint-validate-inspect.md +121 -0
- package/.agents/skills/hyperframes-cli/references/preview-render.md +109 -0
- package/.agents/skills/hyperframes-cli/references/upgrade-info-misc.md +75 -0
- package/.agents/skills/hyperframes-media/SKILL.md +97 -0
- package/.agents/skills/hyperframes-media/assets/sfx/CREDITS.md +35 -0
- package/.agents/skills/hyperframes-media/assets/sfx/manifest.json +97 -0
- package/.agents/skills/hyperframes-media/references/bgm.md +72 -0
- package/.agents/skills/hyperframes-media/references/captions/authoring.md +159 -0
- package/.agents/skills/hyperframes-media/references/captions/motion.md +87 -0
- package/.agents/skills/hyperframes-media/references/captions/transcript-handling.md +97 -0
- package/.agents/skills/hyperframes-media/references/remove-background.md +143 -0
- package/.agents/skills/hyperframes-media/references/requirements.md +29 -0
- package/.agents/skills/hyperframes-media/references/sfx.md +42 -0
- package/.agents/skills/hyperframes-media/references/transcribe.md +52 -0
- package/.agents/skills/hyperframes-media/references/tts-to-captions.md +24 -0
- package/.agents/skills/hyperframes-media/references/tts.md +135 -0
- package/.agents/skills/hyperframes-media/scripts/audio.mjs +282 -0
- package/.agents/skills/hyperframes-media/scripts/heygen-tts.mjs +121 -0
- package/.agents/skills/hyperframes-media/scripts/lib/bgm.mjs +235 -0
- package/.agents/skills/hyperframes-media/scripts/lib/heygen.mjs +131 -0
- package/.agents/skills/hyperframes-media/scripts/lib/sfx.mjs +128 -0
- package/.agents/skills/hyperframes-media/scripts/lib/tts.mjs +220 -0
- package/.agents/skills/hyperframes-media/scripts/lyria-recipe.py +128 -0
- package/.agents/skills/hyperframes-media/scripts/wait-bgm.mjs +167 -0
- package/.agents/skills/hyperframes-registry/SKILL.md +101 -0
- package/.agents/skills/hyperframes-registry/examples/add-block.md +51 -0
- package/.agents/skills/hyperframes-registry/examples/add-component.md +73 -0
- package/.agents/skills/hyperframes-registry/references/contributing.md +166 -0
- package/.agents/skills/hyperframes-registry/references/demo-html-pattern.md +54 -0
- package/.agents/skills/hyperframes-registry/references/discovery.md +215 -0
- package/.agents/skills/hyperframes-registry/references/install-locations.md +45 -0
- package/.agents/skills/hyperframes-registry/references/templates.md +417 -0
- package/.agents/skills/hyperframes-registry/references/wiring-blocks.md +61 -0
- package/.agents/skills/hyperframes-registry/references/wiring-components.md +39 -0
- package/.agents/skills/marketing-psychology/SKILL.md +455 -0
- package/.agents/skills/marketing-psychology/evals/evals.json +88 -0
- package/.agents/skills/mintlify/SKILL.md +328 -0
- package/.agents/skills/product-launch-video/SKILL.md +206 -0
- package/.agents/skills/product-launch-video/references/cut-catalog.md +220 -0
- package/.agents/skills/product-launch-video/references/motion-language.md +156 -0
- package/.agents/skills/product-launch-video/references/story-design.md +373 -0
- package/.agents/skills/product-launch-video/references/visual-design.md +126 -0
- package/.agents/skills/product-launch-video/scripts/assemble-index.mjs +570 -0
- package/.agents/skills/product-launch-video/scripts/audio.mjs +253 -0
- package/.agents/skills/product-launch-video/scripts/build-frame.mjs +536 -0
- package/.agents/skills/product-launch-video/scripts/captions.mjs +508 -0
- package/.agents/skills/product-launch-video/scripts/lib/assets.mjs +55 -0
- package/.agents/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
- package/.agents/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
- package/.agents/skills/product-launch-video/scripts/lib/tokens.mjs +204 -0
- package/.agents/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
- package/.agents/skills/product-launch-video/scripts/lib/transitions.json +71 -0
- package/.agents/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
- package/.agents/skills/product-launch-video/scripts/transitions.mjs +320 -0
- package/.agents/skills/product-launch-video/sub-agents/frame-worker.md +74 -0
- package/.agents/skills/prompt-engineering-patterns/SKILL.md +144 -0
- package/.agents/skills/prompt-engineering-patterns/assets/few-shot-examples.json +106 -0
- package/.agents/skills/prompt-engineering-patterns/assets/prompt-template-library.md +264 -0
- package/.agents/skills/prompt-engineering-patterns/references/chain-of-thought.md +412 -0
- package/.agents/skills/prompt-engineering-patterns/references/details.md +338 -0
- package/.agents/skills/prompt-engineering-patterns/references/few-shot-learning.md +386 -0
- package/.agents/skills/prompt-engineering-patterns/references/prompt-optimization.md +428 -0
- package/.agents/skills/prompt-engineering-patterns/references/prompt-templates.md +484 -0
- package/.agents/skills/prompt-engineering-patterns/references/system-prompts.md +195 -0
- package/.agents/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +279 -0
- package/.agents/skills/remotion-to-hyperframes/SKILL.md +127 -0
- package/.agents/skills/remotion-to-hyperframes/assets/.gitkeep +0 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/run.sh +249 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/README.md +41 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/expected.json +26 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/hf-src/index.html +61 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/package.json +14 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/remotion.config.ts +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/Root.tsx +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/TitleCard.tsx +34 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/index.ts +4 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/tsconfig.json +15 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/README.md +54 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/expected.json +29 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/index.html +118 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/package.json +14 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/remotion.config.ts +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/MultiScene.tsx +105 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/Root.tsx +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/index.ts +4 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/tsconfig.json +15 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/setup.sh +34 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/README.md +85 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/expected.json +41 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/index.html +269 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/package.json +15 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/remotion.config.ts +13 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/Root.tsx +27 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/Stargazed.tsx +37 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/AnimatedNumber.tsx +23 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/StatCard.tsx +59 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/UnderlinedText.tsx +47 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/index.ts +4 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/OutroScene.tsx +18 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/StatsScene.tsx +34 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/TitleScene.tsx +55 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/tsconfig.json +15 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/README.md +51 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/01-use-state.tsx +29 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/02-use-effect-deps.tsx +29 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/03-async-metadata.tsx +39 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/04-third-party-react.tsx +30 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/05-lambda-config.tsx +38 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/06-warnings-only.tsx +36 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/07-custom-hook.tsx +28 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/08-mixed.tsx +41 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/expected.json +85 -0
- package/.agents/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/validate.sh +110 -0
- package/.agents/skills/remotion-to-hyperframes/references/api-map.md +142 -0
- package/.agents/skills/remotion-to-hyperframes/references/escape-hatch.md +115 -0
- package/.agents/skills/remotion-to-hyperframes/references/eval.md +140 -0
- package/.agents/skills/remotion-to-hyperframes/references/fonts.md +112 -0
- package/.agents/skills/remotion-to-hyperframes/references/limitations.md +136 -0
- package/.agents/skills/remotion-to-hyperframes/references/lottie.md +121 -0
- package/.agents/skills/remotion-to-hyperframes/references/media.md +149 -0
- package/.agents/skills/remotion-to-hyperframes/references/parameters.md +167 -0
- package/.agents/skills/remotion-to-hyperframes/references/sequencing.md +195 -0
- package/.agents/skills/remotion-to-hyperframes/references/timing.md +165 -0
- package/.agents/skills/remotion-to-hyperframes/references/transitions.md +114 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/.gitkeep +0 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/frame_strip.sh +107 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/lint_source.py +358 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/render_diff.sh +103 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/tests/fixtures/blocker.tsx +50 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/tests/fixtures/clean.tsx +46 -0
- package/.agents/skills/remotion-to-hyperframes/scripts/tests/smoke.sh +90 -0
- package/.agents/skills/seo-audit/SKILL.md +497 -0
- package/.agents/skills/seo-audit/evals/evals.json +136 -0
- package/.agents/skills/seo-audit/references/ai-writing-detection.md +200 -0
- package/.agents/skills/seo-audit/references/international-seo.md +230 -0
- package/README.md +4 -2
- package/SDK.md +64 -1
- package/dist/agents/coding.agent.d.ts +558 -0
- package/dist/agents/coding.agent.d.ts.map +1 -1
- package/dist/agents/coding.agent.js +8 -0
- package/dist/agents/coding.agent.js.map +1 -1
- package/dist/agents/developer-helper.agent.d.ts +712 -0
- package/dist/agents/developer-helper.agent.d.ts.map +1 -1
- package/dist/agents/developer-helper.agent.js +6 -0
- package/dist/agents/developer-helper.agent.js.map +1 -1
- package/dist/agents/docs-research.agent.d.ts +8 -0
- package/dist/agents/docs-research.agent.d.ts.map +1 -1
- package/dist/agents/finance.agent.d.ts +8 -0
- package/dist/agents/finance.agent.d.ts.map +1 -1
- package/dist/agents/manager.d.ts +837 -2
- package/dist/agents/manager.d.ts.map +1 -1
- package/dist/agents/manager.js +28 -0
- package/dist/agents/manager.js.map +1 -1
- package/dist/agents/security.agent.d.ts +165 -3
- package/dist/agents/security.agent.d.ts.map +1 -1
- package/dist/agents/security.agent.js +3 -0
- package/dist/agents/security.agent.js.map +1 -1
- package/dist/agents/swarm/main.js +1 -1
- package/dist/agents/swarm/main.js.map +1 -1
- package/dist/agents/swarm/registry.d.ts.map +1 -1
- package/dist/agents/swarm/registry.js +232 -26
- package/dist/agents/swarm/registry.js.map +1 -1
- package/dist/cli/doctor.d.ts +14 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +91 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/menu.d.ts.map +1 -1
- package/dist/cli/menu.js +102 -0
- package/dist/cli/menu.js.map +1 -1
- package/dist/cli/setup.d.ts +10 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +178 -0
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/swarm.d.ts +1 -0
- package/dist/cli/swarm.d.ts.map +1 -1
- package/dist/cli/swarm.js +47 -8
- package/dist/cli/swarm.js.map +1 -1
- package/dist/cli/theme.d.ts +0 -24
- package/dist/cli/theme.d.ts.map +1 -1
- package/dist/cli/theme.js +6 -2
- package/dist/cli/theme.js.map +1 -1
- package/dist/config/env.d.ts +10 -0
- package/dist/config/env.d.ts.map +1 -1
- package/dist/config/env.js +38 -17
- package/dist/config/env.js.map +1 -1
- package/dist/index.js +96 -5
- package/dist/index.js.map +1 -1
- package/dist/jobs/trigger-orchestrator.d.ts +5 -1
- package/dist/jobs/trigger-orchestrator.d.ts.map +1 -1
- package/dist/jobs/trigger-orchestrator.js +29 -9
- package/dist/jobs/trigger-orchestrator.js.map +1 -1
- package/dist/jobs/trigger-router.d.ts.map +1 -1
- package/dist/jobs/trigger-router.js +3 -2
- package/dist/jobs/trigger-router.js.map +1 -1
- package/dist/memory/corporate-wiki.d.ts +15 -0
- package/dist/memory/corporate-wiki.d.ts.map +1 -0
- package/dist/memory/corporate-wiki.js +152 -0
- package/dist/memory/corporate-wiki.js.map +1 -0
- package/dist/memory/scratchpad.d.ts +2 -0
- package/dist/memory/scratchpad.d.ts.map +1 -1
- package/dist/memory/scratchpad.js +27 -0
- package/dist/memory/scratchpad.js.map +1 -1
- package/dist/observability/doctor.d.ts.map +1 -1
- package/dist/observability/doctor.js +12 -4
- package/dist/observability/doctor.js.map +1 -1
- package/dist/observability/traces.d.ts +72 -0
- package/dist/observability/traces.d.ts.map +1 -0
- package/dist/observability/traces.js +1134 -0
- package/dist/observability/traces.js.map +1 -0
- package/dist/runtime/swarm.d.ts +1 -1
- package/dist/runtime/swarm.d.ts.map +1 -1
- package/dist/runtime/swarm.js +54 -25
- package/dist/runtime/swarm.js.map +1 -1
- package/dist/safety/approvals.d.ts +2 -2
- package/dist/safety/approvals.d.ts.map +1 -1
- package/dist/safety/approvals.js +47 -1
- package/dist/safety/approvals.js.map +1 -1
- package/dist/safety/redaction.d.ts.map +1 -1
- package/dist/safety/redaction.js +10 -0
- package/dist/safety/redaction.js.map +1 -1
- package/dist/tools/cloud.tool.d.ts +394 -0
- package/dist/tools/cloud.tool.d.ts.map +1 -0
- package/dist/tools/cloud.tool.js +784 -0
- package/dist/tools/cloud.tool.js.map +1 -0
- package/dist/tools/computer-use.tool.d.ts +2 -2
- package/dist/tools/corporate-wiki.tool.d.ts +22 -0
- package/dist/tools/corporate-wiki.tool.d.ts.map +1 -0
- package/dist/tools/corporate-wiki.tool.js +43 -0
- package/dist/tools/corporate-wiki.tool.js.map +1 -0
- package/dist/tools/devops.tool.d.ts +162 -0
- package/dist/tools/devops.tool.d.ts.map +1 -0
- package/dist/tools/devops.tool.js +377 -0
- package/dist/tools/devops.tool.js.map +1 -0
- package/dist/tools/multimedia.tool.d.ts +126 -0
- package/dist/tools/multimedia.tool.d.ts.map +1 -0
- package/dist/tools/multimedia.tool.js +533 -0
- package/dist/tools/multimedia.tool.js.map +1 -0
- package/dist/tools/osint.tool.d.ts +6 -6
- package/dist/tools/sandbox-dev.tool.d.ts +15 -0
- package/dist/tools/sandbox-dev.tool.d.ts.map +1 -0
- package/dist/tools/sandbox-dev.tool.js +146 -0
- package/dist/tools/sandbox-dev.tool.js.map +1 -0
- package/dist/tools/scratchpad.tool.d.ts +8 -0
- package/dist/tools/scratchpad.tool.d.ts.map +1 -1
- package/dist/tools/scratchpad.tool.js +40 -1
- package/dist/tools/scratchpad.tool.js.map +1 -1
- package/dist/tools/setup-assistant.tool.d.ts +1 -1
- package/dist/tools/swarm-ops.tool.d.ts +14 -0
- package/dist/tools/swarm-ops.tool.d.ts.map +1 -1
- package/dist/tools/swarm-ops.tool.js +47 -0
- package/dist/tools/swarm-ops.tool.js.map +1 -1
- package/dist/tools/sysops.tool.d.ts +157 -0
- package/dist/tools/sysops.tool.d.ts.map +1 -0
- package/dist/tools/sysops.tool.js +643 -0
- package/dist/tools/sysops.tool.js.map +1 -0
- package/dist/voice/deepgram.d.ts.map +1 -1
- package/dist/voice/deepgram.js +30 -2
- package/dist/voice/deepgram.js.map +1 -1
- package/package.json +8 -1
- package/scripts/release-github.mjs +23 -16
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Transcript Guide
|
|
2
|
+
|
|
3
|
+
For the `transcribe` CLI invocation, the `.en`-translates-non-English rule, and whisper model selection, see [`../transcribe.md`](../transcribe.md). This file covers what to do with the resulting transcript when authoring captions: input formats, mandatory quality checks, cleaning code, external-API fallbacks.
|
|
4
|
+
|
|
5
|
+
## Supported Input Formats
|
|
6
|
+
|
|
7
|
+
The CLI auto-detects and normalizes these formats:
|
|
8
|
+
|
|
9
|
+
| Format | Extension | Source | Word-level? |
|
|
10
|
+
| --------------------- | --------- | --------------------------------------------------------------------------- | ----------------- |
|
|
11
|
+
| whisper.cpp JSON | `.json` | `hyperframes init --video`, `hyperframes transcribe` | Yes |
|
|
12
|
+
| OpenAI Whisper API | `.json` | `openai.audio.transcriptions.create({ timestamp_granularities: ["word"] })` | Yes |
|
|
13
|
+
| SRT subtitles | `.srt` | Video editors, subtitle tools, YouTube | No (phrase-level) |
|
|
14
|
+
| VTT subtitles | `.vtt` | Web players, YouTube, transcription services | No (phrase-level) |
|
|
15
|
+
| Normalized word array | `.json` | Pre-processed by any tool | Yes |
|
|
16
|
+
|
|
17
|
+
**Word-level timestamps produce better captions.** SRT/VTT give phrase-level timing, which works but can't do per-word animation effects.
|
|
18
|
+
|
|
19
|
+
## Transcript Quality Check (Mandatory)
|
|
20
|
+
|
|
21
|
+
After every transcription, **read the transcript and check for quality issues before proceeding.** Bad transcripts produce nonsensical captions. Never skip this step.
|
|
22
|
+
|
|
23
|
+
### What to look for
|
|
24
|
+
|
|
25
|
+
| Signal | Example | Cause |
|
|
26
|
+
| ---------------------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
|
|
27
|
+
| Music note tokens (`♪`, `�`) | `{ "text": "♪" }` or `{ "text": "�" }` | Whisper detected music, not speech |
|
|
28
|
+
| Garbled / nonsense words | "Do a chin", "Get so gay", "huh" | Model misheard lyrics or background noise |
|
|
29
|
+
| Long gaps with no words | 20+ seconds of only `♪` tokens | Instrumental section — expected, but high ratio means speech is being missed |
|
|
30
|
+
| Repeated filler | Many "huh", "uh", "oh" entries | Model is hallucinating on music |
|
|
31
|
+
| Very short word spans | Words with `end - start < 0.05` | Unreliable timestamp alignment |
|
|
32
|
+
|
|
33
|
+
### Automatic retry rules
|
|
34
|
+
|
|
35
|
+
**If more than 20% of entries are `♪`/`�` tokens, or the transcript contains obvious nonsense words, the transcription failed.** Do not proceed with the bad transcript. Instead:
|
|
36
|
+
|
|
37
|
+
1. **Retry with `medium.en`** if the original used `small.en` or smaller:
|
|
38
|
+
```bash
|
|
39
|
+
npx hyperframes transcribe audio.mp3 --model medium.en
|
|
40
|
+
```
|
|
41
|
+
2. **If `medium.en` also fails** (still >20% music tokens or garbled), tell the user the audio is too noisy for local transcription and suggest:
|
|
42
|
+
- Providing lyrics manually as an SRT/VTT file
|
|
43
|
+
- Using an external API (OpenAI or Groq Whisper — see below)
|
|
44
|
+
3. **Always clean the transcript** before building captions — filter out `♪`/`�` tokens and entries where `text` is a single non-word character. Only real words should reach the caption composition.
|
|
45
|
+
|
|
46
|
+
### Cleaning a transcript
|
|
47
|
+
|
|
48
|
+
After transcription (even with a good model), strip non-word entries:
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
var raw = JSON.parse(transcriptJson);
|
|
52
|
+
var words = raw.filter(function (w) {
|
|
53
|
+
if (!w.text || w.text.trim().length === 0) return false;
|
|
54
|
+
if (/^[♪�\u266a\u266b\u266c\u266d\u266e\u266f]+$/.test(w.text)) return false;
|
|
55
|
+
if (/^(huh|uh|um|ah|oh)$/i.test(w.text) && w.end - w.start < 0.1) return false;
|
|
56
|
+
return true;
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
For model-selection guidance by content type, see [`../transcribe.md`](../transcribe.md) → "Picking a model by content type".
|
|
61
|
+
|
|
62
|
+
## Using External Transcription APIs
|
|
63
|
+
|
|
64
|
+
For the best accuracy, use an external API and import the result:
|
|
65
|
+
|
|
66
|
+
**OpenAI Whisper API** (recommended for quality):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Generate with word timestamps, then import
|
|
70
|
+
curl https://api.openai.com/v1/audio/transcriptions \
|
|
71
|
+
-H "Authorization: Bearer $OPENAI_API_KEY" \
|
|
72
|
+
-F file=@audio.mp3 -F model=whisper-1 \
|
|
73
|
+
-F response_format=verbose_json \
|
|
74
|
+
-F "timestamp_granularities[]=word" \
|
|
75
|
+
-o transcript-openai.json
|
|
76
|
+
|
|
77
|
+
npx hyperframes transcribe transcript-openai.json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Groq Whisper API** (fast, free tier available):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
curl https://api.groq.com/openai/v1/audio/transcriptions \
|
|
84
|
+
-H "Authorization: Bearer $GROQ_API_KEY" \
|
|
85
|
+
-F file=@audio.mp3 -F model=whisper-large-v3 \
|
|
86
|
+
-F response_format=verbose_json \
|
|
87
|
+
-F "timestamp_granularities[]=word" \
|
|
88
|
+
-o transcript-groq.json
|
|
89
|
+
|
|
90
|
+
npx hyperframes transcribe transcript-groq.json
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## If No Transcript Exists
|
|
94
|
+
|
|
95
|
+
1. Check the project root for `transcript.json`, `.srt`, or `.vtt` files.
|
|
96
|
+
2. If none found, run [`../transcribe.md`](../transcribe.md) — pick the starting model from "Picking a model by content type" there.
|
|
97
|
+
3. Run the quality check above. If it fails, retry with a larger model or fall back to manual lyrics / external API.
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Background Removal
|
|
2
|
+
|
|
3
|
+
Make a transparent overlay (typical: a talking head over an arbitrary scene). Uses `u2net_human_seg` (MIT).
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx hyperframes remove-background subject.mp4 -o transparent.webm # default: VP9 + alpha
|
|
7
|
+
npx hyperframes remove-background subject.mp4 -o transparent.mov # ProRes 4444 (editing)
|
|
8
|
+
npx hyperframes remove-background portrait.jpg -o cutout.png # single-image cutout
|
|
9
|
+
npx hyperframes remove-background subject.mp4 -o subject.webm \
|
|
10
|
+
--background-output plate.webm # both layers, one pass
|
|
11
|
+
npx hyperframes remove-background subject.mp4 -o transparent.webm --device cpu
|
|
12
|
+
npx hyperframes remove-background --info # detected providers
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Output Format
|
|
16
|
+
|
|
17
|
+
- **`.webm` (VP9 alpha)** — default. Plug straight into `<video>` for Chrome-native transparent playback (~1 MB / 4s @ 1080p).
|
|
18
|
+
- **`.mov` (ProRes 4444)** — round-trip in editors (Premiere / Resolve / DaVinci). ~50 MB / 4s.
|
|
19
|
+
- **`.png`** — single-image cutout.
|
|
20
|
+
|
|
21
|
+
## Quality (`--quality`)
|
|
22
|
+
|
|
23
|
+
Controls VP9 encoder CRF only — segmentation quality is fixed. Higher quality keeps the cutout's RGB closer to the source MP4 (important when overlaying the cutout on its own source).
|
|
24
|
+
|
|
25
|
+
| Preset | CRF | When |
|
|
26
|
+
| ---------- | --- | --------------------------------------------- |
|
|
27
|
+
| `fast` | 30 | Iterating, smaller files, looser color match |
|
|
28
|
+
| `balanced` | 18 | **Default**; visually identical for most uses |
|
|
29
|
+
| `best` | 12 | Master / final delivery, tightest color match |
|
|
30
|
+
|
|
31
|
+
## Device (`--device`)
|
|
32
|
+
|
|
33
|
+
`auto` (default) picks CoreML on Apple Silicon, CUDA when available, otherwise CPU. Force with `--device cpu | coreml | cuda`. CUDA requires `HYPERFRAMES_CUDA=1` plus a GPU-enabled `onnxruntime-node` build. Use `--info` to inspect detected providers without rendering.
|
|
34
|
+
|
|
35
|
+
## Compositing patterns — pick the right one
|
|
36
|
+
|
|
37
|
+
The cutout WebM is a **re-encoded copy** of the source MP4's RGB. What sits behind it matters.
|
|
38
|
+
|
|
39
|
+
| Pattern | Behind the cutout | Result |
|
|
40
|
+
| -------------------------------------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| **Cutout over a different scene** (most common) | Static image, gradient, unrelated video | Looks great. Single RGB source for the subject. |
|
|
42
|
+
| **Cutout over its own source mp4** (text-behind-subject) | Same mp4 the cutout came from | At `balanced` doubling is barely visible; at `fast` you'll see color shift / edge halo. Use `best` for masters. |
|
|
43
|
+
| **Cutout over a different take of the same person** | Footage of the same subject | **Two overlapping people. Don't do this.** |
|
|
44
|
+
|
|
45
|
+
## Text-behind-subject pattern (two non-obvious rules)
|
|
46
|
+
|
|
47
|
+
Putting a headline behind a presenter cutout:
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<video
|
|
51
|
+
src="presenter.mp4"
|
|
52
|
+
id="bg"
|
|
53
|
+
data-start="0"
|
|
54
|
+
data-duration="6"
|
|
55
|
+
data-track-index="0"
|
|
56
|
+
muted
|
|
57
|
+
playsinline
|
|
58
|
+
></video>
|
|
59
|
+
|
|
60
|
+
<h1 id="headline" style="z-index:2; ...">MAKE IT IN HYPERFRAMES</h1>
|
|
61
|
+
|
|
62
|
+
<div class="cutout-wrap" style="position:absolute; inset:0; z-index:3; opacity:0">
|
|
63
|
+
<video
|
|
64
|
+
src="presenter.webm"
|
|
65
|
+
data-start="0"
|
|
66
|
+
data-duration="6"
|
|
67
|
+
data-track-index="1"
|
|
68
|
+
muted
|
|
69
|
+
playsinline
|
|
70
|
+
></video>
|
|
71
|
+
</div>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
// Flip the wrapper's opacity at the cut, NOT the video's
|
|
76
|
+
tl.set(".cutout-wrap", { opacity: 1 }, 3.3);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Two rules that are easy to miss:
|
|
80
|
+
|
|
81
|
+
1. **Wrap the cutout `<video>` in a non-timed `<div>` and animate the wrapper's opacity, not the video element's.** The framework forces `opacity: 1` on active clips (any element with `data-start` / `data-duration`), so animating the video's opacity directly is silently overridden. The wrapper has no `data-*` attributes, so it's owned by your CSS / GSAP.
|
|
82
|
+
2. **Both videos use `data-start="0"` and `data-media-start="0"`** so the framework decodes them in sync from t=0. Late-mounting the cutout (`data-start=3.3`) introduces a seek + warm-up that lands a frame off the base mp4 — visible as one frame of misalignment at the cut.
|
|
83
|
+
|
|
84
|
+
## Layer separation (`--background-output`)
|
|
85
|
+
|
|
86
|
+
Emits a **second** transparent video alongside the cutout: same source RGB, alpha is `255 - mask` instead of `mask`. The cutout has the subject opaque; the plate has the surroundings opaque (with a transparent hole where the subject was). Use it when text / graphics need to live **between** the two layers.
|
|
87
|
+
|
|
88
|
+
| File | Alpha is… | Use it for |
|
|
89
|
+
| -------------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
90
|
+
| `-o subject.webm` | mask — subject opaque, background transparent | Foreground layer (top) |
|
|
91
|
+
| `--background-output plate.webm` | inverse mask — surroundings opaque, subject transparent | Bottom layer; place text / graphics between this and the subject |
|
|
92
|
+
|
|
93
|
+
Both share the same `--quality` and run from a single inference pass — only encode cost roughly doubles. Only valid for video inputs with `.webm` / `.mov` outputs.
|
|
94
|
+
|
|
95
|
+
**Hole-cut, not inpainted.** The subject region in `plate.webm` is fully transparent — composite something opaque under it to fill the hole.
|
|
96
|
+
|
|
97
|
+
**Single test for whether `--background-output` is the right tool:** _will anything ever be visible through the subject's silhouette where the subject used to be?_ If no, you don't need the plate — `subject.webm` alone over a different background is enough.
|
|
98
|
+
|
|
99
|
+
### Use case → right tool
|
|
100
|
+
|
|
101
|
+
| Use case | Right tool |
|
|
102
|
+
| ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
103
|
+
| Text/graphics between the cutout and the plate (this command's reason for existing) | **Hole-cut** (`--background-output`) |
|
|
104
|
+
| Subject onto an unrelated scene | Just `subject.webm`; ignore the plate |
|
|
105
|
+
| Show the room _without_ the person, alone over no other content | **Clean plate** — needs an inpainter (LaMa, ProPainter, E2FGVI). Not this command. |
|
|
106
|
+
| Replace the subject with a different subject | **Clean plate** — same as above |
|
|
107
|
+
|
|
108
|
+
### Canonical 3-layer template (plate + content + cutout)
|
|
109
|
+
|
|
110
|
+
Ship just the two transparent layers and let arbitrary content live between them — no original mp4 needed:
|
|
111
|
+
|
|
112
|
+
```html
|
|
113
|
+
<!-- z=1 plate: surroundings opaque, subject silhouette transparent -->
|
|
114
|
+
<video
|
|
115
|
+
src="plate.webm"
|
|
116
|
+
data-start="0"
|
|
117
|
+
data-duration="6"
|
|
118
|
+
data-track-index="0"
|
|
119
|
+
muted
|
|
120
|
+
playsinline
|
|
121
|
+
></video>
|
|
122
|
+
|
|
123
|
+
<!-- z=2 your content lives between the layers -->
|
|
124
|
+
<h1 id="headline" style="z-index:2; ...">MAKE IT IN HYPERFRAMES</h1>
|
|
125
|
+
|
|
126
|
+
<!-- z=3 cutout floats the subject back on top -->
|
|
127
|
+
<div class="cutout-wrap" style="position:absolute; inset:0; z-index:3">
|
|
128
|
+
<video
|
|
129
|
+
src="subject.webm"
|
|
130
|
+
data-start="0"
|
|
131
|
+
data-duration="6"
|
|
132
|
+
data-track-index="1"
|
|
133
|
+
muted
|
|
134
|
+
playsinline
|
|
135
|
+
></video>
|
|
136
|
+
</div>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Functionally equivalent to the text-behind-subject pattern above, but doesn't require shipping the original mp4 — the plate replaces it. Use this when delivering just the two transparent layers as a reusable asset.
|
|
140
|
+
|
|
141
|
+
## When `remove-background` is NOT the right tool
|
|
142
|
+
|
|
143
|
+
If a user asks for "the room **without** the person, displayed standalone" (no subject anywhere, no compositing on top), `--background-output` is wrong — its plate has a transparent hole, not a filled-in clean plate. They need an **inpainter**: LaMa, ProPainter, or E2FGVI. Tell them this command can't do it.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Requirements & Caches
|
|
2
|
+
|
|
3
|
+
## Credential & key priority
|
|
4
|
+
|
|
5
|
+
Run `npx hyperframes auth status` to see what's configured and which engines a workflow will use (see the skill's **Preflight** section). Keys resolve in this order — **first match wins**:
|
|
6
|
+
|
|
7
|
+
| Provider | Resolution order (first non-empty wins) | Local deps when used |
|
|
8
|
+
| ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
|
|
9
|
+
| **HeyGen** (TTS + BGM/SFX retrieval) | `$HEYGEN_API_KEY` → `$HYPERFRAMES_API_KEY` → `~/.heygen/credentials` (shared with heygen-cli; `$HEYGEN_CONFIG_DIR` overrides the dir; written by `hyperframes auth login`) | none (REST) |
|
|
10
|
+
| **ElevenLabs** (TTS fallback) | `$ELEVENLABS_API_KEY` | `pip install elevenlabs` |
|
|
11
|
+
| **Lyria** (BGM fallback) | `$GEMINI_API_KEY` → `$GOOGLE_API_KEY` | `pip install google-genai` |
|
|
12
|
+
| **Kokoro** (TTS, no key) | always — final voice fallback | `pip install kokoro-onnx soundfile` |
|
|
13
|
+
| **MusicGen** (BGM, no key) | always — final music fallback | `pip install transformers torch soundfile numpy` |
|
|
14
|
+
|
|
15
|
+
`hyperframes auth login` (browser OAuth) is the recommended setup: one sign-in, every project, no per-repo `.env`. An OAuth login is sent as `Authorization: Bearer`; an API key as `X-Api-Key`. With no HeyGen credential, voice/BGM run fully locally (Kokoro / MusicGen) — `hyperframes auth status` and `hyperframes doctor` both report whether those local deps are installed.
|
|
16
|
+
|
|
17
|
+
## Model caches & system dependencies
|
|
18
|
+
|
|
19
|
+
Each command downloads its own model on first run and caches it under `~/.cache/hyperframes/`:
|
|
20
|
+
|
|
21
|
+
- **TTS (HeyGen)** — no local deps; needs a HeyGen credential + `ffmpeg` on PATH (to transcode the mp3 response to `.wav`). Credential resolves like the CLI: `$HEYGEN_API_KEY` → `$HYPERFRAMES_API_KEY` → `~/.heygen/credentials` (shared with heygen-cli; run `npx hyperframes auth login`). An OAuth login is sent as `Authorization: Bearer`; an API key as `X-Api-Key`.
|
|
22
|
+
- **TTS (ElevenLabs)** — same as HeyGen: API key + `ffmpeg`.
|
|
23
|
+
- **TTS (Kokoro)** — Kokoro-82M (~311 MB) + voices (~27 MB) in `tts/`. Requires Python 3.8+ with `kokoro-onnx` and `soundfile` (`pip install kokoro-onnx soundfile`). Non-English text also needs `espeak-ng` system-wide.
|
|
24
|
+
- **BGM (Lyria)** — needs `$GEMINI_API_KEY` or `$GOOGLE_API_KEY` + `pip install google-genai`. No local model cache.
|
|
25
|
+
- **BGM (MusicGen)** — `pip install transformers torch soundfile`. `facebook/musicgen-small` (~300 MB) cached under `~/.cache/huggingface/` on first run.
|
|
26
|
+
- **Transcribe** — Whisper model size depending on choice (75 MB – 3.1 GB) in `whisper/`. Bundles `whisper.cpp`.
|
|
27
|
+
- **Remove-background** — `u2net_human_seg` (~168 MB ONNX) in `background-removal/models/`. Peak inference RAM ~1.5 GB.
|
|
28
|
+
|
|
29
|
+
Run `npx hyperframes doctor` if a command fails because of a missing dependency.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Sound effects (SFX)
|
|
2
|
+
|
|
3
|
+
Named sound effects, produced by the shared audio engine (`scripts/audio.mjs` → `scripts/lib/sfx.mjs`). **Provider-gated** by the engine's one switch — whether a HeyGen credential is present, decided once (not per cue):
|
|
4
|
+
|
|
5
|
+
- **HeyGen credential present → retrieve every cue** from HeyGen's audio library (`/v3/audio/sounds`, `type=sound_effects`, `min_score=0.4`). Search-and-download, **not** generation. The bundled library is NOT consulted.
|
|
6
|
+
- **No credential → the bundled 21-file library** (`assets/sfx/` + `manifest.json`): match each cue name, copy the matched file into the project. Offline, deterministic, free.
|
|
7
|
+
|
|
8
|
+
There is no `npx hyperframes sfx` command. SFX is never generated — it is retrieved (online) or taken from the bundled library (offline).
|
|
9
|
+
|
|
10
|
+
## Cues — request → meta
|
|
11
|
+
|
|
12
|
+
Each line names the effects it wants: `lines[].sfx: ["whoosh", "ui click"]`. The engine flattens these into cues, resolves them per the switch, dedupes identical `(id, name)` pairs (the same effect named twice downloads/copies once), and writes `audio_meta.sfx[]`:
|
|
13
|
+
|
|
14
|
+
```jsonc
|
|
15
|
+
{
|
|
16
|
+
"id": "3", // joins the cue to the caller's model (frame / scene / segment)
|
|
17
|
+
"name": "whoosh",
|
|
18
|
+
"file": "assets/sfx/whoosh.mp3", // downloaded or copied, relative to project root
|
|
19
|
+
"source": "heygen" | "local", // which route resolved it
|
|
20
|
+
"offset_s": 0, // delay from the line's start
|
|
21
|
+
"duration_s": 0.57,
|
|
22
|
+
"volume": 0.35 // SFX sit UNDER voice + BGM
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
A cue that matches nothing is **skipped** (recorded as an anomaly); SFX never blocks a render.
|
|
27
|
+
|
|
28
|
+
## HeyGen retrieval (credentialed)
|
|
29
|
+
|
|
30
|
+
`searchSounds(name, "sound_effects", { limit: 3, minScore: 0.4 })` → top hit → `assets/sfx/<slug>.mp3`. Results are ranked by `score` (each carries a presigned `audio_url`, `duration`, `description`). The floor is **0.4** because good SFX hits score ~0.5–0.67 — below the API's default `0.7`, which would silently drop most named cues (only whoosh/swoosh-family clears 0.7). `duration_s` comes from the result (else 1.0). Name effects concretely (`glass shatter`, not `dramatic sound`); a vague query returns a poor match.
|
|
31
|
+
|
|
32
|
+
## Bundled library (no credential)
|
|
33
|
+
|
|
34
|
+
21 curated files in `assets/sfx/`, indexed by `manifest.json` — `{ file, duration, description }` per key (e.g. `whoosh`, `pop`, `click`, `chime`, `riser`, `impact-bass-1`, `glitch-1`, `typing`, …). A cue name resolves by **manifest key, file basename, or slug**, so `whoosh`, `whoosh.mp3`, or `"ui click"` (→ slug) all match. Matched files are copied into the project's `assets/sfx/`; `duration_s` comes from the manifest, so timing is known **offline** — e.g. `riser` is 10.03s, so trigger it at `climax − 10.03s`. The manifest's `description` field carries placement hints per effect; read `assets/sfx/manifest.json` for the full set and usage.
|
|
35
|
+
|
|
36
|
+
## Rules
|
|
37
|
+
|
|
38
|
+
- **Volume ~0.35.** SFX must sit under narration and BGM, not fight them.
|
|
39
|
+
- **No match → skip, don't fail.** A missing effect logs an anomaly and moves on; never a render blocker.
|
|
40
|
+
- **Retrieval (credentialed) or bundled library (offline) — never generation.** You search HeyGen by text, or match a name against the 21-file manifest.
|
|
41
|
+
- **One asset per distinct name.** Reuse across lines is deduped to a single download/copy, many cues.
|
|
42
|
+
- **The switch is global, not per cue.** With a credential, retrieval handles even the long tail (effects not in the 21); without one, only the 21 bundled names resolve.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Transcription
|
|
2
|
+
|
|
3
|
+
Create normalized word-level timestamps. **Always specify `--model` explicitly** — the CLI default is `small.en`, which silently translates non-English audio into English.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx hyperframes transcribe audio.mp3 --model small.en # known English
|
|
7
|
+
npx hyperframes transcribe video.mp4 --model small --language es # known Spanish
|
|
8
|
+
npx hyperframes transcribe audio.mp3 --model small # unknown language (auto-detect)
|
|
9
|
+
npx hyperframes transcribe subtitles.srt # import existing
|
|
10
|
+
npx hyperframes transcribe subtitles.vtt
|
|
11
|
+
npx hyperframes transcribe openai-response.json
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Language Rule (Non-Negotiable)
|
|
15
|
+
|
|
16
|
+
`.en` models (`tiny.en` / `base.en` / `small.en` / `medium.en`) **translate** non-English audio into English. This silently destroys the original language.
|
|
17
|
+
|
|
18
|
+
1. **Known English** → `--model small.en` (or `medium.en` for music / noisy audio)
|
|
19
|
+
2. **Known non-English** → `--model small --language <iso-code>` (no `.en` suffix)
|
|
20
|
+
3. **Unknown language** → `--model small` (whisper auto-detects)
|
|
21
|
+
|
|
22
|
+
**CLI default is `small.en`** — do not rely on it; always pass `--model` to make the choice explicit. `--language` also filters out non-target-language segments from mixed-language audio.
|
|
23
|
+
|
|
24
|
+
## Model Sizes
|
|
25
|
+
|
|
26
|
+
| Model | Size | Speed | When |
|
|
27
|
+
| ---------- | ------ | -------- | ------------------------------------- |
|
|
28
|
+
| `tiny` | 75 MB | Fastest | Quick previews, smoke tests |
|
|
29
|
+
| `base` | 142 MB | Fast | Short clips, clear audio |
|
|
30
|
+
| `small` | 466 MB | Moderate | Default for most multilingual content |
|
|
31
|
+
| `medium` | 1.5 GB | Slow | Music with vocals, noisy audio |
|
|
32
|
+
| `large-v3` | 3.1 GB | Slowest | Production quality |
|
|
33
|
+
|
|
34
|
+
### Picking a model by content type
|
|
35
|
+
|
|
36
|
+
1. Speech over silence / light background → `small.en`
|
|
37
|
+
2. Speech over music, or music with vocals → start with `medium.en`
|
|
38
|
+
3. Produced music track (vocals + full instrumentation) → start with `medium.en`; expect to need manual lyrics or an external API ([`captions/transcript-handling.md`](captions/transcript-handling.md) → "Using External Transcription APIs")
|
|
39
|
+
4. Multilingual → `medium` or `large-v3` (no `.en` suffix), pair with `--language`
|
|
40
|
+
|
|
41
|
+
## Output Shape
|
|
42
|
+
|
|
43
|
+
Compositions consume a flat array of word objects. The `id` (`w0`, `w1`, …) is added during normalization for stable references in caption overrides; optional for backwards compatibility.
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
[
|
|
47
|
+
{ "id": "w0", "text": "Hello", "start": 0.0, "end": 0.5 },
|
|
48
|
+
{ "id": "w1", "text": "world.", "start": 0.6, "end": 1.2 }
|
|
49
|
+
]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For mandatory caption-quality checks, retry rules, and the OpenAI/Groq Whisper API import path, see `captions/transcript-handling.md`.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# TTS → Captions
|
|
2
|
+
|
|
3
|
+
When no recorded voiceover exists, generate one and obtain word-level caption timing. Two paths depending on which TTS provider is in use:
|
|
4
|
+
|
|
5
|
+
## Path A — HeyGen (single call, no Whisper)
|
|
6
|
+
|
|
7
|
+
HeyGen returns word timestamps in the same response as the audio. Pass `--words` and you're done:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx hyperframes tts script.txt --provider heygen --output narration.wav --words narration.words.json
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`narration.words.json` is already in the `[{ id, text, start, end }]` shape the captions pipeline consumes — no separate transcribe pass.
|
|
14
|
+
|
|
15
|
+
## Path B — ElevenLabs / Kokoro (TTS → Whisper)
|
|
16
|
+
|
|
17
|
+
These providers don't return word data. Generate the audio, then transcribe:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx hyperframes tts script.txt --voice af_heart --output narration.wav
|
|
21
|
+
npx hyperframes transcribe narration.wav --model small.en # voice af_heart is American English
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Whisper extracts precise word boundaries from the generated audio, so caption timing matches delivery without hand-tuning. Match `--model` to the voice's language (use `small.en` for `a`/`b` prefixes, `small --language <code>` otherwise). Then consume `transcript.json` via the caption references in `captions/`.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Text To Speech
|
|
2
|
+
|
|
3
|
+
`npx hyperframes tts` auto-detects a provider from env vars; explicit override via `--provider`.
|
|
4
|
+
|
|
5
|
+
> **Run the Preflight first — no credential is not a green light to silently use the local voice.** Before generating a voiceover, complete the sign-in **Preflight** (see `../SKILL.md` → Preflight): run `npx hyperframes auth status`, recommend signing in, and **STOP for the user's choice** (sign in for HeyGen voices, or continue offline with local Kokoro). This applies to a one-off "generate a voiceover" request just as much as inside a full workflow.
|
|
6
|
+
|
|
7
|
+
## Provider chain
|
|
8
|
+
|
|
9
|
+
| Order | Provider | Env trigger | Voice IDs | Word timestamps | Audio format |
|
|
10
|
+
| ----- | ----------------- | ------------------------------------------- | ------------------------------------------- | ----------------------------------------- | -------------------- |
|
|
11
|
+
| 1 | HeyGen (Starfish) | `$HEYGEN_API_KEY` / `~/.heygen/credentials` | UUIDs from `GET /v3/voices?engine=starfish` | **Yes** (`word_timestamps[]` in response) | mp3 → wav via ffmpeg |
|
|
12
|
+
| 2 | ElevenLabs | `$ELEVENLABS_API_KEY` | UUIDs from elevenlabs.io dashboard | No | mp3 → wav via ffmpeg |
|
|
13
|
+
| 3 | Kokoro-82M | always (local fallback) | `am_michael`, `af_heart`, … (54 voices) | No | wav direct |
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Auto-detect (HeyGen if key set, else ElevenLabs, else Kokoro)
|
|
17
|
+
npx hyperframes tts "Welcome to HyperFrames" -o narration.wav
|
|
18
|
+
|
|
19
|
+
# Pin the provider explicitly
|
|
20
|
+
npx hyperframes tts "Hello" --provider kokoro
|
|
21
|
+
npx hyperframes tts "Hello" --provider heygen --voice <heygen-uuid>
|
|
22
|
+
npx hyperframes tts "Hello" --provider elevenlabs --voice 21m00Tcm4TlvDq8ikWAM
|
|
23
|
+
|
|
24
|
+
# HeyGen path: capture word timestamps in one call (skips a Whisper pass)
|
|
25
|
+
npx hyperframes tts "Hi there" --words narration.words.json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Self-contained HeyGen (no CLI) — `scripts/heygen-tts.mjs`
|
|
29
|
+
|
|
30
|
+
The published `hyperframes tts` CLI synthesizes locally with Kokoro only. When you
|
|
31
|
+
want HeyGen specifically — best quality **plus** word timestamps in one call — use
|
|
32
|
+
the skill's bundled script, which calls the HeyGen v3 REST API directly and needs
|
|
33
|
+
no CLI provider plumbing:
|
|
34
|
+
|
|
35
|
+
The script resolves a HeyGen credential the same way the CLI does — first source
|
|
36
|
+
wins: `$HEYGEN_API_KEY` → `$HYPERFRAMES_API_KEY` → a project `.env` (auto-loaded,
|
|
37
|
+
walks up ≤5 dirs) → `~/.heygen/credentials` (shared with heygen-cli;
|
|
38
|
+
`$HEYGEN_CONFIG_DIR` overrides the dir). An OAuth login is sent as
|
|
39
|
+
`Authorization: Bearer`; an API key as `X-Api-Key`. If the only credential is an
|
|
40
|
+
expired OAuth token it stops with a hint to run `npx hyperframes auth refresh`.
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Only needed if you haven't run `npx hyperframes auth login`:
|
|
44
|
+
export HEYGEN_API_KEY=... # or put it in a project .env
|
|
45
|
+
|
|
46
|
+
# Synthesize + capture word timestamps in one call (skips a Whisper pass)
|
|
47
|
+
node skills/hyperframes-media/scripts/heygen-tts.mjs \
|
|
48
|
+
"Welcome to HyperFrames." -o narration.wav --words narration.words.json
|
|
49
|
+
|
|
50
|
+
node skills/hyperframes-media/scripts/heygen-tts.mjs ./script.txt -o narration.wav
|
|
51
|
+
node skills/hyperframes-media/scripts/heygen-tts.mjs --list # public starfish voices
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- **Voice:** `--voice <id>` must be a **starfish** voice_id (`--list`, or `GET /v3/voices?engine=starfish`). v2-catalog ids are rejected with HTTP 400. Omit `--voice` (English) and it defaults to **Marcia** (`05f19352e8f74b0392a8f411eba40de1`, a fixed default so the choice is deterministic). Non-English with no `--voice` falls back to the first matching catalog voice.
|
|
55
|
+
- **Output:** `.wav` → transcoded to 44.1k mono via ffmpeg; `.mp3` → raw bytes (no ffmpeg needed).
|
|
56
|
+
- **Words:** `--words <path>` writes the flat `[{id,text,start,end}]` shape below, drop-in for the captions pipeline. HeyGen's `<start>`/`<end>` boundary sentinels are filtered out and ids are re-contiguous.
|
|
57
|
+
- **Non-English:** `--lang <code>` (anything but `en`) is sent as the request `language`.
|
|
58
|
+
|
|
59
|
+
## When to use which provider
|
|
60
|
+
|
|
61
|
+
| Goal | Use |
|
|
62
|
+
| --------------------------------------------------------- | --------------------------------------------------- |
|
|
63
|
+
| Best voice quality + word timestamps in one call | **HeyGen** |
|
|
64
|
+
| Drop-in cloud TTS, big voice catalog | **ElevenLabs** |
|
|
65
|
+
| Offline, no API key, fast iteration | **Kokoro** |
|
|
66
|
+
| Non-English multilingual with deterministic phonemization | **Kokoro** (`ef_dora`, `jf_alpha`, `zf_xiaobei`, …) |
|
|
67
|
+
|
|
68
|
+
## ffmpeg requirement
|
|
69
|
+
|
|
70
|
+
HeyGen + ElevenLabs return mp3. The CLI transcodes to wav when `--output` ends in `.wav` (the default and what downstream `ffprobe` + Whisper expect). If you'd rather skip the transcode, pass `-o file.mp3`. Without `ffmpeg` on PATH, `.wav` output from the cloud providers fails — install ffmpeg or use `.mp3`.
|
|
71
|
+
|
|
72
|
+
## Voice selection (Kokoro)
|
|
73
|
+
|
|
74
|
+
Default `af_heart`. Curated picks:
|
|
75
|
+
|
|
76
|
+
| Content type | Voice |
|
|
77
|
+
| ----------------- | ---------------------- |
|
|
78
|
+
| Product demo | `af_heart`, `af_nova` |
|
|
79
|
+
| Tutorial / how-to | `am_adam`, `bf_emma` |
|
|
80
|
+
| Marketing / promo | `af_sky`, `am_michael` |
|
|
81
|
+
| Documentation | `bf_emma`, `bm_george` |
|
|
82
|
+
| Casual / social | `af_heart`, `af_sky` |
|
|
83
|
+
|
|
84
|
+
Run `npx hyperframes tts --list` for the bundled set.
|
|
85
|
+
|
|
86
|
+
## Multilingual (Kokoro voice prefix → language)
|
|
87
|
+
|
|
88
|
+
The first letter of a Kokoro voice ID picks the phonemizer language; `--lang` overrides auto-detection.
|
|
89
|
+
|
|
90
|
+
| Prefix | Language |
|
|
91
|
+
| ------ | -------------------- |
|
|
92
|
+
| `a` | American English |
|
|
93
|
+
| `b` | British English |
|
|
94
|
+
| `e` | Spanish |
|
|
95
|
+
| `f` | French |
|
|
96
|
+
| `h` | Hindi |
|
|
97
|
+
| `i` | Italian |
|
|
98
|
+
| `j` | Japanese |
|
|
99
|
+
| `p` | Brazilian Portuguese |
|
|
100
|
+
| `z` | Mandarin |
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npx hyperframes tts "La reunión empieza a las nueve" --voice ef_dora --provider kokoro
|
|
104
|
+
npx hyperframes tts "Today is a nice day" --voice af_heart --provider kokoro
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Valid `--lang` codes (only needed to override the voice's auto-detected language): `en-us`, `en-gb`, `es`, `fr-fr`, `hi`, `it`, `pt-br`, `ja`, `zh`.
|
|
108
|
+
|
|
109
|
+
Non-English phonemization requires `espeak-ng` system-wide (`brew install espeak-ng` / `apt-get install espeak-ng`).
|
|
110
|
+
|
|
111
|
+
## Speed
|
|
112
|
+
|
|
113
|
+
- `0.7-0.8` — tutorial, complex content, accessibility
|
|
114
|
+
- `1.0` — natural pace (default)
|
|
115
|
+
- `1.1-1.2` — intros, transitions, upbeat content
|
|
116
|
+
- `1.5+` — rarely appropriate, test carefully
|
|
117
|
+
|
|
118
|
+
Honored by Kokoro + HeyGen; ElevenLabs ignores `--speed` (use voice settings on their dashboard).
|
|
119
|
+
|
|
120
|
+
## Long scripts
|
|
121
|
+
|
|
122
|
+
Past a few paragraphs, write the text to a `.txt` file and pass the path. Inputs over ~5 minutes of speech may benefit from splitting into segments.
|
|
123
|
+
|
|
124
|
+
## HeyGen word-timestamp shape
|
|
125
|
+
|
|
126
|
+
When `--words <path>` is passed to a HeyGen call, the file is written in the same flat shape `transcribe` produces — drop-in compatible with the captions pipeline:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
[
|
|
130
|
+
{ "id": "w0", "text": "Hi", "start": 0.0, "end": 0.21 },
|
|
131
|
+
{ "id": "w1", "text": "there", "start": 0.22, "end": 0.55 }
|
|
132
|
+
]
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
For ElevenLabs / Kokoro, run `npx hyperframes transcribe narration.wav --model small.en` to get the same shape.
|