Commit Graph
80 Commits
Author SHA1 Message Date
Meisoftcoltd ba5a3d5c09 refactor(core): implement robust multi-scene state machine and flawless pipeline routing 2026-06-26 16:49:45 +00:00
Meisoftcoltd 1bdaa80875 fix: Dynamic has_more_batches detection and absolute final fix
- Updated SequentialAudioBatchLoader to dynamically evaluate global_has_more_batches rather than statically assigning False.
- Refactored IncrementalVideoStitcher to calculate is_absolute_final only when both the current chunk is complete and there are no more batches in queue.
- Updated return blocks in stitch method to propagate new is_absolute_final logic.
2026-05-26 06:50:35 +00:00
Meisoftcoltd b417f855c2 feat(video): add IS_ABSOLUTE_FINAL output to IncrementalVideoStitcher
Adds a new boolean output `IS_ABSOLUTE_FINAL` to the `IncrementalVideoStitcher` node.
This determines if the current generation cycle is the very last one across all processed batches, by checking `global_has_more_batches` from `loop.py`. Updates the tuple structures and node signatures to reflect this new return type.
2026-05-25 14:47:09 +00:00
Meisoftcoltd af8ef37b79 Fix ComfyUI aggressive caching in cyclic nodes
Added `IS_CHANGED` class methods to calculation nodes (`AutoLoopCalculator`, `AutoLoopCalculatorTTS`, `AutoLoopCalculatorWan`, `AutoLoopCalculatorLTX`, `AutoLoopCalculatorTTSBatch`) and `LazySessionCache` to force ComfyUI to re-evaluate them continuously, resolving a false positive cache issue that prevented global Python state variables from updating correctly across batch boundaries.
2026-05-25 04:58:11 +00:00
Meisoft 791f394dd5 Merge pull request #118 from Meisoftcoltd/fix-insecure-deserialization-12125730200173000788
🔒 Fix insecure deserialization via torch.load
2026-05-14 22:29:15 +02:00
Meisoftcoltd 71534b968e Use safetensors instead of torch.save/load to fix insecure deserialization 2026-05-14 20:25:20 +00:00
Meisoftcoltd 3afcee2bef test: add safety guards and unit tests for video loop calculators
Added input validations (`source_frame_count <= 0` or `target_frames_per_loop <= 0`) to `AutoLoopCalculatorLTX` (in `loop.py`), and `AutoLoopCalculator`, `AutoLoopCalculatorWan` (in `video.py`). When conditions are met, a safe default is returned to prevent math domain errors. Also included a new comprehensive unit test suite in `tests/test_loop_calculator.py`.
2026-05-14 20:24:55 +00:00
Meisoftcoltd 6cd32fcfe9 Fix: Resolve Unit Clash between TTS chunks and video frames in Sequential Batcher
- Introduce `global_step_by_chunk` ghost variable initialized to `False` in `loop.py`
- Set `loop.global_step_by_chunk = True` in `AutoLoopCalculatorTTS` to indicate chunk mode
- Reset `loop.global_step_by_chunk = False` in video calculators (`AutoLoopCalculator`, `AutoLoopCalculatorWan`, `AutoLoopCalculatorLTX`) to ensure state resets
- Update `SessionImageSender.send_image` timeline management to branch logic, using `is_chunk_mode` to calculate progress differently for text chunks versus video frames
2026-05-13 22:34:58 +00:00
Meisoftcoltd 7b900c10cd feat(tts): implement intelligent text buffering for AutoLoopCalculatorTTS
This commit replaces the raw regex text-splitting logic in `AutoLoopCalculatorTTS` with an "intelligent buffer" approach. It first splits the text by sentence terminators as before, but now aggregates these smaller segments until they contain a minimum of 5 words.

This prevents TTS models from generating robotic, out-of-context micro-audios when encountering trailing ellipses (`...`) or extremely short phrases, leading to more natural intonation and pacing.

