diff --git a/README.md b/README.md index 29baec9..f176573 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,19 @@ Load images directly from a `STRING_LIST`. - `images` (IMAGE) - `count` (INT) +--- + +### 🔹 List Video Files (Input Dir) +Scans your ComfyUI `input` folder for video files. + +**Inputs** +- `subfolder` (STRING) - Subfolder within the input directory. +- `filter` (STRING) - Wildcard filter (default `*`). + +**Outputs** +- `paths` (STRING_LIST) - List of absolute paths. +- `count` (INT) - Number of files found. + > This is the **recommended loader** when using frame deduplication. --- diff --git a/__init__.py b/__init__.py index 9aaf2c5..e04c68d 100644 --- a/__init__.py +++ b/__init__.py @@ -10,15 +10,21 @@ from .load_image_list import ( NODE_CLASS_MAPPINGS as LIST_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS as LIST_NAMES, ) +from .list_video_files import ( + NODE_CLASS_MAPPINGS as VIDEO_MAPPINGS, + NODE_DISPLAY_NAME_MAPPINGS as VIDEO_NAMES, +) NODE_CLASS_MAPPINGS = {} NODE_CLASS_MAPPINGS.update(SAVE_MAPPINGS) NODE_CLASS_MAPPINGS.update(SEQ_MAPPINGS) NODE_CLASS_MAPPINGS.update(LIST_MAPPINGS) +NODE_CLASS_MAPPINGS.update(VIDEO_MAPPINGS) NODE_DISPLAY_NAME_MAPPINGS = {} NODE_DISPLAY_NAME_MAPPINGS.update(SAVE_NAMES) NODE_DISPLAY_NAME_MAPPINGS.update(SEQ_NAMES) NODE_DISPLAY_NAME_MAPPINGS.update(LIST_NAMES) +NODE_DISPLAY_NAME_MAPPINGS.update(VIDEO_NAMES) __all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS"] diff --git a/list_video_files.py b/list_video_files.py new file mode 100644 index 0000000..5ace6df --- /dev/null +++ b/list_video_files.py @@ -0,0 +1,57 @@ +import os +import folder_paths + +class ListVideoFiles: + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "subfolder": ("STRING", {"default": ""}), + "filter": ("STRING", {"default": "*"}), + } + } + + RETURN_TYPES = ("STRING_LIST", "INT") + RETURN_NAMES = ("paths", "count") + FUNCTION = "execute" + CATEGORY = "FrameIO" + DESCRIPTION = """ +Lists video file paths from the ComfyUI input directory. +- Filters by common video extensions (mp4, mkv, mov, avi, webm, etc.). +- Returns a list of strings and the total count. +- Useful for batch processing multiple videos. +""" + + def execute(self, subfolder, filter): + input_dir = folder_paths.get_input_directory() + target_dir = os.path.abspath(os.path.join(input_dir, subfolder)) + + if not os.path.exists(target_dir): + return ([], 0) + + video_extensions = { + ".mp4", ".mkv", ".mov", ".avi", ".webm", + ".mpg", ".mpeg", ".m4v", ".flv", ".wmv", + ".3gp", ".ts", ".m2ts" + } + + files = [] + for root, _, filenames in os.walk(target_dir): + for filename in filenames: + ext = os.path.splitext(filename)[1].lower() + if ext in video_extensions: + if filter == "*" or filter.lower() in filename.lower(): + files.append(os.path.abspath(os.path.join(root, filename))) + + # Sort files naturally + files.sort() + + return (files, len(files)) + +NODE_CLASS_MAPPINGS = { + "ListVideoFiles": ListVideoFiles +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "ListVideoFiles": "List Video Files (Input Dir)" +}