Remove legacy timeline adapter node
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from .ltx_director import LTXDirector
|
from .ltx_director import LTXDirector
|
||||||
from .ltx_director_guide import LTXDirectorGuide, LTXDirectorCropGuides
|
from .ltx_director_guide import LTXDirectorGuide, LTXDirectorCropGuides
|
||||||
from .msr_character import MSRCharacter, MSRCharacterSet
|
from .msr_character import MSRCharacter, MSRCharacterSet
|
||||||
from .timeline_nodes import TimelineSection, TimelineSectionSet, Timeline
|
from .timeline_nodes import TimelineSection, TimelineSectionSet
|
||||||
from comfy_api.latest import ComfyExtension, io
|
from comfy_api.latest import ComfyExtension, io
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
from .latent_slice import CleanLatentSlice
|
from .latent_slice import CleanLatentSlice
|
||||||
@@ -14,7 +14,6 @@ class PromptRelay(ComfyExtension):
|
|||||||
MSRCharacterSet,
|
MSRCharacterSet,
|
||||||
TimelineSection,
|
TimelineSection,
|
||||||
TimelineSectionSet,
|
TimelineSectionSet,
|
||||||
Timeline,
|
|
||||||
LTXDirector,
|
LTXDirector,
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -27,7 +26,6 @@ NODE_CLASS_MAPPINGS = {
|
|||||||
"MSRCharacterSetCS": MSRCharacterSet,
|
"MSRCharacterSetCS": MSRCharacterSet,
|
||||||
"TimelineSectionCS": TimelineSection,
|
"TimelineSectionCS": TimelineSection,
|
||||||
"TimelineSectionSetCS": TimelineSectionSet,
|
"TimelineSectionSetCS": TimelineSectionSet,
|
||||||
"TimelineCS": Timeline,
|
|
||||||
"LTXDirectorGuideCS": LTXDirectorGuide,
|
"LTXDirectorGuideCS": LTXDirectorGuide,
|
||||||
"LTXDirectorCropGuidesCS": LTXDirectorCropGuides,
|
"LTXDirectorCropGuidesCS": LTXDirectorCropGuides,
|
||||||
"CleanLatentSliceCS": CleanLatentSlice,
|
"CleanLatentSliceCS": CleanLatentSlice,
|
||||||
@@ -39,7 +37,6 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
|||||||
"MSRCharacterSetCS": "MSR Character Set DUMAS",
|
"MSRCharacterSetCS": "MSR Character Set DUMAS",
|
||||||
"TimelineSectionCS": "Timeline Section DUMAS",
|
"TimelineSectionCS": "Timeline Section DUMAS",
|
||||||
"TimelineSectionSetCS": "Timeline Section Set DUMAS",
|
"TimelineSectionSetCS": "Timeline Section Set DUMAS",
|
||||||
"TimelineCS": "Timeline DUMAS",
|
|
||||||
"LTXDirectorGuideCS": "LTX Director Guide DUMAS",
|
"LTXDirectorGuideCS": "LTX Director Guide DUMAS",
|
||||||
"LTXDirectorCropGuidesCS": "LTX Director Crop Guides DUMAS",
|
"LTXDirectorCropGuidesCS": "LTX Director Crop Guides DUMAS",
|
||||||
"CleanLatentSliceCS": "Clean Latent Slice DUMAS",
|
"CleanLatentSliceCS": "Clean Latent Slice DUMAS",
|
||||||
|
|||||||
@@ -11550,10 +11550,6 @@ app.registerExtension({
|
|||||||
self.removeInput(idx);
|
self.removeInput(idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const timelineIdx = self.inputs.findIndex(i => i?.name === "timeline");
|
|
||||||
if (timelineIdx !== -1 && self.inputs[timelineIdx]?.link == null) {
|
|
||||||
self.removeInput(timelineIdx);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
this._resolveNodeLinkedValue = function (targetNode, inputName, options = {}) {
|
this._resolveNodeLinkedValue = function (targetNode, inputName, options = {}) {
|
||||||
const originNode = self._findLinkedOriginNode(targetNode, inputName);
|
const originNode = self._findLinkedOriginNode(targetNode, inputName);
|
||||||
@@ -11590,13 +11586,7 @@ app.registerExtension({
|
|||||||
let sectionSetNode = self._findLinkedOriginNode(self, "section_set");
|
let sectionSetNode = self._findLinkedOriginNode(self, "section_set");
|
||||||
let setClass = sectionSetNode?.comfyClass || sectionSetNode?.type || "";
|
let setClass = sectionSetNode?.comfyClass || sectionSetNode?.type || "";
|
||||||
if (!sectionSetNode || setClass !== "TimelineSectionSetCS") {
|
if (!sectionSetNode || setClass !== "TimelineSectionSetCS") {
|
||||||
const timelineNode = self._findLinkedOriginNode(self, "timeline");
|
return null;
|
||||||
const comfyClass = timelineNode?.comfyClass || timelineNode?.type || "";
|
|
||||||
if (!timelineNode || comfyClass !== "TimelineCS") {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
sectionSetNode = self._findLinkedOriginNode(timelineNode, "section_set");
|
|
||||||
setClass = sectionSetNode?.comfyClass || sectionSetNode?.type || "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sections = [];
|
const sections = [];
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ from .prompt_relay import (
|
|||||||
|
|
||||||
from .patches import detect_model_type, apply_patches
|
from .patches import detect_model_type, apply_patches
|
||||||
from .msr_character import MSRCharacterSetData
|
from .msr_character import MSRCharacterSetData
|
||||||
from .timeline_nodes import TimelineData, TimelineSectionSetData
|
from .timeline_nodes import TimelineSectionSetData
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ def _build_runtime_timeline_payload(external_timeline, frame_rate: float) -> tup
|
|||||||
segment_lengths.append(str(section_frames))
|
segment_lengths.append(str(section_frames))
|
||||||
current_start += section_frames
|
current_start += section_frames
|
||||||
|
|
||||||
duration_seconds = max(0.1, float(total_duration_seconds or external_timeline.get("duration") or 0.0))
|
duration_seconds = max(0.1, float(total_duration_seconds or 0.0))
|
||||||
duration_frames = max(1, int(round(duration_seconds * frame_rate)))
|
duration_frames = max(1, int(round(duration_seconds * frame_rate)))
|
||||||
return tdata, " | ".join(local_prompts), ",".join(segment_lengths), duration_seconds, duration_frames
|
return tdata, " | ".join(local_prompts), ",".join(segment_lengths), duration_seconds, duration_frames
|
||||||
|
|
||||||
@@ -2049,11 +2049,6 @@ class LTXDirector(io.ComfyNode):
|
|||||||
optional=True,
|
optional=True,
|
||||||
tooltip="Optional external Timeline Section Set DUMAS payload. When connected, it populates the main timeline track and derives the duration from the sections.",
|
tooltip="Optional external Timeline Section Set DUMAS payload. When connected, it populates the main timeline track and derives the duration from the sections.",
|
||||||
),
|
),
|
||||||
TimelineData.Input(
|
|
||||||
"timeline",
|
|
||||||
optional=True,
|
|
||||||
tooltip="Legacy external Timeline DUMAS payload kept for backward compatibility with older workflows.",
|
|
||||||
),
|
|
||||||
io.Float.Input(
|
io.Float.Input(
|
||||||
"start", force_input=True, optional=True, default=0.0,
|
"start", force_input=True, optional=True, default=0.0,
|
||||||
tooltip="Automation (connection-only). Start time in SECONDS. Overrides the panel Start when connected.",
|
tooltip="Automation (connection-only). Start time in SECONDS. Overrides the panel Start when connected.",
|
||||||
@@ -2089,7 +2084,7 @@ class LTXDirector(io.ComfyNode):
|
|||||||
custom_width=768, custom_height=512, resize_method="maintain aspect ratio",
|
custom_width=768, custom_height=512, resize_method="maintain aspect ratio",
|
||||||
divisible_by=32, img_compression=0, audio_vae=None, optional_latent=None,
|
divisible_by=32, img_compression=0, audio_vae=None, optional_latent=None,
|
||||||
use_custom_audio=False, inpaint_audio=True, use_custom_motion=True, override_audio=False,
|
use_custom_audio=False, inpaint_audio=True, use_custom_motion=True, override_audio=False,
|
||||||
vae=None, reference_strength=1.0, character_set=None, section_set=None, timeline=None,
|
vae=None, reference_strength=1.0, character_set=None, section_set=None,
|
||||||
start=None, end=None, duration=None) -> io.NodeOutput:
|
start=None, end=None, duration=None) -> io.NodeOutput:
|
||||||
input_dir = folder_paths.get_input_directory()
|
input_dir = folder_paths.get_input_directory()
|
||||||
image_cache = {}
|
image_cache = {}
|
||||||
@@ -2106,15 +2101,9 @@ class LTXDirector(io.ComfyNode):
|
|||||||
processed_image_cache[cache_key] = processed
|
processed_image_cache[cache_key] = processed
|
||||||
return processed
|
return processed
|
||||||
|
|
||||||
external_timeline_source = None
|
|
||||||
if section_set is not None:
|
if section_set is not None:
|
||||||
external_timeline_source = {"sections": list((section_set or {}).get("sections") or [])}
|
|
||||||
elif timeline is not None:
|
|
||||||
external_timeline_source = timeline
|
|
||||||
|
|
||||||
if external_timeline_source is not None:
|
|
||||||
external_tdata, external_local_prompts, external_segment_lengths, external_duration_seconds, external_duration_frames = _build_runtime_timeline_payload(
|
external_tdata, external_local_prompts, external_segment_lengths, external_duration_seconds, external_duration_frames = _build_runtime_timeline_payload(
|
||||||
external_timeline_source,
|
{"sections": list((section_set or {}).get("sections") or [])},
|
||||||
float(frame_rate) if frame_rate else 24.0,
|
float(frame_rate) if frame_rate else 24.0,
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ from comfy_api.latest import io
|
|||||||
|
|
||||||
TimelineSectionData = io.Custom("TIMELINE_SECTION")
|
TimelineSectionData = io.Custom("TIMELINE_SECTION")
|
||||||
TimelineSectionSetData = io.Custom("TIMELINE_SECTION_SET")
|
TimelineSectionSetData = io.Custom("TIMELINE_SECTION_SET")
|
||||||
TimelineData = io.Custom("TIMELINE")
|
|
||||||
|
|
||||||
|
|
||||||
class TimelineSection(io.ComfyNode):
|
class TimelineSection(io.ComfyNode):
|
||||||
@classmethod
|
@classmethod
|
||||||
def define_schema(cls):
|
def define_schema(cls):
|
||||||
@@ -97,34 +94,3 @@ class TimelineSectionSet(io.ComfyNode):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return io.NodeOutput({"sections": sections})
|
return io.NodeOutput({"sections": sections})
|
||||||
|
|
||||||
|
|
||||||
class Timeline(io.ComfyNode):
|
|
||||||
@classmethod
|
|
||||||
def define_schema(cls):
|
|
||||||
return io.Schema(
|
|
||||||
node_id="TimelineCS",
|
|
||||||
display_name="Timeline DUMAS",
|
|
||||||
category="WhatDreamsCost DUMAS",
|
|
||||||
description="Builds an external timeline payload for LTX Director from a section set, deriving the total duration from the sections.",
|
|
||||||
inputs=[
|
|
||||||
TimelineSectionSetData.Input(
|
|
||||||
"section_set",
|
|
||||||
optional=True,
|
|
||||||
tooltip="Optional section set. When omitted, the timeline payload contains no sections.",
|
|
||||||
),
|
|
||||||
],
|
|
||||||
outputs=[
|
|
||||||
TimelineData.Output(display_name="timeline"),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def execute(cls, section_set=None, duration=None) -> io.NodeOutput:
|
|
||||||
sections = list((section_set or {}).get("sections") or [])
|
|
||||||
total_duration = sum(max(0.1, float(item.get("duration") or 0.0)) for item in sections)
|
|
||||||
payload = {
|
|
||||||
"duration": max(0.1, float(total_duration or 0.0)),
|
|
||||||
"sections": sections,
|
|
||||||
}
|
|
||||||
return io.NodeOutput(payload)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user