Yearly Pay yearly and get 2 months free on every paid plan. See plans
Conectare Începe gratuit

Videoclipuri explicative animate cu narațiune, cu ToRun MCP și Remotion

Ultima actualizare: 11 nov. 2026

Ce puteți crea

Un agent de programare care rulează comenzi pe computerul dvs., precum Claude Code, opencode sau Cursor, poate crea cu ToRun un scurt videoclip explicativ cu narațiune. Agentul scrie scenariul, cere de la ToRun imaginile scenelor, narațiunea și muzica de fundal și randează videoclipul pe computerul dvs. cu Remotion, o bibliotecă ce transformă componentele React în video.

De ce aveți nevoie

  • Un instrument de programare conectat la serverul MCP ToRun, care poate rula comenzi și scrie fișiere într-un folder: opencode, Claude Code sau Cursor.
  • Node.js 18 sau o versiune mai nouă. Prima randare descarcă browserul cu care randează Remotion.
  • Alocarea unui plan plătit sau un sold în portofel: apelurile API nu folosesc niciodată alocarea gratuită. Consultați cum se plătesc apelurile.

Remotion are propria licență: este gratuit pentru persoane fizice și companii foarte mici, iar companiile mai mari au nevoie de o licență pentru companii. Consultați remotion.dev/license înainte de a-l folosi la lucru.

Proiectul de pornire

Patru fișiere. Cereți agentului să le creeze într-un folder gol sau copiați-le chiar dvs., apoi rulați acolo npm install. Fișierele generate ajung într-un folder public lângă 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 conține întregul videoclip. Fiecare scenă are un caption afișat pe ecran, textul narațiunii say, prompt pentru imagine, numele fișierelor imaginii și narațiunii sale și durata sa în 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 redă scenele una după alta. Fiecare imagine se apropie încet, subtitrarea urcă de jos, narațiunea scenei începe odată cu ea, iar muzica se aude încet pe tot parcursul videoclipului:

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)}
  />
);

Cum creează agentul videoclipul

  1. Scenariu. Agentul scrie scenele în video.json: o idee pe scenă, o subtitrare de câteva cuvinte, una sau două propoziții de rostit. Cereți-i să vă arate scenariul înainte să genereze ceva.

  2. Sold. Apelează account_balance pentru a vedea cât poate cheltui contul. Acest apel este gratuit.

  3. Imagini. Pentru fiecare scenă apelează image_generate cu prompt al scenei și size 1792x1024 și salvează imaginea ca public/scene-1.png, public/scene-2.png și așa mai departe. Dacă o imagine nu este gata în timpul de așteptare, instrumentul returnează un ID de sarcină, iar agentul întreabă job_status până când imaginea este gata.

  4. Narațiune. Pentru fiecare scenă apelează tts_generate cu textul say al scenei și o voce, de exemplu nova, și salvează sunetul ca public/scene-1.mp3 și așa mai departe.

  5. Sincronizare. Setează seconds al fiecărei scene la durata narațiunii sale plus aproximativ o jumătate de secundă. tts_generate returnează această durată ca duration_seconds, măsurată din fișierul audio. Dacă răspunsul conține și duration_estimated: true, durata a putut fi doar estimată din text, așa că agentul măsoară fișierul. Pentru a verifica singur un fișier:

    npx remotion ffprobe -v error -show_entries format=duration -of csv=p=0 public/scene-1.mp3
    
  6. Muzică (opțional). Apelează music_generate cu un prompt precum „calm instrumental background, soft piano”, with_vocals setat la false și duration_seconds apropiat de durata videoclipului. Instrumentul returnează un ID de sarcină; agentul întreabă job_status până când piesa este gata și o salvează ca public/music.mp3. Fără muzică, eliminați linia music din video.json.

  7. Previzualizare și randare. npm run studio deschide o previzualizare în browser. npm run render scrie out/explainer.mp4.

Fiecare link de fișier returnat de un instrument se descarcă fără autentificare. Păstrați linkul întreg, inclusiv partea de după semnul întrebării:

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

Cereți agentului dvs.

Fă un videoclip explicativ de 30 de secunde despre cum funcționează sincronizarea în aplicația noastră, cu proiectul de pornire Remotion de la torun.ai/docs/mcp-motion-explainers. Patru scene. Arată-mi mai întâi scenariul din video.json. Apoi generează câte o imagine pentru fiecare scenă, fără text, narează fiecare scenă cu vocea nova, adaugă muzică instrumentală discretă, potrivește durata fiecărei scene cu narațiunea ei și randează.

Pentru un videoclip vertical, cereți width 1080 și height 1920 în video.json și imagini cu size 1024x1792.

Cât costă

  • image_generate, tts_generate și music_generate sunt apeluri plătite, taxate în Runs la aceleași prețuri ca în aplicație. Un videoclip cu patru scene și muzică înseamnă patru imagini, patru narațiuni și o piesă.
  • account_balance și job_status sunt gratuite.
  • Randarea rulează pe computerul dvs. Modificarea subtitrărilor, a sincronizării sau a mișcării și randarea din nou nu costă nimic în ToRun; generarea din nou a unei imagini sau a unei narațiuni este un nou apel plătit.
  • Când o singură generare ar costa mai mult decât pragul cheii, instrumentul răspunde mai întâi cu prețul, iar agentul vă întreabă înainte să ruleze apelul.
  • Tot ce generează agentul este salvat și în biblioteca dvs. ToRun.

Sfaturi

  • Cereți imagini fără text. Cuvintele le poartă subtitrarea, iar modelele de imagini scriu adesea textul greșit.
  • Limitați fiecare scenă la o idee și una sau două propoziții de narațiune.
  • Alegeți o voce și păstrați-o pe tot parcursul videoclipului.
  • Păstrați volumul muzicii între 0.1 și 0.15, ca narațiunea să rămână clară.
V-ați blocat? Forumul răspunde de obicei în câteva ore; suportul, în 24 de ore. Întrebați pe forum Contactați asistența