All existing loop and timeline injections are preserved.
2026-05-11 21:48:30 +00:00
Meisoftcoltd d1d5f47562 feat(tts): implement regex-based robust chunking for AutoLoopCalculatorTTS
Replaced simple paragraph/sentence splitting with advanced regex
to gracefully handle split scenarios involving `.`, `?`, `!`,
quotes, ellipses, and `\n`. Punctuation is correctly retained on
the chunks to assure proper TTS intonation.

Moved `import re` to module level imports.
2026-05-09 17:46:49 +00:00
Meisoftcoltd d6c2a4b012 Fix RuntimeError due to in-place tensor updates in InferenceMode
Refactors `IncrementalVideoStitcher.stitch` to eliminate in-place assignments
into a pre-allocated empty tensor when loading image frames in parallel, which
caused `RuntimeError: Inplace update to inference tensor outside InferenceMode
is not allowed.` in newer PyTorch versions.

The refactored implementation uses a pure map function to return individual
tensors and concatenates them sequentially using `torch.cat`, remaining thread-safe
and compatible with PyTorch's `InferenceMode`. Security against deserialization
vulnerabilities is preserved by ensuring `weights_only=True` remains when loading
audio caches.
2026-05-02 21:55:05 +00:00
Meisoft 26428789ae Merge pull request #103 from Meisoftcoltd/fix-insecure-deserialization-torch-load-video-3886399146367191308
🔒 [security fix] Insecure Deserialization via torch.load() in video.py
2026-05-02 22:44:51 +02:00
Meisoftcoltd 4ce91323a1 🔒 Security fix: Use weights_only=True in torch.load()
Added `weights_only=True` to `torch.load()` in `video.py` to prevent insecure deserialization and potential arbitrary code execution via crafted pickle files. This change restricts the unpickler to only load tensors, primitive types, and basic containers, which is sufficient for the audio dictionary being loaded.
2026-05-02 20:44:38 +00:00
Meisoft cb7b0374ae Merge pull request #102 from Meisoftcoltd/update-tts-calculator-split-mode-4843793747721075440
feat: Update AutoLoopCalculatorTTS to support sentence and paragraph splitting
2026-05-02 22:43:02 +02:00
Meisoftcoltd 08edcf71cb feat: add split mode to AutoLoopCalculatorTTS
This commit introduces a new dropdown to the `AutoLoopCalculatorTTS` node inside `video.py`, allowing text to be split by either "Párrafos (Saltos de línea)" or "Frases (Puntos)". When splitting by sentences, it cleanly preserves the periods to maintain proper intonation in TTS systems. Output pins are renamed (`current_text`, `total_chunks`) for better semantics.
2026-05-02 20:31:44 +00:00
Meisoftcoltd 60fc92fec0 🧹 Cleanup unused and redundant imports in video.py
- Removed unused import `sys`.
- Removed unused import `nodes`.
- Removed redundant duplicate import `torch`.
- Removed orphaned comment related to the duplicate import.
2026-05-02 20:29:12 +00:00
Meisoft a875f536da Merge pull request #98 from Meisoftcoltd/perf-concurrent-image-loading-13430517007901480050
⚡ [Performance] Concurrent image loading in Video Stitcher
2026-04-30 16:56:44 +02:00
Meisoftcoltd 12a55c7fd6 ⚡ [Performance] Concurrent image loading in Video Stitcher
Introduced concurrent image loading and processing in the Video Stitcher node
using ThreadPoolExecutor. This optimizes the transition from disk-cached PNGs
to the final video tensor by parallelizing I/O and color conversion.

