비디오 생성

비디오 생성 (Video Generation)

experimental_generateVideo 함수를 사용해 비디오 모델로 프롬프트 기반의 비디오를 생성하는 방법을 설명하는 문서예요.

출처: 문서

본문

참고: 비디오 생성은 실험적 기능이에요. API는 향후 버전에서 변경될 수 있어요.

AI SDK는 비디오 모델을 사용해 주어진 프롬프트를 기반으로 비디오를 생성하는 experimental_generateVideo 함수를 제공해요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A cat walking on a treadmill',
});

base64 또는 uint8Array 속성을 사용해 비디오 데이터에 접근할 수 있어요:

const base64 = video.base64; // base64 video data
const uint8Array = video.uint8Array; // Uint8Array video data

설정 (Settings)

종횡비 (Aspect Ratio)

종횡비는 {width}:{height} 형식의 문자열로 지정해요. 모델은 몇 가지 종횡비만 지원하며, 지원되는 종횡비는 모델과 프로바이더마다 달라요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A cat walking on a treadmill',
  aspectRatio: '16:9',
});

일부 모델은 'adaptive'도 허용하는데, 이 경우 고정 값 대신 입력 미디어에서 출력 비율을 프로바이더가 유도하게 해요. 이는 출력이 입력의 비율을 상속하는 이미지-투-비디오(image-to-video), 비디오 편집, 비디오 확장에서 일반적으로 필요하며, 명시적 비율은 거부돼요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: { image: firstFrame, text: 'A cat walking on a treadmill' },
  aspectRatio: 'adaptive',
});

해상도 (Resolution)

해상도는 {width}x{height} 형식의 문자열로 지정해요. 모델은 특정 해상도만 지원하며, 지원되는 해상도는 모델과 프로바이더마다 달라요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A serene mountain landscape at sunset',
  resolution: '1280x720',
});

지속시간 (Duration)

일부 비디오 모델은 생성할 비디오의 지속시간을 초 단위로 지정하는 것을 지원해요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A timelapse of clouds moving across the sky',
  duration: 5,
});

초당 프레임 (Frames Per Second / FPS)

일부 비디오 모델은 생성할 비디오의 초당 프레임 수를 지정할 수 있게 해 줘요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A hummingbird in slow motion',
  fps: 24,
});

오디오 생성 (Audio Generation)

일부 비디오 모델은 비디오와 함께 오디오를 생성할 수 있어요. generateAudio 옵션을 사용해 이를 제어하세요:

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A jazz band playing in a cozy club',
  generateAudio: true,
});

여러 비디오 생성 (Generating Multiple Videos)

experimental_generateVideo는 한 번에 여러 비디오 생성을 지원해요:

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { videos } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A rocket launching into space',
  n: 3, // number of videos to generate
});

참고: experimental_generateVideo는 요청된 수의 비디오를 생성하기 위해 필요할 때마다 모델을 자동으로 (병렬로) 호출해요.

각 비디오 모델은 단일 API 호출에서 생성할 수 있는 비디오 수에 내부 제한이 있어요. AI SDK는 n 매개변수로 여러 비디오를 요청할 때 요청을 적절히 배치함으로써 이를 자동으로 관리해요. 대부분의 비디오 모델은 계산 비용 때문에 호출당 1개의 비디오만 생성하는 것을 지원해요.

필요하다면 maxVideosPerCall 설정으로 이 동작을 오버라이드할 수 있어요:

const { videos } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A rocket launching into space',
  maxVideosPerCall: 2, // Override the default batch size
  n: 4, // Will make 2 calls of 2 videos each
});

이미지-투-비디오 생성 (Image-to-Video Generation)

일부 비디오 모델은 입력 이미지에서 비디오를 생성하는 것을 지원해요. 프롬프트 객체로 이미지를 제공할 수 있어요:

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: {
    image: 'https://example.com/my-image.png',
    text: 'Animate this image with gentle motion',
  },
});

이미지를 base64 문자열이나 Uint8Array로도 제공할 수 있어요:

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: {
    image: imageBase64String, // or imageUint8Array
    text: 'Animate this image',
  },
});

첫·마지막 프레임 (First and Last Frame)

일부 비디오 모델은 비디오의 시작 및/또는 끝 프레임을 제공하는 첫-마지막 프레임 생성을 지원해요. frameImages 옵션을 사용해 역할이 태그된 이미지를 프로바이더에 구애받지 않는 방식으로 전달하세요:

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'The cat walks across the scene and transforms into a dog by the end',
  frameImages: [
    {
      image: 'https://example.com/first-frame.png',
      frameType: 'first_frame',
    },
    {
      image: 'https://example.com/last-frame.png',
      frameType: 'last_frame',
    },
  ],
});

참조 입력 (Reference Inputs)

