Skip to content

Commit caab292

Browse files
committed
implement LtxvEditVideo API node
1 parent 35fa091 commit caab292

File tree

1 file changed

+85
-4
lines changed

1 file changed

+85
-4
lines changed

comfy_api_nodes/nodes_ltxv.py

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
from pydantic import BaseModel, Field
66
from typing_extensions import override
77

8-
from comfy_api.input_impl import VideoFromFile
9-
from comfy_api.latest import IO, ComfyExtension
8+
from comfy_api.latest import IO, ComfyExtension, Input, InputImpl
109
from comfy_api_nodes.util import (
1110
ApiEndpoint,
1211
get_number_of_images,
1312
sync_op_raw,
1413
upload_images_to_comfyapi,
1514
validate_string,
15+
validate_video_duration,
16+
validate_video_dimensions,
17+
validate_video_frame_count,
18+
upload_video_to_comfyapi,
1619
)
1720

1821
MODELS_MAP = {
@@ -31,6 +34,14 @@ class ExecuteTaskRequest(BaseModel):
3134
image_uri: Optional[str] = Field(None)
3235

3336

37+
class VideoEditRequest(BaseModel):
38+
video_uri: str = Field(...)
39+
prompt: str = Field(...)
40+
start_time: int = Field(...)
41+
duration: int = Field(...)
42+
mode: str = Field(...)
43+
44+
3445
class TextToVideoNode(IO.ComfyNode):
3546
@classmethod
3647
def define_schema(cls):
@@ -103,7 +114,7 @@ async def execute(
103114
as_binary=True,
104115
max_retries=1,
105116
)
106-
return IO.NodeOutput(VideoFromFile(BytesIO(response)))
117+
return IO.NodeOutput(InputImpl.VideoFromFile(BytesIO(response)))
107118

108119

109120
class ImageToVideoNode(IO.ComfyNode):
@@ -183,7 +194,76 @@ async def execute(
183194
as_binary=True,
184195
max_retries=1,
185196
)
186-
return IO.NodeOutput(VideoFromFile(BytesIO(response)))
197+
return IO.NodeOutput(InputImpl.VideoFromFile(BytesIO(response)))
198+
199+
200+
class EditVideoNode(IO.ComfyNode):
201+
@classmethod
202+
def define_schema(cls):
203+
return IO.Schema(
204+
node_id="LtxvApiEditVideoNode",
205+
display_name="LTXV Video To Video",
206+
category="api node/video/LTXV",
207+
description="Edit a specific section of a video by replacing audio, video, or both using AI generation.",
208+
inputs=[
209+
IO.Video.Input("video"),
210+
IO.String.Input(
211+
"prompt",
212+
multiline=True,
213+
default="",
214+
),
215+
IO.Combo.Input("mode", options=["replace_video", "replace_audio", "replace_audio_and_video"]),
216+
IO.Float.Input("start_time", min=0.0, default=0.0),
217+
IO.Float.Input("duration", min=1.0, max=20.0, default=3),
218+
],
219+
outputs=[
220+
IO.Video.Output(),
221+
],
222+
hidden=[
223+
IO.Hidden.auth_token_comfy_org,
224+
IO.Hidden.api_key_comfy_org,
225+
IO.Hidden.unique_id,
226+
],
227+
is_api_node=True,
228+
)
229+
230+
@classmethod
231+
async def execute(
232+
cls,
233+
video: Input.Video,
234+
prompt: str,
235+
mode: str,
236+
start_time: float,
237+
duration: float,
238+
) -> IO.NodeOutput:
239+
validate_string(prompt, min_length=1, max_length=10000)
240+
validate_video_dimensions(video, max_width=3840, max_height=2160)
241+
validate_video_duration(video, max_duration=20)
242+
validate_video_frame_count(video, max_frame_count=505)
243+
video_duration = video.get_duration()
244+
if start_time >= video_duration:
245+
raise ValueError(
246+
f"Invalid start_time ({start_time}). Start time is greater than input video duration ({video_duration})"
247+
)
248+
response = await sync_op_raw(
249+
cls,
250+
# ApiEndpoint(
251+
# "https://api.ltx.video/v1/retake",
252+
# "POST",
253+
# headers={"Authorization": "Bearer PLACE_YOUR_API_KEY"},
254+
# ),
255+
ApiEndpoint("/proxy/ltx/v1/retake", "POST"),
256+
data=VideoEditRequest(
257+
video_uri=await upload_video_to_comfyapi(cls, video),
258+
prompt=prompt,
259+
mode=mode,
260+
start_time=int(start_time),
261+
duration=int(duration),
262+
),
263+
as_binary=True,
264+
max_retries=1,
265+
)
266+
return IO.NodeOutput(InputImpl.VideoFromFile(BytesIO(response)))
187267

188268

189269
class LtxvApiExtension(ComfyExtension):
@@ -192,6 +272,7 @@ async def get_node_list(self) -> list[type[IO.ComfyNode]]:
192272
return [
193273
TextToVideoNode,
194274
ImageToVideoNode,
275+
EditVideoNode,
195276
]
196277

197278

0 commit comments

Comments
 (0)