- Replaced sequential loop with ThreadPoolExecutor.map
- Wrapped executor.map in list() to ensure exception propagation
- Verified ~85% speedup in mocked I/O-bound benchmarks
2026-04-30 14:55:12 +00:00
Meisoftcoltd b854a90bf9 feat: add AutoLoopCalculatorTTS and update IncrementalVideoStitcher for audio caching
- Registered `AutoLoopCalculatorTTS` in `NODE_DISPLAY_NAME_MAPPINGS`.
- Added `AutoLoopCalculatorTTS` class to `video.py` to allow looping through text paragraphs instead of video frames.
- Replaced the implementation of `IncrementalVideoStitcher` to cache audio tensors as `.pt` files and concatenate them along the time axis on the final cycle.
2026-04-28 17:26:50 +00:00
Meisoftcoltd e4f53ca75a feat(video): add conditional FFmpeg audio standardizer for VHS safety
- Introduced `standardize_video_file` helper in `video.py`.
- The helper creates a physical video clone via FFmpeg, copying the video stream exactly to retain quality while limiting the audio stream.
- Audio limits are conditionally applied using `torchaudio.info` (<=44100Hz and <=2 Channels) to avoid unnecessary processing.
- Implemented a "Fail-Fast" approach with `raise Exception` if the FFmpeg cloning process fails, preventing silent downstream crashes.
- Injected the helper directly into `VideoAnalyzerFaceDetector` and `VideoAnalyzerSceneDetector` to secure the path passed down to VHS.
2026-04-25 18:50:46 +00:00
Meisoftcoltd de0797ddb9 Refactor audio extraction and clean up residual files
- Created `extract_and_standardize_audio` helper in `video.py` to standardize audio to 44100Hz and Stereo format.
- Refactored `VideoAnalyzerFaceDetector` and `VideoAnalyzerSceneDetector` to use the new helper function.
- Permanently deleted `modify_facedetector.py`, `modify_facedetector2.py`, and `modify_facedetector3.py` residual scripts.
2026-04-25 13:46:36 +00:00
Meisoftcoltd d660a6b41b Refactor loop calculators to prioritize scene cuts over face cuts\n\n* Added SCENE_CUTS type to VideoAnalyzerSceneDetector.\n* Replaced "safe_faces_list" usage in loop calculators with "scene_cuts_list" as priority.\n* Removed dead code/scripts: update_video.py, fix_newlines.py, fix_tqdm.py, add_scenedetector.py. 2026-04-25 12:20:48 +00:00
Meisoftcoltd 5983ff65b4 feat: rename video analyzer to face detector, add global cache, and introduce scene detector node
- Renamed `VideoAnalyzerWithAudio` to `VideoAnalyzerFaceDetector`.
- Introduced `VIDEO_ANALYSIS_CACHE` and `current_loop_index` for cycle caching.
- Created `VideoAnalyzerSceneDetector` to detect scene changes via pixel difference.
- Added dynamic reference frame preview functionality outside the caching logic.
- Registered nodes with proper display names in `__init__.py`.
2026-04-24 21:29:55 +00:00
Meisoftcoltd ce6041da4a feat: rename [DEBUG] to [Secuencial Batcher] and add STRING log outputs to all nodes
This commit addresses two primary requests:
1. Replaces all console log prefixes `[DEBUG]` (and variations) with `[Secuencial Batcher]`.
2. Extends the `RETURN_TYPES` and `RETURN_NAMES` of all nodes to output a `log` string containing exactly the text emitted via `print()`. This string is constructed by intercepting `print()` calls inside node methods using a local wrapper and appending the texts to a list, which is then returned joined by newlines.
2026-04-19 13:33:52 +00:00
Meisoftcoltd 7187f783b4 feat: enforce 4n+1 frame rule for WanVideo VAE padding and calculations
Replaces the previous "multiple of 4" rule with the `4n + 1` logic across
the AutoLoopCalculatorWan and VAESafeFramePadder nodes. This prevents frame
loss / truncation inside the VAE and ensures absolute consistency for
long generation runs and video reconstruction. Mention of "múltiplo de 4"
in the primary README has also been updated to "regla de 4n + 1".
2026-04-12 19:02:40 +00:00
Meisoftcoltd 444b6c6513 Fix VAE frame loss by forcing timeline completion on final chunk and optimize stitcher RAM via lightweight PNG caching. 2026-04-12 16:10:56 +00:00
Meisoftcoltd 8dc273ff16 fix: blindar IncrementalVideoStitcher para evitar sobreescritura de frames
- Se introduce la subcarpeta `meisoft_video_cache`.
- Se guardan los lotes con un timestamp en milisegundos para evitar sobreescrituras en caso de que falle el `current_loop_index`.
- Se incorpora `@classmethod def IS_CHANGED` con `time.time()` para obligar a ComfyUI a ejecutar siempre el nodo e ignorar el cache.
- El directorio temporal se limpia correctamente en el ciclo 0 y se destruye tras ensamblar el vídeo completo.
2026-04-12 14:26:43 +00:00
Meisoftcoltd 0d794fc10e fix: decouple timeline from frame padding to prevent EOF crashes
Replaced artificial safe limit in AutoLoopCalculatorWan (video.py) and
AutoLoopCalculatorLTX (loop.py) with actual physical source frame limit.
This prevents trigger nodes from falsely requesting frames past the EOF
which resulted in "RuntimeError: No frames generated".
2026-04-12 10:26:08 +00:00
Meisoftcoltd 1b75c40e3e feat: add VAESafeFramePadder and update loop calculators math
- Added VAESafeFramePadder to `tools.py` which clones the last frame
  of an image tensor to satisfy mathematical rules (4n for WanVideo,
  8n+1 for LTX) avoiding audio clipping and VAE crashes.
