This commit is contained in:
justumen
2024-09-13 07:49:15 +02:00
parent d0b40589ea
commit 0cdec9184c
9 changed files with 119 additions and 6 deletions

View File

@@ -1,4 +1,4 @@
# 🔗 Comfyui : Bjornulf_custom_nodes v0.22 🔗
# 🔗 Comfyui : Bjornulf_custom_nodes v0.23 🔗
# ☁ Usage in cloud :
@@ -65,6 +65,7 @@ wget --content-disposition -P /workspace/ComfyUI/models/checkpoints "https://civ
- **v0.20**: Changes for lobechat save image : include the code of free VRAM hack + ignore missing images filenames
- **v0.21**: Add a new write text node that also display the text in the comfyui console (good for debugging)
- **v0.22**: Allow write text node to use random selection like this {hood|helmet} will randomly choose between hood or helmet.
- **v0.23**: And a new node: Pause, resume or stop workflow.
# 📝 Nodes descriptions
@@ -326,3 +327,15 @@ So, not perfect but better than being stuck at 6GB of VRAM used if I know I won'
Just connect this node with your workflow, it takes an image as input and return the same image without any changes.
❗ Comfyui is using cache to run faster (like not reloading checkpoints), so only use this free VRAM node when you need it.
❗ For this node to work properly, you need to enable the dev/api mode in ComfyUI. (You can do that in the settings)
### 35 - ⏸️ Paused. Resume or Stop ?
![pause resume stop](screenshots/pause1.png)
![pause resume stop](screenshots/pause2.png)
![pause resume stop](screenshots/pause3.png)
**Description:**
Automatically pause the workflow, and rings a bell when it does. (play the audio `bell.m4a` file provided)
You can then manually resume or stop the workflow by clicking on the node's buttons.
I do that let's say for example if I have a very long upscaling process, I can check if the input is good before continuing. Sometimes I might stop the workflow and restart it with another seed.
You can connect any type of node to the pause node, above is an example with text, but you can send an IMAGE or whatever else, in the node `input = output`. (Of course you need to send the output to something that has the correct format...)

View File

@@ -40,7 +40,7 @@ from .character_description import CharacterDescriptionGenerator
from .text_to_speech import TextToSpeech
from .loop_combine_texts_by_lines import CombineTextsByLines
from .free_vram_hack import FreeVRAM
# from .pause_resume import PauseResume
from .pause_resume_stop import PauseResume
# from .check_black_image import CheckBlackImage
# from .clear_vram import ClearVRAM
@@ -49,7 +49,7 @@ from .free_vram_hack import FreeVRAM
NODE_CLASS_MAPPINGS = {
# "Bjornulf_CustomStringType": CustomStringType,
"Bjornulf_ollamaLoader": ollamaLoader,
# "Bjornulf_PauseResume": PauseResume,
"Bjornulf_PauseResume": PauseResume,
"Bjornulf_FreeVRAM": FreeVRAM,
"Bjornulf_CombineTextsByLines": CombineTextsByLines,
"Bjornulf_TextToSpeech": TextToSpeech,
@@ -98,7 +98,7 @@ NODE_CLASS_MAPPINGS = {
NODE_DISPLAY_NAME_MAPPINGS = {
# "Bjornulf_CustomStringType": "!!! CUSTOM STRING TYPE !!!",
"Bjornulf_ollamaLoader": "🦙 Ollama (Description)",
# "Bjornulf_PauseResume": "⏸️ Pause/Resume",
"Bjornulf_PauseResume": "⏸️ Paused. Resume or Stop ?",
"Bjornulf_FreeVRAM": "🧹 Free VRAM hack",
"Bjornulf_CombineTextsByLines": "♻ Loop (All Lines from input 🔗 combine by lines)",
"Bjornulf_TextToSpeech": "🔊 TTS - Text to Speech",

BIN
bell.m4a Normal file

Binary file not shown.

63
pause_resume_stop.py Normal file
View File

@@ -0,0 +1,63 @@
import time
from aiohttp import web
from server import PromptServer
import logging
from pydub import AudioSegment
from pydub.playback import play
import os
class Everything(str):
def __ne__(self, __value: object) -> bool:
return False
class PauseResume:
is_paused = True
should_stop = False
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"input": (Everything("*"), {"forceInput": True})
}
}
RETURN_TYPES = (Everything("*"),)
RETURN_NAMES = ("output",)
FUNCTION = "loop_resume_or_stop"
CATEGORY = "Bjornulf"
def play_audio(self):
audio_file = os.path.join(os.path.dirname(__file__), 'bell.m4a')
sound = AudioSegment.from_file(audio_file, format="m4a")
play(sound)
def loop_resume_or_stop(self, input):
self.play_audio()
self.input = input
while PauseResume.is_paused and not PauseResume.should_stop:
logging.info(f"PauseResume.is_paused: {PauseResume.is_paused}, PauseResume.should_stop: {PauseResume.should_stop}")
time.sleep(1) # Sleep to prevent busy waiting
if PauseResume.should_stop:
PauseResume.should_stop = False # Reset for next run
PauseResume.is_paused = True
PauseResume.should_stop = False
raise Exception("Workflow stopped by user")
PauseResume.is_paused = True
PauseResume.should_stop = False
return (self.input,)
@PromptServer.instance.routes.get("/bjornulf_resume")
async def resume_node(request):
logging.info("Resume node called")
PauseResume.is_paused = False
return web.Response(text="Node resumed")
@PromptServer.instance.routes.get("/bjornulf_stop")
async def stop_node(request):
logging.info("Stop node called")
PauseResume.should_stop = True
PauseResume.is_paused = False # Ensure the loop exits
return web.Response(text="Workflow stopped")

View File

@@ -1,7 +1,7 @@
[project]
name = "bjornulf_custom_nodes"
description = "Nodes: Ollama, Text to Speech, Save image for Bjornulf LobeChat, Text with random Seed, Random line from input, Combine images (Background + Overlay alpha), Image to grayscale (black & white), Remove image Transparency (alpha), Resize Image, ..."
version = "0.21"
version = "0.23"
license = {file = "LICENSE"}
[project.urls]

BIN
screenshots/pause1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
screenshots/pause2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
screenshots/pause3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

37
web/js/pauseresume.js Normal file
View File

@@ -0,0 +1,37 @@
import { app } from "../../../scripts/app.js";
app.registerExtension({
name: "Bjornulf.PauseResume",
async nodeCreated(node) {
if (node.comfyClass === "Bjornulf_PauseResume") {
const resumeButton = node.addWidget("button", "Resume", "Resume", () => {
fetch('/bjornulf_resume', { method: 'GET' })
.then(response => response.text())
.then(data => {
console.log('Resume response:', data);
// You can update the UI here if needed
})
.catch(error => console.error('Error:', error));
});
const stopButton = node.addWidget("button", "Stop", "Stop", () => {
fetch('/bjornulf_stop', { method: 'GET' })
.then(response => response.text())
.then(data => {
console.log('Stop response:', data);
// You can update the UI here if needed
})
.catch(error => console.error('Error:', error));
});
}
}
});
// BASIC BUTTON
// app.registerExtension({
// name: "Bjornulf.PauseResume",
// async nodeCreated(node) {
// if (node.comfyClass === "Bjornulf_PauseResume") {
// node.addWidget("button","Resume","Resume", (...args) => { console.log("lol"); } )
// }
// }
// });