| 1 | import os |
| 2 | |
| 3 | from .api_media import generate_video_api |
| 4 | from .storage import append_artifact, task_output_dir, update_task |
| 5 | from .utils import artifact, copy_input_file, run_blocking, write_json |
| 6 | |
| 7 | |
| 8 | def required_param(params: dict, key: str) -> str: |
| 9 | value = params.get(key) |
| 10 | if not value: |
| 11 | raise ValueError(f"action_transfer pipeline requires {key}") |
| 12 | return str(value) |
| 13 | |
| 14 | |
| 15 | async def run(task_id: str, params: dict) -> tuple[dict, list[dict]]: |
| 16 | output_dir = task_output_dir(task_id) |
| 17 | os.makedirs(output_dir, exist_ok=True) |
| 18 | |
| 19 | prompt = params.get("prompt_text") or params.get("prompt") or "" |
| 20 | image_path = params.get("image_path") or params.get("image_asset") |
| 21 | video_path = params.get("video_path") or params.get("video_asset") |
| 22 | if not prompt.strip(): |
| 23 | raise ValueError("action_transfer requires prompt_text") |
| 24 | if not image_path: |
| 25 | raise ValueError("action_transfer requires image_path") |
| 26 | if not video_path: |
| 27 | raise ValueError("action_transfer requires video_path") |
| 28 | |
| 29 | image_path = copy_input_file(image_path, output_dir, "input_image") |
| 30 | video_path = copy_input_file(video_path, output_dir, "input_video") |
| 31 | final_video_path = os.path.join(output_dir, "final.mp4") |
| 32 | video_model = required_param(params, "video_model") |
| 33 | |
| 34 | update_task(task_id, progress=20, message="Calling action-transfer video API") |
| 35 | await run_blocking( |
| 36 | generate_video_api, |
| 37 | prompt=prompt, |
| 38 | model=video_model, |
| 39 | output_path=final_video_path, |
| 40 | image_path=None, |
| 41 | duration=int(params.get("duration") or 5), |
| 42 | video_ratio=params.get("video_ratio") or "9:16", |
| 43 | first_clip_path=video_path, |
| 44 | reference_image_path=image_path, |
| 45 | negative_prompt=params.get("negative_prompt"), |
| 46 | video_resolution=params.get("video_resolution") or params.get("resolution"), |
| 47 | watermark=params.get("watermark"), |
| 48 | prompt_extend=params.get("prompt_extend"), |
| 49 | ) |
| 50 | |
| 51 | request_path = write_json(os.path.join(output_dir, "request.json"), { |
| 52 | "prompt": prompt, |
| 53 | "image_path": image_path, |
| 54 | "video_path": video_path, |
| 55 | "video_model": video_model, |
| 56 | }) |
| 57 | artifacts = [ |
| 58 | artifact(request_path, "text", "request"), |
| 59 | artifact(image_path, "image", "input_image"), |
| 60 | artifact(video_path, "video", "input_video"), |
| 61 | artifact(final_video_path, "video", "final"), |
| 62 | ] |
| 63 | for item in artifacts: |
| 64 | append_artifact(task_id, item) |
| 65 | return {"video_path": final_video_path, "request_path": request_path}, artifacts |
| 66 |