ModelHargaPerusahaan
500+ API Model AI, Semua Dalam Satu API. Hanya Di CometAPI
API Model
Pengembang
Mulai CepatDokumentasiDasbor API
Perusahaan
Tentang kamiPerusahaan
Sumber Daya
Model AIBlogCatatan PerubahanDukungan
Syarat dan Ketentuan LayananKebijakan Privasi
© 2026 CometAPI · All rights reserved
Home/Models/Doubao/Doubao-Seedance-2-0
D

Doubao-Seedance-2-0

Per Detik:$0.08
Seedance 2.0 adalah model fondasi video multimodal generasi berikutnya dari ByteDance yang berfokus pada pembuatan video naratif sinematik multi-shot. Berbeda dari demo teks-ke-video single-shot, Seedance 2.0 menekankan kontrol berbasis referensi (gambar, klip pendek, audio), konsistensi karakter/gaya yang koheren di seluruh shot, serta sinkronisasi audio/video bawaan — dengan tujuan menjadikan video AI berguna bagi alur kerja kreatif profesional dan pravisualisasi.
Baru
Penggunaan komersial
Ikhtisar
Fitur
Harga
API
Versi

Spesifikasi teknis Doubao Seedance 2.0

ItemDetails
Product familyKeluarga generasi video ByteDance Seedance
CometAPI slugdoubao-seedance-2-0
ProviderByteDance / BytePlus ModelArk
Model typeModel generasi video
Input modalitiesTeks, gambar, audio, video
Reference capacityHingga 9 gambar, 3 klip video, dan 3 klip audio dalam satu permintaan multimodal
Output typeVideo MP4
Output resolution480p, 720p, 1080p
Aspect ratios21:9, 16:9, 4:3, 1:1, 3:4, 9:16
Output duration4–15 detik
API stylePembuatan video berbasis tugas asinkron

Apa itu Doubao Seedance 2.0?

Doubao Seedance 2.0 adalah model generasi video multimodal andalan ByteDance (dirilis pada Februari 2026). Model ini menggunakan arsitektur generasi gabungan audio–video terpadu yang memungkinkan kontrol presisi setingkat sutradara dengan merujuk banyak gambar, klip video, dan berkas audio secara simultan. Model ini unggul dalam menghasilkan video sinematik yang stabil gerakannya dengan sinkronisasi audio native — ideal bagi kreator profesional yang membutuhkan fisika realistis, konsistensi karakter, dan komposisi adegan yang kompleks.

Fitur utama Doubao Seedance 2.0 di CometAPI

  • Generasi multimodal terpadu: Menerima input teks, gambar, audio, dan video dalam satu alur kerja, sehingga pengguna dapat mengarahkan sebuah adegan dengan materi referensi yang lebih kaya dibanding generator berbasis teks saja.
  • Kontrol gaya sutradara: Model ini dirancang untuk mengikuti prompt terkait performa, pencahayaan, bayangan, pergerakan kamera, ritme gerak, dan karakteristik suara.
  • Penyuntingan dan perpanjangan video: Seedance 2.0 tidak terbatas pada generasi tahap pertama; mendukung penyuntingan klip, karakter, aksi, dan alur cerita tertentu, serta perpanjangan maju/mundur.
  • Sinkronisasi audiovisual yang kuat: ByteDance menonjolkan output stereo dua kanal serta sinkronisasi musik latar, suara ambien, dan perilaku sulih suara untuk hasil yang lebih imersif.
  • Keterkendalian tinggi untuk adegan kompleks: Menekankan peningkatan penanganan interaksi kompleks, adegan bergerak, dan kewajaran fisik dibanding Seedance 1.5.
  • Output berorientasi produksi: API mendukung pengaturan rasio, durasi, dan watermark yang dapat dikonfigurasi, sehingga model ini praktis untuk alur kerja konten berulang.

Performa benchmark

ByteDance menyatakan Seedance 2.0 menggunakan evaluasi internal SeedVideoBench-2.0 dan menempati posisi terdepan di dimensi tugas text-to-video, image-to-video, dan multimodal. Model ini meningkatkan kualitas generasi, akurasi fisik, realisme, dan keterkendalian dibanding Seedance 1.5, terutama pada interaksi kompleks dan adegan dengan banyak gerakan.

Mode API Seedance 2.0 dan Seedance 2.0 Fast di CometAPI