- Registered the new tool in `__init__.py` under NODE_DISPLAY_NAME_MAPPINGS.
- Updated `AutoLoopCalculatorWan` in `video.py` to pad and round up to a
  multiple of 4.
- Updated `AutoLoopCalculatorLTX` in `loop.py` to pad and round up to an
  8n+1 multiple.
2026-04-12 01:33:46 +00:00
Meisoftcoltd 2731ab0779 feat(video): add native ComfyUI progress bar to VideoAnalyzerWithAudio
Inject `comfy.utils.ProgressBar` into the frame scanning loop in `VideoAnalyzerWithAudio`. This provides a visual native green progress bar directly on the node in the ComfyUI interface, giving real-time feedback during long video analyses without requiring the user to monitor the terminal output.
2026-04-10 08:30:56 +00:00
Meisoftcoltd 35975007e7 fix(video): fix cache invalidation in VideoAnalyzerWithAudio
Update `IS_CHANGED` in `VideoAnalyzerWithAudio` to rely on the video path
and node parameters instead of `os.path.getmtime` and `time.time()`. This fixes
an issue where the node would constantly invalidate the cache and re-run on
every execution, rather than reusing cached results when inputs have not changed.
2026-04-10 08:19:59 +00:00
Meisoftcoltd 63e84c2aa1 Fix Micro-Cycle Death Loops in frame calculation
This commit patches the `SessionImageSender`, `AutoLoopCalculatorWan`,
and `AutoLoopCalculatorLTX` nodes to prevent infinite loops caused by
extreme truncation at the end of video sequences.

- `image.py`: Ensures `SessionImageSender` accepts the entire batch if no
  faces are detected, rather than defaulting to frame 0, which previously
  trapped the workflow in a 1-frame micro-cycle loop.
- `video.py`: Updates `AutoLoopCalculatorWan` to always round the final
  chunk size up to the nearest multiple of 4, removing the strict
  cropping logic that broke the 3D VAE rule.
- `loop.py`: Updates `AutoLoopCalculatorLTX` to always round the final
  chunk size up to the nearest `8n + 1` value, removing the strict
  cropping logic that broke the DiT rule.
