Árlega Greiddu árlega og fáðu 2 mánuði ókeypis á öllum greiddum áskriftum. Skoða áskriftir
Skrá inn Byrjaðu ókeypis

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ð

  1. 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.

  2. Inneign. Hann kallar á account_balance til að sjá hverju aðgangurinn getur eytt. Það kall er ókeypis.

  3. Myndir. Fyrir hvert atriði kallar hann á image_generate með prompt atriðisins og size upp á 1792x1024, og vistar myndina sem public/scene-1.png, public/scene-2.png og svo framvegis. Ef mynd er ekki tilbúin innan biðtímans skilar verkfærið verkauðkenni, og þjónninn spyr job_status þar til hún er tilbúin.

  4. Sögumannsrödd. Fyrir hvert atriði kallar hann á tts_generate með say-texta atriðisins og rödd, til dæmis nova, og vistar hljóðið sem public/scene-1.mp3 og svo framvegis.

  5. Tímasetning. Hann stillir seconds hvers atriðis á lengd sögumannsraddar þess að viðbættri um hálfri sekúndu. tts_generate skilar þeirri lengd sem duration_seconds, mældri úr hljóðskránni. Ef svarið segir líka duration_estimated: true var 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.mp3
    
  6. Tónlist (valfrjálst). Hann kallar á music_generate með kvaðningu eins og „calm instrumental background, soft piano“, with_vocals stillt á false og duration_seconds nálægt lengd myndskeiðsins. Verkfærið skilar verkauðkenni; þjónninn spyr job_status þar til lagið er tilbúið og vistar það sem public/music.mp3. Ef þú vilt enga tónlist skaltu fjarlægja línuna music úr video.json.

  7. Forskoðun og birting. npm run studio opnar forskoðun í vafranum þínum. npm run render skrifar out/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_generate og music_generate eru 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_balance og job_status eru ó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.1 og 0.15 svo sögumannsröddin haldist skýr.
Stopp? Spjallborðið svarar yfirleitt innan nokkurra klukkustunda; þjónustan innan 24 klukkustunda. Spyrðu á spjallborðinu Hafa samband við þjónustu