├── MEDIA ├── media_list.txt ├── screen_node_01.png ├── screen_node_02.png ├── screen_node_03.png └── screen_node_02.png~ ├── WORKFLOWS ├── workflows.txt └── NAI-prompt-composer.json ├── .gitattributes ├── __init__.py ├── SCRIPTS ├── lightings.csv ├── cameras.csv ├── motions.csv ├── agents.csv ├── styles.csv └── scenes.csv ├── tasks.txt ├── README.md └── scripts_pipeline.py /MEDIA/media_list.txt: -------------------------------------------------------------------------------- 1 | workflows list -------------------------------------------------------------------------------- /WORKFLOWS/workflows.txt: -------------------------------------------------------------------------------- 1 | workflows list -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /MEDIA/screen_node_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KoreTeknology/ComfyUI-Universal-Styler/HEAD/MEDIA/screen_node_01.png -------------------------------------------------------------------------------- /MEDIA/screen_node_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KoreTeknology/ComfyUI-Universal-Styler/HEAD/MEDIA/screen_node_02.png -------------------------------------------------------------------------------- /MEDIA/screen_node_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KoreTeknology/ComfyUI-Universal-Styler/HEAD/MEDIA/screen_node_03.png -------------------------------------------------------------------------------- /MEDIA/screen_node_02.png~: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/KoreTeknology/ComfyUI-Universal-Styler/HEAD/MEDIA/screen_node_02.png~ -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.5.1" 2 | 3 | from .scripts_pipeline import * 4 | 5 | # Kore Teknology - ComfyUI Custom nodes Packages 6 | # https://github.com/KoreTeknology/ComfyUI-Universal-Styler 7 | # designed by uriel Deveaud 8 | # Contact: https://www.linkedin.com/groups/13109092/ 9 | # Release 0.5.1 (16/02/2025) -------------------------------------------------------------------------------- /SCRIPTS/lightings.csv: -------------------------------------------------------------------------------- 1 | name,short_prompt,long_prompt 2 | Select a lighting...,, 3 | Artificial,"Artificial Indoor Lighting.","Artificial Indoor Lighting.", 4 | Natural,"Natural Sunlight.","Natural Sunlight.", 5 | Vibrant,"Vibrant Stage Lighting.","Vibrant Stage Lighting.", 6 | Vivid,"Vivid Spotlights.","Vivid Spotlights.", 7 | Warm,"Warm ambiance.","Warm ambiance.", -------------------------------------------------------------------------------- /tasks.txt: -------------------------------------------------------------------------------- 1 | channels <> agents 2 | 3 | Re-order the script sequence according to the prompt engineering documentation from LTXV: 4 | 5 | - Start with main action in a single sentence 6 | - Add specific details about movements and gestures 7 | - Describe character/object appearances precisely 8 | - Include background and environment details 9 | - Specify camera angles and movements 10 | - Describe lighting and colors 11 | - Note any changes or sudden events 12 | -------------------------------------------------------------------------------- /SCRIPTS/cameras.csv: -------------------------------------------------------------------------------- 1 | name,short_prompt,long_prompt 2 | Select a camera...,,, 3 | Prime Lens,"Fixed focal length.","Fixed focal length.", 4 | Zoom Lens,"Variable focal length.","Variable focal length.", 5 | Standard Lens,"General purpose 50mm full frame.","General purpose 50mm full frame.", 6 | Wide-angle Lens,"Field of view 24mm.","Field of view 24mm.", 7 | Telephoto Lens,"Telephoto Lens 70-200mm.","Telephoto Lens 70-200mm.", 8 | Fish's Eye Lens,"Fish's Eye View.","Fish's Eye View.", 9 | Macro Lens,"Macro,extrem close-up.","Macro,extrem close-up.", 10 | -------------------------------------------------------------------------------- /SCRIPTS/motions.csv: -------------------------------------------------------------------------------- 1 | name,short_prompt,long_prompt 2 | Select a motion...,,, 3 | Rotating Left,"Horizontal camera rotate to the left","Horizontal camera [rotate:8] to the [left:0.7]", 4 | Rotating Right,"Horizontal camera rotate to the right","Horizontal camera [rotate:8] to the [right:0.7]", 5 | Panning Left,"Horizontal camera move to the left","Horizontal camera [move:8] to the [left:0.7]", 6 | Panning Right,"Horizontal camera move to the right","Horizontal camera [move:8] to the [right:0.7]", 7 | Titlting Up,"Vertical camera move to up","Vertical camera [move:8] to [up:0.5]", 8 | Titlting Down,"Vertical camera move to bottom","Vertical camera [move:8] to [bottom:0.5]", 9 | Zoom In,"Camera zoom close to the scene","Camera zoom close the scene", 10 | Zoom Out,"Camera zoom far from the subject","Camera zoom far from the subject", 11 | -------------------------------------------------------------------------------- /SCRIPTS/agents.csv: -------------------------------------------------------------------------------- 1 | name,short_prompt,long_prompt 2 | Select an agent...,"with the skill of a digital artist.","with the skill of a digital artist.", 3 | Graphic Designer,"with the skill of graphic designer.","with the skills of creating new digital contents and very attractive.", 4 | Visual Fx Supervisor,"with he skill of a visual effect supervisor.","with the skills of editing videos and applying visual effects layers.", 5 | Video Producer,"with the skill of a video producer.","with the skills of video editing and publishing, of a video producer." 6 | Storyboarder,"with a skill of a storyboarder.","with the skill of a professional storyboarder.", 7 | Game Developer,"with a skill of a Game Developer.","with the skill of a professional Game Developer.", 8 | Marketing Manager,"with a skill of a Marketing Manager.","with the skill of a professional Marketing Manager.", 9 | Fashion Designer,"with a skill of a fashion designer","with a skill of a fashion designer", 10 | -------------------------------------------------------------------------------- /SCRIPTS/styles.csv: -------------------------------------------------------------------------------- 1 | name,short_prompt,long_prompt 2 | Select a style...,,, 3 | Artistic Realism,"Artistic Realism.","Artistic Realism.", 4 | Artistic Impressionism,"Artistic Impressionism.","Artistic Impressionism.", 5 | Artistic Expressionism,"Artistic Expressionism.","Artistic Expressionism.", 6 | Artistic Cubism,"Artistic Cubism.","Artistic Cubism.", 7 | Artictic conceptual,"Conceptual Art.","Conceptual Art.", 8 | Artistic Surrealism,"Artistic Surrealism.","Artistic Surrealism.", 9 | Artistic Pop,"Artistic Pop.","Artistic Pop.", 10 | Artistic Street,"Graffiti art.","Graffiti art.", 11 | Abstract Reality,"Abstract visual.","Abstract forms and shapes.", 12 | Abstract Expressionism,"Abstract Expressionism.","Abstract Expressionism.", 13 | Abstract Minimalism,"Abstract Minimalism.","Abstract Minimalism.", 14 | Photorealism color,"8K, Realistic colors, Hyperrealism, Depth of Field.","High definition, ultra resolution, high quality image.", 15 | Photorealism Black and white,"Photorealism Black and white.","Photorealism Black and white.", 16 | Photorealism Sepia,"Photorealism Sepia.","Photorealism Sepia.", 17 | Photorealism Vintage,"Photorealism Vintage.","Photorealism Vintage.", 18 | Digital 3D Art,"Digital 3D Art.","Digital 3D Art.", 19 | Cartoon Anime,"Manga cartoon style.","Manga cartoon style.", 20 | Video Cinematic,"Film and video art.","Film and video art.", 21 | Industrial design,"Industrial design.","CAD blueprint.", 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ComfyUI Universal Styler 2 | ```py 3 | VERSION: Release 0.5.1 - UPDATED 02/2025 - Licensed under GNU General Public License v3.0 4 | ``` 5 | Hi, this is a research Node based project on *Artificial Intelligence* using ComfyUI[^1] visual editor with **VRAM Local processing**[^2] focus in mind. This set of custom node is intended to *offer a large palette of prompting scenrarios*, based on your scripting database[^3]. This package also includes a set of workflows[^4], associated with each feature and a database template folder. This last set of files can be replaced by your own CSV files. It will works fine with image and video models like Stable diffusion and LTXV checkpoints. Feel free to accomodate and customize this template for each project. 6 | 7 | 8 | 9 | > [!IMPORTANT] 10 | >>> THIS PACKAGE WAS FULLY REBUILD AFTER VERSION 0.5, 11 | >> OLD NODES MAY NOT WORK AS EXPECTED IN YOUR OLD WORKFLOWS! To avoid errors, remplace old nodes by the latest version from the main node menu. 12 | 13 | mockup 14 | 15 | ## :radio_button: Working Features 16 | 17 | - **Load script presets from CSV database** (Scene, Camera, Motion, Lighting, Style) 18 | - **Contextual agents included** (Dedicated Agents database file) 19 | - **Prompt sequences compiler (concatenate)** (Optional Prefix, Various options available) 20 | - **Channel drive (Chain-follow)** (Full references register) 21 | - **Prompt build setup** Database model card available as a node 22 | 23 | ## :radio_button: Features Under Development 24 | 25 | - **NEW set of script templates!** 26 | - **Select database folder path in front-end & Update** 27 | - **Seed INT Field with output connector** 28 | - **Metadata read/write** 29 | - Save database new item (same as save text node + options) 30 | 31 | --- 32 | 33 | ## :radio_button: ComfyUI Installation and Custom Nodes 34 | 35 | After installing [**ComfyUI**](https://github.com/comfyanonymous/ComfyUI) services with your prefered plateform (i am suggesting the use of [**Stability Matrix**](https://github.com/LykosAI/StabilityMatrix) as it is easy to install and give a lot of controls), make sure you install the additional and necessary custom nodes. Then you need to install [GIT software](https://git-scm.com/) (if it is not done already) on your computer. To install these custom nodes, open a CMD window in the \ComfyUI\custom_nodes folder. And "git clone" each one of them. By adding the link after "git clone". 36 | 37 | - [ComfyUi-Manager](https://github.com/ltdrdata/ComfyUI-Manager) 38 | 39 | --- 40 | 41 | ## :radio_button: Infos 42 | 43 | * Author: **Uriel Deveaud** - [Kore Teknology](https://github.com/KoreTeknology) 44 | * Contact: [Linkedin ComfyUI Users Group](https://www.linkedin.com/groups/13109092/) 45 | * License: This project is released under the GPL License. 46 | * This work is dedicated to all ComfyUI users around the world ;) 47 | 48 | [^1]: **ComfyUI** is the free and open source AI creation suite. It supports Stable Diffusion 1.5, 2. XL, Flux and video models LTXV, hunhyan, Mochi. Please, visit the [ComfyUI Github page](https://github.com/comfyanonymous/ComfyUI). 49 | 50 | [^2]: Large language models (LLM) are very large deep learning models that are pre-trained on vast amounts of data. The underlying transformer is a set of neural networks that consist of an encoder and a decoder with self-attention capabilities. 51 | 52 | [^3]: A scripting database can be compared to a storyboard 53 | 54 | [^4]: The provided workflows offer the basic festures thry a simple pipeline design 55 | -------------------------------------------------------------------------------- /SCRIPTS/scenes.csv: -------------------------------------------------------------------------------- 1 | name,short_prompt,long_prompt 2 | Select a scene...,, 3 | Swirling Vortex,A swirling vortex of vibrant colors and abstract shapes.,"A swirling vortex of vibrant, saturated colors and abstract shapes, reminiscent of a psychedelic dream. Include fractal patterns, distorted faces, and melting landscapes. The overall composition should feel fluid and dynamic, with a sense of movement and energy. Render in a style inspired by Alex Grey and Mati Klarwein, with a focus on intricate detail and luminous colors. Add a touch of bioluminescence and subtle geometric patterns. Artstation trending, 8k resolution, intricate detail, highly detailed, psychedelic art, vibrant colors, fractal patterns, swirling vortex." 4 | Gothic Griffin,"A majestic griffin perched atop a crumbling gothic tower, overlooking a misty valley at dawn.","A majestic griffin, with feathers of burnished gold and piercing emerald eyes, perched atop a crumbling gothic tower, its gargoyles worn by time and weather. The tower overlooks a misty valley at dawn, the first rays of sunlight breaking through the fog, illuminating the dew-covered landscape. The scene is rendered in a hyperrealistic style, with intricate details in the griffin's plumage and the tower's stonework. Focus on dramatic lighting and a sense of ancient power. Artstation trending, 8k resolution, intricate detail, photorealistic, sharp focus." 5 | Chrome Spaceship,"A sleek, chrome spaceship landing on a desolate, alien planet.","A sleek, chrome spaceship, with glowing blue engine nacelles and intricate paneling, landing on a desolate, alien planet with red sand and towering rock formations. The sky is a hazy orange, with two moons visible. A lone figure in a spacesuit walks down the ramp. Render in a style reminiscent of Syd Mead, with a focus on clean lines and retro-futuristic design. Include volumetric lighting and a sense of scale. Artstation trending, 8k resolution, intricate detail, photorealistic, sharp focus, HDR." 6 | Talking Woman,A woman with brown hair talk to another woman,"A woman with long brown hair and light skin smiles at another woman with long blonde hair. The woman with brown hair wears a black jacket and has a small, barely noticeable mole on her right cheek. The camera angle is a close-up, focused on the woman with brown hair's face. The lighting is warm and natural, likely from the setting sun, casting a soft glow on the scene. The scene appears to be real-life footage. " 7 | Walking Woman,A woman walks away from a white jeep,"A woman walks away from a white Jeep parked on a city street at night, then ascends a staircase and knocks on a door. The woman, wearing a dark jacket and jeans, walks away from the Jeep parked on the left side of the street, her back to the camera; she walks at a steady pace, her arms swinging slightly by her sides; the street is dimly lit, with streetlights casting pools of light on the wet pavement; a man in a dark jacket and jeans walks past the Jeep in the opposite direction; the camera follows the woman from behind as she walks up a set of stairs towards a building with a green door; she reaches the top of the stairs and turns left, continuing to walk towards the building; she reaches the door and knocks on it with her right hand; the camera remains stationary, focused on the doorway; the scene is captured in real-life footage. " 8 | Dressed Woman,"A woman with blond hair, wearing black dress","A woman with blonde hair styled up, wearing a black dress with sequins and pearl earrings, looks down with a sad expression on her face. The camera remains stationary, focused on the woman's face. The lighting is dim, casting soft shadows on her face. The scene appears to be from a movie or TV show. " 9 | Valley Mountain,A snow-covered mountain,"The camera pans over a snow-covered mountain range, revealing a vast expanse of snow-capped peaks and valleys.The mountains are covered in a thick layer of snow, with some areas appearing almost white while others have a slightly darker, almost grayish hue. The peaks are jagged and irregular, with some rising sharply into the sky while others are more rounded. The valleys are deep and narrow, with steep slopes that are also covered in snow. The trees in the foreground are mostly bare, with only a few leaves remaining on their branches. The sky is overcast, with thick clouds obscuring the sun. The overall impression is one of peace and tranquility, with the snow-covered mountains standing as a testament to the power and beauty of nature. " 10 | Blue Woman,a woman wearing a blue jacket,"A woman with light skin, wearing a blue jacket and a black hat with a veil, looks down and to her right, then back up as she speaks; she has brown hair styled in an updo, light brown eyebrows, and is wearing a white collared shirt under her jacket; the camera remains stationary on her face as she speaks; the background is out of focus, but shows trees and people in period clothing; the scene is captured in real-life footage. " 11 | VintagePhone,A man talks to a vintage phone,"A man in a dimly lit room talks on a vintage telephone, hangs up, and looks down with a sad expression. He holds the black rotary phone to his right ear with his right hand, his left hand holding a rocks glass with amber liquid. He wears a brown suit jacket over a white shirt, and a gold ring on his left ring finger. His short hair is neatly combed, and he has light skin with visible wrinkles around his eyes. The camera remains stationary, focused on his face and upper body. The room is dark, lit only by a warm light source off-screen to the left, casting shadows on the wall behind him. The scene appears to be from a movie. " 12 | Prison Guard,A prison guard sittinng at a table with a woman,"A prison guard unlocks and opens a cell door to reveal a young man sitting at a table with a woman. The guard, wearing a dark blue uniform with a badge on his left chest, unlocks the cell door with a key held in his right hand and pulls it open; he has short brown hair, light skin, and a neutral expression. The young man, wearing a black and white striped shirt, sits at a table covered with a white tablecloth, facing the woman; he has short brown hair, light skin, and a neutral expression. The woman, wearing a dark blue shirt, sits opposite the young man, her face turned towards him; she has short blonde hair and light skin. The camera remains stationary, capturing the scene from a medium distance, positioned slightly to the right of the guard. The room is dimly lit, with a single light fixture illuminating the table and the two figures. The walls are made of large, grey concrete blocks, and a metal door is visible in the background. The scene is captured in real-life footage. " 13 | Bloody Face,A woman with blood on her face,"A woman with blood on her face and a white tank top looks down and to her right, then back up as she speaks. She has dark hair pulled back, light skin, and her face and chest are covered in blood. The camera angle is a close-up, focused on the woman's face and upper torso. The lighting is dim and blue-toned, creating a somber and intense atmosphere. The scene appears to be from a movie or TV show. " 14 | Grey Hair,A man with graying hair,"A man with graying hair, a beard, and a gray shirt looks down and to his right, then turns his head to the left. The camera angle is a close-up, focused on the man's face. The lighting is dim, with a greenish tint. The scene appears to be real-life footage. Step " 15 | -------------------------------------------------------------------------------- /WORKFLOWS/NAI-prompt-composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "last_node_id": 49, 3 | "last_link_id": 73, 4 | "nodes": [ 5 | { 6 | "id": 14, 7 | "type": "LoadText|pysssss", 8 | "pos": [ 9 | 2330, 10 | 1900 11 | ], 12 | "size": [ 13 | 315, 14 | 82 15 | ], 16 | "flags": {}, 17 | "order": 0, 18 | "mode": 0, 19 | "inputs": [], 20 | "outputs": [ 21 | { 22 | "name": "STRING", 23 | "type": "STRING", 24 | "links": [ 25 | 13, 26 | 14 27 | ], 28 | "slot_index": 0 29 | } 30 | ], 31 | "properties": { 32 | "Node name for S&R": "LoadText|pysssss" 33 | }, 34 | "widgets_values": [ 35 | "output", 36 | "file.txt" 37 | ] 38 | }, 39 | { 40 | "id": 7, 41 | "type": "SaveText|pysssss", 42 | "pos": [ 43 | 3100, 44 | 1930 45 | ], 46 | "size": [ 47 | 400, 48 | 200 49 | ], 50 | "flags": {}, 51 | "order": 3, 52 | "mode": 4, 53 | "inputs": [ 54 | { 55 | "name": "text", 56 | "type": "STRING", 57 | "widget": { 58 | "name": "text" 59 | }, 60 | "link": 13 61 | } 62 | ], 63 | "outputs": [ 64 | { 65 | "name": "STRING", 66 | "type": "STRING", 67 | "links": null 68 | } 69 | ], 70 | "properties": { 71 | "Node name for S&R": "SaveText|pysssss" 72 | }, 73 | "widgets_values": [ 74 | "output", 75 | "file.txt", 76 | "new only", 77 | true, 78 | "" 79 | ] 80 | }, 81 | { 82 | "id": 15, 83 | "type": "ShowText|pysssss", 84 | "pos": [ 85 | 2730, 86 | 2030 87 | ], 88 | "size": [ 89 | 315, 90 | 76 91 | ], 92 | "flags": {}, 93 | "order": 4, 94 | "mode": 0, 95 | "inputs": [ 96 | { 97 | "name": "text", 98 | "type": "STRING", 99 | "widget": { 100 | "name": "text" 101 | }, 102 | "link": 14 103 | } 104 | ], 105 | "outputs": [ 106 | { 107 | "name": "STRING", 108 | "type": "STRING", 109 | "shape": 6, 110 | "links": null 111 | } 112 | ], 113 | "properties": { 114 | "Node name for S&R": "ShowText|pysssss" 115 | }, 116 | "widgets_values": [ 117 | "", 118 | "My Text" 119 | ] 120 | }, 121 | { 122 | "id": 48, 123 | "type": "ShowText|pysssss", 124 | "pos": [ 125 | 2860, 126 | 1000 127 | ], 128 | "size": [ 129 | 400, 130 | 76 131 | ], 132 | "flags": {}, 133 | "order": 6, 134 | "mode": 0, 135 | "inputs": [ 136 | { 137 | "name": "text", 138 | "type": "STRING", 139 | "widget": { 140 | "name": "text" 141 | }, 142 | "link": 72 143 | } 144 | ], 145 | "outputs": [ 146 | { 147 | "name": "STRING", 148 | "type": "STRING", 149 | "shape": 6, 150 | "links": null 151 | } 152 | ], 153 | "title": "Preview Text", 154 | "properties": { 155 | "Node name for S&R": "ShowText|pysssss" 156 | }, 157 | "widgets_values": [ 158 | "", 159 | "#0001" 160 | ], 161 | "color": "#232", 162 | "bgcolor": "#353", 163 | "shape": 1 164 | }, 165 | { 166 | "id": 8, 167 | "type": "Set DB Prompt", 168 | "pos": [ 169 | 1800, 170 | 1120 171 | ], 172 | "size": [ 173 | 450, 174 | 340 175 | ], 176 | "flags": {}, 177 | "order": 1, 178 | "mode": 0, 179 | "inputs": [], 180 | "outputs": [ 181 | { 182 | "name": "prompt title", 183 | "type": "STRING", 184 | "links": [], 185 | "slot_index": 0 186 | }, 187 | { 188 | "name": "short prompt", 189 | "type": "STRING", 190 | "links": null 191 | }, 192 | { 193 | "name": "long prompt", 194 | "type": "STRING", 195 | "links": null 196 | }, 197 | { 198 | "name": "project dir", 199 | "type": "STRING", 200 | "links": [], 201 | "slot_index": 3 202 | } 203 | ], 204 | "properties": { 205 | "Node name for S&R": "Set DB Prompt" 206 | }, 207 | "widgets_values": [ 208 | "Scene_1/Motion_A/V1", 209 | "short", 210 | "long", 211 | "/outputs/project_name..." 212 | ], 213 | "color": "#223", 214 | "bgcolor": "#335", 215 | "shape": 1 216 | }, 217 | { 218 | "id": 49, 219 | "type": "PrimitiveNode", 220 | "pos": [ 221 | 2030, 222 | 1020 223 | ], 224 | "size": [ 225 | 210, 226 | 58 227 | ], 228 | "flags": {}, 229 | "order": 2, 230 | "mode": 0, 231 | "inputs": [], 232 | "outputs": [ 233 | { 234 | "name": "STRING", 235 | "type": "STRING", 236 | "widget": { 237 | "name": "channel_input" 238 | }, 239 | "links": [ 240 | 73 241 | ] 242 | } 243 | ], 244 | "title": "Channel Def", 245 | "properties": { 246 | "Run widget replace on values": false 247 | }, 248 | "widgets_values": [ 249 | "ACCC" 250 | ], 251 | "shape": 1 252 | }, 253 | { 254 | "id": 24, 255 | "type": "ShowText|pysssss", 256 | "pos": [ 257 | 2860, 258 | 1370 259 | ], 260 | "size": [ 261 | 400, 262 | 76 263 | ], 264 | "flags": {}, 265 | "order": 8, 266 | "mode": 0, 267 | "inputs": [ 268 | { 269 | "name": "text", 270 | "type": "STRING", 271 | "widget": { 272 | "name": "text" 273 | }, 274 | "link": 70 275 | } 276 | ], 277 | "outputs": [ 278 | { 279 | "name": "STRING", 280 | "type": "STRING", 281 | "shape": 6, 282 | "links": null 283 | } 284 | ], 285 | "title": "Preview Text", 286 | "properties": { 287 | "Node name for S&R": "ShowText|pysssss" 288 | }, 289 | "widgets_values": [ 290 | "", 291 | "Blurry, text" 292 | ], 293 | "color": "#232", 294 | "bgcolor": "#353", 295 | "shape": 1 296 | }, 297 | { 298 | "id": 12, 299 | "type": "ShowText|pysssss", 300 | "pos": [ 301 | 2860, 302 | 1130 303 | ], 304 | "size": [ 305 | 400, 306 | 180 307 | ], 308 | "flags": {}, 309 | "order": 7, 310 | "mode": 0, 311 | "inputs": [ 312 | { 313 | "name": "text", 314 | "type": "STRING", 315 | "widget": { 316 | "name": "text" 317 | }, 318 | "link": 69 319 | } 320 | ], 321 | "outputs": [ 322 | { 323 | "name": "STRING", 324 | "type": "STRING", 325 | "shape": 6, 326 | "links": null 327 | } 328 | ], 329 | "title": "Preview Text", 330 | "properties": { 331 | "Node name for S&R": "ShowText|pysssss" 332 | }, 333 | "widgets_values": [ 334 | "", 335 | "with the skills of video editing and publishing, of a video producer. Camera zoom close the scene A swirling vortex of vibrant, saturated colors and abstract shapes, reminiscent of a psychedelic dream. Include fractal patterns, distorted faces, and melting landscapes. The overall composition should feel fluid and dynamic, with a sense of movement and energy. Render in a style inspired by Alex Grey and Mati Klarwein, with a focus on intricate detail and luminous colors. Add a touch of bioluminescence and subtle geometric patterns. Artstation trending, 8k resolution, intricate detail, highly detailed, psychedelic art, vibrant colors, fractal patterns, swirling vortex. " 336 | ], 337 | "color": "#232", 338 | "bgcolor": "#353", 339 | "shape": 1 340 | }, 341 | { 342 | "id": 47, 343 | "type": "Load and Remix Prompts from Database", 344 | "pos": [ 345 | 2280, 346 | 1110 347 | ], 348 | "size": [ 349 | 450, 350 | 350 351 | ], 352 | "flags": {}, 353 | "order": 5, 354 | "mode": 0, 355 | "inputs": [ 356 | { 357 | "name": "channel_input", 358 | "type": "STRING", 359 | "widget": { 360 | "name": "channel_input" 361 | }, 362 | "link": 73 363 | } 364 | ], 365 | "outputs": [ 366 | { 367 | "name": "channel output", 368 | "type": "STRING", 369 | "links": [ 370 | 72 371 | ], 372 | "slot_index": 0 373 | }, 374 | { 375 | "name": "positive prompt", 376 | "type": "STRING", 377 | "links": [ 378 | 69 379 | ] 380 | }, 381 | { 382 | "name": "negative prompt", 383 | "type": "STRING", 384 | "links": [ 385 | 70 386 | ] 387 | } 388 | ], 389 | "properties": { 390 | "Node name for S&R": "Load and Remix Prompts from Database" 391 | }, 392 | "widgets_values": [ 393 | "ACCC", 394 | "extended", 395 | "Video Producer", 396 | "Swirling Vortex", 397 | "", 398 | "Zoom In", 399 | "Close-Up", 400 | "Augmented reality art", 401 | "Backlighting", 402 | "Basic negative prompt", 403 | "#0001", 404 | true 405 | ], 406 | "color": "#223", 407 | "bgcolor": "#335", 408 | "shape": 1 409 | } 410 | ], 411 | "links": [ 412 | [ 413 | 13, 414 | 14, 415 | 0, 416 | 7, 417 | 0, 418 | "STRING" 419 | ], 420 | [ 421 | 14, 422 | 14, 423 | 0, 424 | 15, 425 | 0, 426 | "STRING" 427 | ], 428 | [ 429 | 69, 430 | 47, 431 | 1, 432 | 12, 433 | 0, 434 | "STRING" 435 | ], 436 | [ 437 | 70, 438 | 47, 439 | 2, 440 | 24, 441 | 0, 442 | "STRING" 443 | ], 444 | [ 445 | 72, 446 | 47, 447 | 0, 448 | 48, 449 | 0, 450 | "STRING" 451 | ], 452 | [ 453 | 73, 454 | 49, 455 | 0, 456 | 47, 457 | 0, 458 | "STRING" 459 | ] 460 | ], 461 | "groups": [], 462 | "config": {}, 463 | "extra": { 464 | "ds": { 465 | "scale": 0.8769226950000101, 466 | "offset": [ 467 | -1652.1440263656566, 468 | -847.5644698324861 469 | ] 470 | }, 471 | "node_versions": { 472 | "ComfyUI-Custom-Scripts": "a53ef9b617ed1331640d7a2cd97644995908dc00" 473 | } 474 | }, 475 | "version": 0.4 476 | } -------------------------------------------------------------------------------- /scripts_pipeline.py: -------------------------------------------------------------------------------- 1 | import os 2 | import re 3 | import folder_paths 4 | 5 | ### SET MAIN CHANNEL NODE 6 | 7 | class SetMainChannel: 8 | @classmethod 9 | def INPUT_TYPES(cls): 10 | return { 11 | "required": { 12 | "channel": ("STRING", {"default": "CH_0001", "multiline":False}), 13 | } 14 | } 15 | 16 | RETURN_TYPES = ("STRING",) 17 | RETURN_NAMES = ("channel output",) 18 | FUNCTION = "set_mainchannel" 19 | CATEGORY = "🛡️ NAI Scripting Pipeline" 20 | 21 | def set_mainchannel(self, channel): 22 | return (channel,) 23 | 24 | 25 | ### SAVE SCRIPT NODE 26 | 27 | class SaveScriptToDatabase: 28 | @classmethod 29 | def INPUT_TYPES(cls): 30 | return { 31 | "required": { 32 | "prompt_title": ("STRING", {"default": "Scene_1/Motion_A/V1", "multiline":False}), 33 | "prompt_short": ("STRING", {"default": "short", "multiline":True}), 34 | "prompt_long": ("STRING", {"default": "long", "multiline":True}), 35 | "project_dir": ("STRING", {"default": "/outputs/project_name...", "multiline":False}), 36 | } 37 | } 38 | 39 | RETURN_TYPES = ("STRING","STRING","STRING","STRING",) 40 | RETURN_NAMES = ("prompt title", "short prompt", "long prompt", "project dir",) 41 | FUNCTION = "save_script" 42 | CATEGORY = "🛡️ NAI Scripting Pipeline" 43 | 44 | def save_script(self, prompt_title, prompt_short, prompt_long, project_dir): 45 | return (prompt_title,prompt_short,prompt_long,project_dir) 46 | 47 | 48 | ### LOAD SCIPTS NODE 49 | 50 | class LoadScriptsFromDatabase: 51 | """ 52 | Loads scripts from Database (csv file), and returns concatenated output string data. 53 | """ 54 | 55 | # LOAD AGENTS FROM DATABASE 56 | 57 | @staticmethod 58 | def load_agents_csv(agents_path: str): 59 | """Loads AGENTS Database file (CSV). It has three columns. It Ignores the first row (header). 60 | Returns: List of scripts. Each script is a dict with keys: script_name and value: [short_script, long_script] 61 | """ 62 | agents = {"Error loading agents.csv, check the console": ["",""]} 63 | 64 | # Verify folder ! 65 | print(f"""YOUR FOLDER: {folder_paths.base_path}""") 66 | 67 | if not os.path.exists(agents_path): 68 | print(f"""Error. No agents.csv found. Add your own agents.csv in the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 69 | Your current root directory is: {folder_paths.base_path} 70 | """) 71 | return agents 72 | try: 73 | with open(agents_path, "r", encoding="utf-8") as f: 74 | agents = [[x.replace('"', '').replace('\n','') for x in re.split(',(?=(?:[^"]*"[^"]*")*[^"]*$)', line)] for line in f.readlines()[1:]] 75 | agents = {x[0]: [x[1],x[2]] for x in agents} 76 | except Exception as e: 77 | print(f"""Error loading agents.csv. Make sure it is located into the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 78 | Your current root directory is: {folder_paths.base_path} 79 | Error: {e} 80 | """) 81 | return agents 82 | 83 | # LOAD SCENES FROM DATABASE 84 | 85 | @staticmethod 86 | def load_scenes_csv(scenes_path: str): 87 | """Loads SCENES Database file (CSV). It has three columns. It Ignores the first row (header). 88 | Returns: List of scripts. Each script is a dict with keys: script_name and value: [short_script, long_script] 89 | """ 90 | scenes = {"Error loading scenes.csv, check the console": ["",""]} 91 | if not os.path.exists(scenes_path): 92 | print(f"""Error. No scenes.csv found. Add your own scenes.csv in the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 93 | Your current root directory is: {folder_paths.base_path} 94 | """) 95 | return scenes 96 | try: 97 | with open(scenes_path, "r", encoding="utf-8") as f: 98 | scenes = [[x.replace('"', '').replace('\n','') for x in re.split(',(?=(?:[^"]*"[^"]*")*[^"]*$)', line)] for line in f.readlines()[1:]] 99 | scenes = {x[0]: [x[1],x[2]] for x in scenes} 100 | except Exception as e: 101 | print(f"""Error loading scenes.csv. Make sure it is located into the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 102 | Your current root directory is: {folder_paths.base_path} 103 | Error: {e} 104 | """) 105 | return scenes 106 | 107 | # LOAD MOTION FROM DATABASE 108 | 109 | @staticmethod 110 | def load_motions_csv(motions_path: str): 111 | """Loads MOTIONS Database file (CSV). It has three columns. It Ignores the first row (header). 112 | Returns: List of scripts. Each script is a dict with keys: script_name and value: [short_script, long_script] 113 | """ 114 | motions = {"Error loading motions.csv, check the console": ["",""]} 115 | if not os.path.exists(motions_path): 116 | print(f"""Error. No motions.csv found. Add your own motions.csv in the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 117 | Your current root directory is: {folder_paths.base_path} 118 | """) 119 | return motions 120 | try: 121 | with open(motions_path, "r", encoding="utf-8") as f: 122 | motions = [[x.replace('"', '').replace('\n','') for x in re.split(',(?=(?:[^"]*"[^"]*")*[^"]*$)', line)] for line in f.readlines()[1:]] 123 | motions = {x[0]: [x[1],x[2]] for x in motions} 124 | except Exception as e: 125 | print(f"""Error loading motions.csv. Make sure it is located into the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 126 | Your current root directory is: {folder_paths.base_path} 127 | Error: {e} 128 | """) 129 | return motions 130 | 131 | # LOAD LIGHTINGS FROM DATABASE 132 | 133 | @staticmethod 134 | def load_lightings_csv(lightings_path: str): 135 | """Loads LIGHTINGS Database file (CSV). It has three columns. It Ignores the first row (header). 136 | Returns: List of scripts. Each script is a dict with keys: script_name and value: [short_script, long_script] 137 | """ 138 | lightings = {"Error loading lightings.csv, check the console": ["",""]} 139 | if not os.path.exists(lightings_path): 140 | print(f"""Error. No lightings.csv found. Add your own lightings.csv in the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 141 | Your current root directory is: {folder_paths.base_path} 142 | """) 143 | return lightings 144 | try: 145 | with open(lightings_path, "r", encoding="utf-8") as f: 146 | lightings = [[x.replace('"', '').replace('\n','') for x in re.split(',(?=(?:[^"]*"[^"]*")*[^"]*$)', line)] for line in f.readlines()[1:]] 147 | lightings = {x[0]: [x[1],x[2]] for x in lightings} 148 | except Exception as e: 149 | print(f"""Error loading lightings.csv. Make sure it is located into the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 150 | Your current root directory is: {folder_paths.base_path} 151 | Error: {e} 152 | """) 153 | return lightings 154 | 155 | # LOAD STYLES FROM DATABASE 156 | 157 | @staticmethod 158 | def load_styles_csv(styles_path: str): 159 | """Loads STYLES Database file (CSV). It has three columns. It Ignores the first row (header). 160 | Returns: List of scripts. Each script is a dict with keys: script_name and value: [short_script, long_script] 161 | """ 162 | styles = {"Error loading styles.csv, check the console": ["",""]} 163 | if not os.path.exists(styles_path): 164 | print(f"""Error. No styles.csv found. Add your own styles.csv in the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 165 | Your current root directory is: {folder_paths.base_path} 166 | """) 167 | return styles 168 | try: 169 | with open(styles_path, "r", encoding="utf-8") as f: 170 | styles = [[x.replace('"', '').replace('\n','') for x in re.split(',(?=(?:[^"]*"[^"]*")*[^"]*$)', line)] for line in f.readlines()[1:]] 171 | styles = {x[0]: [x[1],x[2]] for x in styles} 172 | except Exception as e: 173 | print(f"""Error loading styles.csv. Make sure it is located into the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 174 | Your current root directory is: {folder_paths.base_path} 175 | Error: {e} 176 | """) 177 | return styles 178 | 179 | # LOAD CAMERAS FROM DATABASE 180 | 181 | @staticmethod 182 | def load_cameras_csv(cameras_path: str): 183 | """Loads CAMERAS Database file (CSV). It has three columns. It Ignores the first row (header). 184 | Returns: List of scripts. Each script is a dict with keys: script_name and value: [short_script, long_script] 185 | """ 186 | cameras = {"Error loading cameras.csv, check the console": ["",""]} 187 | if not os.path.exists(cameras_path): 188 | print(f"""Error. No cameras.csv found. Add your own cameras.csv in the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 189 | Your current root directory is: {folder_paths.base_path} 190 | """) 191 | return cameras 192 | try: 193 | with open(cameras_path, "r", encoding="utf-8") as f: 194 | cameras = [[x.replace('"', '').replace('\n','') for x in re.split(',(?=(?:[^"]*"[^"]*")*[^"]*$)', line)] for line in f.readlines()[1:]] 195 | cameras = {x[0]: [x[1],x[2]] for x in cameras} 196 | except Exception as e: 197 | print(f"""Error loading cameras.csv. Make sure it is located into the custom_nodes/ComfyUI-Universal-Styler directory of ComfyUI. Then press "Refresh". 198 | Your current root directory is: {folder_paths.base_path} 199 | Error: {e} 200 | """) 201 | return cameras 202 | 203 | # CUSTOM NODES SETUP 204 | 205 | @classmethod 206 | def INPUT_TYPES(cls): 207 | cls.agents_csv = cls.load_agents_csv(os.path.join(folder_paths.base_path, "custom_nodes\\ComfyUI-Universal-Styler\\SCRIPTS\\agents.csv")) 208 | cls.scenes_csv = cls.load_scenes_csv(os.path.join(folder_paths.base_path, "custom_nodes\\ComfyUI-Universal-Styler\\SCRIPTS\\scenes.csv")) 209 | cls.motions_csv = cls.load_motions_csv(os.path.join(folder_paths.base_path, "custom_nodes\\ComfyUI-Universal-Styler\\SCRIPTS\\motions.csv")) 210 | cls.lightings_csv = cls.load_lightings_csv(os.path.join(folder_paths.base_path, "custom_nodes\\ComfyUI-Universal-Styler\\SCRIPTS\\lightings.csv")) 211 | cls.styles_csv = cls.load_styles_csv(os.path.join(folder_paths.base_path, "custom_nodes\\ComfyUI-Universal-Styler\\SCRIPTS\\styles.csv")) 212 | cls.cameras_csv = cls.load_cameras_csv(os.path.join(folder_paths.base_path, "custom_nodes\\ComfyUI-Universal-Styler\\SCRIPTS\\cameras.csv")) 213 | return { 214 | "required": { 215 | "channel_input": ("STRING", {"forceInput": True}), 216 | "mode": (["normal", "extended", "solo agent output", "experimental"],), 217 | "agents": (list(cls.agents_csv.keys()),), 218 | "scenes": (list(cls.scenes_csv.keys()),), 219 | "script_prefix": ("STRING", {"multiline": False,"default": ""}), 220 | "cameras": (list(cls.cameras_csv.keys()),), 221 | "motions": (list(cls.motions_csv.keys()),), 222 | "styles": (list(cls.styles_csv.keys()),), 223 | "lightings": (list(cls.lightings_csv.keys()),), 224 | "channel_follow": ("STRING", {"multiline": False,"default": "#0001"}), 225 | "channel_encode": ("BOOLEAN", {"default": False}), 226 | }, 227 | } 228 | 229 | RETURN_TYPES = ("STRING","STRING",) 230 | RETURN_NAMES = ("channel output", "script output",) 231 | FUNCTION = "load_scripts" 232 | CATEGORY = "🛡️ NAI Scripting Pipeline" 233 | 234 | def load_scripts(self, script_prefix, channel_input, mode, agents, styles, motions, cameras, lightings, scenes, channel_follow, channel_encode): 235 | short_compiled_prompt = script_prefix + "" + self.agents_csv[agents][0] + "" + self.motions_csv[motions][0]+ "" + self.cameras_csv[cameras][0] + "" + self.scenes_csv[scenes][0]+ "" + self.styles_csv[styles][0]+ "" + self.lightings_csv[lightings][0] 236 | 237 | long_compiled_prompt = script_prefix + "" + self.agents_csv[agents][1] + "" + self.motions_csv[motions][1] + "" + self.cameras_csv[cameras][1]+ "" + self.scenes_csv[scenes][1]+ "" + self.styles_csv[styles][1]+ "" + self.lightings_csv[lightings][1] 238 | 239 | channel_concat = channel_input + "/" + channel_follow 240 | 241 | compiled_prompt_moded = channel_concat + "/ SCE/ " + self.scenes_csv[scenes][0]+ "/ MOT/ " + self.motions_csv[motions][0]+ "/ CAM/ " + self.cameras_csv[cameras][0]+ "/ AGT/ " + self.agents_csv[agents][0]+ "/ STL/ " + self.styles_csv[styles][0]+ "/ LGT/ " + self.lightings_csv[lightings][0] 242 | 243 | solo_agent_script = "AGENT: " +self.agents_csv[agents][0] + "/DETAILS: " + self.agents_csv[agents][1] 244 | 245 | if channel_encode == True: 246 | if mode == "normal": 247 | return (channel_concat, short_compiled_prompt) 248 | elif mode == "extended": 249 | return (channel_concat, long_compiled_prompt) 250 | elif mode == "experimental": 251 | return (channel_concat, compiled_prompt_moded) 252 | elif mode == "solo agent output": 253 | return (channel_concat, solo_agent_script) 254 | else: 255 | if mode == "normal": 256 | return (channel_follow, short_compiled_prompt) 257 | elif mode == "extended": 258 | return (channel_follow, long_compiled_prompt) 259 | elif mode == "experimental": 260 | return (channel_follow, compiled_prompt_moded) 261 | elif mode == "solo agent output": 262 | return (channel_follow, solo_agent_script) 263 | 264 | 265 | # REQUIRED 266 | 267 | NODE_CLASS_MAPPINGS = { 268 | "🛡️ Set Main Channel": SetMainChannel, 269 | "🛡️ Load Scripts from Database": LoadScriptsFromDatabase, 270 | "🛡️ Save Script to Database (In progress)": SaveScriptToDatabase, 271 | } 272 | 273 | NODE_DISPLAY_NAME_MAPPINGS = { 274 | "SetMainChannel": "Set Main Channel", 275 | "LoadScriptsFromDatabase": "Load Scripts from Database", 276 | "SaveScriptToDatabase": "Save Script to Database", 277 | } --------------------------------------------------------------------------------