ModelNama model di CometAPITerbaik untukPerbedaan utama
Seedance 2.0doubao-seedance-2-0Pembuatan video multimodal berkualitas tertinggiTumpukan referensi terluas dan keterkendalian terkuat di keluarga Seedance 2.0.
Seedance 2.0 fastdoubao-seedance-2-0-fastProduksi lebih cepat saat kualitas dapat sedikit dikorbankanMenurut ByteDance, kemampuannya sama dengan Seedance 2.0, tetapi menghasilkan lebih cepat.
Seedance 1.5 Prodoubao-seedance-1-5-proPembuatan audio–video generasi sebelumnyaSeedance 1.5 Pro diposisikan sebagai model gabungan audio–video native, sedangkan Seedance 2.0 memperluas tumpukan referensi dan penyuntingan multimodal.

Kekuatan dibanding kompetitor:

  • vs Kling 3.0: Kontrol referensi multimodal dan audio native yang lebih baik.
  • vs Sora 2: Presisi referensi dan kemampuan multi-shot lebih unggul; durasi maksimum sedikit lebih rendah.
  • vs Veo 3.1: Lebih unggul dalam konsistensi karakter dan kepatuhan pada prompt untuk alur kerja yang sarat referensi; Veo unggul dalam grading sinematik mentah dan klip yang lebih panjang.

Unggul untuk video berfokus pada manusia dan berorientasi performa.

Coba Seedance 2.0 AI Video Generator di CometAPI

Langkah 1: Langkah 1: Daftar untuk Kunci API

Mulailah langsung di CometAPI Playground untuk mencoba Doubao Seedance 2.0 tanpa penyiapan atau pemrograman. Cukup masuk ke akun CometAPI Anda, buka halaman model doubao-seedance-2-0, unggah gambar referensi, klip video pendek, atau berkas audio Anda, tambahkan prompt deskriptif, dan buat video pratinjau secara instan. Ini adalah cara tercepat untuk memahami bagaimana Seedance 2.0 menangani konsistensi gerak, tampilan karakter, pergerakan kamera, dan sinkronisasi audio native.

Langkah 2: Dapatkan akses API untuk Seedance 2.0 di CometAPI

Buat atau gunakan kunci CometAPI yang sudah ada untuk mengaktifkan akses penuh ke Doubao Seedance 2.0. Setelah masuk, buka bagian API Token di konsol Anda, buat kunci baru, dan salin. Lalu kunjungi halaman detail model Seedance 2.0 dan API doc di CometAPI untuk meninjau parameter yang didukung untuk integrasi ke proyek Anda.

Langkah 3: Kirim permintaan pertama Anda dengan API Seedance 2.0

Gunakan endpoint CometAPI untuk mengirim permintaan pembuatan video pertama Anda dengan prompt teks yang jelas dan berkas referensi opsional (gambar, video, atau audio). Sistem akan memproses tugas secara asinkron, mengembalikan ID tugas, dan menyediakan video MP4 yang dapat diunduh setelah selesai. Anda kemudian dapat menyempurnakan prompt, menyesuaikan pengaturan, dan melakukan skala untuk video pemasaran, konten media sosial, pipeline video otomatis, atau aplikasi kreatif yang didukung oleh Seedance 2.0.

Alur kerja ini memberi Anda percobaan cepat di Playground dan transisi mulus ke penggunaan produksi melalui CometAPI.

Alasan utama memilih Seedance 2.0 di CometAPI

Mengapa menggunakan CometAPI untuk Seedance 2.0

  • Akses langsung melalui API atau Playground
  • Kontrol parameter yang mudah (durasi, resolusi, format)
  • Mendukung alur kerja text-to-video dan image-to-video
  • Penanganan tugas bawaan untuk pembuatan video asinkron

API terpadu dan ramah pengembang

CometAPI menawarkan endpoint yang bersih dan terstandardisasi yang bekerja mulus dengan format bergaya OpenAI yang familier atau endpoint tugas video khusus. Anda mendapatkan pembuatan tugas, polling, dan unduhan MP4 yang sederhana tanpa harus berurusan dengan autentikasi Volcengine yang kompleks atau batasan regional.

Harga hemat biaya

CometAPI biasanya menawarkan tarif per detik yang lebih kompetitif dibanding penyedia langsung, memungkinkan Anda menghasilkan video berkualitas tinggi dalam skala besar untuk pemasaran, media sosial, atau pipeline otomatis tanpa membebani anggaran.

Pengujian cepat dengan Playground

Bereksperimenlah segera di CometAPI Playground. Unggah gambar, video, dan berkas audio referensi, sesuaikan prompt, dan pratinjau hasil dalam hitungan menit — sempurna untuk iterasi gaya, gerak, dan sinkronisasi audio sebelum masuk produksi.

