返回 VideoClaw
action_transfer.py
根目录 / video-claw / video-claw / backend / pipelines / action_transfer.py
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
66 lines PYTHON