diff --git a/__init__.py b/__init__.py index a2564e1..dc6e8ee 100644 --- a/__init__.py +++ b/__init__.py @@ -202,6 +202,8 @@ class Lexicon(metaclass=LexiconMeta): G = '🟩', "Green" GAMMA = 'πŸ”†', "Gamma" GI = 'πŸ’š', "Green Channel" + GLSL_CUSTOM = 'πŸ§™πŸ½β€β™€οΈ', "User GLSL Shader" + GLSL_INTERNAL = 'πŸ§™πŸ½', "Internal GLSL Shader" GRADIENT = 'πŸ‡²πŸ‡Ί', "Gradient" H = 'πŸ‡­', "Hue" HI = 'HI', "High / Top of range" @@ -877,16 +879,16 @@ class Session(metaclass=Singleton): JOV_IGNORE_NODE = [] node_count = 0 - for f in (ROOT / 'core').iterdir(): - if f.suffix != ".py" or f.stem.startswith('_'): + for fname in (ROOT / 'core').iterdir(): + if fname.suffix != ".py" or fname.stem.startswith('_'): continue - if f.stem in JOV_IGNORE_NODE or f.stem+'.py' in JOV_IGNORE_NODE: - logger.warning(f"πŸ’€ [IGNORED] Jovimetrix.core.{f.stem}") + if fname.stem in JOV_IGNORE_NODE or fname.stem+'.py' in JOV_IGNORE_NODE: + logger.warning(f"πŸ’€ [IGNORED] Jovimetrix.core.{fname.stem}") continue try: - module = importlib.import_module(f"Jovimetrix.core.{f.stem}") + module = importlib.import_module(f"Jovimetrix.core.{fname.stem}") except Exception as e: - logger.warning(f"module failed {f}") + logger.warning(f"module failed {fname}") logger.warning(str(e)) continue @@ -912,8 +914,11 @@ class Session(metaclass=Singleton): else: Session.CLASS_MAPPINGS[name] = class_object - desc = class_object.DESCRIPTION if hasattr(class_object, 'DESCRIPTION') else "" - NODE_LIST_MAP[name] = desc.split('.')[0].strip('\n') + if not name.endswith(Lexicon.GLSL_CUSTOM): + desc = class_object.DESCRIPTION if hasattr(class_object, 'DESCRIPTION') else "" + NODE_LIST_MAP[name] = desc.split('.')[0].strip('\n') + else: + logger.debug(f"customs {name}") node_count += 1 logger.info(f"βœ… {module.__name__}") diff --git a/core/compose.py b/core/compose.py index 8c3af31..fedeb5b 100644 --- a/core/compose.py +++ b/core/compose.py @@ -42,7 +42,7 @@ JOV_CATEGORY = "COMPOSE" class EnumColorMatchMode(Enum): REINHARD = 30 LUT = 10 - HISTOGRAM = 20 + # HISTOGRAM = 20 class EnumColorMatchMap(Enum): USER_MAP = 0 @@ -335,7 +335,7 @@ class ColorMatchNode(JOVImageNode): NAME = "COLOR MATCH (JOV) πŸ’ž" CATEGORY = f"JOVIMETRIX πŸ”ΊπŸŸ©πŸ”΅/{JOV_CATEGORY}" DESCRIPTION = """ -Adjust the color scheme of one image to match another with the Color Match Node. Choose from various color matching modes, including LUT, Histogram, and Reinhard. You can specify options like color maps, the number of colors, and whether to flip or invert the images. This node allows for the creation of seamless and cohesive visuals, making it ideal for texture work or masking in motion graphics and design projects. +Adjust the color scheme of one image to match another with the Color Match Node. Choose from various color matching LUTs or Reinhard matching. You can specify a custom user color maps, the number of colors, and whether to flip or invert the images. """ @classmethod @@ -385,7 +385,7 @@ Adjust the color scheme of one image to match another with the Color Match Node. if pA.ndim == 3 and pA.shape[2] == 4: mask = image_mask(pA) - h, w = pA.shape[:2] + # h, w = pA.shape[:2] if pB is None: pB = channel_solid(chan=EnumImageType.BGR) else: @@ -399,10 +399,7 @@ Adjust the color scheme of one image to match another with the Color Match Node. pB = None colormap = EnumColorMap[colormap] pA = color_match_lut(pA, colormap.value, pB, num_colors) - case EnumColorMatchMode.HISTOGRAM: - pB = image_scalefit(pB, w, h, EnumScaleMode.CROP) - pB = image_scalefit(pB, w, h, EnumScaleMode.MATTE) - pA = color_match_histogram(pA, pB) + case EnumColorMatchMode.REINHARD: pA = color_match_reinhard(pA, pB) @@ -410,10 +407,8 @@ Adjust the color scheme of one image to match another with the Color Match Node. if invert == True: pA = image_invert(pA, 1) - logger.debug(mask) if mask is not None: pA = image_mask_add(pA, mask) - logger.debug(pA.shape) images.append(cv2tensor_full(pA, matte)) pbar.update_absolute(idx) @@ -659,6 +654,7 @@ Remaps an input image using a gradient lookup table (LUT). The gradient image wi pbar = ProgressBar(len(params)) for idx, (pA, gradient, flip, mode, sample, wihi, matte) in enumerate(params): pA = channel_solid(chan=EnumImageType.BGR) if pA is None else tensor2cv(pA) + mask = None if pA.ndim == 3 and pA.shape[2] == 4: mask = image_mask(pA) diff --git a/core/create_glsl.py b/core/create_glsl.py index 4f0c131..79c4ce7 100644 --- a/core/create_glsl.py +++ b/core/create_glsl.py @@ -268,10 +268,10 @@ def import_dynamic() -> Tuple[str,...]: class_name = name.title().replace(' ', '_') class_name = f'GLSLNode_{class_name}' - emoji = 'πŸ§™πŸ½β€β™€οΈ' + emoji = Lexicon.GLSL_CUSTOM sort_order = sort if fname.startswith(root): - emoji = 'πŸ§™πŸ½' + emoji = Lexicon.GLSL_INTERNAL sort_order -= 10000 category = GLSLNodeDynamic.CATEGORY diff --git a/core/device_stream.py b/core/device_stream.py index cfa4272..7b6c14d 100644 --- a/core/device_stream.py +++ b/core/device_stream.py @@ -293,6 +293,7 @@ Sends frames to a specified route, typically for live streaming or recording pur super().__init__(*arg, **kw) self.__route = "" self.__unique = uuid.uuid4() + self.__device = StreamManager().capture(self.__unique, static=True) def run(self, **kw) -> Tuple[torch.Tensor]: diff --git a/node_list.json b/node_list.json index 019a3b0..ae21872 100644 --- a/node_list.json +++ b/node_list.json @@ -15,9 +15,7 @@ "FLATTEN (JOV) \u2b07\ufe0f": "Combine multiple input images into a single image by summing their pixel values", "GLSL (JOV) \ud83c\udf69": "Execute custom GLSL (OpenGL Shading Language) fragment shaders to generate images or apply effects", "GLSL BLEND LINEAR (JOV) \ud83e\uddd9\ud83c\udffd": "Simple linear blend between two images", - "GLSL FILTER RANGE (JOV) \ud83e\uddd9\ud83c\udffd\u200d\u2640\ufe0f": "Select pixels from start color through end color", "GLSL GRAYSCALE (JOV) \ud83e\uddd9\ud83c\udffd": "Convert input to grayscale", - "GLSL HSV ADJUST (JOV) \ud83e\uddd9\ud83c\udffd": "HSV ADJUST", "GLSL HSV-2-LAB (JOV) \ud83e\uddd9\ud83c\udffd": "Convert HSV input to LAB", "GLSL HSV-2-RGB (JOV) \ud83e\uddd9\ud83c\udffd": "Convert HSV input to RGB", "GLSL LAB-2-HSV (JOV) \ud83e\uddd9\ud83c\udffd": "Convert LAB color space to HSV", diff --git a/sup/stream.py b/sup/stream.py index 3bb493f..cfab802 100644 --- a/sup/stream.py +++ b/sup/stream.py @@ -4,6 +4,7 @@ Media Stream Support """ import os +import ssl import sys import json import time @@ -20,6 +21,8 @@ import mss.tools import numpy as np from PIL import Image, ImageGrab +from comfy.cli_args import args as cmd_args + from loguru import logger # SPOUT SUPPORT @@ -557,6 +560,8 @@ class StreamingServer(metaclass=Singleton): self.__host = host self.__port = port self.__address = (self.__host, self.__port) + self.__tls_keyfile = cmd_args.tls_keyfile + self.__tls_certfile = cmd_args.tls_certfile self.__thread_server = threading.Thread(target=self.__server, daemon=True) self.__thread_server.start() self.__thread_capture = threading.Thread(target=self.__capture, daemon=True) @@ -564,7 +569,19 @@ class StreamingServer(metaclass=Singleton): logger.info("STARTED") def __server(self) -> None: - httpd = ThreadingHTTPServer(self.__address, lambda *args: StreamingHandler(StreamingServer.OUT, *args)) + handler = lambda *args: StreamingHandler(StreamingServer.OUT, *args) + httpd = ThreadingHTTPServer(self.__address, handler) + + if self.__tls_keyfile and self.__tls_certfile: + # HTTPS mode + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + context.load_cert_chain(self.__tls_certfile, self.__tls_keyfile) + httpd.socket = context.wrap_socket(httpd.socket, server_side=True) + logger.info(f"HTTPS server {self.__address}") + else: + # HTTP mode + logger.info(f"HTTP server {self.__address}") + while True: httpd.handle_request()