rw-integrate-video

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Integrate Video Generation

集成视频生成

PREREQUISITE: Run
+rw-check-compatibility
first. Run
+rw-fetch-api-reference
to load the latest API reference before integrating. Requires
+rw-setup-api-key
for API credentials. Requires
+rw-integrate-uploads
when the user has local files to use as input.
Help users add Runway video generation to their server-side code.
前提条件: 先运行
+rw-check-compatibility
。集成前运行
+rw-fetch-api-reference
加载最新的API参考文档。需要
+rw-setup-api-key
来配置API凭证。当用户有本地文件作为输入时,需要
+rw-integrate-uploads
帮助用户在其服务端代码中添加Runway视频生成功能。

Available Models

可用模型

ModelBest ForInputCostSpeed
seedance2
Reference image and video, long durationText, Image, and/or Video36 credits/secStandard
gen4.5
High quality, general purposeText and/or Image12 credits/secStandard
gen4_turbo
Fast, image-drivenImage required5 credits/secFast
gen4_aleph
Video editing/transformationVideo + Text/Image15 credits/secStandard
veo3
Premium Google modelText/Image40 credits/secStandard
veo3.1
High quality Google modelText/Image20-40 credits/secStandard
veo3.1_fast
Fast Google modelText/Image10-15 credits/secFast
Model selection guidance:
  • Default recommendation:
    gen4.5
    — best balance of quality and cost
  • Product ads / e-commerce:
    seedance2
    — up to 15s, supports reference image and video
  • Budget-conscious:
    gen4_turbo
    (requires image) or
    veo3.1_fast
  • Highest quality:
    veo3
    (most expensive)
  • Video-to-video editing:
    gen4_aleph
    or
    seedance2
模型适用场景输入类型成本生成速度
seedance2
参考图像/视频、长时长生成文本、图像和/或视频36积分/秒标准速度
gen4.5
高质量、通用场景文本和/或图像12积分/秒标准速度
gen4_turbo
快速生成、图像驱动必须输入图像5积分/秒快速
gen4_aleph
视频编辑/转场视频 + 文本/图像15积分/秒标准速度
veo3
Google高端模型文本/图像40积分/秒标准速度
veo3.1
Google高质量模型文本/图像20-40积分/秒标准速度
veo3.1_fast
Google快速模型文本/图像10-15积分/秒快速
模型选择指南:
  • 默认推荐:
    gen4.5
    — 质量与成本的最佳平衡
  • 产品广告/电商场景:
    seedance2
    — 最长支持15秒,支持参考图像和视频
  • 预算敏感场景:
    gen4_turbo
    (需输入图像)或
    veo3.1_fast
  • 最高质量需求:
    veo3
    (成本最高)
  • 视频转视频编辑:
    gen4_aleph
    seedance2

Security

安全注意事项

promptImage
,
promptVideo
,
videoUri
, and
references[].uri
are fetched server-side by the Runway API — treat them like any outbound fetch:
  • Prefer
    runway://
    URIs
    from
    +rw-integrate-uploads
    — scoped to your account, no arbitrary web content.
  • If accepting URLs from clients, validate first: require
    https://
    , allowlist trusted hosts, reject private addresses. See the Express.js example below.
  • Never forward
    req.body.imageUrl
    (or similar) straight into
    promptImage
    /
    promptVideo
    . The SDK snippets below use raw URLs for brevity — they aren't production templates.
  • Treat generated outputs as untrusted when piping into downstream automations — ingested media influences the result.
promptImage
promptVideo
videoUri
references[].uri
Runway API在服务器端获取——请像处理其他外部请求一样对待:
  • 优先使用
    runway://
    格式的URI
    ,该URI来自
    +rw-integrate-uploads
    ,仅作用于您的账户,不会加载任意网络内容。
  • 如果接收客户端传入的URL,需先验证:要求使用
    https://
    协议,仅允许可信域名,拒绝私有地址。请参考下方的Express.js示例。
  • 切勿直接将
    req.body.imageUrl
    (或类似字段)传入
    promptImage
    /
    promptVideo
    。下方的SDK代码片段为简洁起见使用了原始URL,但它们并非生产环境模板。
  • 当将生成的输出接入下游自动化流程时,请将其视为不可信内容——输入的媒体会影响生成结果。