Singkatnya, jika Anda menginginkan kekuatan kreatif Seedance 2.0 — kontrol referensi terbaik di kelasnya, gerakan yang natural, dan audio native — tanpa repot mengakses langsung ByteDance, CometAPI saat ini adalah salah satu platform terbaik untuk menggunakannya.

FAQ

What kinds of inputs does Seedance 2.0 support for video generation?

Seedance 2.0 mendukung masukan multimodal termasuk prompt teks, hingga 9 gambar, hingga 3 klip video pendek, dan hingga 3 file audio, yang dapat dikombinasikan secara bebas untuk pembuatan yang kaya dan terkontrol.

Can Seedance 2.0 maintain character and style consistency across multiple video shots?

Ya — Seedance 2.0 dirancang untuk penceritaan multi-shot yang koheren dengan karakter, gaya visual, dan atmosfer yang konsisten di seluruh adegan, sehingga mengurangi masalah drift video AI yang umum.

What outputs and quality levels can I expect from Seedance 2.0 videos?

Seedance 2.0 dapat menghasilkan video kelas sinematik (hingga resolusi 2K) dengan audio asli, dialog yang tersinkronisasi, dan sintesis gerak yang alami, biasanya dalam klip berdurasi 5–60 detik.

How does Seedance 2.0 handle audio and lip synchronization?

Model ini menghasilkan audio dan video secara bersamaan, menyediakan sinkronisasi audio-visual asli dengan sinkronisasi bibir pada tingkat fonem dalam 8+ bahasa untuk ucapan dan efek suara yang alami.

Is Seedance 2.0 suitable for professional creative projects like marketing or narrative shorts?

Ya — kontrol multimodal, kontinuitas multi-shot, dan keluaran fidelitas tinggi dari Seedance 2.0 membuatnya cocok untuk video pemasaran, film pendek naratif, iklan, dan aplikasi profesional lainnya.

How do referencing assets (images, video clips) work in Seedance 2.0 prompts?

Pengguna dapat mengunggah aset referensi lalu menjelaskan dengan bahasa alami bagaimana masing-masing harus memengaruhi gerakan, pergerakan kamera, atau elemen gaya, sehingga memberikan kontrol yang sangat terperinci terhadap konten yang dihasilkan.

Does Seedance 2.0 allow editing and extension of existing videos?

Ya — model ini mendukung perpanjangan video dan pengeditan terarah seperti menambahkan adegan, mengganti karakter, atau mengubah segmen tertentu sambil mempertahankan bagian yang tidak diedit.

What are known limitations or typical generation lengths with Seedance 2.0?

Panjang keluaran yang umum berkisar dari ~5 hingga ~60 detik per video, dan menggabungkan banyak aset atau pengaturan beresolusi tinggi dapat meningkatkan waktu pembuatan.

Fitur untuk Doubao-Seedance-2-0

Jelajahi fitur-fitur utama dari Doubao-Seedance-2-0, yang dirancang untuk meningkatkan performa dan kegunaan. Temukan bagaimana kemampuan-kemampuan ini dapat menguntungkan proyek Anda dan meningkatkan pengalaman pengguna.

Harga untuk Doubao-Seedance-2-0

Jelajahi harga kompetitif untuk Doubao-Seedance-2-0, dirancang untuk berbagai anggaran dan kebutuhan penggunaan. Paket fleksibel kami memastikan Anda hanya membayar untuk apa yang Anda gunakan, memudahkan untuk meningkatkan skala seiring berkembangnya kebutuhan Anda. Temukan bagaimana Doubao-Seedance-2-0 dapat meningkatkan proyek Anda sambil menjaga biaya tetap terkendali.

doubao-seedance Video Generation Pricing

Parameters

ParameterDescription
Duration (seconds)4–15 seconds, default 5 seconds
Aspect Ratio (size)21:9 / 16:9 / 4:3 / 1:1 / 3:4 / 9:16, default 16:9
Resolution480p / 720p / 1080p*, default 720p

*1080p only available for doubao-seedance-1-5-pro and doubao-seedance-1-0-pro

Pricing (Per Second)

Model480p720p1080p
doubao-seedance-2-0$0.08$0.24—
doubao-seedance-2-0-fast$0.064$0.192—
doubao-seedance-1-5-pro$0.018$0.04147$0.09331
doubao-seedance-1-0-pro$0.01875$0.0432$0.0972

💡 Billed per second. Total cost = price per second × video duration (seconds). Duration range: 4–15 seconds.

Kode contoh dan API untuk Doubao-Seedance-2-0

Akses kode sampel komprehensif dan sumber daya API untuk Doubao-Seedance-2-0 guna mempermudah proses integrasi Anda. Dokumentasi terperinci kami menyediakan panduan langkah demi langkah, membantu Anda memanfaatkan potensi penuh Doubao-Seedance-2-0 dalam proyek Anda.
POST
/v1/videos
Python
JavaScript
Curl
import json
import os
import time

