"""Volcano Engine Seedance (ARK) video generation API client.""" import requests from django.conf import settings MODEL_MAP = { 'seedance_2.0': 'doubao-seedance-2-0-260128', 'seedance_2.0_fast': 'doubao-seedance-2-0-fast-260128', } def _headers(): return { 'Content-Type': 'application/json', 'Authorization': f'Bearer {settings.ARK_API_KEY}', } def create_task(prompt, model, content_items, aspect_ratio, duration, generate_audio=True): """Create a video generation task. Args: prompt: Text prompt for video generation. model: Model key ('seedance_2.0' or 'seedance_2.0_fast'). content_items: List of media content dicts (image_url, video_url, audio_url). aspect_ratio: Video aspect ratio ('16:9', '9:16', etc.). duration: Video duration in seconds. generate_audio: Whether to generate audio with the video. Returns: dict: API response with task id and status. """ url = f'{settings.ARK_BASE_URL}/contents/generations/tasks' content = [] if prompt: content.append({'type': 'text', 'text': prompt}) content.extend(content_items) payload = { 'model': MODEL_MAP.get(model, model), 'content': content, 'generate_audio': generate_audio, 'ratio': aspect_ratio, 'duration': duration, 'watermark': False, } resp = requests.post(url, json=payload, headers=_headers(), timeout=60) resp.raise_for_status() return resp.json() def query_task(task_id): """Query a video generation task by its ARK task ID. Returns: dict: Task status, content (video URL on success), usage info. """ url = f'{settings.ARK_BASE_URL}/contents/generations/tasks/{task_id}' resp = requests.get(url, headers=_headers(), timeout=30) resp.raise_for_status() return resp.json() def extract_video_url(task_response): """Extract the video URL from a completed task response.""" content = task_response.get('content') if not content: return None # content could be a list of items or a dict if isinstance(content, list): for item in content: if item.get('type') == 'video_url': return item.get('video_url', {}).get('url') elif isinstance(content, dict): if 'video_url' in content: url = content['video_url'] return url.get('url') if isinstance(url, dict) else url return None def map_status(ark_status): """Map ARK task status to our DB status.""" mapping = { 'running': 'processing', 'submitted': 'queued', 'queued': 'queued', 'succeeded': 'completed', 'failed': 'failed', } return mapping.get(ark_status, 'processing')