Endpoints

API端点

Text-to-Video:
POST /v1/text_to_video

文本转视频:
POST /v1/text_to_video

Generate video from a text prompt only.
Compatible models:
seedance2
,
gen4.5
,
veo3
,
veo3.1
,
veo3.1_fast
javascript
// Node.js SDK
import RunwayML from '@runwayml/sdk';

const client = new RunwayML();

const task = await client.textToVideo.create({
  model: 'gen4.5',
  promptText: 'A golden retriever running through a field of wildflowers at sunset',
  ratio: '1280:720',
  duration: 5
}).waitForTaskOutput();

// task.output is an array of signed URLs
const videoUrl = task.output[0];
python
undefined
仅通过文本提示生成视频。
兼容模型:
seedance2
,
gen4.5
,
veo3
,
veo3.1
,
veo3.1_fast
javascript
// Node.js SDK
import RunwayML from '@runwayml/sdk';

const client = new RunwayML();

const task = await client.textToVideo.create({
  model: 'gen4.5',
  promptText: 'A golden retriever running through a field of wildflowers at sunset',
  ratio: '1280:720',
  duration: 5
}).waitForTaskOutput();

// task.output is an array of signed URLs
const videoUrl = task.output[0];
python
undefined

Python SDK

Python SDK

from runwayml import RunwayML
client = RunwayML()
task = client.text_to_video.create( model='gen4.5', prompt_text='A golden retriever running through a field of wildflowers at sunset', ratio='1280:720', duration=5 ).wait_for_task_output()
video_url = task.output[0]
undefined
from runwayml import RunwayML
client = RunwayML()
task = client.text_to_video.create( model='gen4.5', prompt_text='A golden retriever running through a field of wildflowers at sunset', ratio='1280:720', duration=5 ).wait_for_task_output()
video_url = task.output[0]
undefined

Image-to-Video:
POST /v1/image_to_video

图像转视频:
POST /v1/image_to_video

Animate a still image into a video.
Compatible models:
seedance2
,
gen4.5
,
gen4_turbo
,
veo3
,
veo3.1
,
veo3.1_fast
Recommended: upload via
+rw-integrate-uploads
and pass the returned
runway://
URI.
javascript
// Node.js SDK — preferred flow
import fs from 'fs';

const upload = await client.uploads.createEphemeral(
  fs.createReadStream('/path/to/image.jpg')
);

const task = await client.imageToVideo.create({
  model: 'gen4.5',
  promptImage: upload.runwayUri,
  promptText: 'The scene comes to life with gentle wind',
  ratio: '1280:720',
  duration: 5
}).waitForTaskOutput();
External URLs also work — only pass origins you control (see Security):
javascript
const task = await client.imageToVideo.create({
  model: 'gen4.5',
  promptImage: 'https://cdn.yourapp.com/landscape.jpg',
  promptText: 'Camera slowly pans right revealing a mountain range',
  ratio: '1280:720',
  duration: 5
}).waitForTaskOutput();
python
undefined
将静态图像生成为动态视频。
兼容模型:
seedance2
,
gen4.5
,
gen4_turbo
,
veo3
,
veo3.1
,
veo3.1_fast
推荐流程: 通过
+rw-integrate-uploads
上传文件,传入返回的
runway://
格式URI。
javascript
// Node.js SDK — 推荐流程
import fs from 'fs';

const upload = await client.uploads.createEphemeral(
  fs.createReadStream('/path/to/image.jpg')
);