import requests

# Get your CometAPI key from https://www.cometapi.com/console/token, and paste it here
COMETAPI_KEY = os.environ.get("COMETAPI_KEY") or "<YOUR_COMETAPI_KEY>"
BASE_URL = "https://api.cometapi.com"
OUTPUT_DIR = "./output"
POLL_INTERVAL_SECONDS = 10
RETRY_DELAY_SECONDS = 5
MAX_CREATE_ATTEMPTS = 5
MAX_QUERY_ATTEMPTS = 3
TERMINAL_STATUSES = {"success", "completed", "failed", "error"}
SUCCESS_STATUSES = {"success", "completed"}

def is_progress_complete(progress):
    if isinstance(progress, int):
        return progress >= 100
    if isinstance(progress, float):
        return progress >= 100
    if isinstance(progress, str):
        try:
            return float(progress.rstrip("%")) >= 100
        except ValueError:
            return False
    return False

def is_transient_status(status_code):
    return status_code == 429 or 500 <= status_code < 600

def create_task(files):
    for attempt in range(1, MAX_CREATE_ATTEMPTS + 1):
        response = requests.post(
            f"{BASE_URL}/v1/videos",
            headers=headers,
            files=files,
            timeout=30,
        )
        if response.ok:
            return response
        if not is_transient_status(response.status_code) or attempt == MAX_CREATE_ATTEMPTS:
            response.raise_for_status()
        print(f"Create request returned {response.status_code}, retrying...")
        time.sleep(RETRY_DELAY_SECONDS)

    raise SystemExit("Failed to create task.")

def get_task(task_id):
    for attempt in range(1, MAX_QUERY_ATTEMPTS + 1):
        response = requests.get(
            f"{BASE_URL}/v1/videos/{task_id}",
            headers=headers,
            timeout=15,
        )
        if response.ok:
            return response
        if not is_transient_status(response.status_code) or attempt == MAX_QUERY_ATTEMPTS:
            response.raise_for_status()
        print(f"Status request returned {response.status_code}, retrying...")
        time.sleep(RETRY_DELAY_SECONDS)

    raise SystemExit("Failed to query task.")

if COMETAPI_KEY == "<YOUR_COMETAPI_KEY>":
    print("Set COMETAPI_KEY before running this example.")
    raise SystemExit(0)

headers = {"Authorization": f"Bearer {COMETAPI_KEY}"}

create_response = create_task(
    {
        "prompt": (None, "A slow cinematic camera push across a coastal landscape at sunrise."),
        "model": (None, "doubao-seedance-2-0"),
        "seconds": (None, "5"),
        "size": (None, "16:9"),
        "resolution": (None, "720p"),
    }
)
create_response.raise_for_status()
create_result = create_response.json()

task_id = create_result.get("id") or create_result.get("task_id")
if not task_id:
    print(json.dumps(create_result, indent=2))
    raise SystemExit("No task id returned.")

print(f"Task created: {task_id}")
print(f"Initial status: {create_result.get('status')}")

while True:
    task_response = get_task(task_id)
    task_response.raise_for_status()
    task = task_response.json()
    status = str(task.get("status") or "unknown")
    normalized_status = status.lower()
    progress = task.get("progress")
    should_try_download = normalized_status in SUCCESS_STATUSES or (
        normalized_status == "unknown" and is_progress_complete(progress)
    )

    print(f"Status: {status}, progress: {progress}")

    if should_try_download or normalized_status in TERMINAL_STATUSES:
        if should_try_download:
            video_url = task.get("video_url") or ""
            content_url = f"{BASE_URL}/v1/videos/{task_id}/content"
            output_path = os.path.join(OUTPUT_DIR, f"{task_id}.mp4")

            os.makedirs(OUTPUT_DIR, exist_ok=True)
            with requests.get(
                content_url,
                headers=headers,
                timeout=120,
                stream=True,
            ) as video_response:
                video_response.raise_for_status()
                with open(output_path, "wb") as output_file:
                    for chunk in video_response.iter_content(chunk_size=8192):
                        if chunk:
                            output_file.write(chunk)

            print(f"Video URL: {video_url}")
            print(f"Content endpoint: {content_url}")
            print(f"Saved to {output_path}")
            print(f"File size: {os.path.getsize(output_path)} bytes")
        else:
            print(json.dumps(task, indent=2))
            raise SystemExit(1)
        break

    time.sleep(POLL_INTERVAL_SECONDS)

Python Code Example

import json
import os
import time

import requests

