101 lines
3.4 KiB
Python
101 lines
3.4 KiB
Python
import logging
|
||
from typing import Tuple
|
||
|
||
# Initialize logger
|
||
logger = logging.getLogger(__name__)
|
||
|
||
class FramesToSeconds:
|
||
"""ComfyUI node that converts a frame count into seconds based on the
|
||
frames-per-second (fps) value.
|
||
|
||
The node outputs both a floating-point and an integer representation of the
|
||
duration in seconds, plus it echoes the fps and frames values.
|
||
"""
|
||
|
||
# ------------------------------------------------------------------
|
||
# ComfyUI required class attributes
|
||
# ------------------------------------------------------------------
|
||
@classmethod
|
||
def INPUT_TYPES(cls):
|
||
"""Define node inputs.
|
||
`frames` is the number of frames to convert.
|
||
`fps` is an integer slider ranging from 8 to 30 frames-per-second.
|
||
"""
|
||
return {
|
||
"required": {
|
||
"frames": (
|
||
"INT",
|
||
{
|
||
"default": 1,
|
||
"min": 0,
|
||
"max": 1_000_000,
|
||
"tooltip": "Frame count representing the duration to convert.",
|
||
},
|
||
),
|
||
"fps": (
|
||
"INT",
|
||
{
|
||
"default": 25,
|
||
"min": 8,
|
||
"max": 30,
|
||
"step": 1,
|
||
"tooltip": "Frames-per-second for the conversion (8–30).",
|
||
},
|
||
),
|
||
}
|
||
}
|
||
|
||
RETURN_TYPES = ("FLOAT", "INT", "FLOAT", "INT")
|
||
RETURN_NAMES = (
|
||
"duration_seconds",
|
||
"duration_seconds_int",
|
||
"fps",
|
||
"frames",
|
||
)
|
||
FUNCTION = "convert"
|
||
CATEGORY = "llm_toolkit/utils/audio"
|
||
|
||
# ------------------------------------------------------------------
|
||
# Core logic
|
||
# ------------------------------------------------------------------
|
||
def convert(self, frames: int, fps: int) -> Tuple[float, int, float, int]:
|
||
"""Convert a frame count into seconds.
|
||
|
||
Args:
|
||
frames: Total number of frames.
|
||
fps: Frames-per-second value used for conversion.
|
||
|
||
Returns:
|
||
Tuple(duration_seconds_float, duration_seconds_int, fps_float, frames_int)
|
||
"""
|
||
try:
|
||
if fps <= 0:
|
||
raise ValueError("fps must be a positive integer")
|
||
|
||
duration_seconds = frames / fps
|
||
duration_seconds_int = int(round(duration_seconds))
|
||
|
||
logger.debug(
|
||
"FramesToSeconds: frames=%s, fps=%s, duration_seconds=%s",
|
||
frames,
|
||
fps,
|
||
duration_seconds,
|
||
)
|
||
|
||
return duration_seconds, duration_seconds_int, float(fps), frames
|
||
except Exception as e:
|
||
logger.error("FramesToSeconds: error during conversion: %s", e, exc_info=True)
|
||
# Return zeros on failure
|
||
return 0.0, 0, 0.0, 0
|
||
|
||
|
||
# -------------------------------------------------------------------------
|
||
# ComfyUI mappings so the node is discoverable
|
||
# -------------------------------------------------------------------------
|
||
NODE_CLASS_MAPPINGS = {
|
||
"FramesToSeconds": FramesToSeconds,
|
||
}
|
||
|
||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||
"FramesToSeconds": "Frames → Seconds (LLMToolkit)",
|
||
} |