mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 23:00:03 +00:00
fix: double-audio bug + lint rules + docs guide + capture improvements
Double-audio bug fix: - scaffolding.ts: stop writing index.html in captures/ (root cause — runtime discovered scaffold + real index.html as two compositions) - New lint rule: multiple_root_compositions — errors if >1 root HTML - New lint rule: duplicate_audio_track — warns on overlapping audio Capture improvements (from testing 30+ websites): - Catalog runs BEFORE extractHtml (which mutates DOM — converts img src to data URLs). HeyKuba: 2 images → 78. - networkidle2 instead of networkidle0 (unblocks SPAs with WebSockets) - Lazy-load image wait, CSS background-image cataloging - SVG naming from class/id/parent (not just aria-label) - Gemini batch 5→20, pause 12s→2s, maxOutputTokens 300→500 - Asset descriptions sorted: captioned first Docs: - New guide: guides/website-to-video.mdx (full tutorial) - CLI docs: added capture and snapshot commands - docs.json: website-to-video in Guides nav C
This commit is contained in:
@@ -61,51 +61,13 @@ export async function generateProjectScaffold(
|
||||
progress: (stage: string, detail?: string) => void,
|
||||
warnings: string[],
|
||||
): Promise<void> {
|
||||
// Ensure capture output is a valid HyperFrames project (index.html + meta.json)
|
||||
const indexPath = join(outputDir, "index.html");
|
||||
// Capture output is a DATA folder, not a video project.
|
||||
// The agent builds index.html + compositions/ during step 6.
|
||||
// We only write meta.json (project metadata) — NOT index.html.
|
||||
// Writing index.html here caused a double-audio bug: the runtime
|
||||
// discovered both the scaffold and the agent's real index.html as
|
||||
// valid compositions, playing two audio tracks offset in time.
|
||||
const metaPath = join(outputDir, "meta.json");
|
||||
if (!existsSync(indexPath)) {
|
||||
writeFileSync(
|
||||
indexPath,
|
||||
`<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=1920, height=1080" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
html, body { margin: 0; width: 1920px; height: 1080px; overflow: hidden; background: #000; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Root composition wrapper — AGENT: update data-duration to match total video length -->
|
||||
<div data-composition-id="main" data-width="1920" data-height="1080" data-start="0" data-duration="28">
|
||||
|
||||
<!-- SCENE SLOTS — AGENT: adjust count, durations, and IDs to match your scene plan -->
|
||||
<div id="scene-1" data-composition-src="compositions/scene-1.html" data-start="0" data-duration="7" data-track-index="1" data-width="1920" data-height="1080"></div>
|
||||
<div id="scene-2" data-composition-src="compositions/scene-2.html" data-start="7" data-duration="7" data-track-index="1" data-width="1920" data-height="1080"></div>
|
||||
<div id="scene-3" data-composition-src="compositions/scene-3.html" data-start="14" data-duration="7" data-track-index="1" data-width="1920" data-height="1080"></div>
|
||||
<div id="scene-4" data-composition-src="compositions/scene-4.html" data-start="21" data-duration="7" data-track-index="1" data-width="1920" data-height="1080"></div>
|
||||
|
||||
<!-- NARRATION — AGENT: update src after generating TTS -->
|
||||
<audio id="narration" data-start="0" data-duration="28" data-track-index="0" data-volume="1" src="narration.wav"></audio>
|
||||
|
||||
<!-- CAPTIONS (optional — only add if user requests captions/subtitles) -->
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
window.__timelines = window.__timelines || {};
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
window.__timelines["main"] = tl;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`,
|
||||
"utf-8",
|
||||
);
|
||||
}
|
||||
if (!existsSync(metaPath)) {
|
||||
const hostname = new URL(url).hostname.replace(/^www\./, "");
|
||||
writeFileSync(
|
||||
|
||||
Reference in New Issue
Block a user