# Get your CometAPI key from https://www.cometapi.com/console/token, and paste it here
COMETAPI_KEY = os.environ.get("COMETAPI_KEY") or "<YOUR_COMETAPI_KEY>"
BASE_URL = "https://api.cometapi.com"
OUTPUT_DIR = "./output"
POLL_INTERVAL_SECONDS = 10
RETRY_DELAY_SECONDS = 5
MAX_CREATE_ATTEMPTS = 5
MAX_QUERY_ATTEMPTS = 3
TERMINAL_STATUSES = {"success", "completed", "failed", "error"}
SUCCESS_STATUSES = {"success", "completed"}


def is_progress_complete(progress):
    if isinstance(progress, int):
        return progress >= 100
    if isinstance(progress, float):
        return progress >= 100
    if isinstance(progress, str):
        try:
            return float(progress.rstrip("%")) >= 100
        except ValueError:
            return False
    return False


def is_transient_status(status_code):
    return status_code == 429 or 500 <= status_code < 600


def create_task(files):
    for attempt in range(1, MAX_CREATE_ATTEMPTS + 1):
        response = requests.post(
            f"{BASE_URL}/v1/videos",
            headers=headers,
            files=files,
            timeout=30,
        )
        if response.ok:
            return response
        if not is_transient_status(response.status_code) or attempt == MAX_CREATE_ATTEMPTS:
            response.raise_for_status()
        print(f"Create request returned {response.status_code}, retrying...")
        time.sleep(RETRY_DELAY_SECONDS)

    raise SystemExit("Failed to create task.")


def get_task(task_id):
    for attempt in range(1, MAX_QUERY_ATTEMPTS + 1):
        response = requests.get(
            f"{BASE_URL}/v1/videos/{task_id}",
            headers=headers,
            timeout=15,
        )
        if response.ok:
            return response
        if not is_transient_status(response.status_code) or attempt == MAX_QUERY_ATTEMPTS:
            response.raise_for_status()
        print(f"Status request returned {response.status_code}, retrying...")
        time.sleep(RETRY_DELAY_SECONDS)

    raise SystemExit("Failed to query task.")

if COMETAPI_KEY == "<YOUR_COMETAPI_KEY>":
    print("Set COMETAPI_KEY before running this example.")
    raise SystemExit(0)

headers = {"Authorization": f"Bearer {COMETAPI_KEY}"}

create_response = create_task(
    {
        "prompt": (None, "A slow cinematic camera push across a coastal landscape at sunrise."),
        "model": (None, "doubao-seedance-2-0"),
        "seconds": (None, "5"),
        "size": (None, "16:9"),
        "resolution": (None, "720p"),
    }
)
create_response.raise_for_status()
create_result = create_response.json()

task_id = create_result.get("id") or create_result.get("task_id")
if not task_id:
    print(json.dumps(create_result, indent=2))
    raise SystemExit("No task id returned.")

print(f"Task created: {task_id}")
print(f"Initial status: {create_result.get('status')}")

while True:
    task_response = get_task(task_id)
    task_response.raise_for_status()
    task = task_response.json()
    status = str(task.get("status") or "unknown")
    normalized_status = status.lower()
    progress = task.get("progress")
    should_try_download = normalized_status in SUCCESS_STATUSES or (
        normalized_status == "unknown" and is_progress_complete(progress)
    )

    print(f"Status: {status}, progress: {progress}")

    if should_try_download or normalized_status in TERMINAL_STATUSES:
        if should_try_download:
            video_url = task.get("video_url") or ""
            content_url = f"{BASE_URL}/v1/videos/{task_id}/content"
            output_path = os.path.join(OUTPUT_DIR, f"{task_id}.mp4")

            os.makedirs(OUTPUT_DIR, exist_ok=True)
            with requests.get(
                content_url,
                headers=headers,
                timeout=120,
                stream=True,
            ) as video_response:
                video_response.raise_for_status()
                with open(output_path, "wb") as output_file:
                    for chunk in video_response.iter_content(chunk_size=8192):
                        if chunk:
                            output_file.write(chunk)

            print(f"Video URL: {video_url}")
            print(f"Content endpoint: {content_url}")
            print(f"Saved to {output_path}")
            print(f"File size: {os.path.getsize(output_path)} bytes")
        else:
            print(json.dumps(task, indent=2))
            raise SystemExit(1)
        break

    time.sleep(POLL_INTERVAL_SECONDS)

JavaScript Code Example

import fs from "fs";
import path from "path";

