mirror of
https://github.com/blw1138/Zordon.git
synced 2025-12-17 16:58:12 +00:00
Get detailed formats from engines (#38)
* Add get_detected_gpus() and supported_render_engines() to Blender class * Parse help args for Blender * Return dict instead of list * Parse args for FFMPEG * Add API to get renderer args * Only return available renderers * Parse help args for Blender * Return dict instead of list * Parse args for FFMPEG * Rebase off master * Rebase * Change methods from class methods to instance methods * FFMPEG format fetching
This commit is contained in:
0
lib/engines/blender_engine.py
Normal file
0
lib/engines/blender_engine.py
Normal file
4
lib/engines/ffmpeg_engine.py
Normal file
4
lib/engines/ffmpeg_engine.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print(FFMPEG.get_frame_count('/Users/brett/Desktop/Big_Fire_02.mov'))
|
||||||
@@ -561,6 +561,15 @@ def delete_engine_download():
|
|||||||
return "Success" if delete_result else ("Error deleting requested engine", 500)
|
return "Success" if delete_result else ("Error deleting requested engine", 500)
|
||||||
|
|
||||||
|
|
||||||
|
@server.get('/api/renderer/<renderer>/args')
|
||||||
|
def get_renderer_args(renderer):
|
||||||
|
try:
|
||||||
|
renderer_engine_class = RenderWorkerFactory.class_for_name(renderer).engine()
|
||||||
|
return renderer_engine_class.get_arguments()
|
||||||
|
except LookupError:
|
||||||
|
return f"Cannot find renderer '{renderer}'", 400
|
||||||
|
|
||||||
|
|
||||||
@server.route('/upload')
|
@server.route('/upload')
|
||||||
def upload_file_page():
|
def upload_file_page():
|
||||||
return render_template('upload.html', supported_renderers=RenderWorkerFactory.supported_renderers())
|
return render_template('upload.html', supported_renderers=RenderWorkerFactory.supported_renderers())
|
||||||
|
|||||||
@@ -48,3 +48,7 @@ class BaseRenderEngine(object):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def get_output_formats(cls):
|
def get_output_formats(cls):
|
||||||
raise NotImplementedError(f"get_output_formats not implemented for {cls.__name__}")
|
raise NotImplementedError(f"get_output_formats not implemented for {cls.__name__}")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_arguments(cls):
|
||||||
|
pass
|
||||||
|
|||||||
@@ -96,3 +96,52 @@ class Blender(BaseRenderEngine):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f'Error packing .blend file: {e}')
|
logger.error(f'Error packing .blend file: {e}')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_arguments(self):
|
||||||
|
help_text = subprocess.check_output([self.renderer_path(), '-h']).decode('utf-8')
|
||||||
|
lines = help_text.splitlines()
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
current_category = None
|
||||||
|
current_option = None
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
# Check if line starts with - or --, indicating a new option
|
||||||
|
if line.endswith('Options:'):
|
||||||
|
current_category = line.split('Options')[0].strip()
|
||||||
|
options[current_category] = {}
|
||||||
|
elif line.startswith("-") or line.startswith("/"):
|
||||||
|
parts = line.split(' or ')
|
||||||
|
flag = parts[-1] # Choose the verbose option
|
||||||
|
has_argument = '<' in flag and '>' in flag
|
||||||
|
flag = flag.split(' <')[0] # Remove argument placeholder
|
||||||
|
current_option = flag.strip("--") or flag
|
||||||
|
options[current_category][current_option] = {
|
||||||
|
'flag': flag, 'description': '', 'takes_argument': has_argument
|
||||||
|
}
|
||||||
|
elif line == "" and current_option is not None:
|
||||||
|
current_option = None
|
||||||
|
elif current_option is not None:
|
||||||
|
d = options[current_category][current_option]['description']
|
||||||
|
d = d + (' ' if d else '') + line
|
||||||
|
options[current_category][current_option]['description'] = d
|
||||||
|
|
||||||
|
return options
|
||||||
|
|
||||||
|
def get_detected_gpus(self):
|
||||||
|
engine_output = subprocess.run([self.renderer_path(), '-E', 'help'], timeout=SUBPROCESS_TIMEOUT,
|
||||||
|
capture_output=True).stdout.decode('utf-8')
|
||||||
|
gpu_names = re.findall(r"DETECTED GPU: (.+)", engine_output)
|
||||||
|
return gpu_names
|
||||||
|
|
||||||
|
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()
|
||||||
|
render_engines = [x.strip() for x in engine_output.split('Blender Engine Listing:')[-1].strip().splitlines()]
|
||||||
|
return render_engines
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
x = Blender.get_detected_gpus()
|
||||||
|
print(x)
|
||||||
|
|||||||
@@ -26,12 +26,28 @@ class FFMPEG(BaseRenderEngine):
|
|||||||
encoders = [m.groupdict() for m in re.finditer(pattern, raw_stdout)]
|
encoders = [m.groupdict() for m in re.finditer(pattern, raw_stdout)]
|
||||||
return encoders
|
return encoders
|
||||||
|
|
||||||
|
def get_formats(self):
|
||||||
|
encoders = [x['name'] for x in self.get_all_formats() if 'E' in x['type']]
|
||||||
|
return encoders
|
||||||
|
|
||||||
def get_all_formats(self):
|
def get_all_formats(self):
|
||||||
raw_stdout = subprocess.check_output([self.renderer_path(), '-formats'], stderr=subprocess.DEVNULL,
|
formats_raw = subprocess.check_output([self.renderer_path(), '-formats'], stderr=subprocess.DEVNULL,
|
||||||
timeout=SUBPROCESS_TIMEOUT).decode('utf-8')
|
timeout=SUBPROCESS_TIMEOUT).decode('utf-8')
|
||||||
pattern = '(?P<type>[DE]{1,2})\s+(?P<name>\S{2,})\s+(?P<description>.*)'
|
pattern = '(?P<type>[DE]{1,2})\s+(?P<id>\S{2,})\s+(?P<name>.*)'
|
||||||
formats = [m.groupdict() for m in re.finditer(pattern, raw_stdout)]
|
all_formats = [m.groupdict() for m in re.finditer(pattern, formats_raw)]
|
||||||
return formats
|
return all_formats
|
||||||
|
|
||||||
|
def extension_for_format(self, ffmpeg_format):
|
||||||
|
# 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')
|
||||||
|
pattern = r"Common extensions: (\w+)"
|
||||||
|
common_extensions = re.findall(pattern, format_detail_raw)
|
||||||
|
found_extensions = []
|
||||||
|
if common_extensions:
|
||||||
|
found_extensions = common_extensions[0].split(',')
|
||||||
|
return found_extensions
|
||||||
|
|
||||||
def get_output_formats(self):
|
def get_output_formats(self):
|
||||||
return [x for x in self.get_all_formats() if 'E' in x['type'].upper()]
|
return [x for x in self.get_all_formats() if 'E' in x['type'].upper()]
|
||||||
@@ -45,6 +61,32 @@ class FFMPEG(BaseRenderEngine):
|
|||||||
frame_number = int(match[-1])
|
frame_number = int(match[-1])
|
||||||
return frame_number
|
return frame_number
|
||||||
|
|
||||||
|
def get_arguments(self):
|
||||||
|
help_text = subprocess.check_output([self.renderer_path(), '-h', 'long'], stderr=subprocess.STDOUT).decode('utf-8')
|
||||||
|
lines = help_text.splitlines()
|
||||||
|
|
||||||
|
options = {}
|
||||||
|
current_category = None
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if line.endswith(":") and "options" in line.lower():
|
||||||
|
current_category = line.split('options')[0].strip()
|
||||||
|
options[current_category] = {}
|
||||||
|
elif line: # Ignore blank lines
|
||||||
|
split_line = line.split(' ', 2)
|
||||||
|
flag = split_line[0]
|
||||||
|
argument = split_line[1] if len(split_line) > 1 else ''
|
||||||
|
description = split_line[2] if len(split_line) > 2 else ''
|
||||||
|
|
||||||
|
if current_category:
|
||||||
|
name = flag.strip('-')
|
||||||
|
options[current_category][name] = {
|
||||||
|
'flag': flag, 'description': description.strip(), 'takes_argument': bool(argument)
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print(FFMPEG.get_frame_count('/Users/brett/Desktop/Big_Fire_02.mov'))
|
print(FFMPEG().get_all_formats())
|
||||||
Reference in New Issue
Block a user