2026-04-08 21:22:08 +00:00
Meisoftcoltd 1c90c848e2 feat: implement deep VRAM defragmentation and PyTorch memory allocator fix
- Enforced a strict memory cleanup sequence in `MeisoftVRAMDefragmenter` (including IPC cleanup and CUDA synchronization).
- Injected `PYTORCH_CUDA_ALLOC_CONF="max_split_size_mb:128"` in `__init__.py` to prevent VRAM micro-fragmentation.
- Added `unload_detector` option to `VideoAnalyzerWithAudio` to eagerly destroy the face detector model and free VRAM.
2026-04-08 11:56:02 +00:00
Meisoftcoltd 1e36f9e915 feat: implement VRAM defragmentation strategy and optimization
- Created `MeisoftVRAMDefragmenter` in `vram_node.py` as a passthrough to force model unloading, Python garbage collection, and CUDA cache defragmentation.
- Registered the new node in `__init__.py`.
- Added light memory cleanup on intermediate batch loops in `loop.py`, alongside a heavy cleanup (including ctypes `malloc_trim`) at the end.
- Added `unload_detector_after_analysis` boolean flag to `VideoAnalyzerWithAudio` in `video.py` to allow releasing the BBOX detector model immediately after use.
2026-04-08 07:48:48 +00:00
Meisoftcoltd bd6016f559 fix: bypass keyframe save and output full tensor on final cycle
- Updated `SessionImageSender` to conditionally save keyframe only when not in the final cycle.
- Updated `IncrementalVideoStitcher` to return full concatenated tensor when in the final cycle, avoiding dummy frame output and blocking downstream nodes.
- Expose `IS_FINAL_CYCLE` boolean from `IncrementalVideoStitcher` to UI for downstream conditionals.
2026-04-05 21:32:14 +00:00
Meisoftcoltd 608be49841 fix: Silence YOLO outputs and improve transparency in calculators 2026-04-05 17:03:15 +00:00
Meisoftcoltd 93d479fb6c fix: correct ImpactPack tuple unpacking and add tqdm to video frame scan
- Fixed tuple index extraction (`res[0]`) for `SEGS` object in bbox_detector.
- Silenced Ultralytics/YOLO console spam by wrapping detection logic in `redirect_stdout`.
- Upgraded the `while True:` loop to a `for` loop with `tqdm` for a clean progress bar, while preserving the RGB frame conversion logic for accuracy.
2026-04-05 11:26:17 +00:00
Meisoftcoltd a5db690cdf feat: implement proportional adjustment logic for AutoLoopCalculators
- Patches `AutoLoopCalculator` in `video.py` to add base proportional adjustment without VAE constraints.
- Patches `AutoLoopCalculatorLTX` in `loop.py` to enforce the strict 8n + 1 frame rule for LTX models, matching its calculation mathematically correctly for proportional chunking.
- Fixes `__pycache__` to be excluded correctly.
2026-04-05 09:36:44 +00:00
Meisoftcoltd 8ae2905bb3 feat: modularize VideoAnalyzerWithAudio to accept external YOLO/ONNX models
- Add optional `bbox_detector` input to `VideoAnalyzerWithAudio`.
- Implement GPU-accelerated face detection using external BBOX_DETECTOR models.
- Support both ImpactPack and standard ONNX bounding box output formats.
- Retain CPU-based OpenCV face detection as a fallback.
- Rename node in UI to "🕵️ Video Analyzer Face detector + Audio".
- Update README.md and README_EN.md to reflect new architecture and wiring.
2026-04-04 23:56:51 +00:00
Meisoftcoltd dc0d3db2f8 feat: proportional frame target recalculation for wanvideo calculator
* Add MEISOFT PATCH to AutoLoopCalculatorWan to dynamically adjust target frames based on safe effective frame multiples.
* Replace static math.ceil calculations and frame absorptions to equitably distribute frames for 3D VAE rendering.
* Simplify chunk limits validation utilizing pre-calculated mathematical bounds, preventing VAE crash micro-cycles.
2026-04-04 19:33:17 +00:00
Meisoftcoltd e77fca6dcf feat: change VideoAnalyzerWithAudio output path type to wildcard
Changed the output type for the video path in the VideoAnalyzerWithAudio
node from STRING to `*` to allow for flexible wildcard connections in
ComfyUI. Also updated the return name to video_path to accurately
reflect the output variable.
2026-04-03 08:21:25 +00:00
Meisoftcoltd 8ab37acb47 feat: Global Update v1.5.2
- Improve error handling in video.py to capture and display Torchaudio exceptions.
- Add explicit list of dependencies in requirements.txt.
- Introduce install.py for automated installation of Python and OS dependencies (FFmpeg).
- Complete redesign of Spanish and English READMEs with v1.5.2 Changelog, new features, and professional workflow setup.
2026-04-02 06:52:39 +00:00
Meisoftcoltd 8afdfa703f Refactor VideoAnalyzerWithAudio input to natively support VHS hybrid connections
Updated the `VideoAnalyzerWithAudio` node in `video.py` to match the exact behavior of `VHS_LoadVideo`. By removing the wildcard (`*`) hack and providing a valid tuple with a local file list alongside `{"forceInput": False, "video_upload": True}`, the node now officially renders a standard ComfyUI file uploader widget that can be cleanly converted to a `STRING` input via right-click ("Convert video to input").

