Hreyfð útskýringarmyndskeið með sögumannsrödd, með ToRun MCP og Remotion
Síðast uppfært 11 nóv. 2026
Hvað þú getur gert
Forritunarþjónn sem keyrir skipanir á tölvunni þinni, eins og Claude Code, opencode eða Cursor, getur búið til stutt útskýringarmyndskeið með sögumannsrödd með ToRun. Þjónninn skrifar handritið, biður ToRun um myndirnar fyrir atriðin, sögumannsröddina og bakgrunnstónlistina, og birtir (renderar) myndskeiðið á tölvunni þinni með Remotion, safni sem breytir React-íhlutum í myndskeið.
Hvað þú þarft
- Forritunarverkfæri tengt MCP-þjóni ToRun sem getur keyrt skipanir og skrifað skrár í möppu: opencode, Claude Code eða Cursor.
- Node.js 18 eða nýrra. Fyrsta birtingin sækir vafrann sem Remotion birtir með.
- Kvóta úr greiddri áskrift eða inneign í veskinu: API-köll nota aldrei ókeypis kvótann. Sjá hvernig greitt er fyrir köll.
Remotion hefur sitt eigið leyfi: það er ókeypis fyrir einstaklinga og mjög lítil fyrirtæki, og stærri fyrirtæki þurfa fyrirtækjaleyfi. Kynntu þér remotion.dev/license áður en þú notar það í vinnu.
Upphafsverkefnið
Fjórar skrár. Biddu þjóninn að búa þær til í tómri möppu, eða afritaðu þær sjálf/ur, og keyrðu síðan npm install þar. Skrárnar sem eru búnar til fara í public, við hliðina á 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 geymir allt myndskeiðið. Hvert atriði hefur caption sem birtist á skjánum, textann say fyrir sögumannsröddina, prompt fyrir myndina, skráarheitin fyrir mynd þess og sögumannsrödd, og lengd þess í 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 spilar atriðin hvert á eftir öðru. Hver mynd þysjast hægt inn, textinn rennur upp neðan frá, sögumannsrödd atriðisins byrjar á sama tíma, og tónlistin hljómar lágt allt myndskeiðið:
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)}
/>
);
Hvernig þjónninn býr til myndskeiðið
Handrit. Þjónninn skrifar atriðin í
video.json: ein hugmynd í hverju atriði, texti með fáeinum orðum, ein eða tvær setningar til að segja. Biddu hann að sýna þér handritið áður en hann býr eitthvað til.Inneign. Hann kallar á
account_balancetil að sjá hverju aðgangurinn getur eytt. Það kall er ókeypis.Myndir. Fyrir hvert atriði kallar hann á
image_generatemeðpromptatriðisins ogsizeupp á1792x1024, og vistar myndina sempublic/scene-1.png,public/scene-2.pngog svo framvegis. Ef mynd er ekki tilbúin innan biðtímans skilar verkfærið verkauðkenni, og þjónninn spyrjob_statusþar til hún er tilbúin.Sögumannsrödd. Fyrir hvert atriði kallar hann á
tts_generatemeðsay-texta atriðisins og rödd, til dæmisnova, og vistar hljóðið sempublic/scene-1.mp3og svo framvegis.Tímasetning. Hann stillir
secondshvers atriðis á lengd sögumannsraddar þess að viðbættri um hálfri sekúndu.tts_generateskilar þeirri lengd semduration_seconds, mældri úr hljóðskránni. Ef svarið segir líkaduration_estimated: truevar aðeins hægt að áætla lengdina út frá textanum, svo þjónninn mælir skrána. Til að athuga skrá sjálf/ur:npx remotion ffprobe -v error -show_entries format=duration -of csv=p=0 public/scene-1.mp3Tónlist (valfrjálst). Hann kallar á
music_generatemeð kvaðningu eins og „calm instrumental background, soft piano“,with_vocalsstillt áfalseogduration_secondsnálægt lengd myndskeiðsins. Verkfærið skilar verkauðkenni; þjónninn spyrjob_statusþar til lagið er tilbúið og vistar það sempublic/music.mp3. Ef þú vilt enga tónlist skaltu fjarlægja línunamusicúrvideo.json.Forskoðun og birting.
npm run studioopnar forskoðun í vafranum þínum.npm run renderskrifarout/explainer.mp4.
Sérhver skráartengill sem verkfærin skila sækist án innskráningar. Haltu öllum tenglinum, líka hlutanum á eftir spurningarmerkinu:
curl -L -o public/scene-1.png "<the image link>"
Biddu þjóninn þinn
Búðu til 30 sekúndna útskýringarmyndskeið um hvernig samstillingin í appinu okkar virkar, með Remotion-upphafsverkefninu á torun.ai/docs/mcp-motion-explainers. Fjögur atriði. Sýndu mér fyrst handritið í video.json. Búðu síðan til eina mynd fyrir hvert atriði án texta, settu sögumannsrödd með röddinni nova á hvert atriði, bættu við rólegri hljóðfæratónlist, láttu lengd hvers atriðis passa við sögumannsrödd þess og birtu.
Fyrir lóðrétt myndskeið, biddu um width 1080 og height 1920 í video.json og myndir með size 1024x1792.
Hvað það kostar
image_generate,tts_generateogmusic_generateeru greidd köll, gjaldfærð í Runs á sama verði og í appinu. Myndskeið með fjórum atriðum og tónlist eru fjórar myndir, fjórar sögumannsraddir og eitt lag.account_balanceogjob_statuseru ókeypis.- Birtingin fer fram á tölvunni þinni. Að breyta textum, tímasetningu eða hreyfingu og birta aftur kostar ekkert hjá ToRun; að búa til mynd eða sögumannsrödd upp á nýtt er nýtt greitt kall.
- Þegar ein gerð myndi kosta meira en þröskuldur lykilsins svarar verkfærið fyrst með verðinu, og þjónninn þinn spyr þig áður en hann framkvæmir kallið.
- Allt sem þjónninn býr til er líka vistað í Safni þínu á ToRun.
Ráð
- Biddu um myndir án texta. Orðin eiga heima í myndatextanum, og myndlíkön stafsetja texta oft rangt.
- Takmarkaðu hvert atriði við eina hugmynd og eina eða tvær setningar af sögumannsrödd.
- Veldu eina rödd og haltu henni allt myndskeiðið.
- Hafðu hljóðstyrk tónlistarinnar á milli
0.1og0.15svo sögumannsröddin haldist skýr.