From ee655b3376e5734b16a0b65ed103c1fcd295dded Mon Sep 17 00:00:00 2001 From: Verolelb <115535732+Verolelb@users.noreply.github.com> Date: Tue, 23 Dec 2025 12:40:23 +0100 Subject: [PATCH] Update: Added resize modes (Fit, Stretch) and FPS output --- README.md | 128 +++++++++++----------------- video_workbench.py | 91 +++++++++++--------- workflow_example/AutoEditVideo.json | 2 +- 3 files changed, 104 insertions(+), 117 deletions(-) diff --git a/README.md b/README.md index e7e94cd..6273d59 100644 --- a/README.md +++ b/README.md @@ -1,92 +1,68 @@ -\# 🎬 ComfyUI Video Workbench +# 🎬 ComfyUI Auto-Edit Workbench +A powerful Custom Node for **ComfyUI** that acts as a **mini video editing studio**. +It automatically assembles (concatenates) multiple video clips from a folder into a single sequence, handling resolution resizing, aspect ratios, and frame rates intelligently. +## ✨ Key Features -A powerful Custom Node for ComfyUI that acts as a \*\*mini video editing workbench\*\*. +* **Batch Assembly**: Loads all video files from a specific folder automatically. +* **3 Resize Modes**: + * **Crop (Fill Screen)**: Fills the screen, cropping edges if necessary (perfect for mixing vertical/horizontal footage). + * **Fit (Black Bars)**: Adds black borders (letterboxing) so the entire video is visible. + * **Stretch**: Distorts the video to fit the target resolution perfectly. +* **Smart Strategies**: + * **Resolution**: Auto-detect from the *First Video*, *Smallest*, *Largest*, or use a *Custom* size. + * **FPS**: Auto-detect from *First Video*, *Lowest*, *Highest*, or *Custom*. +* **Audio Support**: Concatenates audio tracks seamlessly. +* **Safety Limits**: `limit_duration_sec` parameter to trim the output (great for testing without Out-Of-Memory errors). -It automatically assembles (concatenates) multiple video clips from a folder into a single sequence, handling resolution resizing (crop/fill) and FPS matching intelligently. +## 📦 Installation +### Method 1: ComfyUI Manager (Recommended) +1. Install [ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager). +2. Click **"Install via Git URL"**. +3. Paste this repository URL: `https://github.com/Verolelb/ComfyUI-Video-Workbench`. +### Method 2: Manual Installation +1. Navigate to your `ComfyUI/custom_nodes/` directory. +2. Clone this repository: + ```bash + git clone https://github.com/Verolelb/ComfyUI-Video-Workbench.git + ``` +3. Open a terminal in this folder and install the requirement: + ```bash + pip install -r requirements.txt + ``` + *(This node relies on `moviepy` and `numpy`).* -\## ✨ Features +## 🛠️ How to use +### 1. Inputs +* **`directory_path`**: Absolute path to your video folder (e.g., `C:/Users/You/Desktop/MyClips`). +* **`sort_strategy`**: Order of clips (Alphabetical, Date, Random). +* **`resize_mode`**: + * Use **Crop** for immersive, full-screen montages (e.g., Shorts/Reels). + * Use **Fit** to preserve all details with black bars. +* **`resolution_strategy`**: Keep it on **"First Video"** to let the first clip dictate the format of the whole timeline. +* **`fps_strategy`**: Keep on **"First Video"** or force a **Custom** value (e.g., 24, 30, 60). -\* \*\*Batch Assembly\*\*: Loads all video files from a specified folder. +### 2. Outputs -\* \*\*Smart Resizing\*\*: Automatically handles mixed aspect ratios (Vertical TikToks + Horizontal YouTube). +1. **`IMAGE`**: The assembled video stream. +2. **`AUDIO`**: The combined audio track. +3. **`FLOAT` (fps)**: The final frame rate (useful to connect to the "frame_rate" input of saving nodes). -  \* \*Center Crop / Aspect Fill logic included.\* +### 3. Recommended Workflow for Saving -\* \*\*Intelligent Strategies\*\*: +To save the video **with audio**, it is highly recommended to use the **Video Combine** node from the [ComfyUI-VideoHelperSuite](https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite). -  \* \*\*Resolution\*\*: Can adapt to the \*First Video\*, the \*Smallest\*, the \*Largest\*, or a \*Custom\* size. +* Connect `AutoEditWorkbench` **IMAGE** -> `Video Combine` **images**. +* Connect `AutoEditWorkbench` **AUDIO** -> `Video Combine` **audio**. +* Connect `AutoEditWorkbench` **FPS** -> `Video Combine` **frame_rate** (Convert widget to input). +* Set format to **`video/h264-mp4`**. -  \* \*\*FPS\*\*: Can adapt to the \*First Video\*, \*Lowest\*, \*Highest\*, or \*Custom\*. - -\* \*\*Audio Support\*\*: Concatenates audio tracks perfectly. - -\* \*\*Safety Limits\*\*: Duration limit parameter to prevent Out-Of-Memory errors during testing. - - - -\## 📦 Installation - - - -\### Method 1: ComfyUI Manager (Recommended) - -1\. Install \[ComfyUI Manager](https://github.com/ltdrdata/ComfyUI-Manager). - -2\. Search for "Video Workbench" (once indexed) or "Install via Git URL". - -3\. Paste this repository URL. - - - -\### Method 2: Manual - -1\. Go to your `ComfyUI/custom\_nodes/` directory. - -2\. Clone this repo: - -  ```bash - -  git clone https://github.com/Verolelb/ComfyUI-Video-Workbench.git - -  ``` - -3\. Install dependencies: - -  ```bash - -  pip install -r requirements.txt - -  ``` - - - -\## 🛠️ How to use - - - -1\. \*\*Directory Path\*\*: Paste the absolute path to your folder containing video clips (e.g., `C:/Users/You/Videos/Vacation`). - -2\. \*\*Sort Strategy\*\*: Choose how to order the clips (Alphabetical, Date, Random). - -3\. \*\*Resolution \& FPS Strategy\*\*: - -  \* Leave on \*\*"First Video"\*\* to let the first clip dictate the settings for the whole timeline. - -  \* Use \*\*"Custom"\*\* to force specific dimensions (e.g., 1080x1920). - - - -\## ❤️ Credits - - - -Created by \*\*Verolelb\*\*. - -Powered by \[MoviePy](https://zulko.github.io/moviepy/). +## ❤️ Credits +Created by **Verolelb**. +Powered by [MoviePy](https://zulko.github.io/moviepy/). \ No newline at end of file diff --git a/video_workbench.py b/video_workbench.py index 839a6a7..8d5aaf7 100644 --- a/video_workbench.py +++ b/video_workbench.py @@ -5,7 +5,7 @@ import random # Try to import moviepy try: - from moviepy.editor import VideoFileClip, concatenate_videoclips + from moviepy.editor import VideoFileClip, concatenate_videoclips, ColorClip, CompositeVideoClip except ImportError: print("❌ Error: 'moviepy' is not installed. Please run: pip install moviepy") @@ -20,6 +20,9 @@ class AutoEditWorkbench: "directory_path": ("STRING", {"default": "./input/my_footage", "multiline": False}), "sort_strategy": (["alphabetical_asc", "alphabetical_desc", "date_oldest", "date_newest", "random"],), + # --- RESIZE MODES --- + "resize_mode": (["Crop (Fill Screen)", "Fit (Black Bars)", "Stretch"], {"default": "Crop (Fill Screen)"}), + # --- RESOLUTION SETTINGS --- "resolution_strategy": (["First Video", "Smallest (Min Area)", "Largest (Max Area)", "Custom"], {"default": "First Video"}), "custom_width": ("INT", {"default": 512, "min": 64, "max": 4096, "step": 8}), @@ -34,14 +37,12 @@ class AutoEditWorkbench: }, } - # AJOUT DE LA SORTIE FPS (FLOAT) ICI RETURN_TYPES = ("IMAGE", "AUDIO", "FLOAT") RETURN_NAMES = ("images", "audio", "fps") - FUNCTION = "process_workbench" CATEGORY = "VideoTools/Editing" - def process_workbench(self, directory_path, sort_strategy, + def process_workbench(self, directory_path, sort_strategy, resize_mode, resolution_strategy, custom_width, custom_height, fps_strategy, custom_fps, limit_duration_sec): @@ -64,27 +65,23 @@ class AutoEditWorkbench: elif sort_strategy == "date_newest": files.sort(key=os.path.getmtime, reverse=True) elif sort_strategy == "random": random.shuffle(files) - # --- 2. Strategy Analysis (Resolution & FPS) --- + # --- 2. Strategy Analysis --- target_w, target_h = custom_width, custom_height target_fps = custom_fps - # Helper to read metadata quickly def get_meta(p): try: with VideoFileClip(p) as c: return {'w': c.w, 'h': c.h, 'fps': c.fps, 'area': c.w*c.h} except: return None - # Check if we need to scan all files need_scan = (resolution_strategy not in ["Custom", "First Video"]) or (fps_strategy not in ["Custom", "First Video"]) - # Optimization: Apply "First Video" immediately without scanning everything if possible if resolution_strategy == "First Video" or fps_strategy == "First Video": m = get_meta(files[0]) if m: if resolution_strategy == "First Video": target_w, target_h = m['w'], m['h'] if fps_strategy == "First Video": target_fps = m['fps'] - # Full scan if needed (Min/Max strategies) if need_scan: stats = [m for f in files if (m := get_meta(f))] if stats: @@ -100,30 +97,55 @@ class AutoEditWorkbench: elif fps_strategy == "Highest FPS": target_fps = max(stats, key=lambda x: x['fps'])['fps'] - print(f"🎯 [AutoEdit] Target: {target_w}x{target_h} @ {target_fps:.2f} fps") + print(f"🎯 [AutoEdit] Target: {target_w}x{target_h} @ {target_fps:.2f} fps | Mode: {resize_mode}") # --- 3. Clip Processing --- clips = [] for file in files: try: clip = VideoFileClip(file) - # Aspect Fill / Center Crop Logic - ratio_target = target_w / target_h - ratio_clip = clip.w / clip.h - if ratio_clip > ratio_target: - # Clip is wider -> Resize Height, Crop Width - clip = clip.resize(height=target_h) - clip = clip.crop(x1=clip.w/2 - target_w/2, width=target_w) - else: - # Clip is taller -> Resize Width, Crop Height - clip = clip.resize(width=target_w) - clip = clip.crop(y1=clip.h/2 - target_h/2, height=target_h) - - # Finalize - clip = clip.resize((target_w, target_h)) + # --- RESIZE LOGIC --- + if resize_mode == "Stretch": + # Ignore aspect ratio, just squish/stretch + clip = clip.resize((target_w, target_h)) + + elif resize_mode == "Fit (Black Bars)": + # Resize to fit inside box, keep aspect ratio + # Check which dimension is the limiting factor + ratio_target = target_w / target_h + ratio_clip = clip.w / clip.h + + if ratio_clip > ratio_target: + # Video is "wider" than target -> Fit Width + clip = clip.resize(width=target_w) + else: + # Video is "taller" than target -> Fit Height + clip = clip.resize(height=target_h) + + # Create black background and composite + background = ColorClip(size=(target_w, target_h), color=(0,0,0), duration=clip.duration) + clip = CompositeVideoClip([background, clip.set_position("center")]) + + else: # Default: Crop (Fill Screen) + ratio_target = target_w / target_h + ratio_clip = clip.w / clip.h + + if ratio_clip > ratio_target: + # Clip is wider -> Resize Height, Crop Width + clip = clip.resize(height=target_h) + clip = clip.crop(x1=clip.w/2 - target_w/2, width=target_w) + else: + # Clip is taller -> Resize Width, Crop Height + clip = clip.resize(width=target_w) + clip = clip.crop(y1=clip.h/2 - target_h/2, height=target_h) + + clip = clip.resize((target_w, target_h)) + + # Finalize FPS clip = clip.set_fps(target_fps) clips.append(clip) + except Exception as e: print(f"⚠️ Warning: Skipped {file}. Reason: {e}") @@ -133,56 +155,45 @@ class AutoEditWorkbench: # --- 4. Concatenation --- final_clip = concatenate_videoclips(clips, method="compose") - # Duration Limit if limit_duration_sec > 0 and final_clip.duration > limit_duration_sec: final_clip = final_clip.subclip(0, limit_duration_sec) - # --- 5. Export Video (Tensor) --- + # --- 5. Export Video --- print("⏳ [AutoEdit] Converting video frames to Tensor...") frames = [frame for frame in final_clip.iter_frames()] video_np = np.stack(frames) video_tensor = torch.from_numpy(video_np).float() / 255.0 - # --- 6. Export Audio (Tensor) --- + # --- 6. Export Audio --- audio_dict = None if final_clip.audio is not None: sr = 44100 print(f"🔊 [AutoEdit] Processing Audio (Duration: {final_clip.duration}s)...") - try: - # Sync duration to prevent errors final_clip.audio = final_clip.audio.set_duration(final_clip.duration) - - # Iterate by 1-second chunks to avoid MemoryError and Numpy compatibility issues audio_chunks = [] + # Chunk processing for stability for chunk in final_clip.audio.iter_chunks(fps=sr, chunk_duration=1.0): audio_chunks.append(chunk) if len(audio_chunks) > 0: audio_np = np.vstack(audio_chunks) - - # Ensure correct shape for ComfyUI - if len(audio_np.shape) == 1: # Mono + if len(audio_np.shape) == 1: audio_np = audio_np.reshape((-1, 1)) - - # (Samples, Channels) -> (1, Channels, Samples) audio_tensor = torch.from_numpy(audio_np.T).float().unsqueeze(0) audio_dict = {"waveform": audio_tensor, "sample_rate": sr} print("✅ [AutoEdit] Audio ready.") else: print("⚠️ [AutoEdit] Audio track was empty.") - except Exception as e: print(f"❌ [AutoEdit] Audio Error: {e}") - # Cleanup resources final_clip.close() for c in clips: c.close() - # RETOUR AVEC LE FPS EN PLUS return (video_tensor, audio_dict, float(target_fps)) -# Mappings for ComfyUI +# Mappings NODE_CLASS_MAPPINGS = { "AutoEditWorkbench": AutoEditWorkbench } diff --git a/workflow_example/AutoEditVideo.json b/workflow_example/AutoEditVideo.json index 00a9ab3..b5d4dc3 100644 --- a/workflow_example/AutoEditVideo.json +++ b/workflow_example/AutoEditVideo.json @@ -1 +1 @@ -{"id":"8a0f659b-10a2-4d93-96c4-052c5d7643ee","revision":0,"last_node_id":9,"last_link_id":22,"nodes":[{"id":2,"type":"VHS_VideoCombine","pos":[-1874.2441845555702,-2296.548995897136],"size":[343.48707601299293,466.34893024865596],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":17},{"localized_name":"audio","name":"audio","shape":7,"type":"AUDIO","link":18},{"localized_name":"meta_batch","name":"meta_batch","shape":7,"type":"VHS_BatchManager","link":null},{"localized_name":"vae","name":"vae","shape":7,"type":"VAE","link":null},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT","widget":{"name":"frame_rate"},"link":21},{"localized_name":"loop_count","name":"loop_count","type":"INT","widget":{"name":"loop_count"},"link":null},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"pingpong","name":"pingpong","type":"BOOLEAN","widget":{"name":"pingpong"},"link":null},{"localized_name":"save_output","name":"save_output","type":"BOOLEAN","widget":{"name":"save_output"},"link":null},{"name":"pix_fmt","type":["yuv420p","yuv420p10le"],"widget":{"name":"pix_fmt"},"link":null},{"name":"crf","type":"INT","widget":{"name":"crf"},"link":null},{"name":"save_metadata","type":"BOOLEAN","widget":{"name":"save_metadata"},"link":null},{"name":"trim_to_audio","type":"BOOLEAN","widget":{"name":"trim_to_audio"},"link":null}],"outputs":[{"localized_name":"Filenames","name":"Filenames","type":"VHS_FILENAMES","links":null}],"properties":{"cnr_id":"comfyui-videohelpersuite","ver":"3234937ff5f3ca19068aaba5042771514de2429d","Node name for S&R":"VHS_VideoCombine"},"widgets_values":{"frame_rate":16,"loop_count":0,"filename_prefix":"WAN22","format":"video/h264-mp4","pix_fmt":"yuv420p","crf":12,"save_metadata":true,"trim_to_audio":false,"pingpong":false,"save_output":true,"videopreview":{"hidden":false,"paused":false,"params":{"filename":"WAN22_00010-audio.mp4","subfolder":"","type":"output","format":"video/h264-mp4","frame_rate":25,"workflow":"WAN22_00010.png","fullpath":"D:\\ComfyUI_windows_portable\\ComfyUI\\output\\WAN22_00010-audio.mp4"}}}},{"id":6,"type":"VHS_VideoCombine","pos":[-1884.3203327691767,-1718.1667982753331],"size":[343.48707601299293,466.34893024865596],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":19},{"localized_name":"audio","name":"audio","shape":7,"type":"AUDIO","link":20},{"localized_name":"meta_batch","name":"meta_batch","shape":7,"type":"VHS_BatchManager","link":null},{"localized_name":"vae","name":"vae","shape":7,"type":"VAE","link":null},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT","widget":{"name":"frame_rate"},"link":22},{"localized_name":"loop_count","name":"loop_count","type":"INT","widget":{"name":"loop_count"},"link":null},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"pingpong","name":"pingpong","type":"BOOLEAN","widget":{"name":"pingpong"},"link":null},{"localized_name":"save_output","name":"save_output","type":"BOOLEAN","widget":{"name":"save_output"},"link":null},{"name":"pix_fmt","type":["yuv420p","yuv420p10le"],"widget":{"name":"pix_fmt"},"link":null},{"name":"crf","type":"INT","widget":{"name":"crf"},"link":null},{"name":"save_metadata","type":"BOOLEAN","widget":{"name":"save_metadata"},"link":null},{"name":"trim_to_audio","type":"BOOLEAN","widget":{"name":"trim_to_audio"},"link":null}],"outputs":[{"localized_name":"Filenames","name":"Filenames","type":"VHS_FILENAMES","links":null}],"title":"COMPRESS","properties":{"cnr_id":"comfyui-videohelpersuite","ver":"3234937ff5f3ca19068aaba5042771514de2429d","Node name for S&R":"VHS_VideoCombine"},"widgets_values":{"frame_rate":16,"loop_count":0,"filename_prefix":"WAN22_comp","format":"video/h264-mp4","pix_fmt":"yuv420p","crf":24,"save_metadata":true,"trim_to_audio":false,"pingpong":false,"save_output":true,"videopreview":{"hidden":false,"paused":false,"params":{"filename":"WAN22_comp_00010-audio.mp4","subfolder":"","type":"output","format":"video/h264-mp4","frame_rate":25,"workflow":"WAN22_comp_00010.png","fullpath":"D:\\ComfyUI_windows_portable\\ComfyUI\\output\\WAN22_comp_00010-audio.mp4"}}}},{"id":9,"type":"AutoEditWorkbench","pos":[-2544.9368907854946,-2001.8041477618626],"size":[271.859375,266],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"directory_path","name":"directory_path","type":"STRING","widget":{"name":"directory_path"},"link":null},{"localized_name":"sort_strategy","name":"sort_strategy","type":"COMBO","widget":{"name":"sort_strategy"},"link":null},{"localized_name":"resolution_strategy","name":"resolution_strategy","type":"COMBO","widget":{"name":"resolution_strategy"},"link":null},{"localized_name":"custom_width","name":"custom_width","type":"INT","widget":{"name":"custom_width"},"link":null},{"localized_name":"custom_height","name":"custom_height","type":"INT","widget":{"name":"custom_height"},"link":null},{"localized_name":"fps_strategy","name":"fps_strategy","type":"COMBO","widget":{"name":"fps_strategy"},"link":null},{"localized_name":"custom_fps","name":"custom_fps","type":"INT","widget":{"name":"custom_fps"},"link":null},{"localized_name":"limit_duration_sec","name":"limit_duration_sec","type":"FLOAT","widget":{"name":"limit_duration_sec"},"link":null}],"outputs":[{"localized_name":"images","name":"images","type":"IMAGE","links":[17,19]},{"localized_name":"audio","name":"audio","type":"AUDIO","links":[18,20]},{"localized_name":"fps","name":"fps","type":"FLOAT","links":[21,22]}],"properties":{"aux_id":"Verolelb/ComfyUI-Video-Workbench","ver":"e20e12b38a92b237ecf2b53d9126b43ff62756e3","Node name for S&R":"AutoEditWorkbench"},"widgets_values":["C:\\Users\\kuro5\\Downloads\\test","alphabetical_asc","First Video",512,512,"First Video",24,0]}],"links":[[17,9,0,2,0,"IMAGE"],[18,9,1,2,1,"AUDIO"],[19,9,0,6,0,"IMAGE"],[20,9,1,6,1,"AUDIO"],[21,9,2,2,4,"FLOAT"],[22,9,2,6,4,"FLOAT"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.6115909044841586,"offset":[3280.379146236631,2621.618419934006]},"workflowRendererVersion":"LG"},"version":0.4} \ No newline at end of file +{"id":"8a0f659b-10a2-4d93-96c4-052c5d7643ee","revision":0,"last_node_id":10,"last_link_id":28,"nodes":[{"id":2,"type":"VHS_VideoCombine","pos":[-2042.887137077505,-2333.3045111903803],"size":[343.48707601299293,466.34893024865596],"flags":{},"order":1,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":23},{"localized_name":"audio","name":"audio","shape":7,"type":"AUDIO","link":24},{"localized_name":"meta_batch","name":"meta_batch","shape":7,"type":"VHS_BatchManager","link":null},{"localized_name":"vae","name":"vae","shape":7,"type":"VAE","link":null},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT","widget":{"name":"frame_rate"},"link":25},{"localized_name":"loop_count","name":"loop_count","type":"INT","widget":{"name":"loop_count"},"link":null},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"pingpong","name":"pingpong","type":"BOOLEAN","widget":{"name":"pingpong"},"link":null},{"localized_name":"save_output","name":"save_output","type":"BOOLEAN","widget":{"name":"save_output"},"link":null},{"name":"pix_fmt","type":["yuv420p","yuv420p10le"],"widget":{"name":"pix_fmt"},"link":null},{"name":"crf","type":"INT","widget":{"name":"crf"},"link":null},{"name":"save_metadata","type":"BOOLEAN","widget":{"name":"save_metadata"},"link":null},{"name":"trim_to_audio","type":"BOOLEAN","widget":{"name":"trim_to_audio"},"link":null}],"outputs":[{"localized_name":"Filenames","name":"Filenames","type":"VHS_FILENAMES","links":null}],"properties":{"cnr_id":"comfyui-videohelpersuite","ver":"3234937ff5f3ca19068aaba5042771514de2429d","Node name for S&R":"VHS_VideoCombine"},"widgets_values":{"frame_rate":16,"loop_count":0,"filename_prefix":"WAN22","format":"video/h264-mp4","pix_fmt":"yuv420p","crf":12,"save_metadata":true,"trim_to_audio":false,"pingpong":false,"save_output":true,"videopreview":{"hidden":false,"paused":false,"params":{"filename":"WAN22_00014-audio.mp4","subfolder":"","type":"output","format":"video/h264-mp4","frame_rate":25,"workflow":"WAN22_00014.png","fullpath":"D:\\ComfyUI_windows_portable\\ComfyUI\\output\\WAN22_00014-audio.mp4"}}}},{"id":6,"type":"VHS_VideoCombine","pos":[-1600.5461338139992,-1657.628302498228],"size":[343.48707601299293,466.34893024865596],"flags":{},"order":2,"mode":0,"inputs":[{"localized_name":"images","name":"images","type":"IMAGE","link":26},{"localized_name":"audio","name":"audio","shape":7,"type":"AUDIO","link":27},{"localized_name":"meta_batch","name":"meta_batch","shape":7,"type":"VHS_BatchManager","link":null},{"localized_name":"vae","name":"vae","shape":7,"type":"VAE","link":null},{"localized_name":"frame_rate","name":"frame_rate","type":"FLOAT","widget":{"name":"frame_rate"},"link":28},{"localized_name":"loop_count","name":"loop_count","type":"INT","widget":{"name":"loop_count"},"link":null},{"localized_name":"filename_prefix","name":"filename_prefix","type":"STRING","widget":{"name":"filename_prefix"},"link":null},{"localized_name":"format","name":"format","type":"COMBO","widget":{"name":"format"},"link":null},{"localized_name":"pingpong","name":"pingpong","type":"BOOLEAN","widget":{"name":"pingpong"},"link":null},{"localized_name":"save_output","name":"save_output","type":"BOOLEAN","widget":{"name":"save_output"},"link":null},{"name":"pix_fmt","type":["yuv420p","yuv420p10le"],"widget":{"name":"pix_fmt"},"link":null},{"name":"crf","type":"INT","widget":{"name":"crf"},"link":null},{"name":"save_metadata","type":"BOOLEAN","widget":{"name":"save_metadata"},"link":null},{"name":"trim_to_audio","type":"BOOLEAN","widget":{"name":"trim_to_audio"},"link":null}],"outputs":[{"localized_name":"Filenames","name":"Filenames","type":"VHS_FILENAMES","links":null}],"title":"COMPRESS","properties":{"cnr_id":"comfyui-videohelpersuite","ver":"3234937ff5f3ca19068aaba5042771514de2429d","Node name for S&R":"VHS_VideoCombine"},"widgets_values":{"frame_rate":16,"loop_count":0,"filename_prefix":"WAN22_comp","format":"video/h264-mp4","pix_fmt":"yuv420p","crf":24,"save_metadata":true,"trim_to_audio":false,"pingpong":false,"save_output":true,"videopreview":{"hidden":false,"paused":false,"params":{"filename":"WAN22_comp_00014-audio.mp4","subfolder":"","type":"output","format":"video/h264-mp4","frame_rate":25,"workflow":"WAN22_comp_00014.png","fullpath":"D:\\ComfyUI_windows_portable\\ComfyUI\\output\\WAN22_comp_00014-audio.mp4"}}}},{"id":10,"type":"AutoEditWorkbench","pos":[-2550.2262615422846,-1946.457997751766],"size":[271.859375,290],"flags":{},"order":0,"mode":0,"inputs":[{"localized_name":"directory_path","name":"directory_path","type":"STRING","widget":{"name":"directory_path"},"link":null},{"localized_name":"sort_strategy","name":"sort_strategy","type":"COMBO","widget":{"name":"sort_strategy"},"link":null},{"localized_name":"resize_mode","name":"resize_mode","type":"COMBO","widget":{"name":"resize_mode"},"link":null},{"localized_name":"resolution_strategy","name":"resolution_strategy","type":"COMBO","widget":{"name":"resolution_strategy"},"link":null},{"localized_name":"custom_width","name":"custom_width","type":"INT","widget":{"name":"custom_width"},"link":null},{"localized_name":"custom_height","name":"custom_height","type":"INT","widget":{"name":"custom_height"},"link":null},{"localized_name":"fps_strategy","name":"fps_strategy","type":"COMBO","widget":{"name":"fps_strategy"},"link":null},{"localized_name":"custom_fps","name":"custom_fps","type":"INT","widget":{"name":"custom_fps"},"link":null},{"localized_name":"limit_duration_sec","name":"limit_duration_sec","type":"FLOAT","widget":{"name":"limit_duration_sec"},"link":null}],"outputs":[{"localized_name":"images","name":"images","type":"IMAGE","links":[23,26]},{"localized_name":"audio","name":"audio","type":"AUDIO","links":[24,27]},{"localized_name":"fps","name":"fps","type":"FLOAT","links":[25,28]}],"properties":{"aux_id":"Verolelb/ComfyUI-Video-Workbench","ver":"fc7d474d46752f615bc0c1ee6a7ef25642bd453d","Node name for S&R":"AutoEditWorkbench"},"widgets_values":["C:\\Users\\kuro5\\Downloads\\test","alphabetical_asc","Crop (Fill Screen)","First Video",512,512,"First Video",24,0]}],"links":[[23,10,0,2,0,"IMAGE"],[24,10,1,2,1,"AUDIO"],[25,10,2,2,4,"FLOAT"],[26,10,0,6,0,"IMAGE"],[27,10,1,6,1,"AUDIO"],[28,10,2,6,4,"FLOAT"]],"groups":[],"config":{},"extra":{"ds":{"scale":0.7400249944258326,"offset":[3567.5503545344054,2635.8870301353213]},"workflowRendererVersion":"LG"},"version":0.4} \ No newline at end of file