Letno Plačajte letno in pridobite 2 meseca brezplačno pri vsakem plačljivem paketu. Oglejte si pakete
Prijava Začni brezplačno

Animirani razlagalni videi s pripovedjo z ToRun MCP in Remotion

Zadnja posodobitev: 11 nov. 2026

Kaj lahko naredite

Agent za programiranje, ki zaganja ukaze na vašem računalniku, na primer Claude Code, opencode ali Cursor, lahko s ToRun naredi kratek razlagalni video s pripovedjo. Agent napiše scenarij, od ToRun zahteva slike prizorov, pripoved in glasbeno podlago ter video upodobi na vašem računalniku z Remotion, knjižnico, ki komponente React spremeni v video.

Kaj potrebujete

  • Orodje za programiranje, povezano s strežnikom MCP ToRun, ki lahko zaganja ukaze in zapisuje datoteke v mapo: opencode, Claude Code ali Cursor.
  • Node.js 18 ali novejši. Prvo upodabljanje prenese brskalnik, s katerim Remotion upodablja.
  • Kvoto plačljivega paketa ali dobroimetje v denarnici: klici API nikoli ne uporabljajo brezplačne kvote. Glejte kako se klici plačujejo.

Remotion ima svojo licenco: za posameznike in zelo majhna podjetja je brezplačen, večja podjetja pa potrebujejo podjetniško licenco. Preden ga uporabite za delo, preverite remotion.dev/license.

Začetni projekt

Štiri datoteke. Prosite agenta, naj jih ustvari v prazni mapi, ali jih kopirajte sami, nato pa tam zaženite npm install. Ustvarjene datoteke gredo v mapo public poleg 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 vsebuje celoten video. Vsak prizor ima caption, ki se prikaže na zaslonu, besedilo pripovedi say, prompt slike, imena datotek svoje slike in pripovedi ter svojo dolžino 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 predvaja prizore enega za drugim. Vsaka slika se počasi približuje, napis se dvigne od spodaj, pripoved prizora se začne skupaj z njim, glasba pa tiho igra pod celotnim videom:

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

Kako agent naredi video

  1. Scenarij. Agent zapiše prizore v video.json: ena zamisel na prizor, napis iz nekaj besed, en ali dva stavka za izgovoriti. Prosite ga, naj vam pokaže scenarij, preden karkoli ustvari.

  2. Dobroimetje. Pokliče account_balance, da vidi, koliko lahko račun porabi. Ta klic je brezplačen.

  3. Slike. Za vsak prizor pokliče image_generate s prompt prizora in size 1792x1024 ter shrani sliko kot public/scene-1.png, public/scene-2.png in tako naprej. Če slika ni pripravljena v času čakanja, orodje vrne ID opravila, agent pa sprašuje job_status, dokler slika ni pripravljena.

  4. Pripoved. Za vsak prizor pokliče tts_generate z besedilom say prizora in glasom, na primer nova, ter shrani zvok kot public/scene-1.mp3 in tako naprej.

  5. Časovna uskladitev. Vsakemu prizoru nastavi seconds na dolžino njegove pripovedi in približno pol sekunde. tts_generate vrne to dolžino kot duration_seconds, izmerjeno iz zvočne datoteke. Če odgovor vsebuje tudi duration_estimated: true, je bilo dolžino mogoče le oceniti iz besedila, zato agent izmeri datoteko. Če želite datoteko preveriti sami:

    npx remotion ffprobe -v error -show_entries format=duration -of csv=p=0 public/scene-1.mp3
    
  6. Glasba (neobvezno). Pokliče music_generate s pozivom, kot je „calm instrumental background, soft piano“, with_vocals, nastavljenim na false, in duration_seconds blizu dolžine videa. Orodje vrne ID opravila; agent sprašuje job_status, dokler skladba ni pripravljena, in jo shrani kot public/music.mp3. Brez glasbe odstranite vrstico music iz video.json.

  7. Predogled in upodabljanje. npm run studio odpre predogled v brskalniku. npm run render zapiše out/explainer.mp4.

Vsako povezavo do datoteke, ki jo vrne orodje, je mogoče prenesti brez prijave. Shranite celotno povezavo, vključno z delom za vprašajem:

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

Prosite svojega agenta

Naredi 30-sekundni razlagalni video o tem, kako deluje sinhronizacija v naši aplikaciji, z začetnim projektom Remotion s torun.ai/docs/mcp-motion-explainers. Štirje prizori. Najprej mi pokaži scenarij v video.json. Nato za vsak prizor ustvari eno sliko brez besedila, vsakemu prizoru dodaj pripoved z glasom nova, dodaj tiho instrumentalno glasbo, uskladi dolžino vsakega prizora z njegovo pripovedjo in upodobi.

Za navpični video zahtevajte width 1080 in height 1920 v video.json ter slike s size 1024x1792.

Koliko stane

  • image_generate, tts_generate in music_generate so plačljivi klici, ki se zaračunajo v Runs po enakih cenah kot v aplikaciji. Video s štirimi prizori in glasbo pomeni štiri slike, štiri pripovedi in eno skladbo.
  • account_balance in job_status sta brezplačna.
  • Upodabljanje poteka na vašem računalniku. Sprememba napisov, časovne uskladitve ali gibanja in ponovno upodabljanje v ToRun ne stane nič; ponovno ustvarjanje slike ali pripovedi je nov plačljiv klic.
  • Ko bi eno ustvarjanje stalo več od praga ključa, orodje najprej odgovori s ceno, vaš agent pa vas vpraša, preden izvede klic.
  • Vse, kar agent ustvari, se shrani tudi v vašo knjižnico ToRun.

Nasveti

  • Zahtevajte slike brez besedila. Besede nosi napis, modeli za slike pa besedilo pogosto napišejo napačno.
  • Vsak prizor omejite na eno zamisel ter en ali dva stavka pripovedi.
  • Izberite en glas in ga obdržite skozi ves video.
  • Glasnost glasbe ohranite med 0.1 in 0.15, da pripoved ostane jasna.
Ste obtičali? Forum običajno odgovori v nekaj urah, podpora v 24 urah. Vprašajte na forumu Stik s podporo