Also retained the absolute `VALIDATE_INPUTS` shield returning `True`, guaranteeing dynamic wire inputs (e.g. from YTDLP) won't cause ComfyUI execution queue validation errors when dealing with paths generated at runtime. Cleaned up internal list unpacking hacks in `IS_CHANGED` and `analyze` since standard strings are now properly passed.
2026-04-01 13:49:06 +00:00
Meisoftcoltd b85e6b9181 fix(video): change video input type to wildcard to support dynamic connections
Replaced the strict 'STRING' input type with the '*' wildcard in `VideoAnalyzerWithAudio`. This bypasses ComfyUI's strict type checking for the input port, allowing downloading nodes (like YTDPL) that output custom types (e.g., `VIDEO_PATH` or `PATH`) to connect seamlessly. Updated `VALIDATE_INPUTS` comments to reflect its role as a 'Total Shield' for bypassing dynamic path validation.
2026-04-01 13:08:09 +00:00
Meisoftcoltd 44af2b0db5 Fix ComfyUI strict pre-flight validation for dynamic video downloads
- Inject VALIDATE_INPUTS method into VideoAnalyzerWithAudio class.
- Allows downstream dynamic file paths while keeping manual VHS upload widget intact.
2026-04-01 12:48:45 +00:00
Meisoftcoltd 0cdc0394fe refactor: remove VALIDATE_INPUTS to fix dynamic routing block
Deleted `opt_video_path` parameter and the strict `VALIDATE_INPUTS` classmethod in `VideoAnalyzerWithAudio`. ComfyUI was validating the cached manual widget value before downstream dynamic nodes could finish processing strings. Routing everything directly through a single `video` input and completely removing `VALIDATE_INPUTS` properly delegates execution dependency to ComfyUI's native graph path order.
2026-04-01 12:20:54 +00:00
Meisoftcoltd 091cffe3d4 Update VALIDATE_INPUTS in VideoAnalyzerWithAudio
Implemented a hybrid validation logic in the `VALIDATE_INPUTS` method of `VideoAnalyzerWithAudio`.
This bypasses the strict `os.path.exists()` check if the optional dynamic input (`opt_video_path`) is connected, allowing ComfyUI to start the workflow and wait for upstream nodes (like downloaders) to create the file at runtime.
Strict physical file validation is maintained for the standard manual video upload widget.
2026-04-01 11:36:58 +00:00
Meisoftcoltd 5a9bafe7d6 feat: add optional physical wire input for video path to VideoAnalyzerWithAudio
Added an optional `opt_video_path` string input (with `forceInput: True`) to the `VideoAnalyzerWithAudio` node. This allows the node to receive a video path from another upstream node physically via a wire connection, bypassing the default file upload widget when connected. The `IS_CHANGED`, `VALIDATE_INPUTS` and `analyze` methods were uniformly updated to intercept and prioritize this new optional input.
2026-04-01 11:13:06 +00:00
Meisoftcoltd bc49d06000 feat: allow absolute paths in VideoAnalyzerWithAudio
Update `VideoAnalyzerWithAudio` in `video.py` to support absolute paths for the `video_name` parameter. The node's `IS_CHANGED`, `VALIDATE_INPUTS`, and `analyze` methods have been modified to first check if the provided path exists directly using `os.path.exists()`. If it does, it uses the path directly, enabling the use of absolute paths. Otherwise, it falls back to the default `folder_paths.get_annotated_filepath()`.
2026-03-31 16:08:05 +00:00
Meisoftcoltd 480ae9d815 feat: add AutoLoopCalculatorWan node with mathematical truncation for WanVideo 3D VAE
- Register `AutoLoopCalculatorWan` with its visual display name in `__init__.py`.
- Append `AutoLoopCalculatorWan` class definition to `video.py`.
- The new node enforces strict truncation in multiples of 4 to prevent 3D VAE crashes on the WanVideo model while skipping asymmetric trailing frames.
2026-03-31 15:30:44 +00:00