// Get your CometAPI key from https://www.cometapi.com/console/token, and paste it here
const api_key = process.env.COMETAPI_KEY || "<YOUR_COMETAPI_KEY>";
const base_url = "https://api.cometapi.com";
const output_dir = "./output";
const poll_interval_ms = 10_000;
const retry_delay_ms = 5_000;
const max_create_attempts = 5;
const max_query_attempts = 3;
const terminal_statuses = new Set(["success", "completed", "failed", "error"]);
const success_statuses = new Set(["success", "completed"]);

function is_progress_complete(progress) {
  if (typeof progress === "number") {
    return progress >= 100;
  }

  if (typeof progress === "string") {
    const numeric = Number(progress.replace(/%$/, ""));
    return Number.isFinite(numeric) && numeric >= 100;
  }

  return false;
}

function is_transient_status(status) {
  return status === 429 || status >= 500;
}

async function fetch_with_retry(url, options, attempts, label) {
  for (let attempt = 1; attempt <= attempts; attempt += 1) {
    const response = await fetch(url, options);
    if (response.ok) {
      return response;
    }

    if (!is_transient_status(response.status) || attempt === attempts) {
      return response;
    }

    console.log(`${label} returned ${response.status}, retrying...`);
    await new Promise((resolve) => setTimeout(resolve, retry_delay_ms));
  }

  throw new Error(`${label} failed`);
}

if (api_key === "<YOUR_COMETAPI_KEY>") {
  console.log("Set COMETAPI_KEY before running this example.");
  process.exit(0);
}

const headers = {
  Authorization: `Bearer ${api_key}`,
};

const form = new FormData();
form.set("prompt", "A slow cinematic camera push across a coastal landscape at sunrise.");
form.set("model", "doubao-seedance-2-0");
form.set("seconds", "5");
form.set("size", "16:9");
form.set("resolution", "720p");

const create_response = await fetch_with_retry(`${base_url}/v1/videos`, {
  method: "POST",
  headers,
  body: form,
}, max_create_attempts, "Create request");

if (!create_response.ok) {
  console.log(await create_response.text());
  process.exit(1);
}

const create_result = await create_response.json();
const task_id = create_result.id || create_result.task_id;

if (!task_id) {
  console.log(JSON.stringify(create_result, null, 2));
  process.exit(1);
}

console.log(`Task created: ${task_id}`);
console.log(`Initial status: ${create_result.status}`);

while (true) {
  const task_response = await fetch_with_retry(`${base_url}/v1/videos/${task_id}`, {
    headers,
  }, max_query_attempts, "Status request");

  if (!task_response.ok) {
    console.log(await task_response.text());
    process.exit(1);
  }

  const task = await task_response.json();
  const status = String(task.status || "unknown");
  const normalized_status = status.toLowerCase();
  const progress = task.progress;
  const should_try_download = success_statuses.has(normalized_status) || (
    normalized_status === "unknown" && is_progress_complete(progress)
  );

  console.log(`Status: ${status}, progress: ${progress}`);

  if (should_try_download || terminal_statuses.has(normalized_status)) {
    if (should_try_download) {
      const video_url = task.video_url || "";
      const content_url = `${base_url}/v1/videos/${task_id}/content`;
      const output_path = path.join(output_dir, `${task_id}.mp4`);

      if (!fs.existsSync(output_dir)) {
        fs.mkdirSync(output_dir, { recursive: true });
      }

      const video_response = await fetch(content_url, { headers });
      if (!video_response.ok) {
        console.log(await video_response.text());
        process.exit(1);
      }

      const video_buffer = Buffer.from(await video_response.arrayBuffer());
      fs.writeFileSync(output_path, video_buffer);

      console.log(`Video URL: ${video_url}`);
      console.log(`Content endpoint: ${content_url}`);
      console.log(`Saved to ${output_path}`);
      console.log(`File size: ${fs.statSync(output_path).size} bytes`);
    } else {
      console.log(JSON.stringify(task, null, 2));
      process.exit(1);
    }
    break;
  }

  await new Promise((resolve) => setTimeout(resolve, poll_interval_ms));
}

Curl Code Example

#!/bin/bash

set -euo pipefail

# Get your CometAPI key from https://www.cometapi.com/console/token
# Export it as: export COMETAPI_KEY="your-key-here"

if [[ -z "${COMETAPI_KEY:-}" ]]; then
  echo "Set COMETAPI_KEY before running this example."
  exit 0
fi

BASE_URL="https://api.cometapi.com"
OUTPUT_DIR="./output"
POLL_INTERVAL_SECONDS=10
RETRY_DELAY_SECONDS=5
MAX_CREATE_ATTEMPTS=5
MAX_QUERY_ATTEMPTS=3

