Sora 2 API 종료 D-6: Veo 3.1·Seedance 2.5 갈아타기 어댑터 코드 2종

Sora 2 API가 2026년 9월 24일에 완전히 종료됩니다. 이 글을 쓰는 오늘 기준으로 D-6입니다. 종료 후에는 모든 영상 생성 요청이 410 Gone 에러를 반환하니, 아직 Sora 2 API를 호출하는 파이프라인이 있다면 이번 주말이 사실상 마지막 작업 시간입니다. 전체 이전 전략은 이전 가이드 5단계에서 다뤘고, 오늘은 그 후속편으로 실제로 붙여넣어 쓸 수 있는 어댑터 코드를 정리합니다. 대상은 Google Veo 3.1(Gemini API)과 Seedance 2.5(fal.ai) 두 경로입니다.

핵심은 어댑터 한 장입니다

영상 생성 API는 어디든 구조가 같습니다. 요청 제출 → 작업 ID 수신 → 완료까지 폴링 → 결과 파일 다운로드. 이 비동기 잡 패턴만 인터페이스로 묶어두면, 엔진이 또 바뀌어도 어댑터 파일 하나만 갈아끼우면 됩니다. 먼저 공통 인터페이스부터 만듭니다.

# video_engine.py
from abc import ABC, abstractmethod

class VideoEngine(ABC):
    @abstractmethod
    def generate(self, prompt: str, duration: int = 8,
                 resolution: str = "720p", out_path: str = "out.mp4") -> str:
        """영상을 생성하고 저장된 파일 경로를 반환"""

기존 코드에서 Sora를 직접 호출하던 부분을 전부 이 인터페이스 뒤로 숨기는 것이 이번 작업의 전부입니다.

경로 1: Google Veo 3.1 (Gemini API)

google-genai 파이썬 SDK를 쓰면 폴링까지 깔끔하게 처리됩니다. 모델 ID는 veo-3.1-generate-preview이고, 빠르고 저렴한 Fast·Lite 변형도 있습니다.

# pip install google-genai
import time
from google import genai
from google.genai import types

class VeoEngine(VideoEngine):
    def __init__(self):
        self.client = genai.Client()  # GEMINI_API_KEY 환경변수 사용

    def generate(self, prompt, duration=8, resolution="720p", out_path="out.mp4"):
        op = self.client.models.generate_videos(
            model="veo-3.1-generate-preview",
            prompt=prompt,
            config=types.GenerateVideosConfig(
                aspect_ratio="16:9",
                resolution=resolution,  # 720p / 1080p / 4k
            ),
        )
        while not op.done:
            time.sleep(10)
            op = self.client.operations.get(op)
        video = op.response.generated_videos[0]
        self.client.files.download(file=video.video, destination=out_path)
        return out_path

주의할 점: Veo 3.1은 클립 길이가 4·6·8초로 제한되고, 1080p 이상은 8초에서만 됩니다. 오디오는 기본 포함이며 끌 수 없습니다. Sora에서 10초 이상 클립을 뽑던 워크플로우라면 영상 연장(extension) 기능을 쓰거나 아래 Seedance 경로가 맞습니다.

경로 2: Seedance 2.5 (fal.ai)

한 클립을 길게 뽑아야 한다면 Seedance 2.5가 답입니다. 최대 30초까지 네이티브로 생성되고 오디오도 요금에 포함돼 있습니다. fal.ai의 큐 API는 표준 REST라서 SDK 없이 requests만으로 됩니다.

import os, time, requests

FAL_KEY = os.environ["FAL_KEY"]
MODEL = "bytedance/seedance-2.5/text-to-video"

class SeedanceEngine(VideoEngine):
    def generate(self, prompt, duration=10, resolution="720p", out_path="out.mp4"):
        headers = {"Authorization": "Key " + FAL_KEY}
        r = requests.post(
            "https://queue.fal.run/" + MODEL,
            headers=headers,
            json={
                "prompt": prompt,
                "duration": str(duration),   # "4"~"30"
                "resolution": resolution,    # 480p / 720p
                "aspect_ratio": "16:9",
                "generate_audio": True,
            },
        ).json()
        status_url = r["status_url"]
        while True:
            s = requests.get(status_url, headers=headers).json()
            if s["status"] == "COMPLETED":
                break
            time.sleep(5)
        result = requests.get(r["response_url"], headers=headers).json()
        video_url = result["video"]["url"]
        with open(out_path, "wb") as f:
            f.write(requests.get(video_url).content)
        return out_path

요금은 토큰제입니다. 2026년 9월 기준 fal 공식 페이지 기준 1,000토큰당 $0.0214로, 720p 5초 클립이 약 $2.31입니다. 해상도가 네이티브 480p·720p까지라서, 1080p가 필요하면 생성 후 업스케일로 올리는 구성이 일반적입니다.

갈아탈 때 걸리는 차이 3가지

1. 클립 길이

Veo 3.1은 최대 8초, Seedance 2.5는 최대 30초입니다. 쇼츠용 컷 편집 파이프라인이라면 8초로도 충분하지만, 한 씬을 길게 이어가는 드라마형 콘텐츠는 Seedance 쪽이 편집 공수를 크게 줄여줍니다.

2. 해상도 정책

Veo는 4K까지 네이티브 지원, Seedance는 720p까지입니다. 업스케일 단계를 파이프라인에 넣을지가 여기서 갈립니다.

3. 요금 구조

Veo는 초당 과금, Seedance(fal)는 토큰제입니다. 같은 분량이라도 해상도·길이 조합에 따라 비용이 뒤집히니, 엔진별 초당 환산 비용은 가격 비교 글의 계산 방식으로 본인 워크로드 기준으로 한 번 뽑아보시길 권합니다.

오늘 할 일

거창한 마이그레이션 프로젝트가 아니라, 위의 video_engine.py 한 장을 만들고 기존 코드의 Sora 호출부를 VideoEngine 인터페이스로 바꾼 뒤, 두 어댑터 중 하나로 짧은 스모크 테스트 영상 1개를 뽑아보는 것까지가 오늘 분량입니다. 9월 24일 아침에 410 에러 알림을 받고 시작하는 것보다, 오늘 30분이 훨씬 쌉니다.

Leave a Comment