> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apimart.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Pembuatan Video Gemini Omni 1.2 Flash

> Video dari teks atau gambar, referensi beberapa subjek, interpolasi frame awal/akhir, pengeditan dan perpanjangan. Hingga 4K, 24fps, dengan audio.

> [!NOTE]
>
> Pembuatan video dari teks atau gambar mendukung bilangan bulat 3–15 detik, dengan default 10. Interpolasi frame awal/akhir dan segmen tambahan pada perpanjangan mendukung maksimal 10 detik. Pengeditan mengabaikan `duration` dan mempertahankan durasi video sumber. Input video secara default diedit; perpanjangan memerlukan `"omni_reference_task_type": "extend"`.

```bash cURL theme={null}
curl --request POST \
  --url https://api.apimart.ai/v1/videos/generations \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "gemini-omni-1.2-flash",
    "prompt": "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
    "aspect_ratio": "16:9",
    "resolution": "720p",
    "duration": 15
  }'
```

```python Python theme={null}
import time
import requests

base_url = "https://api.apimart.ai"
headers = {"Authorization": "Bearer <token>"}
payload = {
    "model": "gemini-omni-1.2-flash",
    "prompt": "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
    "aspect_ratio": "16:9",
    "resolution": "720p",
    "duration": 15,
}
response = requests.post(
    f"{base_url}/v1/videos/generations",
    headers=headers, json=payload, timeout=30,
)
response.raise_for_status()
task_id = response.json()["data"][0]["task_id"]
print(task_id)

deadline = time.monotonic() + 600
while time.monotonic() < deadline:
    response = requests.get(
        f"{base_url}/v1/tasks/{task_id}", headers=headers, timeout=30,
    )
    response.raise_for_status()
    task = response.json()["data"]
    if task["status"] == "completed":
        print(task["result"]["videos"][0]["url"][0])
        break
    if task["status"] == "failed":
        raise RuntimeError(task["error"]["message"])
    time.sleep(5)
else:
    raise TimeoutError(f"Continue polling task {task_id}")
```

```javascript JavaScript theme={null}
const baseUrl = "https://api.apimart.ai";
const headers = {
  Authorization: "Bearer <token>",
  "Content-Type": "application/json",
};
const response = await fetch(`${baseUrl}/v1/videos/generations`, {
  method: "POST",
  headers,
  signal: AbortSignal.timeout(30_000),
  body: JSON.stringify({
    model: "gemini-omni-1.2-flash",
    prompt: "A marble rolling fast on a chain reaction style track, continuous smooth shot.",
    aspect_ratio: "16:9",
    resolution: "720p",
    duration: 15,
  }),
});
if (!response.ok) throw new Error(await response.text());
const taskId = (await response.json()).data[0].task_id;
console.log(taskId);

async function waitForTask(taskId) {
  const deadline = Date.now() + 600_000;
  while (Date.now() < deadline) {
    const response = await fetch(`${baseUrl}/v1/tasks/${taskId}`, {
      headers,
      signal: AbortSignal.timeout(30_000),
    });
    if (!response.ok) throw new Error(await response.text());
    const task = (await response.json()).data;
    if (task.status === "completed") return task.result.videos[0].url[0];
    if (task.status === "failed") throw new Error(task.error.message);
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
  throw new Error(`Continue polling task ${taskId}`);
}
console.log(await waitForTask(taskId));
```

```json 200 theme={null}
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01EXAMPLE"
    }
  ]
}
```

## Autentikasi

**Authorization** `string` *required*