일부 비디오 모델은 하나 이상의 참조 이미지나 비디오를 제공하는 참조-투-비디오 생성을 지원하며, 모델이 이를 생성된 비디오에 통합해요. inputReferences 옵션을 사용해 해당 입력을 프로바이더에 구애받지 않는 방식으로 전달하세요:

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'The two characters meet in a bustling market',
  inputReferences: [
    'https://example.com/character-1.png',
    'https://example.com/character-2.png',
  ],
});

URL 기반 비디오 참조의 경우 명시적 mediaType이 있는 객체 형태를 사용하세요:

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'Match the motion in the reference clip',
  inputReferences: [
    {
      data: 'https://example.com/reference.mp4',
      mediaType: 'video/mp4',
    },
  ],
});

프로바이더는 각 참조를 미디어 타입(이미지 vs 비디오)별로 라우팅하며, 참조 종류가 지원되지 않으면 경고를 내보내요 (예: 이미지 참조만 받는 프로바이더는 비디오 참조에 대해 경고하고 무시해요).

시드 제공 (Providing a Seed)

experimental_generateVideo 함수에 seed를 제공해 비디오 생성 과정의 출력을 제어할 수 있어요. 모델이 지원하면 같은 seed는 항상 같은 비디오를 만들어요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A cat walking on a treadmill',
  seed: 1234567890,
});

프로바이더별 설정 (Provider-specific Settings)

비디오 모델은 종종 프로바이더, 심지어 모델별 설정을 갖고 있어요. providerOptions 매개변수를 사용해 이러한 설정을 experimental_generateVideo 함수에 전달할 수 있어요. 프로바이더에 대한 옵션은 요청 본문 속성이 돼요.

import { experimental_generateVideo as generateVideo } from 'ai';
import { fal } from '@ai-sdk/fal';

const { video } = await generateVideo({
  model: fal.video('luma-dream-machine/ray-2'),
  prompt: 'A cat walking on a treadmill',
  aspectRatio: '16:9',
  providerOptions: {
    fal: { loop: true, motionStrength: 0.8 },
  },
});

중단 신호와 타임아웃 (Abort Signals and Timeouts)

experimental_generateVideo는 AbortSignal 타입의 선택적 abortSignal 매개변수를 받으며, 비디오 생성 과정을 중단하거나 타임아웃을 설정하는 데 사용할 수 있어요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A cat walking on a treadmill',
  abortSignal: AbortSignal.timeout(60000), // Abort after 60 seconds
});

참고: 비디오 생성은 일반적으로 이미지 생성보다 더 오래 걸려요. 모델과 비디오 길이에 따라 더 긴 타임아웃(60초 이상)을 사용하는 것을 고려하세요.

폴링 (Polling)

비디오 생성은 완료되는 데 몇 분이 걸릴 수 있는 비동기 프로세스예요. SDK는 비디오가 준비되었는지 확인하기 위해 프로바이더를 자동으로 폴링해요. 폴링 동작을 구성할 수 있어요:

import { experimental_generateVideo as generateVideo } from 'ai';
import { fal } from '@ai-sdk/fal';

const { video } = await generateVideo({
  model: fal.video('luma-dream-machine/ray-2'),
  prompt: 'A cinematic timelapse of a city from dawn to dusk',
  duration: 10,
  poll: {
    intervalMs: 5000, // Check every 5 seconds (default)
    timeoutMs: 600000, // Timeout after 10 minutes (default)
  },
});

자체 sleep 프리미티브를 제공하는 내구성 있는 워크플로의 경우 이를 poll.delay로 전달하세요. 커스텀 지연은 폴링 간격과 웹훅 타임아웃 모두에 사용돼요.

웹훅 (Webhooks)

네이티브 웹훅 지원이 있는 모델의 경우 공개 URL과 애플리케이션이 웹훅 요청을 받으면 resolve되는 promise를 반환하는 webhook 팩토리를 전달하세요:

import { fal } from '@ai-sdk/fal';
import { experimental_generateVideo as generateVideo } from 'ai';
import { createWebhook } from './create-webhook';

const { video } = await generateVideo({
  model: fal.video('luma-dream-machine/ray-2'),
  prompt: 'A cinematic timelapse of a city from dawn to dusk',
  poll: {
    timeoutMs: 600000, // Wait up to 10 minutes for the webhook
  },
  webhook: async () => {
    const { url, received } = await createWebhook();
    return { url, received };
  },
});

createWebhook은 반환 전에 웹훅 리스너를 등록하는 애플리케이션 특정 헬퍼예요. 그 received promise는 요청 headers와 body로 resolve되어야 해요. SDK는 url을 프로바이더에 보내고, received를 기다린 다음 완성된 비디오를 검색해요.

poll을 webhook과 함께 제공할 수 있어요. 네이티브 웹훅 지원이 있는 모델의 경우 poll.timeoutMs는 SDK가 알림을 기다리는 시간을 제한해요. 모델이 웹훅을 지원하지 않으면 SDK는 제공된 간격과 타임아웃으로 폴링에 폴백해요.

커스텀 헤더 (Custom Headers)