const task = await client.imageToVideo.create({
  model: 'gen4.5',
  promptImage: upload.runwayUri,
  promptText: 'The scene comes to life with gentle wind',
  ratio: '1280:720',
  duration: 5
}).waitForTaskOutput();
外部URL也可使用——仅传入您可控的源地址(参考安全注意事项):
javascript
const task = await client.imageToVideo.create({
  model: 'gen4.5',
  promptImage: 'https://cdn.yourapp.com/landscape.jpg',
  promptText: 'Camera slowly pans right revealing a mountain range',
  ratio: '1280:720',
  duration: 5
}).waitForTaskOutput();
python
undefined

Python SDK

Python SDK

task = client.image_to_video.create( model='gen4.5', prompt_image='https://cdn.yourapp.com/landscape.jpg', prompt_text='Camera slowly pans right revealing a mountain range', ratio='1280:720', duration=5 ).wait_for_task_output()
undefined
task = client.image_to_video.create( model='gen4.5', prompt_image='https://cdn.yourapp.com/landscape.jpg', prompt_text='Camera slowly pans right revealing a mountain range', ratio='1280:720', duration=5 ).wait_for_task_output()
undefined

Video-to-Video:
POST /v1/video_to_video

视频转视频:
POST /v1/video_to_video

Transform an existing video with a text prompt and/or reference image.
Compatible models:
gen4_aleph
,
seedance2
javascript
// Node.js SDK — gen4_aleph
const task = await client.videoToVideo.create({
  model: 'gen4_aleph',
  videoUri: 'https://cdn.yourapp.com/source.mp4',
  promptText: 'Transform into an animated cartoon style',
}).waitForTaskOutput();
javascript
// Node.js SDK — seedance2 video-to-video (with optional image reference)
const task = await client.videoToVideo.create({
  model: 'seedance2',
  promptVideo: 'https://cdn.yourapp.com/input.mp4',
  promptText: 'Transform into a warm golden sunset scene',
  references: [{ type: 'image', uri: 'https://cdn.yourapp.com/style_ref.jpg' }]
}).waitForTaskOutput();
seedance2 VTV input requirements: max 15 seconds, max 32 MB, min 720p resolution, MP4 recommended.
通过文本提示和/或参考图像转换现有视频。
兼容模型:
gen4_aleph
,
seedance2
javascript
// Node.js SDK — gen4_aleph
const task = await client.videoToVideo.create({
  model: 'gen4_aleph',
  videoUri: 'https://cdn.yourapp.com/source.mp4',
  promptText: 'Transform into an animated cartoon style',
}).waitForTaskOutput();
javascript
// Node.js SDK — seedance2视频转视频(可选图像参考)
const task = await client.videoToVideo.create({
  model: 'seedance2',
  promptVideo: 'https://cdn.yourapp.com/input.mp4',
  promptText: 'Transform into a warm golden sunset scene',
  references: [{ type: 'image', uri: 'https://cdn.yourapp.com/style_ref.jpg' }]
}).waitForTaskOutput();
seedance2视频转视频输入要求: 最长15秒,最大32MB,最低720p分辨率,推荐使用MP4格式。

Seedance 2

Seedance 2

Seedance 2 supports text-to-video, image-to-video (two modes), and video-to-video. It uses pixel-based ratios:
1280:720
,
720:1280
,
960:960
,
1112:834
,
834:1112
,
1470:630
,
992:432
,
864:496
,
752:560
,
640:640
,
560:752
,
496:864
.
Seedance 2支持文本转视频、图像转视频(两种模式)和视频转视频。它支持以下像素比例:
1280:720
,
720:1280
,
960:960
,
1112:834
,
834:1112
,
1470:630
,
992:432
,
864:496
,
752:560
,
640:640
,
560:752
,
496:864

Text-to-Video

文本转视频

javascript
const task = await client.textToVideo.create({
  model: 'seedance2',
  promptText: 'A calm ocean wave gently crashing on a sandy beach at sunset',
  duration: 5,
  ratio: '1280:720'
}).waitForTaskOutput();
javascript
const task = await client.textToVideo.create({
  model: 'seedance2',
  promptText: 'A calm ocean wave gently crashing on a sandy beach at sunset',
  duration: 5,
  ratio: '1280:720'
}).waitForTaskOutput();

