diff --git a/main.spec b/main.spec index 850cff5..39717b1 100644 --- a/main.spec +++ b/main.spec @@ -26,7 +26,7 @@ a = Analysis( runtime_hooks=[], excludes=[], noarchive=False, - optimize=2, + optimize=0, ) pyz = PYZ(a.pure) diff --git a/src/engines/blender/blender_engine.py b/src/engines/blender/blender_engine.py index 44822c9..c9e9c9f 100644 --- a/src/engines/blender/blender_engine.py +++ b/src/engines/blender/blender_engine.py @@ -6,6 +6,8 @@ from src.utilities.misc_helper import system_safe_path logger = logging.getLogger() +_creationflags = subprocess.CREATE_NO_WINDOW if platform.system() == 'Windows' else 0 + class Blender(BaseRenderEngine): @@ -35,7 +37,8 @@ class Blender(BaseRenderEngine): try: render_path = self.renderer_path() if render_path: - ver_out = subprocess.check_output([render_path, '-v'], timeout=SUBPROCESS_TIMEOUT) + ver_out = subprocess.check_output([render_path, '-v'], timeout=SUBPROCESS_TIMEOUT, + creationflags=_creationflags) version = ver_out.decode('utf-8').splitlines()[0].replace('Blender', '').strip() except Exception as e: logger.error(f'Failed to get Blender version: {e}') @@ -50,7 +53,7 @@ class Blender(BaseRenderEngine): if os.path.exists(project_path): try: return subprocess.run([self.renderer_path(), '-b', project_path, '--python-expr', python_expression], - capture_output=True, timeout=timeout) + capture_output=True, timeout=timeout, creationflags=_creationflags) except Exception as e: logger.error(f"Error running python expression in blender: {e}") else: @@ -67,7 +70,7 @@ class Blender(BaseRenderEngine): command = [self.renderer_path(), '-b', '--python', script_path] if project_path: command.insert(2, project_path) - return subprocess.run(command, capture_output=True, timeout=timeout) + return subprocess.run(command, capture_output=True, timeout=timeout, creationflags=_creationflags) except Exception as e: logger.exception(f"Error running python script in blender: {e}") @@ -116,7 +119,7 @@ class Blender(BaseRenderEngine): return None def get_arguments(self): - help_text = subprocess.check_output([self.renderer_path(), '-h']).decode('utf-8') + help_text = subprocess.check_output([self.renderer_path(), '-h'], creationflags=_creationflags).decode('utf-8') lines = help_text.splitlines() options = {} @@ -164,7 +167,7 @@ class Blender(BaseRenderEngine): def supported_render_engines(self): engine_output = subprocess.run([self.renderer_path(), '-E', 'help'], timeout=SUBPROCESS_TIMEOUT, - capture_output=True).stdout.decode('utf-8').strip() + capture_output=True, creationflags=_creationflags).stdout.decode('utf-8').strip() render_engines = [x.strip() for x in engine_output.split('Blender Engine Listing:')[-1].strip().splitlines()] return render_engines diff --git a/src/engines/core/base_engine.py b/src/engines/core/base_engine.py index f1bdf30..57fbf5c 100644 --- a/src/engines/core/base_engine.py +++ b/src/engines/core/base_engine.py @@ -1,5 +1,6 @@ import logging import os +import platform import subprocess logger = logging.getLogger() @@ -61,8 +62,9 @@ class BaseRenderEngine(object): path = self.renderer_path() if not path: raise FileNotFoundError("renderer path not found") + creationflags = subprocess.CREATE_NO_WINDOW if platform.system() == 'Windows' else 0 help_doc = subprocess.check_output([path, '-h'], stderr=subprocess.STDOUT, - timeout=SUBPROCESS_TIMEOUT).decode('utf-8') + timeout=SUBPROCESS_TIMEOUT, creationflags=creationflags).decode('utf-8') return help_doc def get_project_info(self, project_path, timeout=10): diff --git a/src/engines/core/base_worker.py b/src/engines/core/base_worker.py index 407f4ca..9676865 100644 --- a/src/engines/core/base_worker.py +++ b/src/engines/core/base_worker.py @@ -326,9 +326,10 @@ class BaseRenderWorker(Base): self.__process = subprocess.Popen(subprocess_cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=False, preexec_fn=os.setsid) else: # windows + creationflags = subprocess.CREATE_NEW_PROCESS_GROUP | subprocess.CREATE_NO_WINDOW self.__process = subprocess.Popen(subprocess_cmds, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=False, - creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) + creationflags=creationflags) # Start watchdog self.__last_output_time = time.time() diff --git a/src/engines/ffmpeg/ffmpeg_engine.py b/src/engines/ffmpeg/ffmpeg_engine.py index 4f2ab9f..70e456f 100644 --- a/src/engines/ffmpeg/ffmpeg_engine.py +++ b/src/engines/ffmpeg/ffmpeg_engine.py @@ -3,6 +3,8 @@ import re from src.engines.core.base_engine import * +_creationflags = subprocess.CREATE_NO_WINDOW if platform.system() == 'Windows' else 0 + class FFMPEG(BaseRenderEngine): binary_names = {'linux': 'ffmpeg', 'windows': 'ffmpeg.exe', 'macos': 'ffmpeg'} @@ -22,8 +24,8 @@ class FFMPEG(BaseRenderEngine): return FFMPEGUI.get_options(self) def supported_extensions(self): - help_text = (subprocess.check_output([self.renderer_path(), '-h', 'full'], stderr=subprocess.STDOUT) - .decode('utf-8')) + help_text = (subprocess.check_output([self.renderer_path(), '-h', 'full'], stderr=subprocess.STDOUT, + creationflags=_creationflags).decode('utf-8')) found = re.findall(r'extensions that .* is allowed to access \(default "(.*)"', help_text) found_extensions = set() for match in found: @@ -33,8 +35,8 @@ class FFMPEG(BaseRenderEngine): def version(self): version = None try: - ver_out = subprocess.check_output([self.renderer_path(), '-version'], - timeout=SUBPROCESS_TIMEOUT).decode('utf-8') + ver_out = subprocess.check_output([self.renderer_path(), '-version'], timeout=SUBPROCESS_TIMEOUT, + creationflags=_creationflags).decode('utf-8') match = re.match(r".*version\s*([\w.*]+)\W*", ver_out) if match: version = match.groups()[0] @@ -49,7 +51,8 @@ class FFMPEG(BaseRenderEngine): 'ffprobe', '-v', 'quiet', '-print_format', 'json', '-show_streams', '-select_streams', 'v', project_path ] - output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, text=True) + output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, text=True, + creationflags=_creationflags) video_info = json.loads(output) # Extract the necessary information @@ -80,7 +83,7 @@ class FFMPEG(BaseRenderEngine): def get_encoders(self): raw_stdout = subprocess.check_output([self.renderer_path(), '-encoders'], stderr=subprocess.DEVNULL, - timeout=SUBPROCESS_TIMEOUT).decode('utf-8') + timeout=SUBPROCESS_TIMEOUT, creationflags=_creationflags).decode('utf-8') pattern = r'(?P[VASFXBD.]{6})\s+(?P\S{2,})\s+(?P.*)' encoders = [m.groupdict() for m in re.finditer(pattern, raw_stdout)] return encoders @@ -92,7 +95,8 @@ class FFMPEG(BaseRenderEngine): def get_all_formats(self): try: formats_raw = subprocess.check_output([self.renderer_path(), '-formats'], stderr=subprocess.DEVNULL, - timeout=SUBPROCESS_TIMEOUT).decode('utf-8') + timeout=SUBPROCESS_TIMEOUT, + creationflags=_creationflags).decode('utf-8') pattern = r'(?P[DE]{1,2})\s+(?P\S{2,})\s+(?P.*)' all_formats = [m.groupdict() for m in re.finditer(pattern, formats_raw)] return all_formats @@ -104,7 +108,8 @@ class FFMPEG(BaseRenderEngine): # Extract the common extension using regex muxer_flag = 'muxer' if 'E' in ffmpeg_format['type'] else 'demuxer' format_detail_raw = subprocess.check_output( - [self.renderer_path(), '-hide_banner', '-h', f"{muxer_flag}={ffmpeg_format['id']}"]).decode('utf-8') + [self.renderer_path(), '-hide_banner', '-h', f"{muxer_flag}={ffmpeg_format['id']}"], + creationflags=_creationflags).decode('utf-8') pattern = r"Common extensions: (\w+)" common_extensions = re.findall(pattern, format_detail_raw) found_extensions = [] @@ -118,7 +123,7 @@ class FFMPEG(BaseRenderEngine): def get_frame_count(self, path_to_file): raw_stdout = subprocess.check_output([self.renderer_path(), '-i', path_to_file, '-map', '0:v:0', '-c', 'copy', '-f', 'null', '-'], stderr=subprocess.STDOUT, - timeout=SUBPROCESS_TIMEOUT).decode('utf-8') + timeout=SUBPROCESS_TIMEOUT, creationflags=_creationflags).decode('utf-8') match = re.findall(r'frame=\s*(\d+)', raw_stdout) if match: frame_number = int(match[-1]) @@ -126,8 +131,8 @@ class FFMPEG(BaseRenderEngine): return -1 def get_arguments(self): - help_text = (subprocess.check_output([self.renderer_path(), '-h', 'long'], stderr=subprocess.STDOUT) - .decode('utf-8')) + help_text = (subprocess.check_output([self.renderer_path(), '-h', 'long'], stderr=subprocess.STDOUT, + creationflags=_creationflags).decode('utf-8')) lines = help_text.splitlines() options = {}