Annuale Paga annualmente e ottieni 2 mesi gratis su ogni piano a pagamento. Vedi i piani
Accedi Inizia gratis

Video esplicativi animati e narrati con ToRun MCP e Remotion

Ultimo aggiornamento: 11 nov 2026

Cosa puoi creare

Un agente di programmazione che esegue comandi sul tuo computer, come Claude Code, opencode o Cursor, può creare con ToRun un breve video esplicativo narrato. L'agente scrive il copione, chiede a ToRun le immagini delle scene, la narrazione e la musica di sottofondo, e renderizza il video sul tuo computer con Remotion, una libreria che trasforma componenti React in video.

Cosa ti serve

  • Uno strumento di programmazione collegato al server MCP di ToRun che possa eseguire comandi e scrivere file in una cartella: opencode, Claude Code o Cursor.
  • Node.js 18 o versioni successive. Il primo rendering scarica il browser con cui Remotion esegue il rendering.
  • La quota di un piano a pagamento o un saldo nel portafoglio: le chiamate API non usano mai la quota gratuita. Vedi come vengono pagate le chiamate.

Remotion ha una propria licenza: è gratuito per i privati e per le aziende molto piccole, mentre le aziende più grandi hanno bisogno di una licenza aziendale. Consulta remotion.dev/license prima di usarlo per lavoro.

Il progetto iniziale

Quattro file. Chiedi al tuo agente di crearli in una cartella vuota, o copiali tu stesso, poi esegui npm install in quella cartella. I file generati vanno in una cartella public accanto a 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 contiene l'intero video. Ogni scena ha una caption mostrata sullo schermo, il testo della narrazione say, il prompt dell'immagine, i nomi dei file della sua immagine e della sua narrazione, e la sua durata 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 riproduce le scene una dopo l'altra. Ogni immagine si avvicina lentamente, la didascalia sale in primo piano, la narrazione della scena parte insieme a lei e la musica suona a basso volume sotto tutto il 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)}
  />
);

Come l'agente crea il video

  1. Copione. L'agente scrive le scene in video.json: un'idea per scena, una didascalia di poche parole, una o due frasi da dire. Chiedigli di mostrarti il copione prima di generare qualsiasi cosa.

  2. Saldo. Chiama account_balance per vedere quanto può spendere l'account. Questa chiamata è gratuita.

  3. Immagini. Per ogni scena chiama image_generate con il prompt della scena e size 1792x1024, e salva l'immagine come public/scene-1.png, public/scene-2.png e così via. Se un'immagine non è pronta entro il tempo di attesa, lo strumento restituisce un id di job, e l'agente interroga job_status finché l'immagine non è pronta.

  4. Narrazione. Per ogni scena chiama tts_generate con il testo say della scena e una voce, ad esempio nova, e salva l'audio come public/scene-1.mp3 e così via.

  5. Tempi. Imposta i seconds di ogni scena sulla durata della sua narrazione più circa mezzo secondo. tts_generate restituisce questa durata come duration_seconds, misurata dal file audio. Se la risposta dice anche duration_estimated: true, la durata è stata solo stimata dal testo, quindi l'agente misura il file. Per controllare un file tu stesso:

    npx remotion ffprobe -v error -show_entries format=duration -of csv=p=0 public/scene-1.mp3
    
  6. Musica (facoltativa). Chiama music_generate con un prompt come "calm instrumental background, soft piano", with_vocals impostato su false e duration_seconds vicino alla durata del video. Lo strumento restituisce un id di job; l'agente interroga job_status finché la traccia non è pronta e la salva come public/music.mp3. Senza musica, rimuovi la riga music da video.json.

  7. Anteprima e rendering. npm run studio apre un'anteprima nel tuo browser. npm run render scrive out/explainer.mp4.

Ogni link a un file restituito da uno strumento si scarica senza effettuare l'accesso. Conserva il link intero, compresa la parte dopo il punto interrogativo:

curl -L -o public/scene-1.png "<the image link>"

Chiedilo al tuo agente

Crea un video esplicativo di 30 secondi su come funziona la sincronizzazione della nostra app, con il progetto iniziale Remotion di torun.ai/docs/mcp-motion-explainers. Quattro scene. Mostrami prima il copione in video.json. Poi genera un'immagine per scena senza testo, narra ogni scena con la voce nova, aggiungi una musica strumentale tranquilla, regola i tempi di ogni scena sulla sua narrazione ed esegui il rendering.

Per un video verticale, chiedi width 1080 e height 1920 in video.json, e immagini con size 1024x1792.

Quanto costa

  • image_generate, tts_generate e music_generate sono chiamate a pagamento, addebitate in Runs agli stessi prezzi dell'app. Un video con quattro scene e musica corrisponde a quattro immagini, quattro narrazioni e una traccia.
  • account_balance e job_status sono gratuite.
  • Il rendering avviene sul tuo computer. Cambiare didascalie, tempi o movimenti e rifare il rendering non costa nulla su ToRun; generare di nuovo un'immagine o una narrazione è una nuova chiamata a pagamento.
  • Quando una singola generazione costerebbe più della soglia della chiave, lo strumento risponde prima con il prezzo, e il tuo agente ti chiede conferma prima di eseguire la chiamata.
  • Tutto ciò che l'agente genera viene salvato anche nella tua libreria ToRun.

Consigli

  • Chiedi immagini senza testo. La didascalia porta le parole, e i modelli di immagine spesso sbagliano a scrivere il testo.
  • Limita ogni scena a un'idea e a una o due frasi di narrazione.
  • Scegli una voce e mantienila per tutto il video.
  • Tieni il volume della musica tra 0.1 e 0.15, così la narrazione resta chiara.
Bloccato? Il forum di solito risponde in poche ore; il supporto entro 24 ore. Chiedi al forum Contatta l'assistenza