Image-to-Video — Mode 1: First / Last Frame

图像转视频 — 模式1:首帧/末帧

Use a specific image as the first and/or last frame. The
references
field cannot be used in this mode.
javascript
const task = await client.imageToVideo.create({
  model: 'seedance2',
  promptText: 'Smooth transition from day to night in a cozy mountain cabin',
  promptImage: [
    { uri: 'https://cdn.yourapp.com/image.jpg', position: 'first' },
    { uri: 'https://cdn.yourapp.com/image2.jpg', position: 'last' }
  ],
  duration: 4,
  ratio: '1280:720'
}).waitForTaskOutput();
promptImage
is an array of objects with
uri
(required) and
position
(
"first"
or
"last"
, defaults to first).
将指定图像作为视频的首帧和/或末帧。此模式下不可使用
references
字段。
javascript
const task = await client.imageToVideo.create({
  model: 'seedance2',
  promptText: 'Smooth transition from day to night in a cozy mountain cabin',
  promptImage: [
    { uri: 'https://cdn.yourapp.com/image.jpg', position: 'first' },
    { uri: 'https://cdn.yourapp.com/image2.jpg', position: 'last' }
  ],
  duration: 4,
  ratio: '1280:720'
}).waitForTaskOutput();
promptImage
是一个对象数组,每个对象包含
uri
(必填)和
position
(可选值
"first"
"last"
,默认值为first)。

Image-to-Video — Mode 2: Image Reference

图像转视频 — 模式2:图像参考

Use an image as a stylistic/content reference rather than a literal frame.
promptImage
is still required (as a URI string or single-item array).
javascript
const task = await client.imageToVideo.create({
  model: 'seedance2',
  promptText: 'Smooth transition from day to night in a cozy mountain cabin',
  promptImage: 'https://cdn.yourapp.com/image.jpg',
  references: [{ type: 'image', uri: 'https://cdn.yourapp.com/reference.jpg' }],
  duration: 4,
  ratio: '1280:720'
}).waitForTaskOutput();
These two ITV modes are mutually exclusive — you cannot use
position
in
promptImage
and
references
in the same request.
将图像作为风格/内容参考,而非字面意义上的帧。
promptImage
仍为必填项(可为URI字符串或单元素数组)。
javascript
const task = await client.imageToVideo.create({
  model: 'seedance2',
  promptText: 'Smooth transition from day to night in a cozy mountain cabin',
  promptImage: 'https://cdn.yourapp.com/image.jpg',
  references: [{ type: 'image', uri: 'https://cdn.yourapp.com/reference.jpg' }],
  duration: 4,
  ratio: '1280:720'
}).waitForTaskOutput();
这两种图像转视频模式互斥——您不能在同一个请求中同时使用
promptImage
position
参数和
references
字段。

Video-to-Video

视频转视频

Transform an existing video guided by a text prompt, optionally with an image reference.
python
task = client.video_to_video.create(
    model='seedance2',
    prompt_video='https://cdn.yourapp.com/input.mp4',
    prompt_text='Transform into a warm golden sunset scene',
    references=[{'type': 'image', 'uri': 'https://cdn.yourapp.com/style_ref.jpg'}]
).wait_for_task_output()
VTV input requirements: max 15 seconds, max 32 MB, min 720p resolution, MP4 recommended.
通过文本提示转换现有视频,可选添加图像参考。
python
task = client.video_to_video.create(
    model='seedance2',
    prompt_video='https://cdn.yourapp.com/input.mp4',
    prompt_text='Transform into a warm golden sunset scene',
    references=[{'type': 'image', 'uri': 'https://cdn.yourapp.com/style_ref.jpg'}]
).wait_for_task_output()
视频转视频输入要求: 最长15秒,最大32MB,最低720p分辨率,推荐使用MP4格式。

Seedance 2 Parameters

Seedance 2参数

