Ability to set custom start / end frames (#14)

* Accept start / end frames in job submissions. Start / end frame support for Blender

* Remove old render_all_frames variables and misc cleanup

* Client work - Client determines frame count for FFMPEG and shows frame picker UI
This commit is contained in:
2023-06-11 20:45:16 -05:00
committed by GitHub
parent 94bb1e4362
commit 78a389080c
6 changed files with 102 additions and 49 deletions

View File

@@ -12,6 +12,7 @@ import psutil
import requests
import threading
from lib.workers.blender_worker import Blender
from lib.workers.ffmpeg_worker import FFMPEG
from lib.server.server_proxy import RenderServerProxy
logger = logging.getLogger()
@@ -57,6 +58,7 @@ class NewJobWindow(Frame):
self.clients = clients or []
self.server_proxy = RenderServerProxy(hostname=clients[0] if clients else None)
self.chosen_file = None
self.project_info = {}
self.presets = {}
self.renderer_info = {}
self.priority = IntVar(value=2)
@@ -128,15 +130,27 @@ class NewJobWindow(Frame):
self.output_entry.pack(side=LEFT, padx=5, expand=True, fill=X)
self.output_format = Combobox(output_frame, state="readonly", values=['JPG', 'MOV', 'PNG'], width=9)
self.output_format.pack(padx=5, pady=5)
self.output_format.pack(side=LEFT, padx=5, pady=5)
self.output_format['state'] = DISABLED
# frame_range frame
frame_range_frame = Frame(job_frame)
frame_range_frame.pack(fill=X)
Label(frame_range_frame, text="Frames", width=label_width).pack(side=LEFT, padx=5, pady=5, expand=False)
self.start_frame_spinbox = Spinbox(frame_range_frame, from_=0, to=50000, width=5)
self.start_frame_spinbox.pack(side=LEFT, expand=False, padx=5, pady=5)
Label(frame_range_frame, text="to").pack(side=LEFT, pady=5, expand=False)
self.end_frame_spinbox = Spinbox(frame_range_frame, from_=0, to=50000, width=5)
self.end_frame_spinbox.pack(side=LEFT, expand=False, padx=5, pady=5)
# Blender
self.blender_frame = None
self.blender_cameras_frame = None
self.blender_engine = StringVar(value='CYCLES')
self.blender_pack_textures = BooleanVar(value=False)
self.blender_render_all_frames = BooleanVar(value=False)
self.blender_multiple_cameras = BooleanVar(value=False)
self.blender_cameras_list = None
@@ -177,10 +191,11 @@ class NewJobWindow(Frame):
self.output_entry.delete(0, END)
if self.chosen_file:
# Generate a default output name
output_name = os.path.basename(self.chosen_file).split('.')[0]
output_name = os.path.splitext(os.path.basename(self.chosen_file))[-1].strip('.')
self.output_entry.insert(0, os.path.basename(output_name))
# Try to determine file type
extension = self.chosen_file.split('.')[-1] # not the best way to do this
extension = os.path.splitext(self.chosen_file)[-1].strip('.') # not the best way to do this
for renderer, renderer_info in self.renderer_info.items():
supported = [x.lower().strip('.') for x in renderer_info.get('supported_extensions', [])]
if extension.lower().strip('.') in supported:
@@ -206,11 +221,29 @@ class NewJobWindow(Frame):
if self.blender_frame:
self.blender_frame.pack_forget()
if not self.chosen_file:
return
if renderer == 'blender':
self.project_info = Blender.get_scene_info(self.chosen_file)
self.draw_blender_settings()
elif renderer == 'ffmpeg':
f = FFMPEG.get_frame_count(self.chosen_file)
self.project_info['frame_end'] = f
# set frame start / end numbers fetched from fils
if self.project_info.get('frame_start'):
self.start_frame_spinbox.delete(0, 'end')
self.start_frame_spinbox.insert(0, self.project_info['frame_start'])
if self.project_info.get('frame_end'):
self.end_frame_spinbox.delete(0, 'end')
self.end_frame_spinbox.insert(0, self.project_info['frame_end'])
# redraw lower ui
self.draw_custom_args()
self.draw_submit_button()
# check supported export formats
if self.renderer_info.get(renderer, {}).get('supported_export_formats', None):
formats = self.renderer_info[renderer]['supported_export_formats']
if formats and isinstance(formats[0], dict):
@@ -257,12 +290,6 @@ class NewJobWindow(Frame):
def draw_blender_settings(self):
scene_data = None
# get file stats
if self.chosen_file:
scene_data = Blender.get_scene_info(self.chosen_file)
# blender settings
self.blender_frame = LabelFrame(self, text="Blender Settings")
self.blender_frame.pack(fill=X, padx=5)
@@ -285,12 +312,10 @@ class NewJobWindow(Frame):
Checkbutton(pack_frame, text="Pack Textures", variable=self.blender_pack_textures, onvalue=True, offvalue=False
).pack(anchor=W, side=LEFT, padx=5)
Checkbutton(pack_frame, text="Render All Frames", variable=self.blender_render_all_frames, onvalue=True,
offvalue=False).pack(anchor=W, side=LEFT, padx=5)
# multi cams
def draw_scene_cams(event=None):
if scene_data:
if self.project_info:
show_cams_checkbutton['state'] = NORMAL
if self.blender_multiple_cameras.get():
self.blender_cameras_frame = Frame(self.blender_frame)
@@ -298,7 +323,7 @@ class NewJobWindow(Frame):
Label(self.blender_cameras_frame, text="Cameras", width=label_width).pack(side=LEFT, padx=5, pady=5)
choices = [f"{x['name']} - {int(float(x['lens']))}mm" for x in scene_data['cameras']]
choices = [f"{x['name']} - {int(float(x['lens']))}mm" for x in self.project_info['cameras']]
choices.sort()
self.blender_cameras_list = ChecklistBox(self.blender_cameras_frame, choices, relief="sunken")
self.blender_cameras_list.pack(padx=5, fill=X)
@@ -310,7 +335,7 @@ class NewJobWindow(Frame):
self.blender_cameras_frame.pack_forget()
# multiple cameras checkbox
camera_count = len(scene_data.get('cameras', [])) if scene_data else 0
camera_count = len(self.project_info.get('cameras', [])) if self.project_info else 0
show_cams_checkbutton = Checkbutton(pack_frame, text=f'Multiple Cameras ({camera_count})', offvalue=False,
onvalue=True,
variable=self.blender_multiple_cameras, command=draw_scene_cams)
@@ -336,6 +361,8 @@ class NewJobWindow(Frame):
'client': client,
'output_path': os.path.join(os.path.dirname(self.chosen_file), self.output_entry.get()),
'args': {'raw': self.custom_args_entry.get()},
'start_frame': self.start_frame_spinbox.get(),
'end_frame': self.end_frame_spinbox.get(),
'name': None}
job_list = []
@@ -356,7 +383,6 @@ class NewJobWindow(Frame):
return
# add all Blender args
job_json['args']['engine'] = self.blender_engine.get()
job_json['args']['render_all_frames'] = self.blender_render_all_frames.get()
job_json['args']['export_format'] = self.output_format.get()
# multiple camera rendering