Gunakan autentikasi Bearer Token. Dapatkan kunci di [halaman pengelolaan API Key](https://apimart.ai/keys) dan kirim permintaan dengan `Content-Type: application/json`.

## Parameter permintaan

**model** `string` *required*

Harus `gemini-omni-1.2-flash`.

**prompt** `string` *required*

Instruksi teks wajib: jelaskan adegan untuk teks ke video, atau gerakan, gaya, dan perubahan untuk mode lainnya. `prompt` wajib disertakan meskipun Anda memberikan gambar referensi, frame awal/akhir, video, atau `extend_from_task_id`. Jika dihilangkan, API mengembalikan HTTP 400.

**duration** `integer` (default: 10)

Durasi output untuk pembuatan video dari teks atau gambar, bilangan bulat `3`–`15`, default `10`. Interpolasi frame awal/akhir dan perpanjangan hanya mendukung `3`–`10` detik. Untuk perpanjangan, ini adalah panjang segmen tambahan; video yang dikembalikan mencakup video asli dan segmen tambahan. Pengeditan mengabaikan `duration` dan mempertahankan durasi video sumber. Nilai parameter di luar rentang membuat tugas gagal dengan `invalid_duration`.

**resolution** `string` (default: 720p)

`360p` / `720p` / `1080p` / `4k`, tidak peka huruf besar/kecil; `2160p` dianggap `4k`. `1080p` dan `4k` menggunakan upsampling. Resolusi memengaruhi token output dan saldo yang dicadangkan. Nilai lain membuat tugas gagal dengan `invalid_resolution`.

**aspect\_ratio** `string` (default: 16:9)

Hanya `16:9` (lanskap, default) dan `9:16` (potret). Nilai lain dianggap `16:9`.

**image\_urls** `string[]`

Gambar referensi hanya berupa URL HTTP(S) langsung ke gambar yang dapat diakses publik. Data URL dan Base64 tidak didukung. Satu gambar menjadi frame awal; beberapa gambar menjadi referensi subjek. Maksimal 10 gambar termasuk frame awal/akhir. Untuk karakter, disarankan maksimal 2 karakter dengan hingga 3 gambar per karakter, total tidak lebih dari 6 gambar.

**first\_frame\_image** `string`

Gambar frame awal. Jika digunakan sendiri, video dimulai dari gambar ini; bersama `last_frame_image`, mengaktifkan interpolasi antara frame awal dan akhir. Hanya URL HTTP(S) langsung ke gambar yang dapat diakses publik yang didukung.

**last\_frame\_image** `string`

Gambar frame akhir; memerlukan `first_frame_image`, jika tidak tugas gagal dengan `invalid_frame_images`. Gunakan rasio yang sama untuk kedua gambar dan sesuaikan dengan `aspect_ratio`. Hanya URL HTTP(S) langsung ke gambar yang dapat diakses publik yang didukung.

**image\_with\_roles** `object[]`

Array gambar dengan peran, setara dengan kolom langsung frame awal/akhir. Pilih salah satu cara. Semua gambar yang digunakan dihitung dalam batas total 10.

**Item array**

**url** `string` *required*

Hanya URL HTTP(S) langsung ke gambar yang dapat diakses publik yang didukung.

**role** `string` *required*

`first_frame` adalah frame awal dan `last_frame` adalah frame akhir. Peran lain dianggap referensi. Frame akhir memerlukan frame awal.

**video\_urls** `string[]`

Video untuk diedit atau diperpanjang: maksimal 1 klip dengan durasi paling lama 15 detik. Hanya URL HTTP(S) langsung ke video yang dapat diakses publik yang didukung. Data URL dan Base64 tidak didukung. Input video secara default diedit.

**omni\_reference\_task\_type** `string` (default: auto)

Jenis tugas: `auto` (default, ditentukan dari input) / `edit` (pengeditan) / `extend` (perpanjangan) / `reference` (beberapa gambar referensi). Juga menerima `text_to_video` / `image_to_video` / `reference_to_video`. Jika dihilangkan atau diatur ke `auto`, `video_urls` dan `extend_from_task_id` secara default melakukan pengeditan. Untuk memperpanjang, tetapkan `extend` secara eksplisit.

**extend\_from\_task\_id** `string`

ID tugas pembuatan Anda sebelumnya untuk menggunakan kembali video tanpa mengunggah ulang. Defaultnya adalah pengeditan. Dengan `"omni_reference_task_type": "extend"`, segmen hingga 10 detik ditambahkan di akhir.

## Kemampuan dan batasan

* Output video adalah 24fps dengan dialog, musik, atau efek suara. Jelaskan audio yang diinginkan dalam `prompt`.
* Input audio, system prompt, `temperature`, dan parameter prompt negatif tidak didukung. Tulis hal yang perlu dihindari langsung dalam `prompt`.
* Batasan wilayah penyedia: di EEA, Swiss, dan Inggris, pengeditan atau perpanjangan video yang diunggah serta pengeditan gambar berisi anak di bawah umur tidak didukung.
* Semua output menyertakan watermark SynthID yang tidak terlihat.

## Contoh penggunaan

Kirim setiap JSON ke `POST /v1/videos/generations`. Ganti URL media dan ID tugas contoh dengan input milik Anda yang dapat digunakan.

### Video potret 4K berdurasi 15 detik

```json theme={null}
{
  "model": "gemini-omni-1.2-flash",
  "prompt": "Aerial shot over a misty mountain lake at sunrise, birds flying, slow forward camera move.",
  "aspect_ratio": "9:16",
  "resolution": "4k",
  "duration": 15
}
```

### Gambar ke video dan referensi subjek

```json theme={null}
{
  "model": "gemini-omni-1.2-flash",
  "prompt": "The cat playfully bats at the ball of yarn.",
  "image_urls": [
    "https://example.com/cat.png",
    "https://example.com/yarn.png"
  ],
  "duration": 12
}
```

### Interpolasi frame awal dan akhir

```json theme={null}
{
  "model": "gemini-omni-1.2-flash",
  "prompt": "Smooth transition, camera slowly pushes in.",
  "first_frame_image": "https://example.com/start.jpg",
  "last_frame_image": "https://example.com/end.jpg",
  "aspect_ratio": "16:9",
  "duration": 8
}
```

### Menetapkan frame melalui peran gambar

```json theme={null}
{
  "model": "gemini-omni-1.2-flash",
  "prompt": "A smooth cinematic transition from sunrise to a starry night.",
  "image_with_roles": [
    {
      "url": "https://example.com/sunrise.jpg",
      "role": "first_frame"
    },
    {
      "url": "https://example.com/night.jpg",
      "role": "last_frame"
    }
  ],
  "duration": 8
}
```

### Pengeditan video

```json theme={null}
{
  "model": "gemini-omni-1.2-flash",
  "prompt": "Make the violin invisible. Keep everything else the same.",
  "video_urls": [
    "https://example.com/clip.mp4"
  ]
}
```

Pengeditan mempertahankan durasi video sumber; `duration` tidak berpengaruh.

Gunakan instruksi pengeditan yang singkat dan spesifik. Untuk perubahan sebagian, tambahkan `Keep everything else the same`.

### Memperpanjang tugas sebelumnya

```json theme={null}
{
  "model": "gemini-omni-1.2-flash",
  "prompt": "The camera continues panning across the mountains.",
  "extend_from_task_id": "task_01PREVIOUS",
  "omni_reference_task_type": "extend",
  "duration": 8
}
```

Untuk memperpanjang video yang diunggah, ganti `extend_from_task_id` dengan `video_urls` dan pertahankan `"omni_reference_task_type": "extend"`. Video yang dikembalikan berisi video asli diikuti segmen tambahan. `duration` hanya mengatur durasi tambahan, maksimal 10 detik; biaya hanya dikenakan untuk detik tambahan. Misalnya, video sumber 5 detik dengan `duration: 4` menghasilkan video sekitar 9 detik.

## Respons pengiriman dan status tugas

Pengiriman berhasil mengembalikan HTTP 200; baca `data[0].task_id`. Periksa [status tugas](https://docs.apimart.ai/id/api-reference/tasks/status.md) setiap 5–10 detik hingga `completed` atau `failed`. Disarankan waktu tunggu total 10 menit. Jika klien mengalami timeout, terus periksa tugas awal tanpa mengirim ulang.

```bash theme={null}
curl --request GET \
  --url https://api.apimart.ai/v1/tasks/task_01EXAMPLE \
  --header 'Authorization: Bearer <token>'
```

Perkiraan waktu: video 360p berdurasi 15 detik membutuhkan sekitar 30 detik; video 4K berdurasi 15 detik sekitar 5 menit. Pastikan melalui status tugas.

```json theme={null}
{
  "code": 200,
  "data": {
    "id": "task_01EXAMPLE",
    "status": "completed",
    "progress": 100,
    "result": {
      "videos": [
        {
          "url": [
            "https://cdn.example.com/gemini_omni_video.mp4"
          ]
        }
      ]
    }
  }
}
```

`data` dalam respons status adalah objek tugas. `data.result.videos[0].url` adalah array; URL pertama berada di `data.result.videos[0].url[0]`. Video dapat diputar atau diunduh langsung. Simpan salinan untuk penyimpanan jangka panjang. `data.cost` adalah biaya akhir dalam USD.

| Status | Tindakan |
| - | - |
| `pending` / `processing` | Terus periksa; kemajuan tersedia di `data.progress`. |
| `completed` | Baca URL dan simpan video. |
| `failed` | Baca `data.error.message`. Tugas gagal tidak dikenakan biaya. |

## Penagihan dan saldo cadangan

Penagihan berdasarkan token: resolusi memengaruhi token video output per detik. Untuk pembuatan video dari teks atau gambar, `duration` menentukan durasi output. Pengeditan mengabaikan parameter ini dan mempertahankan durasi video sumber; perpanjangan menggunakannya hanya untuk segmen tambahan. Lihat [harga APIMart](https://apimart.ai/pricing) untuk tarif aktual.

Saat dikirim, saldo dicadangkan berdasarkan resolusi dan `max(10, duration)` detik; jika ada input video, estimasinya 15 detik. Cadangan bukan biaya akhir. Setelah berhasil, jumlah disesuaikan dengan penggunaan aktual; baca `data.cost` untuk biaya akhir.

Perpanjangan hanya ditagih untuk detik tambahan. Tugas gagal tidak dikenakan biaya. Saldo yang tidak mencukupi untuk cadangan menghasilkan HTTP 402.

## Penanganan kesalahan

Kesalahan parameter (`invalid_*` / `unsupported_*`) langsung mengubah tugas menjadi `failed` tanpa biaya. Periksa status meskipun pengiriman berhasil.

| Kesalahan / status | Penyebab dan tindakan |
| - | - |
| `invalid_duration` | `duration` di luar 3–15, atau interpolasi / perpanjangan melebihi 10 detik. Gunakan bilangan bulat dalam rentang. |
| `invalid_task_type` | Nilai `omni_reference_task_type` tidak didukung. Gunakan `auto` / `edit` / `extend` / `reference`; `text_to_video` / `image_to_video` / `reference_to_video` juga diterima. |
| `invalid_resolution` | Gunakan `360p` / `720p` / `1080p` / `4k`; `2160p` juga diterima. |
| `invalid_frame_images` | Hanya frame akhir yang diberikan. Tambahkan frame awal. |
| `unsupported_image_count` | Lebih dari 10 gambar termasuk frame awal/akhir. Kurangi jumlahnya. |
| `unsupported_video_count` | Lebih dari 1 video input. Gunakan satu klip berdurasi maksimal 15 detik. |
| `HTTP 400` | Parameter wajib `prompt` tidak ada. Sertakan instruksi teks meskipun memberikan media. |
| `HTTP 401` | Kunci tidak valid. Periksa Authorization. |
| `HTTP 402` | Saldo tidak cukup untuk cadangan. Isi saldo atau turunkan resolusi. |
| `HTTP 429` | Batas permintaan tercapai. Coba lagi dengan jeda yang meningkat. |
| `status: failed` | Kesalahan penyedia atau penolakan kebijakan konten. Baca `data.error.message` dan sesuaikan permintaan. |

## Pertanyaan umum

### Apakah `prompt` tetap wajib jika saya memberikan gambar atau video?

Ya. Semua mode memerlukan `prompt`, termasuk pembuatan dari gambar, interpolasi frame awal/akhir, pengeditan, perpanjangan, dan penggunaan kembali video melalui `extend_from_task_id`. Jika kolom ini dihilangkan, API mengembalikan HTTP 400.

### Bisakah saya mengirim gambar atau video Base64 secara langsung?

Tidak. `image_urls`, `first_frame_image`, `last_frame_image`, `image_with_roles[].url`, dan `video_urls` hanya menerima URL HTTP(S) langsung yang dapat diakses publik. Jangan mengirim `data:image/...`, `data:video/...`, atau string Base64 mentah.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.