Erklärvideos mit Sprecherstimme und Animation mit ToRun MCP und Remotion
Zuletzt aktualisiert am 11 Nov. 2026
Was Sie erstellen können
Ein Coding-Agent, der Befehle auf Ihrem Computer ausführt, etwa Claude Code, opencode oder Cursor, kann mit ToRun ein kurzes Erklärvideo mit Sprecherstimme erstellen. Der Agent schreibt das Skript, fordert bei ToRun die Szenenbilder, die Sprecherstimme und die Hintergrundmusik an und rendert das Video auf Ihrem Computer mit Remotion, einer Bibliothek, die React-Komponenten in Videos verwandelt.
Was Sie brauchen
- Ein mit dem ToRun-MCP-Server verbundenes Coding-Tool, das in einem Ordner Befehle ausführen und Dateien schreiben kann: opencode, Claude Code oder Cursor.
- Node.js 18 oder neuer. Beim ersten Rendern wird der Browser heruntergeladen, mit dem Remotion rendert.
- Das Kontingent eines bezahlten Plans oder ein Wallet-Guthaben: API-Aufrufe nutzen nie das kostenlose Kontingent. Siehe wie Aufrufe bezahlt werden.
Remotion hat eine eigene Lizenz: Für Einzelpersonen und sehr kleine Unternehmen ist es kostenlos, größere Unternehmen brauchen eine Unternehmenslizenz. Lesen Sie remotion.dev/license, bevor Sie es beruflich einsetzen.
Das Starterprojekt
Vier Dateien. Bitten Sie Ihren Agent, sie in einem leeren Ordner anzulegen, oder kopieren Sie sie selbst, und führen Sie dort dann npm install aus. Generierte Dateien kommen in einen Ordner public neben 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 enthält das ganze Video. Jede Szene hat eine caption, die auf dem Bildschirm erscheint, den Sprechertext say, den Bild-prompt, die Dateinamen ihres Bildes und ihrer Sprecherstimme sowie ihre Länge in 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 spielt die Szenen nacheinander ab. Jedes Bild zoomt langsam heran, die Bildunterschrift gleitet nach oben ein, die Sprecherstimme der Szene beginnt mit ihr, und die Musik läuft leise unter dem ganzen Video:
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)}
/>
);
Wie der Agent das Video erstellt
Skript. Der Agent schreibt die Szenen in
video.json: eine Idee pro Szene, eine Bildunterschrift aus wenigen Wörtern, ein oder zwei Sätze zum Sprechen. Bitten Sie ihn, Ihnen das Skript zu zeigen, bevor er etwas generiert.Guthaben. Er ruft
account_balanceauf, um zu sehen, was das Konto ausgeben kann. Dieser Aufruf ist kostenlos.Bilder. Für jede Szene ruft er
image_generatemit dempromptder Szene undsize1792x1024auf und speichert das Bild alspublic/scene-1.png,public/scene-2.pngund so weiter. Ist ein Bild innerhalb der Wartezeit nicht fertig, gibt das Tool eine Job-ID zurück, und der Agent fragtjob_status, bis das Bild fertig ist.Sprecherstimme. Für jede Szene ruft er
tts_generatemit demsay-Text der Szene und einer Stimme auf, zum Beispielnova, und speichert das Audio alspublic/scene-1.mp3und so weiter.Timing. Er setzt die
secondsjeder Szene auf die Länge ihrer Sprecherstimme plus etwa eine halbe Sekunde.tts_generategibt diese Länge alsduration_secondszurück, gemessen an der Audiodatei. Steht in der Antwort außerdemduration_estimated: true, konnte die Länge nur aus dem Text geschätzt werden, und der Agent misst die Datei. So prüfen Sie eine Datei selbst:npx remotion ffprobe -v error -show_entries format=duration -of csv=p=0 public/scene-1.mp3Musik (optional). Er ruft
music_generatemit einem Prompt wie „calm instrumental background, soft piano“ auf, mitwith_vocalsauffalseundduration_secondsnahe an der Länge des Videos. Das Tool gibt eine Job-ID zurück; der Agent fragtjob_status, bis der Track fertig ist, und speichert ihn alspublic/music.mp3. Ohne Musik entfernen Sie die Zeilemusicausvideo.json.Vorschau und Rendern.
npm run studioöffnet eine Vorschau in Ihrem Browser.npm run renderschreibtout/explainer.mp4.
Jeder Dateilink, den ein Tool zurückgibt, lässt sich ohne Anmeldung herunterladen. Behalten Sie den ganzen Link, einschließlich des Teils nach dem Fragezeichen:
curl -L -o public/scene-1.png "<the image link>"
Fragen Sie Ihren Agent
Erstelle ein 30-sekündiges Erklärvideo darüber, wie die Synchronisierung unserer App funktioniert, mit dem Remotion-Starterprojekt von torun.ai/docs/mcp-motion-explainers. Vier Szenen. Zeig mir zuerst das Skript in video.json. Generiere dann pro Szene ein Bild ohne Text darin, sprich jede Szene mit der Stimme nova ein, füge leise Instrumentalmusik hinzu, richte jede Szene zeitlich an ihrer Sprecherstimme aus und rendere.
Für ein Hochformatvideo bitten Sie in video.json um width 1080 und height 1920 und um Bilder mit size 1024x1792.
Was es kostet
image_generate,tts_generateundmusic_generatesind kostenpflichtige Aufrufe und werden in Runs zu denselben Preisen wie in der App berechnet. Ein Video mit vier Szenen und Musik besteht aus vier Bildern, vier Sprecheraufnahmen und einem Track.account_balanceundjob_statussind kostenlos.- Das Rendern läuft auf Ihrem Computer. Bildunterschriften, Timing oder Bewegung zu ändern und neu zu rendern kostet bei ToRun nichts; ein Bild oder eine Sprecheraufnahme neu zu generieren ist ein neuer kostenpflichtiger Aufruf.
- Würde eine einzelne Generierung mehr kosten als der Schwellenwert des Schlüssels, antwortet das Tool zuerst mit dem Preis, und Ihr Agent fragt Sie, bevor er den Aufruf ausführt.
- Alles, was der Agent generiert, wird auch in Ihrer ToRun-Bibliothek gespeichert.
Tipps
- Bitten Sie um Bilder ohne Text darin. Die Bildunterschrift trägt die Worte, und Bildmodelle schreiben Text oft falsch.
- Beschränken Sie jede Szene auf eine Idee und ein oder zwei Sätze Sprechertext.
- Wählen Sie eine Stimme und behalten Sie sie für das ganze Video.
- Halten Sie die Musiklautstärke zwischen
0.1und0.15, damit die Sprecherstimme klar bleibt.