From 333a281eefa631671cb4987851a85aba1a8f77e7 Mon Sep 17 00:00:00 2001 From: Ethan Fel <28683423+ethanfel@users.noreply.github.com> Date: Sat, 15 Aug 2026 22:10:24 +0200 Subject: [PATCH] docs: simplify demo to SPEED and BIM-VFI --- README.md | 5 +- .../tween_speed_bim_model_lab.json | 323 ++++++++ .../tween_speed_ldf_model_lab.json | 757 ------------------ tests/test_demo_workflow.py | 53 ++ 4 files changed, 378 insertions(+), 760 deletions(-) create mode 100644 example_workflows/tween_speed_bim_model_lab.json delete mode 100644 example_workflows/tween_speed_ldf_model_lab.json create mode 100644 tests/test_demo_workflow.py diff --git a/README.md b/README.md index 78be57d..ec257be 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,9 @@ Dependencies are declared in `pyproject.toml` and `requirements.txt` and are ins ### Demo workflow -Import [`example_workflows/tween_speed_ldf_model_lab.json`](example_workflows/tween_speed_ldf_model_lab.json) for the recommended starter graph. It requires [ComfyUI-VideoHelperSuite](https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite) for video loading and encoding. +Import [`example_workflows/tween_speed_bim_model_lab.json`](example_workflows/tween_speed_bim_model_lab.json) for the recommended starter graph. It requires [ComfyUI-VideoHelperSuite](https://github.com/Kosinkadink/ComfyUI-VideoHelperSuite) for video loading and encoding. -- The enabled SPEED branch loads a 25-frame, 24 FPS sample, automatically tunes memory settings, interpolates to 48 FPS, preserves audio, and writes `Tween/demo_speed_24_to_48`. -- The LDF-VFI branch is visibly grouped and muted by default so the workflow does not unexpectedly download ~6.4 GB or reserve ~20 GB VRAM. Enable its three coral nodes when you want to compare the sequence-native model. +- The SPEED and BIM-VFI branches load the same 25-frame, 24 FPS sample, tune memory settings independently, interpolate to 48 FPS, preserve audio, and save separate comparison videos. - Keep the loader's `force_rate`, Tween's `source_fps`/`target_fps`, and Video Combine's `frame_rate` synchronized when changing cadence. ### cupy (accelerates BIM-VFI, SGM-VFI, and GIMM-VFI) diff --git a/example_workflows/tween_speed_bim_model_lab.json b/example_workflows/tween_speed_bim_model_lab.json new file mode 100644 index 0000000..37c75fe --- /dev/null +++ b/example_workflows/tween_speed_bim_model_lab.json @@ -0,0 +1,323 @@ +{ + "last_node_id": 9, + "last_link_id": 14, + "nodes": [ + { + "id": 1, + "type": "VHS_LoadVideoPath", + "pos": [20, 170], + "size": [300, 310], + "flags": {}, + "order": 0, + "mode": 0, + "inputs": [ + {"name": "meta_batch", "shape": 7, "type": "VHS_BatchManager", "link": null}, + {"name": "vae", "shape": 7, "type": "VAE", "link": null} + ], + "outputs": [ + {"name": "IMAGE", "type": "IMAGE", "links": [1, 8]}, + {"name": "frame_count", "type": "INT", "links": null}, + {"name": "audio", "type": "AUDIO", "links": [7, 14]}, + {"name": "video_info", "type": "VHS_VIDEOINFO", "links": null} + ], + "properties": { + "cnr_id": "comfyui-videohelpersuite", + "Node name for S&R": "VHS_LoadVideoPath" + }, + "widgets_values": { + "video": "", + "force_rate": 24, + "custom_width": 0, + "custom_height": 0, + "frame_load_cap": 25, + "skip_first_frames": 0, + "select_every_nth": 1, + "format": "AnimateDiff", + "videopreview": { + "hidden": false, + "paused": false, + "params": { + "filename": "", + "type": "path", + "format": "video/", + "force_rate": 24, + "custom_width": 0, + "custom_height": 0, + "frame_load_cap": 25, + "skip_first_frames": 0, + "select_every_nth": 1 + } + } + } + }, + { + "id": 2, + "type": "LoadSPEEDVFIModel", + "pos": [390, 150], + "size": [300, 105], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [], + "outputs": [ + {"name": "model", "type": "SPEED_VFI_MODEL", "links": [2, 4]} + ], + "properties": { + "aux_id": "ComfyUI-Tween.git", + "Node name for S&R": "LoadSPEEDVFIModel" + }, + "widgets_values": ["speed.pt", "auto"], + "color": "#243b32", + "bgcolor": "#315244" + }, + { + "id": 3, + "type": "VFIOptimizer", + "pos": [390, 320], + "size": [310, 150], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + {"name": "images", "type": "IMAGE", "link": 1}, + {"name": "model", "type": "*", "link": 2} + ], + "outputs": [ + {"name": "images", "type": "IMAGE", "links": [3]}, + {"name": "settings", "type": "VFI_SETTINGS", "links": [5]} + ], + "properties": { + "aux_id": "ComfyUI-Tween.git", + "Node name for S&R": "VFIOptimizer" + }, + "widgets_values": [2, 0], + "color": "#243b32", + "bgcolor": "#315244" + }, + { + "id": 4, + "type": "SPEEDVFIInterpolate", + "pos": [760, 220], + "size": [355, 360], + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [ + {"name": "images", "type": "IMAGE", "link": 3}, + {"name": "model", "type": "SPEED_VFI_MODEL", "link": 4}, + {"name": "settings", "shape": 7, "type": "VFI_SETTINGS", "link": 5} + ], + "outputs": [ + {"name": "images", "type": "IMAGE", "links": [6]}, + {"name": "oversampled", "type": "IMAGE", "links": null}, + {"name": "elapsed_seconds", "type": "FLOAT", "links": null} + ], + "properties": { + "aux_id": "ComfyUI-Tween.git", + "Node name for S&R": "SPEEDVFIInterpolate" + }, + "widgets_values": [2, 10, true, false, 1, 0, 24, 48, 0], + "color": "#243b32", + "bgcolor": "#315244" + }, + { + "id": 5, + "type": "VHS_VideoCombine", + "pos": [1170, 220], + "size": [360, 340], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + {"name": "images", "type": "IMAGE", "link": 6}, + {"name": "audio", "shape": 7, "type": "AUDIO", "link": 7}, + {"name": "meta_batch", "shape": 7, "type": "VHS_BatchManager", "link": null}, + {"name": "vae", "shape": 7, "type": "VAE", "link": null} + ], + "outputs": [ + {"name": "Filenames", "type": "VHS_FILENAMES", "links": null} + ], + "properties": { + "cnr_id": "comfyui-videohelpersuite", + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 48, + "loop_count": 0, + "filename_prefix": "Tween/demo_speed_24_to_48", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 19, + "save_metadata": true, + "trim_to_audio": false, + "pingpong": false, + "save_output": true, + "videopreview": {"hidden": false, "paused": false, "params": {}} + }, + "color": "#243b32", + "bgcolor": "#315244" + }, + { + "id": 6, + "type": "LoadBIMVFIModel", + "pos": [390, 790], + "size": [300, 125], + "flags": {}, + "order": 5, + "mode": 0, + "inputs": [], + "outputs": [ + {"name": "model", "type": "BIM_VFI_MODEL", "links": [9, 11]} + ], + "properties": { + "aux_id": "ComfyUI-Tween.git", + "Node name for S&R": "LoadBIMVFIModel" + }, + "widgets_values": ["bim_vfi.pth", true, 3], + "color": "#28384a", + "bgcolor": "#36506b" + }, + { + "id": 7, + "type": "VFIOptimizer", + "pos": [390, 970], + "size": [310, 150], + "flags": {}, + "order": 6, + "mode": 0, + "inputs": [ + {"name": "images", "type": "IMAGE", "link": 8}, + {"name": "model", "type": "*", "link": 9} + ], + "outputs": [ + {"name": "images", "type": "IMAGE", "links": [10]}, + {"name": "settings", "type": "VFI_SETTINGS", "links": [12]} + ], + "properties": { + "aux_id": "ComfyUI-Tween.git", + "Node name for S&R": "VFIOptimizer" + }, + "widgets_values": [2, 0], + "color": "#28384a", + "bgcolor": "#36506b" + }, + { + "id": 8, + "type": "BIMVFIInterpolate", + "pos": [760, 860], + "size": [355, 340], + "flags": {}, + "order": 7, + "mode": 0, + "inputs": [ + {"name": "images", "type": "IMAGE", "link": 10}, + {"name": "model", "type": "BIM_VFI_MODEL", "link": 11}, + {"name": "settings", "shape": 7, "type": "VFI_SETTINGS", "link": 12} + ], + "outputs": [ + {"name": "images", "type": "IMAGE", "links": [13]}, + {"name": "oversampled", "type": "IMAGE", "links": null}, + {"name": "elapsed_seconds", "type": "FLOAT", "links": null} + ], + "properties": { + "aux_id": "ComfyUI-Tween.git", + "Node name for S&R": "BIMVFIInterpolate" + }, + "widgets_values": [2, 10, true, false, 1, 0, 24, 48], + "color": "#28384a", + "bgcolor": "#36506b" + }, + { + "id": 9, + "type": "VHS_VideoCombine", + "pos": [1170, 860], + "size": [360, 340], + "flags": {}, + "order": 8, + "mode": 0, + "inputs": [ + {"name": "images", "type": "IMAGE", "link": 13}, + {"name": "audio", "shape": 7, "type": "AUDIO", "link": 14}, + {"name": "meta_batch", "shape": 7, "type": "VHS_BatchManager", "link": null}, + {"name": "vae", "shape": 7, "type": "VAE", "link": null} + ], + "outputs": [ + {"name": "Filenames", "type": "VHS_FILENAMES", "links": null} + ], + "properties": { + "cnr_id": "comfyui-videohelpersuite", + "Node name for S&R": "VHS_VideoCombine" + }, + "widgets_values": { + "frame_rate": 48, + "loop_count": 0, + "filename_prefix": "Tween/demo_bim_24_to_48", + "format": "video/h264-mp4", + "pix_fmt": "yuv420p", + "crf": 19, + "save_metadata": true, + "trim_to_audio": false, + "pingpong": false, + "save_output": true, + "videopreview": {"hidden": false, "paused": false, "params": {}} + }, + "color": "#28384a", + "bgcolor": "#36506b" + } + ], + "links": [ + [1, 1, 0, 3, 0, "IMAGE"], + [2, 2, 0, 3, 1, "*"], + [3, 3, 0, 4, 0, "IMAGE"], + [4, 2, 0, 4, 1, "SPEED_VFI_MODEL"], + [5, 3, 1, 4, 2, "VFI_SETTINGS"], + [6, 4, 0, 5, 0, "IMAGE"], + [7, 1, 2, 5, 1, "AUDIO"], + [8, 1, 0, 7, 0, "IMAGE"], + [9, 6, 0, 7, 1, "*"], + [10, 7, 0, 8, 0, "IMAGE"], + [11, 6, 0, 8, 1, "BIM_VFI_MODEL"], + [12, 7, 1, 8, 2, "VFI_SETTINGS"], + [13, 8, 0, 9, 0, "IMAGE"], + [14, 1, 2, 9, 1, "AUDIO"] + ], + "groups": [ + { + "id": 1, + "title": "INPUT · 24 FPS / 25 FRAMES", + "bounding": [-20, 100, 360, 470], + "color": "#625d52", + "font_size": 22, + "flags": {} + }, + { + "id": 2, + "title": "SPEED", + "bounding": [350, 100, 1240, 520], + "color": "#347a56", + "font_size": 22, + "flags": {} + }, + { + "id": 3, + "title": "BIM-VFI", + "bounding": [350, 740, 1240, 510], + "color": "#3f6488", + "font_size": 22, + "flags": {} + } + ], + "config": {}, + "extra": { + "workflowRendererVersion": "LG", + "ue_links": [], + "links_added_by_ue": [], + "ds": {"scale": 0.76, "offset": [80, 80]}, + "frontendVersion": "1.45.19", + "VHS_latentpreview": true, + "VHS_latentpreviewrate": 0, + "VHS_MetadataImage": true, + "VHS_KeepIntermediate": true + }, + "version": 0.4 +} diff --git a/example_workflows/tween_speed_ldf_model_lab.json b/example_workflows/tween_speed_ldf_model_lab.json deleted file mode 100644 index 2b501f4..0000000 --- a/example_workflows/tween_speed_ldf_model_lab.json +++ /dev/null @@ -1,757 +0,0 @@ -{ - "id": "d1b1b840-08a9-4f93-9a1a-5bb9bdb05c39", - "revision": 0, - "last_node_id": 13, - "last_link_id": 11, - "nodes": [ - { - "id": 1, - "type": "Note", - "pos": [ - 0, - 0 - ], - "size": [ - 1420, - 112 - ], - "flags": {}, - "order": 0, - "mode": 0, - "inputs": [], - "outputs": [], - "properties": { - "Node name for S&R": "Note" - }, - "widgets_values": [ - "TWEEN MODEL LAB — SPEED + LDF-VFI\n1) Choose a short input video below. 2) Queue Prompt to run the enabled SPEED path. 3) The LDF-VFI path is muted by default; enable its three coral nodes only when you want the heavier sequence model." - ], - "color": "#1f3a4d", - "bgcolor": "#294d66" - }, - { - "id": 2, - "type": "VHS_LoadVideoPath", - "pos": [ - 20, - 190 - ], - "size": [ - 300, - 310 - ], - "flags": {}, - "order": 1, - "mode": 0, - "inputs": [ - { - "name": "meta_batch", - "shape": 7, - "type": "VHS_BatchManager", - "link": null - }, - { - "name": "vae", - "shape": 7, - "type": "VAE", - "link": null - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 1, - 8 - ] - }, - { - "name": "frame_count", - "type": "INT", - "links": null - }, - { - "name": "audio", - "type": "AUDIO", - "links": [ - 7, - 11 - ] - }, - { - "name": "video_info", - "type": "VHS_VIDEOINFO", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-videohelpersuite", - "Node name for S&R": "VHS_LoadVideoPath" - }, - "widgets_values": { - "video": "", - "force_rate": 24, - "custom_width": 0, - "custom_height": 0, - "frame_load_cap": 25, - "skip_first_frames": 0, - "select_every_nth": 1, - "format": "AnimateDiff", - "videopreview": { - "hidden": false, - "paused": false, - "params": { - "filename": "", - "type": "path", - "format": "video/", - "force_rate": 24, - "custom_width": 0, - "custom_height": 0, - "frame_load_cap": 25, - "skip_first_frames": 0, - "select_every_nth": 1 - } - } - } - }, - { - "id": 3, - "type": "Note", - "pos": [ - 20, - 520 - ], - "size": [ - 300, - 166 - ], - "flags": {}, - "order": 2, - "mode": 0, - "inputs": [], - "outputs": [], - "properties": { - "Node name for S&R": "Note" - }, - "widgets_values": [ - "INPUT SAFETY DEFAULTS\n• force_rate = 24 FPS\n• frame_load_cap = 25 (~1 second)\n• dimensions = source size\n\nFor another source rate, change force_rate here and source_fps in the chosen Tween node. The Video Combine frame rate must match target_fps." - ], - "color": "#3f3520", - "bgcolor": "#594b2d" - }, - { - "id": 4, - "type": "LoadSPEEDVFIModel", - "pos": [ - 390, - 170 - ], - "size": [ - 300, - 105 - ], - "flags": {}, - "order": 3, - "mode": 0, - "inputs": [], - "outputs": [ - { - "name": "model", - "type": "SPEED_VFI_MODEL", - "links": [ - 2, - 4 - ] - } - ], - "properties": { - "aux_id": "ComfyUI-Tween.git", - "Node name for S&R": "LoadSPEEDVFIModel" - }, - "widgets_values": [ - "speed.pt", - "auto" - ], - "color": "#243b32", - "bgcolor": "#315244" - }, - { - "id": 5, - "type": "VFIOptimizer", - "pos": [ - 390, - 330 - ], - "size": [ - 310, - 150 - ], - "flags": {}, - "order": 4, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 1 - }, - { - "name": "model", - "type": "*", - "link": 2 - } - ], - "outputs": [ - { - "name": "images", - "type": "IMAGE", - "links": [ - 3 - ] - }, - { - "name": "settings", - "type": "VFI_SETTINGS", - "links": [ - 5 - ] - } - ], - "properties": { - "aux_id": "ComfyUI-Tween.git", - "Node name for S&R": "VFIOptimizer" - }, - "widgets_values": [ - 2, - 0 - ], - "color": "#243b32", - "bgcolor": "#315244" - }, - { - "id": 6, - "type": "SPEEDVFIInterpolate", - "pos": [ - 760, - 240 - ], - "size": [ - 355, - 340 - ], - "flags": {}, - "order": 5, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 3 - }, - { - "name": "model", - "type": "SPEED_VFI_MODEL", - "link": 4 - }, - { - "name": "settings", - "shape": 7, - "type": "VFI_SETTINGS", - "link": 5 - } - ], - "outputs": [ - { - "name": "images", - "type": "IMAGE", - "links": [ - 6 - ] - }, - { - "name": "oversampled", - "type": "IMAGE", - "links": null - } - ], - "properties": { - "aux_id": "ComfyUI-Tween.git", - "Node name for S&R": "SPEEDVFIInterpolate" - }, - "widgets_values": [ - 2, - 10, - true, - false, - 1, - 0, - 24, - 48, - 0 - ], - "color": "#243b32", - "bgcolor": "#315244" - }, - { - "id": 7, - "type": "VHS_VideoCombine", - "pos": [ - 1170, - 240 - ], - "size": [ - 360, - 340 - ], - "flags": {}, - "order": 6, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 6 - }, - { - "name": "audio", - "shape": 7, - "type": "AUDIO", - "link": 7 - }, - { - "name": "meta_batch", - "shape": 7, - "type": "VHS_BatchManager", - "link": null - }, - { - "name": "vae", - "shape": 7, - "type": "VAE", - "link": null - } - ], - "outputs": [ - { - "name": "Filenames", - "type": "VHS_FILENAMES", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-videohelpersuite", - "Node name for S&R": "VHS_VideoCombine" - }, - "widgets_values": { - "frame_rate": 48, - "loop_count": 0, - "filename_prefix": "Tween/demo_speed_24_to_48", - "format": "video/h264-mp4", - "pix_fmt": "yuv420p", - "crf": 19, - "save_metadata": true, - "trim_to_audio": false, - "pingpong": false, - "save_output": true, - "videopreview": { - "hidden": false, - "paused": false, - "params": {} - } - }, - "color": "#243b32", - "bgcolor": "#315244" - }, - { - "id": 8, - "type": "Note", - "pos": [ - 390, - 20 - ], - "size": [ - 1140, - 110 - ], - "flags": {}, - "order": 7, - "mode": 0, - "inputs": [], - "outputs": [], - "properties": { - "Node name for S&R": "Note" - }, - "widgets_values": [ - "SPEED — RECOMMENDED, ENABLED\nOne-step diffusion midpoint interpolation. This branch uses target-FPS mode (24→48), a fixed seed, and VFI Optimizer settings. First use downloads the official ~447 MB checkpoint and checksum-pinned runtime." - ], - "color": "#234936", - "bgcolor": "#2d6046" - }, - { - "id": 9, - "type": "Note", - "pos": [ - 390, - 760 - ], - "size": [ - 1140, - 125 - ], - "flags": {}, - "order": 8, - "mode": 0, - "inputs": [], - "outputs": [], - "properties": { - "Node name for S&R": "Note" - }, - "widgets_values": [ - "LDF-VFI — ADVANCED, MUTED BY DEFAULT\nRequires an NVIDIA BF16 GPU and roughly 20 GB VRAM; first use downloads ~6.4 GB. To run it, select the three coral nodes below and set Mode → Always. Disable/mute the SPEED output node if you only want LDF. Use 16 sampling steps for the official quality-oriented quick-start setting." - ], - "color": "#5a2d2d", - "bgcolor": "#743b3b" - }, - { - "id": 10, - "type": "LoadLDFVFIModel", - "pos": [ - 390, - 930 - ], - "size": [ - 340, - 190 - ], - "flags": {}, - "order": 9, - "mode": 2, - "inputs": [], - "outputs": [ - { - "name": "model", - "type": "LDF_VFI_MODEL", - "links": [ - 9 - ] - } - ], - "properties": { - "aux_id": "ComfyUI-Tween.git", - "Node name for S&R": "LoadLDFVFIModel" - }, - "widgets_values": [ - "onecat-ai/LDF-VFI", - 256, - 64, - 4, - "slide_chunk_all_block_2x1x1" - ], - "color": "#5a2d2d", - "bgcolor": "#743b3b" - }, - { - "id": 11, - "type": "LDFVFIInterpolate", - "pos": [ - 790, - 930 - ], - "size": [ - 370, - 320 - ], - "flags": {}, - "order": 10, - "mode": 2, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 8 - }, - { - "name": "model", - "type": "LDF_VFI_MODEL", - "link": 9 - } - ], - "outputs": [ - { - "name": "images", - "type": "IMAGE", - "links": [ - 10 - ] - }, - { - "name": "generated_sequence", - "type": "IMAGE", - "links": null - } - ], - "properties": { - "aux_id": "ComfyUI-Tween.git", - "Node name for S&R": "LDFVFIInterpolate" - }, - "widgets_values": [ - 2, - 8, - 8, - 0.1, - 42, - true, - 24, - 48 - ], - "color": "#5a2d2d", - "bgcolor": "#743b3b" - }, - { - "id": 12, - "type": "VHS_VideoCombine", - "pos": [ - 1210, - 930 - ], - "size": [ - 360, - 340 - ], - "flags": {}, - "order": 11, - "mode": 2, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 10 - }, - { - "name": "audio", - "shape": 7, - "type": "AUDIO", - "link": 11 - }, - { - "name": "meta_batch", - "shape": 7, - "type": "VHS_BatchManager", - "link": null - }, - { - "name": "vae", - "shape": 7, - "type": "VAE", - "link": null - } - ], - "outputs": [ - { - "name": "Filenames", - "type": "VHS_FILENAMES", - "links": null - } - ], - "properties": { - "cnr_id": "comfyui-videohelpersuite", - "Node name for S&R": "VHS_VideoCombine" - }, - "widgets_values": { - "frame_rate": 48, - "loop_count": 0, - "filename_prefix": "Tween/demo_ldf_24_to_48", - "format": "video/h264-mp4", - "pix_fmt": "yuv420p", - "crf": 19, - "save_metadata": true, - "trim_to_audio": false, - "pingpong": false, - "save_output": true, - "videopreview": { - "hidden": false, - "paused": false, - "params": {} - } - }, - "color": "#5a2d2d", - "bgcolor": "#743b3b" - }, - { - "id": 13, - "type": "Note", - "pos": [ - 20, - 930 - ], - "size": [ - 300, - 236 - ], - "flags": {}, - "order": 12, - "mode": 0, - "inputs": [], - "outputs": [], - "properties": { - "Node name for S&R": "Note" - }, - "widgets_values": [ - "WHY TWO PATHS?\n\nSPEED\n• Best default for normal pairwise VFI\n• Much smaller and faster\n• 2x midpoint; 4x/8x recursive\n\nLDF-VFI\n• Sequence-native temporal modeling\n• Better suited to long-range coherence\n• 2x–16x, but far heavier\n\nThe LDF demo uses 8 steps for a quicker test. Raise to 16 after the graph is working." - ], - "color": "#40303b", - "bgcolor": "#594353" - } - ], - "links": [ - [ - 1, - 2, - 0, - 5, - 0, - "IMAGE" - ], - [ - 2, - 4, - 0, - 5, - 1, - "*" - ], - [ - 3, - 5, - 0, - 6, - 0, - "IMAGE" - ], - [ - 4, - 4, - 0, - 6, - 1, - "SPEED_VFI_MODEL" - ], - [ - 5, - 5, - 1, - 6, - 2, - "VFI_SETTINGS" - ], - [ - 6, - 6, - 0, - 7, - 0, - "IMAGE" - ], - [ - 7, - 2, - 2, - 7, - 1, - "AUDIO" - ], - [ - 8, - 2, - 0, - 11, - 0, - "IMAGE" - ], - [ - 9, - 10, - 0, - 11, - 1, - "LDF_VFI_MODEL" - ], - [ - 10, - 11, - 0, - 12, - 0, - "IMAGE" - ], - [ - 11, - 2, - 2, - 12, - 1, - "AUDIO" - ] - ], - "groups": [ - { - "id": 1, - "title": "1 · INPUT CLIP", - "bounding": [ - -20, - 135, - 360, - 575 - ], - "color": "#8a6d2f", - "font_size": 24, - "flags": {} - }, - { - "id": 2, - "title": "2 · SPEED — RECOMMENDED / ENABLED", - "bounding": [ - 350, - -20, - 1240, - 650 - ], - "color": "#347a56", - "font_size": 24, - "flags": {} - }, - { - "id": 3, - "title": "3 · LDF-VFI — ADVANCED / MUTED", - "bounding": [ - 350, - 730, - 1240, - 590 - ], - "color": "#8a4646", - "font_size": 24, - "flags": {} - } - ], - "config": {}, - "extra": { - "workflowRendererVersion": "LG", - "ue_links": [], - "links_added_by_ue": [], - "ds": { - "scale": 0.76, - "offset": [ - 80, - 80 - ] - }, - "frontendVersion": "1.45.19", - "VHS_latentpreview": true, - "VHS_latentpreviewrate": 0, - "VHS_MetadataImage": true, - "VHS_KeepIntermediate": true - }, - "version": 0.4 -} diff --git a/tests/test_demo_workflow.py b/tests/test_demo_workflow.py new file mode 100644 index 0000000..7423e53 --- /dev/null +++ b/tests/test_demo_workflow.py @@ -0,0 +1,53 @@ +import json +from pathlib import Path + + +WORKFLOW_PATH = ( + Path(__file__).resolve().parents[1] + / "example_workflows" + / "tween_speed_bim_model_lab.json" +) + + +def _workflow(): + return json.loads(WORKFLOW_PATH.read_text(encoding="utf-8")) + + +def test_speed_bim_demo_is_clean_and_current(): + workflow = _workflow() + node_types = [node["type"] for node in workflow["nodes"]] + + assert "Note" not in node_types + assert not any("LDF" in node_type for node_type in node_types) + assert node_types.count("SPEEDVFIInterpolate") == 1 + assert node_types.count("BIMVFIInterpolate") == 1 + assert [group["title"] for group in workflow["groups"]] == [ + "INPUT · 24 FPS / 25 FRAMES", + "SPEED", + "BIM-VFI", + ] + + +def test_speed_bim_demo_links_are_internally_consistent(): + workflow = _workflow() + nodes = {node["id"]: node for node in workflow["nodes"]} + node_ids = set(nodes) + links = {link[0]: link for link in workflow["links"]} + + assert workflow["last_node_id"] == max(node_ids) + assert workflow["last_link_id"] == max(links) + + for link_id, source_id, source_slot, target_id, target_slot, _ in workflow["links"]: + assert link_id in links + assert source_id in node_ids + assert target_id in node_ids + assert link_id in nodes[source_id]["outputs"][source_slot]["links"] + assert nodes[target_id]["inputs"][target_slot]["link"] == link_id + + for node in workflow["nodes"]: + for input_slot in node.get("inputs", []): + if input_slot.get("link") is not None: + assert input_slot["link"] in links + for output_slot in node.get("outputs", []): + for link_id in output_slot.get("links") or []: + assert link_id in links