Data tells a story, but spreadsheets and static charts don’t. Animated visualizations are compelling — but building them as shareable video (not just an interactive webpage) usually means screen recording with all its artifacts.
Data source → Generate visualization HTML → Animate with GSAP → Render to MP4
Hyperframes renders anything a browser can display. D3 charts, Canvas graphics, SVG diagrams, CSS animations — they all become pixel-perfect video frames.
Your data can come from anywhere — a CSV, an API, a database, or generated programmatically.
# Example: pull GitHub statsimport requestsrepos = requests.get( "https://api.github.com/users/your-username/repos", headers={"Authorization": f"token {GITHUB_TOKEN}"}).json()stats = { "total_repos": len(repos), "languages": {}, "total_stars": sum(r["stargazers_count"] for r in repos),}for r in repos: lang = r.get("language") or "Other" stats["languages"][lang] = stats["languages"].get(lang, 0) + 1
2
Describe the visualization to your AI agent
I have GitHub data for a developer: 13 repos, 472 commits,top languages are TypeScript (5), Dart (3), JavaScript (1).Create a "GitHub Wrapped" style video — vertical 9:16, 45 seconds.Show the stats one by one with animated counters, a bar chart oflanguages that grows, and end with a highlight reel of project names.Use a dark theme with green (#00ff88) accents like GitHub's contribution graph.
The AI agent writes the HTML composition with the data baked into the animation.
3
Add generated audio (optional)
For data visualizations, synthesized audio often works better than voiceover. You can generate tones programmatically:
import wave, struct, math# Generate pitched tones for a sorting visualizersample_rate = 44100samples = []for value in data_points: freq = 200 + (value / max_value) * 1000 # pitch = data value for i in range(int(0.03 * sample_rate)): # 30ms per tone env = 1.0 - (i / (0.03 * sample_rate)) * 0.7 s = env * 0.25 * math.sin(2 * math.pi * freq * i / sample_rate) samples.append(s)with wave.open("data-sound.wav", "w") as wf: wf.setnchannels(1) wf.setsampwidth(2) wf.setframerate(sample_rate) for s in samples: wf.writeframes(struct.pack("<h", int(max(-1, min(1, s)) * 32767)))
import subprocessdef generate_data_video(data, template_dir, output_path): """Generate a video from data using Hyperframes.""" # 1. Write data into the composition with open(f"{template_dir}/data.json", "w") as f: json.dump(data, f) # 2. Render subprocess.run([ "npx", "hyperframes", "render", "--output", output_path, "--quality", "standard" ], cwd=template_dir) return output_path# Generate weekly report videos from databasefor week in get_weekly_metrics(): generate_data_video( data=week, template_dir="templates/weekly-report", output_path=f"renders/report-{week['date']}.mp4" )
Combine with Docs to Video for a fully automated pipeline: data changes → Hyperframes renders visualization → Video Agent adds avatar narration.