is_progress_complete() {
  local progress="$1"
  local normalized="${progress%%%}"

  if [[ -z "$normalized" ]]; then
    return 1
  fi

  [[ "$normalized" =~ ^[0-9]+([.][0-9]+)?$ ]] || return 1
  awk -v value="$normalized" 'BEGIN { exit !(value >= 100) }'
}

create_task() {
  local attempt=1
  while (( attempt <= MAX_CREATE_ATTEMPTS )); do
    local response
    local status_code
    response=$(curl -sS -w $'\n%{http_code}' "${BASE_URL}/v1/videos" \
      -H "Authorization: Bearer $COMETAPI_KEY" \
      -F 'prompt="A slow cinematic camera push across a coastal landscape at sunrise."' \
      -F 'model="doubao-seedance-2-0"' \
      -F 'seconds="5"' \
      -F 'size="16:9"' \
      -F 'resolution="720p"')

    status_code=$(echo "$response" | tail -n 1)
    CREATE_RESPONSE=$(echo "$response" | sed '$d')

    if [[ "$status_code" =~ ^2 ]]; then
      return 0
    fi

    if [[ "$status_code" == "429" || "$status_code" =~ ^5 ]] && (( attempt < MAX_CREATE_ATTEMPTS )); then
      echo "Create request returned ${status_code}, retrying..."
      sleep "$RETRY_DELAY_SECONDS"
      (( attempt += 1 ))
      continue
    fi

    echo "$CREATE_RESPONSE"
    return 1
  done
}

get_task() {
  local task_id="$1"
  local attempt=1
  while (( attempt <= MAX_QUERY_ATTEMPTS )); do
    local response
    local status_code
    response=$(curl -sS -w $'\n%{http_code}' "${BASE_URL}/v1/videos/${task_id}" \
      -H "Authorization: Bearer $COMETAPI_KEY")

    status_code=$(echo "$response" | tail -n 1)
    TASK_RESPONSE=$(echo "$response" | sed '$d')

    if [[ "$status_code" =~ ^2 ]]; then
      return 0
    fi

    if [[ "$status_code" == "429" || "$status_code" =~ ^5 ]] && (( attempt < MAX_QUERY_ATTEMPTS )); then
      echo "Status request returned ${status_code}, retrying..."
      sleep "$RETRY_DELAY_SECONDS"
      (( attempt += 1 ))
      continue
    fi

    echo "$TASK_RESPONSE"
    return 1
  done
}

create_task

TASK_ID=$(echo "$CREATE_RESPONSE" | jq -r '.id // .task_id // empty')

if [[ -z "$TASK_ID" ]]; then
  echo "$CREATE_RESPONSE" | jq .
  echo "No task id returned."
  exit 1
fi

echo "Task created: $TASK_ID"
echo "Initial status: $(echo "$CREATE_RESPONSE" | jq -r '.status // empty')"

while true; do
  get_task "$TASK_ID"

  STATUS=$(echo "$TASK_RESPONSE" | jq -r '.status // empty')
  NORMALIZED_STATUS=$(echo "$STATUS" | tr '[:upper:]' '[:lower:]')
  PROGRESS=$(echo "$TASK_RESPONSE" | jq -r '.progress // empty')
  SHOULD_TRY_DOWNLOAD=0

  if [[ "$NORMALIZED_STATUS" == "success" || "$NORMALIZED_STATUS" == "completed" ]]; then
    SHOULD_TRY_DOWNLOAD=1
  elif [[ "$NORMALIZED_STATUS" == "unknown" ]] && is_progress_complete "$PROGRESS"; then
    SHOULD_TRY_DOWNLOAD=1
  fi

  echo "Status: ${STATUS}, progress: ${PROGRESS}"

  if [[ "$SHOULD_TRY_DOWNLOAD" == "1" || "$NORMALIZED_STATUS" == "failed" || "$NORMALIZED_STATUS" == "error" ]]; then
    if [[ "$SHOULD_TRY_DOWNLOAD" == "1" ]]; then
      VIDEO_URL=$(echo "$TASK_RESPONSE" | jq -r '.video_url // empty')
      CONTENT_URL="${BASE_URL}/v1/videos/${TASK_ID}/content"
      OUTPUT_PATH="${OUTPUT_DIR}/${TASK_ID}.mp4"

      mkdir -p "$OUTPUT_DIR"
      curl -fsS "$CONTENT_URL" \
        -H "Authorization: Bearer $COMETAPI_KEY" \
        -o "$OUTPUT_PATH"

      if [[ ! -s "$OUTPUT_PATH" ]]; then
        echo "Failed to download video"
        exit 1
      fi

      echo "Video URL: ${VIDEO_URL}"
      echo "Content endpoint: ${CONTENT_URL}"
      echo "Saved to ${OUTPUT_PATH}"
      echo "File size: $(wc -c < "$OUTPUT_PATH" | tr -d ' ') bytes"
    else
      echo "$TASK_RESPONSE" | jq .
      exit 1
    fi
    break
  fi

  sleep "$POLL_INTERVAL_SECONDS"