experimental_generateVideo는 타입 Record<string, string>의 선택적 headers 매개변수를 받으며, 비디오 생성 요청에 커스텀 헤더를 추가하는 데 사용할 수 있어요.

import { experimental_generateVideo as generateVideo } from 'ai';
__PROVIDER_IMPORT__;

const { video } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A cat walking on a treadmill',
  headers: { 'X-Custom-Header': 'custom-value' },
});

경고 (Warnings)

모델이 지원되지 않는 매개변수에 대한 경고 같은 경고를 반환하면, 응답의 warnings 속성에서 사용할 수 있어요.

const { video, warnings } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A cat walking on a treadmill',
});

추가 프로바이더별 메타데이터 (Additional Provider-specific Metadata)

일부 프로바이더는 결과 전체 또는 각 비디오에 대해 추가 메타데이터를 노출해요.

const prompt = 'A cat walking on a treadmill';

const { video, providerMetadata } = await generateVideo({
  model: fal.video('luma-dream-machine/ray-2'),
  prompt,
});

// Access provider-specific metadata
const videoMetadata = providerMetadata.fal?.videos[0];
console.log({
  duration: videoMetadata?.duration,
  fps: videoMetadata?.fps,
  width: videoMetadata?.width,
  height: videoMetadata?.height,
});

반환된 providerMetadata의 바깥 키는 프로바이더 이름이에요. 안쪽 값은 메타데이터예요. 메타데이터에는 일반적으로 videos 키가 있으며, 이는 최상위 videos 키와 같은 길이의 배열이에요.

n > 1로 여러 비디오를 생성할 때 responses 배열을 통해 호출별 메타데이터에도 접근할 수 있어요:

const { videos, responses } = await generateVideo({
  model: __VIDEO_MODEL__,
  prompt: 'A rocket launching into space',
  n: 5, // May require multiple API calls
});

// Access metadata from each individual API call
for (const response of responses) {
  console.log({
    timestamp: response.timestamp,
    modelId: response.modelId,
    // Per-call provider metadata (lossless)
    providerMetadata: response.providerMetadata,
  });
}

오류 처리 (Error Handling)

experimental_generateVideo가 유효한 비디오를 생성하지 못하면 AI_NoVideoGeneratedError를 던져요.

이 오류는 AI 프로바이더가 비디오를 생성하지 못할 때 발생해요. 다음 이유 때문에 발생할 수 있어요:

  • 모델이 응답을 생성하지 못함
  • 모델이 파싱할 수 없는 응답을 생성함

이 오류는 문제를 로깅하는 데 도움이 되도록 다음 정보를 보존해요:

  • responses: 타임스탬프, 모델, 헤더를 포함한 비디오 모델 응답에 대한 메타데이터.
  • cause: 오류의 원인. 더 상세한 오류 처리를 위해 사용할 수 있어요.
import {
  experimental_generateVideo as generateVideo,
  NoVideoGeneratedError,
} from 'ai';

try {
  await generateVideo({ model, prompt });
} catch (error) {
  if (NoVideoGeneratedError.isInstance(error)) {
    console.log('NoVideoGeneratedError');
    console.log('Cause:', error.cause);
    console.log('Responses:', error.responses);
  }
}

비디오 모델 (Video Models)

프로바이더 모델 기능
Black Forest Labs flux-3-video 텍스트-투-비디오, 이미지-투-비디오, 키프레임, 비디오 연속, 오디오 생성
FAL luma-dream-machine/ray-2 텍스트-투-비디오, 이미지-투-비디오
FAL minimax-video 텍스트-투-비디오
Google veo-2.0-generate-001 텍스트-투-비디오, 호출당 최대 4개 비디오
Google Vertex veo-3.1-generate-001 텍스트-투-비디오, 오디오 생성
Google Vertex veo-3.1-fast-generate-001 텍스트-투-비디오, 오디오 생성
Google Vertex veo-3.0-generate-001 텍스트-투-비디오, 오디오 생성
Google Vertex veo-3.0-fast-generate-001 텍스트-투-비디오, 오디오 생성
Google Vertex veo-2.0-generate-001 텍스트-투-비디오, 호출당 최대 4개 비디오
Kling AI kling-v2.6-t2v 텍스트-투-비디오
Kling AI kling-v2.6-i2v 이미지-투-비디오
Kling AI kling-v2.6-motion-control 모션 컨트롤
Replicate minimax/video-01 텍스트-투-비디오
xAI grok-imagine-video 텍스트-투-비디오, 이미지-투-비디오, 편집, 확장, R2V
xAI grok-imagine-video-1.5 텍스트-투-비디오, 이미지-투-비디오, 편집, 확장, R2V(참조 오디오 포함)

위는 AI SDK 프로바이더가 지원하는 비디오 모델의 일부일 뿐이에요. 더 많은 내용은 각 프로바이더 문서를 참고하세요.

더 알아보기 (Learn more)