Yıllık Yıllık ödeyin, tüm ücretli planlarda 2 ay ücretsiz. Planları gör
Giriş yap Ücretsiz başla

ToRun MCP ve Remotion ile seslendirilmiş hareketli anlatım videoları

Son güncelleme: 11 Kas 2026

Neler yapabilirsiniz

Claude Code, opencode veya Cursor gibi bilgisayarınızda komut çalıştıran bir kodlama ajanı, ToRun ile kısa, seslendirilmiş bir anlatım videosu hazırlayabilir. Ajan senaryoyu yazar, sahne görsellerini, seslendirmeyi ve arka plan müziğini ToRun'dan ister ve videoyu bilgisayarınızda, React bileşenlerini videoya dönüştüren bir kütüphane olan Remotion ile oluşturur.

Nelere ihtiyacınız var

  • ToRun MCP sunucusuna bağlı, bir klasörde komut çalıştırıp dosya yazabilen bir kodlama aracı: opencode, Claude Code veya Cursor.
  • Node.js 18 veya üstü. İlk oluşturma, Remotion'ın oluşturmada kullandığı tarayıcıyı indirir.
  • Ücretli bir planın payı ya da cüzdan bakiyesi: API çağrıları ücretsiz payı hiçbir zaman kullanmaz. Bkz. çağrılar nasıl ödenir.

Remotion'ın kendi lisansı vardır: bireyler ve çok küçük şirketler için ücretsizdir, daha büyük şirketlerin bir şirket lisansına ihtiyacı vardır. İş için kullanmadan önce remotion.dev/license sayfasına bakın.

Başlangıç projesi

Dört dosya. Ajanınızdan bunları boş bir klasörde oluşturmasını isteyin ya da kendiniz kopyalayın, ardından orada npm install çalıştırın. Üretilen dosyalar package.json dosyasının yanındaki public klasörüne konur.

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 videonun tamamını tutar. Her sahnede ekranda gösterilen bir caption, seslendirme metni say, görsel istemi prompt, görselinin ve seslendirmesinin dosya adları ve seconds cinsinden süresi bulunur:

{
  "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 sahneleri art arda oynatır. Her görsel yavaşça yakınlaşır, alt yazı yukarı doğru belirir, sahnenin seslendirmesi onunla birlikte başlar ve müzik videonun tamamı boyunca alçak sesle çalar:

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

Ajan videoyu nasıl hazırlar

  1. Senaryo. Ajan sahneleri video.json dosyasına yazar: sahne başına bir fikir, birkaç kelimelik bir alt yazı, söylenecek bir ya da iki cümle. Herhangi bir şey üretmeden önce senaryoyu size göstermesini isteyin.

  2. Bakiye. Hesabın ne kadar harcayabileceğini görmek için account_balance aracını çağırır. Bu çağrı ücretsizdir.

  3. Görseller. Her sahne için sahnenin prompt değeri ve size 1792x1024 ile image_generate aracını çağırır ve görseli public/scene-1.png, public/scene-2.png gibi adlarla kaydeder. Bir görsel bekleme süresi içinde hazır olmazsa araç bir iş kimliği döndürür ve ajan görsel hazır olana kadar job_status aracına sorar.

  4. Seslendirme. Her sahne için sahnenin say metni ve bir sesle, örneğin nova, tts_generate aracını çağırır ve sesi public/scene-1.mp3 gibi adlarla kaydeder.

  5. Zamanlama. Her sahnenin seconds değerini seslendirmesinin süresi artı yaklaşık yarım saniye olarak ayarlar. tts_generate bu süreyi ses dosyasından ölçülmüş olarak duration_seconds alanında döndürür. Yanıtta duration_estimated: true de yazıyorsa süre yalnızca metinden tahmin edilebilmiştir, bu yüzden ajan dosyayı ölçer. Bir dosyayı kendiniz kontrol etmek için:

    npx remotion ffprobe -v error -show_entries format=duration -of csv=p=0 public/scene-1.mp3
    
  6. Müzik (isteğe bağlı). "calm instrumental background, soft piano" gibi bir istem, false olarak ayarlanmış with_vocals ve videonun süresine yakın bir duration_seconds ile music_generate aracını çağırır. Araç bir iş kimliği döndürür; ajan parça hazır olana kadar job_status aracına sorar ve onu public/music.mp3 olarak kaydeder. Müzik istemiyorsanız video.json dosyasından music satırını silin.

  7. Önizleme ve oluşturma. npm run studio tarayıcınızda bir önizleme açar. npm run render out/explainer.mp4 dosyasını yazar.

Bir aracın döndürdüğü her dosya bağlantısı oturum açmadan indirilir. Soru işaretinden sonraki kısım da dahil olmak üzere bağlantının tamamını koruyun:

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

Ajanınıza sorun

torun.ai/docs/mcp-motion-explainers adresindeki Remotion başlangıç projesiyle uygulamamızın eşitlemesinin nasıl çalıştığını anlatan 30 saniyelik bir video hazırla. Dört sahne olsun. Önce video.json dosyasındaki senaryoyu bana göster. Ardından her sahne için içinde yazı olmayan bir görsel üret, her sahneyi nova sesiyle seslendir, alçak sesli enstrümantal müzik ekle, her sahneyi seslendirmesine göre zamanla ve videoyu oluştur.

Dikey bir video için video.json dosyasında width 1080 ve height 1920, görseller için de size 1024x1792 isteyin.

Maliyeti ne kadar

  • image_generate, tts_generate ve music_generate ücretli çağrılardır ve uygulamadaki fiyatlarla Runs olarak ücretlendirilir. Dört sahneli ve müzikli bir video dört görsel, dört seslendirme ve bir parçadır.
  • account_balance ve job_status ücretsizdir.
  • Oluşturma bilgisayarınızda yapılır. Alt yazıları, zamanlamayı ya da hareketi değiştirip yeniden oluşturmak ToRun'da hiçbir ücret doğurmaz; bir görseli ya da seslendirmeyi yeniden üretmek yeni bir ücretli çağrıdır.
  • Tek bir üretim anahtarın eşiğinden daha pahalıya mal olacaksa araç önce fiyatı söyler ve ajanınız çağrıyı çalıştırmadan önce size sorar.
  • Ajanın ürettiği her şey ToRun kütüphanenize de kaydedilir.

İpuçları

  • İçinde yazı olmayan görseller isteyin. Sözcükleri alt yazı taşır ve görsel modelleri yazıyı sık sık yanlış yazar.
  • Her sahneyi bir fikir ve bir ya da iki cümlelik seslendirmeyle sınırlayın.
  • Bir ses seçin ve videonun tamamında onu kullanın.
  • Seslendirme net kalsın diye müziğin ses düzeyini 0.1 ile 0.15 arasında tutun.
Takıldınız mı? Forum genellikle birkaç saat içinde, destek ise 24 saat içinde yanıt verir. Foruma sorun Destekle iletişime geçin