ParameterTypeRequiredDescription
model
stringYesMust be
"seedance2"
promptText
stringYesText description of the desired video
duration
numberYes (TTV/ITV)Duration in seconds
ratio
stringYes (TTV/ITV)
1280:720
,
720:1280
,
960:960
,
1112:834
,
834:1112
,
1470:630
promptImage
string or arrayYes (ITV)URI string or array of
{ uri, position? }
objects
promptVideo
stringYes (seedance2 VTV)Input video URI (seedance2 only)
videoUri
stringYes (gen4_aleph VTV)Input video URI (gen4_aleph only)
references
arrayNoImage references —
[{ type: "image", uri: "..." }]
(ITV Mode 2 and VTV only)
参数类型是否必填描述
model
string必须为
"seedance2"
promptText
string目标视频的文本描述
duration
number是(文本转视频/图像转视频)视频时长(秒)
ratio
string是(文本转视频/图像转视频)支持的比例:
1280:720
,
720:1280
,
960:960
,
1112:834
,
834:1112
,
1470:630
promptImage
string 或数组是(图像转视频)URI字符串或
{ uri, position? }
对象数组
promptVideo
string是(seedance2视频转视频)输入视频的URI(仅seedance2可用)
videoUri
string是(gen4_aleph视频转视频)输入视频的URI(仅gen4_aleph可用)
references
array图像参考数组——
[{ type: "image", uri: "..." }]
(仅图像转视频模式2和视频转视频可用)

Character Performance:
POST /v1/character_performance

角色动作生成:
POST /v1/character_performance

Animate a character with facial/body performance.
Compatible models:
act_two
javascript
const task = await client.characterPerformance.create({
  model: 'act_two',
  promptImage: 'https://cdn.yourapp.com/character.jpg',
  promptPerformance: 'https://cdn.yourapp.com/performance.mp4',
  ratio: '1280:720',
  duration: 5
}).waitForTaskOutput();
通过面部/身体动作数据驱动角色动画。
兼容模型:
act_two
javascript
const task = await client.characterPerformance.create({
  model: 'act_two',
  promptImage: 'https://cdn.yourapp.com/character.jpg',
  promptPerformance: 'https://cdn.yourapp.com/performance.mp4',
  ratio: '1280:720',
  duration: 5
}).waitForTaskOutput();

Common Parameters

通用参数

ParameterTypeDescription
model
stringModel ID (required)
promptText
stringText prompt describing the video
promptImage
stringURL, data URI, or
runway://
URI of input image
ratio
stringAspect ratio, e.g.
'1280:720'
,
'720:1280'
duration
numberVideo length in seconds (2-15, model-dependent)
参数类型描述
model
string模型ID(必填)
promptText
string描述目标视频的文本提示
promptImage
string输入图像的URL、data URI或
runway://
格式URI
ratio
string宽高比,例如
'1280:720'
,
'720:1280'
duration
number视频时长(秒,2-15秒,具体取决于模型)

Integration Pattern

集成流程

When helping the user integrate, follow this pattern:
  1. Determine the use case — What type of video generation? (text-to-video, image-to-video, etc.)
  2. Prefer uploads over URLs — Default to
    +rw-integrate-uploads
    so inputs are
    runway://
    URIs. External URLs only from origins you control (see Security).
  3. Select the model — Recommend based on quality/cost/speed needs
  4. Write the server-side handler — Create an API route or server function
  5. Handle the output — Download and store the video, don't serve signed URLs to clients
  6. Add error handling — Wrap in try/catch, handle
    TaskFailedError
帮助用户集成时,请遵循以下流程:
  1. 确定使用场景 — 需要哪种类型的视频生成?(文本转视频、图像转视频等)
  2. 优先使用上传而非URL — 默认使用
    +rw-integrate-uploads
    ,使输入为
    runway://
    格式URI。仅使用您可控源地址的外部URL(参考安全注意事项)。
  3. 选择模型 — 根据质量/成本/速度需求推荐合适的模型
  4. 编写服务端处理逻辑 — 创建API路由或服务端函数
  5. 处理输出结果 — 下载并存储视频,不要将签名URL直接提供给客户端
  6. 添加错误处理 — 使用try/catch包裹代码,处理
    TaskFailedError

