Files
freepik/freepik_cli/api/videos.py
T
valknar 0de3f7d6bc fix: correct per-model video API field names and remove non-existent models
Each video model uses a different image input field:
- kling-o1-pro/std: first_frame (not image)
- kling-elements-pro/std: images (array)
- minimax-hailuo: image, duration fixed at "6"

Also:
- kling-elements requires slug aspect ratios (square_1_1, etc.)
- Remove wan-2.5 and runway-gen4 which return 404

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 18:15:59 +02:00

70 lines
2.1 KiB
Python

"""Video generation API methods."""
from __future__ import annotations
from typing import Any, Optional, Tuple
from freepik_cli.api.client import FreepikClient
from freepik_cli.api.models import (
VIDEO_POST_ENDPOINTS,
VIDEO_STATUS_ENDPOINTS,
VIDEO_IMAGE_FIELDS,
VIDEO_SLUG_ASPECT_RATIO_MODELS,
VideoModel,
get_output_urls,
get_status,
get_task_id,
normalize_aspect_ratio_video,
)
class VideoAPI:
def __init__(self, client: FreepikClient) -> None:
self._client = client
def generate(
self,
model: VideoModel,
image_b64: str,
prompt: Optional[str] = None,
duration: int = 5,
aspect_ratio: str = "16:9",
seed: Optional[int] = None,
) -> str:
"""Submit an image-to-video task. Returns task_id."""
image_field = VIDEO_IMAGE_FIELDS[model]
# kling-elements uses an array; all others use a scalar
if image_field == "images":
payload: dict[str, Any] = {"images": [image_b64]}
else:
payload = {image_field: image_b64}
if prompt:
payload["prompt"] = prompt
# minimax only supports duration=6; clamp silently
effective_duration = duration
if model == VideoModel.MINIMAX_HAILUO:
effective_duration = 6
payload["duration"] = str(effective_duration)
if aspect_ratio:
payload["aspect_ratio"] = normalize_aspect_ratio_video(aspect_ratio, model)
if seed is not None:
payload["seed"] = seed
endpoint = VIDEO_POST_ENDPOINTS[model]
raw = self._client.post(endpoint, json=payload)
return get_task_id(raw)
def get_status(self, model: VideoModel, task_id: str) -> Tuple[str, dict[str, Any]]:
"""Poll status. Returns (status_str, raw_response)."""
endpoint = VIDEO_STATUS_ENDPOINTS[model].format(task_id=task_id)
raw = self._client.get(endpoint)
return get_status(raw), raw
def get_output_urls(self, raw: dict[str, Any]) -> list[str]:
return get_output_urls(raw)