done

Versi Doubao-Seedance-2-0

Alasan Doubao-Seedance-2-0 memiliki beberapa _snapshot_ mungkin mencakup faktor-faktor potensial seperti variasi keluaran setelah pembaruan yang memerlukan _snapshot_ lama untuk konsistensi, memberikan masa transisi bagi pengembang untuk beradaptasi dan bermigrasi, serta _snapshot_ berbeda yang sesuai dengan _endpoint_ global atau regional untuk mengoptimalkan pengalaman pengguna. Untuk perbedaan detail antar versi, silakan merujuk ke dokumentasi resmi.
version
doubao-seedance-2-0
doubao-seedance-2-0-fast

Model Lainnya

O

Sora 2 Pro

Per Detik:$0.24
Sora 2 Pro adalah model pembuatan media kami yang paling canggih dan kuat, mampu menghasilkan video dengan audio tersinkronisasi. Model ini dapat membuat klip video yang detail dan dinamis dari bahasa alami atau gambar.
O

Sora 2

Per Detik:$0.08
Model generasi video yang sangat canggih, dengan efek suara, mendukung format chat.
M

mj_fast_video

Per Permintaan:$0.6
Midjourney video generation
X

Grok Imagine Video

Per Detik:$0.04
Hasilkan video dari prompt teks, animasikan gambar statis, atau sunting video yang sudah ada dengan bahasa alami. API mendukung durasi, rasio aspek, dan resolusi yang dapat dikonfigurasi untuk video yang dihasilkan — dengan SDK yang secara otomatis menangani polling asinkron.
G

Veo 3.1 Pro

Per Detik:$0.25
Veo 3.1-Pro mengacu pada akses/konfigurasi berkemampuan tinggi dari keluarga Veo 3.1 milik Google — sebuah generasi model video berformat pendek yang mendukung audio dan menambahkan audio bawaan yang lebih kaya, kontrol narasi/penyuntingan yang ditingkatkan, serta alat perluasan adegan.
G

Veo 3.1

Per Detik:$0.05
Veo 3.1 adalah pembaruan dari Google yang bertahap namun signifikan untuk keluarga Veo teks-dan-gambar→video, menambahkan audio bawaan yang lebih kaya, keluaran video yang lebih panjang dan lebih dapat dikendalikan, serta pengeditan yang lebih presisi dan kontrol pada tingkat adegan.

Blog Terkait

Cara menggunakan API Seedance 2.0
Apr 17, 2026

Cara menggunakan API Seedance 2.0

Seedance 2.0 API adalah model AI multimodal terbaru dari ByteDance untuk pembuatan video (diluncurkan pada 9 April 2026). Model ini menerima teks, gambar, klip video, dan audio dalam satu permintaan untuk menghasilkan video MP4 sinematik berdurasi 4–15 detik dengan sinkronisasi audio asli, kontrol kamera setingkat sutradara, dan konsistensi gerak yang luar biasa. Untuk menggunakannya: daftar di CometAPI.com, dapatkan kunci API, kirim tugas asinkron melalui REST, lakukan polling hingga selesai, dan unduh URL video.
Apa itu HappyHorse-1.0? Bagaimana cara membandingkan Seedance 2.0?
Apr 11, 2026
seedance-2-0

Apa itu HappyHorse-1.0? Bagaimana cara membandingkan Seedance 2.0?

Pelajari apa itu HappyHorse-1.0, mengapa ia berhasil menduduki puncak papan peringkat video Artificial Analysis, bagaimana perbandingannya dengan Seedance 2.0, dan apa arti peringkat terbaru bagi generasi video AI.
Apa itu Seedance 2.0? Analisis Komprehensif
Mar 24, 2026
seedance-2-0

Apa itu Seedance 2.0? Analisis Komprehensif

Seedance 2.0 adalah model AI generasi berikutnya untuk generasi video multimodal yang dikembangkan oleh ByteDance, yang dapat menghasilkan video sinematik berkualitas tinggi dari teks, gambar, audio, dan video referensi. Model ini menghadirkan generasi audio-video terpadu, kestabilan gerakan, serta pengeditan berbasis referensi, dan dengan cepat menanjak di tolok ukur global seperti Artificial Analysis leaderboard, menempatkannya di antara model video AI teratas pada tahun 2026.