Example: Express.js API Route

示例:Express.js API路由

javascript
import RunwayML from '@runwayml/sdk';
import express from 'express';

const client = new RunwayML();
const app = express();
app.use(express.json());

// `runway://` URIs bypass this check; external URLs must match the allowlist.
const ALLOWED_MEDIA_HOSTS = new Set(['cdn.yourapp.com', 'uploads.yourapp.com']);

function assertTrustedMediaUrl(raw) {
  const u = new URL(raw);
  if (u.protocol !== 'https:') throw new Error('https required');
  if (!ALLOWED_MEDIA_HOSTS.has(u.hostname)) throw new Error('untrusted media host');
  return u.toString();
}

app.post('/api/generate-video', async (req, res) => {
  try {
    const { prompt, imageUrl, model = 'gen4.5', duration = 5 } = req.body;

    const params = {
      model,
      promptText: prompt,
      ratio: '1280:720',
      duration
    };

    let task;
    if (imageUrl) {
      task = await client.imageToVideo.create({
        ...params,
        promptImage: assertTrustedMediaUrl(imageUrl)
      }).waitForTaskOutput();
    } else {
      task = await client.textToVideo.create(params).waitForTaskOutput();
    }

    res.json({ videoUrl: task.output[0] });
  } catch (error) {
    console.error('Video generation failed:', error);
    res.status(400).json({ error: error.message });
  }
});
For browser uploads: POST files to your server, upload via
+rw-integrate-uploads
, and pass the
runway://
URI. Don't accept raw URLs from the browser.
javascript
import RunwayML from '@runwayml/sdk';
import express from 'express';

const client = new RunwayML();
const app = express();
app.use(express.json());

// `runway://`格式URI无需此检查;外部URL必须在允许列表内。
const ALLOWED_MEDIA_HOSTS = new Set(['cdn.yourapp.com', 'uploads.yourapp.com']);

function assertTrustedMediaUrl(raw) {
  const u = new URL(raw);
  if (u.protocol !== 'https:') throw new Error('https required');
  if (!ALLOWED_MEDIA_HOSTS.has(u.hostname)) throw new Error('untrusted media host');
  return u.toString();
}

app.post('/api/generate-video', async (req, res) => {
  try {
    const { prompt, imageUrl, model = 'gen4.5', duration = 5 } = req.body;

    const params = {
      model,
      promptText: prompt,
      ratio: '1280:720',
      duration
    };

    let task;
    if (imageUrl) {
      task = await client.imageToVideo.create({
        ...params,
        promptImage: assertTrustedMediaUrl(imageUrl)
      }).waitForTaskOutput();
    } else {
      task = await client.textToVideo.create(params).waitForTaskOutput();
    }

    res.json({ videoUrl: task.output[0] });
  } catch (error) {
    console.error('Video generation failed:', error);
    res.status(400).json({ error: error.message });
  }
});
浏览器上传场景:将文件上传至您的服务器,再通过
+rw-integrate-uploads
上传至Runway,传入
runway://
格式URI。切勿直接接收浏览器传入的原始URL。

Example: Next.js API Route

示例:Next.js API路由

typescript
// app/api/generate-video/route.ts
import RunwayML from '@runwayml/sdk';
import { NextRequest, NextResponse } from 'next/server';

const client = new RunwayML();

export async function POST(request: NextRequest) {
  const { prompt, imageUrl } = await request.json();

  try {
    const task = imageUrl
      ? await client.imageToVideo.create({
          model: 'gen4.5',
          promptImage: imageUrl,
          promptText: prompt,
          ratio: '1280:720',
          duration: 5
        }).waitForTaskOutput()
      : await client.textToVideo.create({
          model: 'gen4.5',
          promptText: prompt,
          ratio: '1280:720',
          duration: 5
        }).waitForTaskOutput();

    return NextResponse.json({ videoUrl: task.output[0] });
  } catch (error) {
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Generation failed' },
      { status: 500 }
    );
  }
}
typescript
// app/api/generate-video/route.ts
import RunwayML from '@runwayml/sdk';
import { NextRequest, NextResponse } from 'next/server';

