Animovaná vysvětlující videa s komentářem pomocí ToRun MCP a Remotion
Poslední aktualizace: 11 lis 2026
Co můžete vytvořit
Programovací agent, který spouští příkazy ve vašem počítači, například Claude Code, opencode nebo Cursor, může s ToRun vytvořit krátké vysvětlující video s komentářem. Agent napíše scénář, požádá ToRun o obrázky scén, komentář a podkresovou hudbu a vyrenderuje video ve vašem počítači pomocí Remotion, knihovny, která z komponent React dělá video.
Co potřebujete
- Programovací nástroj připojený k MCP serveru ToRun, který umí spouštět příkazy a zapisovat soubory do složky: opencode, Claude Code nebo Cursor.
- Node.js 18 nebo novější. První renderování stáhne prohlížeč, pomocí kterého Remotion renderuje.
- Limit placeného plánu nebo zůstatek v peněžence: volání API nikdy nepoužívají bezplatný limit. Viz jak se volání platí.
Remotion má vlastní licenci: pro jednotlivce a velmi malé firmy je zdarma, větší firmy potřebují firemní licenci. Než ho použijete pro práci, podívejte se na remotion.dev/license.
Výchozí projekt
Čtyři soubory. Požádejte agenta, aby je vytvořil v prázdné složce, nebo je zkopírujte sami, a pak v ní spusťte npm install. Vygenerované soubory se ukládají do složky public vedle package.json.
package.json:
{
"name": "motion-explainer",
"private": true,
"scripts": {
"studio": "remotion studio src/index.ts",
"render": "remotion render src/index.ts Explainer out/explainer.mp4"
},
"dependencies": {
"@remotion/cli": "4.0.539",
"react": "18.3.1",
"react-dom": "18.3.1",
"remotion": "4.0.539"
}
}
video.json obsahuje celé video. Každá scéna má caption zobrazený na obrazovce, text komentáře say, prompt obrázku, názvy souborů svého obrázku a komentáře a svou délku v seconds:
{
"width": 1920,
"height": 1080,
"fps": 30,
"music": { "file": "music.mp3", "volume": 0.12 },
"scenes": [
{
"caption": "Every team has a backlog.",
"say": "Every team has a backlog, and it only grows.",
"prompt": "flat illustration of a wall covered in sticky notes, soft morning light, no text",
"image": "scene-1.png",
"narration": "scene-1.mp3",
"seconds": 5.5
},
{
"caption": "Sort it by what users feel.",
"say": "Sort it by what your users feel, not by what is loudest.",
"prompt": "flat illustration of hands arranging cards into three columns on a desk, no text",
"image": "scene-2.png",
"narration": "scene-2.mp3",
"seconds": 6
},
{
"caption": "Ship the top one this week.",
"say": "Then ship the top one this week.",
"prompt": "flat illustration of a small paper boat leaving a harbour at sunrise, no text",
"image": "scene-3.png",
"narration": "scene-3.mp3",
"seconds": 5
}
]
}
src/index.ts:
import {registerRoot} from 'remotion';
import {Root} from './Root';
registerRoot(Root);
src/Root.tsx přehrává scény jednu po druhé. Každý obrázek se pomalu přibližuje, titulek vyjede zespodu, komentář scény začne spolu s ní a hudba tiše hraje pod celým videem:
import React from 'react';
import {AbsoluteFill, Composition, Html5Audio, Img, interpolate, Series, staticFile, useCurrentFrame} from 'remotion';
import data from '../video.json';
// "say" and "prompt" are the script: the narration text and the image prompt. Rendering reads the rest.
type Scene = {image: string; narration?: string; seconds: number; caption?: string; say?: string; prompt?: string};
type Video = {width: number; height: number; fps: number; music?: {file: string; volume: number}; scenes: Scene[]};
const video = data as Video;
const clamp = {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'} as const;
const framesOf = (scene: Scene) => Math.round(scene.seconds * video.fps);
// One scene: the image slowly zooms in, the caption rises in, the narration plays from the scene's start.
const SceneView: React.FC<{scene: Scene; frames: number}> = ({scene, frames}) => {
const frame = useCurrentFrame();
const fade = interpolate(frame, [0, 10, frames - 10, frames], [0, 1, 1, 0], clamp);
const zoom = interpolate(frame, [0, frames], [1, 1.08]);
const rise = interpolate(frame, [8, 26], [40, 0], clamp);
return (
<AbsoluteFill style={{backgroundColor: 'black', opacity: fade}}>
<Img src={staticFile(scene.image)} style={{width: '100%', height: '100%', objectFit: 'cover', transform: `scale(${zoom})`}} />
{scene.caption ? (
<div
style={{
position: 'absolute', left: '6%', right: '6%', bottom: '8%', transform: `translateY(${rise}px)`,
color: 'white', fontFamily: 'Arial, sans-serif', fontSize: video.height / 18, fontWeight: 700,
textShadow: '0 2px 16px rgba(0,0,0,0.7)',
}}
>
{scene.caption}
</div>
) : null}
{scene.narration ? <Html5Audio src={staticFile(scene.narration)} /> : null}
</AbsoluteFill>
);
};
const Explainer: React.FC = () => (
<AbsoluteFill style={{backgroundColor: 'black'}}>
<Series>
{video.scenes.map((scene, i) => (
<Series.Sequence key={i} durationInFrames={framesOf(scene)}>
<SceneView scene={scene} frames={framesOf(scene)} />
</Series.Sequence>
))}
</Series>
{video.music ? <Html5Audio src={staticFile(video.music.file)} volume={video.music.volume} loop /> : null}
</AbsoluteFill>
);
export const Root: React.FC = () => (
<Composition
id="Explainer"
component={Explainer}
width={video.width}
height={video.height}
fps={video.fps}
durationInFrames={video.scenes.reduce((sum, scene) => sum + framesOf(scene), 0)}
/>
);
Jak agent vytvoří video
Scénář. Agent zapíše scény do
video.json: jedna myšlenka na scénu, titulek o několika slovech, jedna nebo dvě věty k namluvení. Požádejte ho, aby vám scénář ukázal dřív, než cokoli vygeneruje.Zůstatek. Zavolá
account_balance, aby zjistil, kolik může účet utratit. Toto volání je zdarma.Obrázky. Pro každou scénu zavolá
image_generatespromptscény asize1792x1024a uloží obrázek jakopublic/scene-1.png,public/scene-2.pnga tak dále. Pokud obrázek není hotový během doby čekání, nástroj vrátí ID úlohy a agent se ptájob_status, dokud obrázek není hotový.Komentář. Pro každou scénu zavolá
tts_generates textemsayscény a hlasem, napříkladnova, a uloží zvuk jakopublic/scene-1.mp3a tak dále.Časování. Nastaví
secondskaždé scény na délku jejího komentáře plus zhruba půl sekundy.tts_generatevrací tuto délku jakoduration_seconds, změřenou ze zvukového souboru. Pokud odpověď obsahuje takéduration_estimated: true, délku bylo možné jen odhadnout z textu, takže agent soubor změří. Chcete-li soubor zkontrolovat sami:npx remotion ffprobe -v error -show_entries format=duration -of csv=p=0 public/scene-1.mp3Hudba (volitelné). Zavolá
music_generates promptem jako „calm instrumental background, soft piano“,with_vocalsnastaveným nafalseaduration_secondsblízko délce videa. Nástroj vrátí ID úlohy; agent se ptájob_status, dokud skladba není hotová, a uloží ji jakopublic/music.mp3. Bez hudby odstraňte řádekmusiczvideo.json.Náhled a renderování.
npm run studiootevře náhled ve vašem prohlížeči.npm run renderzapíšeout/explainer.mp4.
Každý odkaz na soubor, který nástroj vrátí, lze stáhnout bez přihlášení. Uchovejte celý odkaz včetně části za otazníkem:
curl -L -o public/scene-1.png "<the image link>"
Požádejte svého agenta
Vytvoř 30sekundové vysvětlující video o tom, jak funguje synchronizace v naší aplikaci, s výchozím projektem Remotion z torun.ai/docs/mcp-motion-explainers. Čtyři scény. Nejdřív mi ukaž scénář ve video.json. Pak vygeneruj pro každou scénu jeden obrázek bez textu, namluv každou scénu hlasem nova, přidej tichou instrumentální hudbu, přizpůsob délku každé scény jejímu komentáři a vyrenderuj.
Pro svislé video požádejte o width 1080 a height 1920 ve video.json a o obrázky se size 1024x1792.
Kolik to stojí
image_generate,tts_generateamusic_generatejsou placená volání, účtovaná v Runs za stejné ceny jako v aplikaci. Video se čtyřmi scénami a hudbou znamená čtyři obrázky, čtyři komentáře a jednu skladbu.account_balanceajob_statusjsou zdarma.- Renderování probíhá ve vašem počítači. Změna titulků, časování nebo pohybu a nové renderování v ToRun nic nestojí; nové vygenerování obrázku nebo komentáře je nové placené volání.
- Když by jedno generování stálo víc než práh klíče, nástroj nejprve odpoví cenou a váš agent se vás zeptá, než volání provede.
- Vše, co agent vygeneruje, se také uloží do vaší knihovny ToRun.
Tipy
- Žádejte obrázky bez textu. Slova nese titulek a obrázkové modely text často píšou s chybami.
- Omezte každou scénu na jednu myšlenku a jednu nebo dvě věty komentáře.
- Vyberte si jeden hlas a držte se ho po celé video.
- Udržujte hlasitost hudby mezi
0.1a0.15, aby komentář zůstal srozumitelný.