const client = new RunwayML();

export async function POST(request: NextRequest) {
  const { prompt, imageUrl } = await request.json();

  try {
    const task = imageUrl
      ? await client.imageToVideo.create({
          model: 'gen4.5',
          promptImage: imageUrl,
          promptText: prompt,
          ratio: '1280:720',
          duration: 5
        }).waitForTaskOutput()
      : await client.textToVideo.create({
          model: 'gen4.5',
          promptText: prompt,
          ratio: '1280:720',
          duration: 5
        }).waitForTaskOutput();

    return NextResponse.json({ videoUrl: task.output[0] });
  } catch (error) {
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Generation failed' },
      { status: 500 }
    );
  }
}

Example: FastAPI Route

示例:FastAPI路由

python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from runwayml import RunwayML

app = FastAPI()
client = RunwayML()

class VideoRequest(BaseModel):
    prompt: str
    image_url: str | None = None
    model: str = "gen4.5"
    duration: int = 5

@app.post("/api/generate-video")
async def generate_video(req: VideoRequest):
    try:
        if req.image_url:
            task = client.image_to_video.create(
                model=req.model,
                prompt_image=req.image_url,
                prompt_text=req.prompt,
                ratio="1280:720",
                duration=req.duration
            ).wait_for_task_output()
        else:
            task = client.text_to_video.create(
                model=req.model,
                prompt_text=req.prompt,
                ratio="1280:720",
                duration=req.duration
            ).wait_for_task_output()

        return {"video_url": task.output[0]}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from runwayml import RunwayML

app = FastAPI()
client = RunwayML()

class VideoRequest(BaseModel):
    prompt: str
    image_url: str | None = None
    model: str = "gen4.5"
    duration: int = 5

@app.post("/api/generate-video")
async def generate_video(req: VideoRequest):
    try:
        if req.image_url:
            task = client.image_to_video.create(
                model=req.model,
                prompt_image=req.image_url,
                prompt_text=req.prompt,
                ratio="1280:720",
                duration=req.duration
            ).wait_for_task_output()
        else:
            task = client.text_to_video.create(
                model=req.model,
                prompt_text=req.prompt,
                ratio="1280:720",
                duration=req.duration
            ).wait_for_task_output()

        return {"video_url": task.output[0]}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

Tips

提示

  • Output URLs expire in 24-48 hours. Download videos to your own storage (S3, GCS, local filesystem) immediately after generation.
  • gen4_turbo
    requires an image
    — it cannot do text-only generation.
  • Video-to-video models:
    gen4_aleph
    and
    seedance2
    — use for editing/transforming existing videos.
  • Duration varies by model. Most models support 2-10 seconds; seedance2 supports up to 15 seconds.
  • waitForTaskOutput()
    has a default 10-minute timeout.
    For long-running generations, you may want to implement your own polling loop or increase the timeout.
  • For local files, always use
    +rw-integrate-uploads
    to upload first, then pass the
    runway://
    URI.
  • 输出URL的有效期为24-48小时。生成后请立即将视频下载至您自己的存储服务(S3、GCS、本地文件系统)。
  • gen4_turbo
    必须输入图像
    ——不支持仅文本生成。
  • 视频转视频模型:
    gen4_aleph
    seedance2
    ——用于编辑/转换现有视频。
  • 时长限制因模型而异。大多数模型支持2-10秒;seedance2最长支持15秒。
  • waitForTaskOutput()
    默认超时时间为10分钟
    。对于长时间运行的生成任务,您可能需要实现自定义轮询逻辑或增加超时时间。
  • 处理本地文件时,请始终先使用
    +rw-integrate-uploads
    上传,再传入
    runway://
    格式URI。