Major file reorganization (#26)

* Major file reorganization

* Rearrange imports

* Fix default log level
This commit is contained in:
2023-06-30 21:24:40 -05:00
committed by GitHub
parent 34fbdaa4d9
commit a475aa999a
46 changed files with 117 additions and 128 deletions

View File

@@ -17,9 +17,9 @@ from rich.table import Table
from rich.text import Text from rich.text import Text
from rich.tree import Tree from rich.tree import Tree
from lib.workers.base_worker import RenderStatus, string_to_status from src.workers.base_worker import RenderStatus, string_to_status
from lib.server.server_proxy import RenderServerProxy from src.server_proxy import RenderServerProxy
from lib.utilities.misc_helper import get_time_elapsed from src.utilities.misc_helper import get_time_elapsed
from start_server import start_server from start_server import start_server
""" """

View File

@@ -1,15 +1,12 @@
click~=8.1.3
requests==2.31.0 requests==2.31.0
psutil==5.9.5 psutil==5.9.5
PyYAML~=6.0 PyYAML~=6.0
Flask==2.3.2 Flask==2.3.2
rich==13.4.1 rich==13.4.1
Werkzeug==2.3.5 Werkzeug==2.3.5
tkinterdnd2~=0.3.0
future==0.18.3 future==0.18.3
json2html~=1.3.0 json2html~=1.3.0
SQLAlchemy~=2.0.15 SQLAlchemy~=2.0.15
Pillow==9.5.0 Pillow==9.5.0
zeroconf==0.64.1 zeroconf==0.64.1
requests-toolbelt~=1.0 Pypubsub~=4.0.3
arrow~=1.2.3

View File

@@ -20,16 +20,16 @@ import yaml
from flask import Flask, request, render_template, send_file, after_this_request, Response, redirect, url_for, abort from flask import Flask, request, render_template, send_file, after_this_request, Response, redirect, url_for, abort
from werkzeug.utils import secure_filename from werkzeug.utils import secure_filename
from lib.distributed_job_manager import DistributedJobManager from src.distributed_job_manager import DistributedJobManager
from lib.render_queue import RenderQueue, JobNotFoundError from src.render_queue import RenderQueue, JobNotFoundError
from lib.server.server_proxy import RenderServerProxy from src.server_proxy import RenderServerProxy
from lib.server.zeroconf_server import ZeroconfServer from src.utilities.server_helper import generate_thumbnail_for_job
from lib.utilities.server_helper import generate_thumbnail_for_job from src.utilities.zeroconf_server import ZeroconfServer
from lib.workers.base_worker import string_to_status, RenderStatus from src.worker_factory import RenderWorkerFactory
from lib.workers.worker_factory import RenderWorkerFactory from src.workers.base_worker import string_to_status, RenderStatus
logger = logging.getLogger() logger = logging.getLogger()
server = Flask(__name__, template_folder='templates', static_folder='static') server = Flask(__name__, template_folder='web/templates', static_folder='web/static')
ssl._create_default_https_context = ssl._create_unverified_context # disable SSL for downloads ssl._create_default_https_context = ssl._create_unverified_context # disable SSL for downloads
categories = [RenderStatus.RUNNING, RenderStatus.ERROR, RenderStatus.NOT_STARTED, RenderStatus.SCHEDULED, categories = [RenderStatus.RUNNING, RenderStatus.ERROR, RenderStatus.NOT_STARTED, RenderStatus.SCHEDULED,
@@ -53,13 +53,12 @@ def sorted_jobs(all_jobs, sort_by_date=True):
@server.route('/') @server.route('/')
@server.route('/index') @server.route('/index')
def index(): def index():
with open('config/presets.yaml') as f: with open('config/presets.yaml') as f:
presets = yaml.load(f, Loader=yaml.FullLoader) render_presets = yaml.load(f, Loader=yaml.FullLoader)
return render_template('index.html', all_jobs=sorted_jobs(RenderQueue.all_jobs()), return render_template('index.html', all_jobs=sorted_jobs(RenderQueue.all_jobs()),
hostname=server.config['HOSTNAME'], renderer_info=renderer_info(), hostname=server.config['HOSTNAME'], renderer_info=renderer_info(),
render_clients=[server.config['HOSTNAME']], preset_list=presets) render_clients=[server.config['HOSTNAME']], preset_list=render_presets)
@server.get('/api/jobs') @server.get('/api/jobs')
@@ -131,15 +130,15 @@ def job_thumbnail(job_id):
# Misc status icons # Misc status icons
if found_job.status == RenderStatus.RUNNING: if found_job.status == RenderStatus.RUNNING:
return send_file('static/images/gears.png', mimetype="image/png") return send_file('web/static/images/gears.png', mimetype="image/png")
elif found_job.status == RenderStatus.CANCELLED: elif found_job.status == RenderStatus.CANCELLED:
return send_file('static/images/cancelled.png', mimetype="image/png") return send_file('web/static/images/cancelled.png', mimetype="image/png")
elif found_job.status == RenderStatus.SCHEDULED: elif found_job.status == RenderStatus.SCHEDULED:
return send_file('static/images/scheduled.png', mimetype="image/png") return send_file('web/static/images/scheduled.png', mimetype="image/png")
elif found_job.status == RenderStatus.NOT_STARTED: elif found_job.status == RenderStatus.NOT_STARTED:
return send_file('static/images/not_started.png', mimetype="image/png") return send_file('web/static/images/not_started.png', mimetype="image/png")
# errors # errors
return send_file('static/images/error.png', mimetype="image/png") return send_file('web/static/images/error.png', mimetype="image/png")
# Get job file routing # Get job file routing
@@ -396,9 +395,9 @@ def add_job_handler():
# create & configure jobs # create & configure jobs
worker = RenderWorkerFactory.create_worker(renderer=job_data['renderer'], worker = RenderWorkerFactory.create_worker(renderer=job_data['renderer'],
input_path=loaded_project_local_path, input_path=loaded_project_local_path,
output_path=job_data["output_path"], output_path=job_data["output_path"],
args=job_data.get('args', {})) args=job_data.get('args', {}))
worker.status = job_data.get("initial_status", worker.status) worker.status = job_data.get("initial_status", worker.status)
worker.parent = job_data.get("parent", worker.parent) worker.parent = job_data.get("parent", worker.parent)
worker.name = job_data.get("name", worker.name) worker.name = job_data.get("name", worker.name)
@@ -498,7 +497,6 @@ def clear_history():
@server.route('/api/status') @server.route('/api/status')
def status(): def status():
renderer_data = {} renderer_data = {}
for render_class in RenderWorkerFactory.supported_classes(): for render_class in RenderWorkerFactory.supported_classes():
if render_class.engine.renderer_path(): # only return renderers installed on host if render_class.engine.renderer_path(): # only return renderers installed on host

View File

@@ -1,17 +1,20 @@
import datetime import datetime
import logging import logging
import tkinter as tk import os
import socket
import threading import threading
import time import time
import socket import tkinter as tk
import os
from tkinter import ttk, messagebox, simpledialog from tkinter import ttk, messagebox, simpledialog
from PIL import Image, ImageTk from PIL import Image, ImageTk
from lib.client.new_job_window import NewJobWindow
from lib.server.server_proxy import RenderServerProxy from src.client.new_job_window import NewJobWindow
from lib.server.zeroconf_server import ZeroconfServer # from src.client.server_details import create_server_popup
from lib.workers.base_worker import RenderStatus from src.server_proxy import RenderServerProxy
from lib.utilities.misc_helper import launch_url, file_exists_in_mounts, get_time_elapsed from src.utilities.misc_helper import launch_url, file_exists_in_mounts, get_time_elapsed
from src.utilities.zeroconf_server import ZeroconfServer
from src.workers.base_worker import RenderStatus
logger = logging.getLogger() logger = logging.getLogger()
@@ -31,7 +34,7 @@ def make_sortable(tree):
class DashboardWindow: class DashboardWindow:
lib_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) lib_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
image_path = os.path.join(lib_path, 'server', 'static', 'images') image_path = os.path.join(lib_path, 'web', 'static', 'images')
default_image = Image.open(os.path.join(image_path, 'desktop.png')) default_image = Image.open(os.path.join(image_path, 'desktop.png'))
def __init__(self): def __init__(self):

View File

@@ -4,16 +4,16 @@ import logging
import os.path import os.path
import pathlib import pathlib
import socket import socket
import threading
from tkinter import * from tkinter import *
from tkinter import filedialog, messagebox from tkinter import filedialog, messagebox
from tkinter.ttk import Frame, Label, Entry, Combobox, Progressbar from tkinter.ttk import Frame, Label, Entry, Combobox, Progressbar
import psutil import psutil
import requests
import threading from src.server_proxy import RenderServerProxy
from lib.workers.blender_worker import Blender from src.workers.blender_worker import Blender
from lib.workers.ffmpeg_worker import FFMPEG from src.workers.ffmpeg_worker import FFMPEG
from lib.server.server_proxy import RenderServerProxy
logger = logging.getLogger() logger = logging.getLogger()

View File

@@ -5,11 +5,12 @@ import time
import zipfile import zipfile
from pubsub import pub from pubsub import pub
from lib.render_queue import RenderQueue
from lib.server.server_proxy import RenderServerProxy from src.render_queue import RenderQueue
from lib.server.zeroconf_server import ZeroconfServer from src.server_proxy import RenderServerProxy
from lib.utilities.misc_helper import get_file_size_human from src.utilities.misc_helper import get_file_size_human
from lib.workers.base_worker import RenderStatus, string_to_status from src.utilities.status_utils import RenderStatus, string_to_status
from src.utilities.zeroconf_server import ZeroconfServer
logger = logging.getLogger() logger = logging.getLogger()

View File

@@ -4,8 +4,9 @@ from datetime import datetime
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker from sqlalchemy.orm import sessionmaker
from lib.workers.base_worker import RenderStatus, BaseRenderWorker, Base from src.utilities.status_utils import RenderStatus
from lib.workers.worker_factory import RenderWorkerFactory from src.worker_factory import RenderWorkerFactory
from src.workers.base_worker import Base
logger = logging.getLogger() logger = logging.getLogger()
@@ -83,12 +84,20 @@ class RenderQueue:
@classmethod @classmethod
def load_state(cls): def load_state(cls):
from src.workers.base_worker import BaseRenderWorker
cls.job_queue = cls.session.query(BaseRenderWorker).all() cls.job_queue = cls.session.query(BaseRenderWorker).all()
@classmethod @classmethod
def save_state(cls): def save_state(cls):
cls.session.commit() cls.session.commit()
@classmethod
def prepare_for_shutdown(cls):
running_jobs = cls.jobs_with_status(RenderStatus.RUNNING) # cancel all running jobs
for job in running_jobs:
cls.cancel_job(job)
cls.save_state()
@classmethod @classmethod
def is_available_for_job(cls, renderer, priority=2): def is_available_for_job(cls, renderer, priority=2):
if not RenderWorkerFactory.class_for_name(renderer).engine.renderer_path(): if not RenderWorkerFactory.class_for_name(renderer).engine.renderer_path():
@@ -96,8 +105,9 @@ class RenderQueue:
instances = cls.renderer_instances() instances = cls.renderer_instances()
higher_priority_jobs = [x for x in cls.running_jobs() if x.priority < priority] higher_priority_jobs = [x for x in cls.running_jobs() if x.priority < priority]
max_renderers = renderer in instances.keys() and instances[renderer] >= cls.maximum_renderer_instances.get(renderer, 1) max_allowed_instances = cls.maximum_renderer_instances.get(renderer, 1)
return not max_renderers and not higher_priority_jobs maxed_out_instances = renderer in instances.keys() and instances[renderer] >= max_allowed_instances
return not maxed_out_instances and not higher_priority_jobs
@classmethod @classmethod
def evaluate_queue(cls): def evaluate_queue(cls):

View File

@@ -1,19 +1,21 @@
import json
import logging import logging
import os import os
import json
import requests
import socket import socket
import time
import threading import threading
from lib.workers.base_worker import RenderStatus import time
import requests
from requests_toolbelt.multipart import MultipartEncoder, MultipartEncoderMonitor from requests_toolbelt.multipart import MultipartEncoder, MultipartEncoderMonitor
from src.utilities.status_utils import RenderStatus
status_colors = {RenderStatus.ERROR: "red", RenderStatus.CANCELLED: 'orange1', RenderStatus.COMPLETED: 'green', status_colors = {RenderStatus.ERROR: "red", RenderStatus.CANCELLED: 'orange1', RenderStatus.COMPLETED: 'green',
RenderStatus.NOT_STARTED: "yellow", RenderStatus.SCHEDULED: 'purple', RenderStatus.NOT_STARTED: "yellow", RenderStatus.SCHEDULED: 'purple',
RenderStatus.RUNNING: 'cyan', RenderStatus.WAITING_FOR_SUBJOBS: 'blue'} RenderStatus.RUNNING: 'cyan', RenderStatus.WAITING_FOR_SUBJOBS: 'blue'}
categories = [RenderStatus.RUNNING, RenderStatus.WAITING_FOR_SUBJOBS, RenderStatus.ERROR, RenderStatus.NOT_STARTED, RenderStatus.SCHEDULED, categories = [RenderStatus.RUNNING, RenderStatus.WAITING_FOR_SUBJOBS, RenderStatus.ERROR, RenderStatus.NOT_STARTED,
RenderStatus.COMPLETED, RenderStatus.CANCELLED, RenderStatus.UNDEFINED] RenderStatus.SCHEDULED, RenderStatus.COMPLETED, RenderStatus.CANCELLED, RenderStatus.UNDEFINED]
logger = logging.getLogger() logger = logging.getLogger()
OFFLINE_MAX = 2 OFFLINE_MAX = 2

View File

@@ -1,5 +1,5 @@
import subprocess import subprocess
from lib.engines.ffmpeg_engine import FFMPEG from src.workers.engines.ffmpeg_engine import FFMPEG
def image_sequence_to_video(source_glob_pattern, output_path, framerate=24, encoder="prores_ks", profile=4, def image_sequence_to_video(source_glob_pattern, output_path, framerate=24, encoder="prores_ks", profile=4,

View File

@@ -1,13 +1,9 @@
import logging import logging
import os import os
import socket
import subprocess import subprocess
import threading import threading
import psutil from src.utilities.ffmpeg_helper import generate_thumbnail, save_first_frame
from lib.server.server_proxy import RenderServerProxy
from lib.utilities.ffmpeg_helper import generate_thumbnail, save_first_frame
logger = logging.getLogger() logger = logging.getLogger()
@@ -21,8 +17,8 @@ def generate_thumbnail_for_job(job, thumb_video_path, thumb_image_path, max_widt
try: try:
logger.debug(f"Generating video thumbnail for {source}") logger.debug(f"Generating video thumbnail for {source}")
generate_thumbnail(source_path=source, dest_path=thumb_video_path, max_width=max_width) generate_thumbnail(source_path=source, dest_path=thumb_video_path, max_width=max_width)
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as err:
logger.error(f"Error generating video thumbnail for {source}: {e}") logger.error(f"Error generating video thumbnail for {source}: {err}")
try: try:
os.remove(in_progress_path) os.remove(in_progress_path)

View File

@@ -0,0 +1,20 @@
from enum import Enum
class RenderStatus(Enum):
NOT_STARTED = "not_started"
RUNNING = "running"
COMPLETED = "completed"
CANCELLED = "cancelled"
ERROR = "error"
SCHEDULED = "scheduled"
WAITING_FOR_SUBJOBS = "waiting_for_subjobs"
CONFIGURING = "configuring"
UNDEFINED = "undefined"
def string_to_status(string):
for stat in RenderStatus:
if stat.value == string:
return stat
return RenderStatus.UNDEFINED

View File

@@ -59,6 +59,7 @@ class ZeroconfServer:
@classmethod @classmethod
def _browse_services(cls): def _browse_services(cls):
browser = ServiceBrowser(cls.zeroconf, cls.service_type, [cls._on_service_discovered]) browser = ServiceBrowser(cls.zeroconf, cls.service_type, [cls._on_service_discovered])
browser.is_alive()
@classmethod @classmethod
def _on_service_discovered(cls, zeroconf, service_type, name, state_change): def _on_service_discovered(cls, zeroconf, service_type, name, state_change):

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 995 B

After

Width:  |  Height:  |  Size: 995 B

View File

Before

Width:  |  Height:  |  Size: 81 KiB

After

Width:  |  Height:  |  Size: 81 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

View File

@@ -3,9 +3,9 @@ class RenderWorkerFactory:
@staticmethod @staticmethod
def supported_classes(): def supported_classes():
# to add support for any additional RenderWorker classes, import their classes and add to list here # to add support for any additional RenderWorker classes, import their classes and add to list here
from .blender_worker import BlenderRenderWorker from src.workers.blender_worker import BlenderRenderWorker
from .aerender_worker import AERenderWorker from src.workers.aerender_worker import AERenderWorker
from .ffmpeg_worker import FFMPEGRenderWorker from src.workers.ffmpeg_worker import FFMPEGRenderWorker
classes = [BlenderRenderWorker, AERenderWorker, FFMPEGRenderWorker] classes = [BlenderRenderWorker, AERenderWorker, FFMPEGRenderWorker]
return classes return classes

View File

@@ -1,11 +1,14 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import glob import glob
import json import json
import logging
import os
import re import re
import time import time
from .base_worker import * from src.workers.base_worker import BaseRenderWorker, timecode_to_frames
from ..engines.aerender_engine import AERender from src.workers.engines.aerender_engine import AERender
def aerender_path(): def aerender_path():
paths = glob.glob('/Applications/*After Effects*/aerender') paths = glob.glob('/Applications/*After Effects*/aerender')

View File

@@ -6,38 +6,19 @@ import os
import subprocess import subprocess
import threading import threading
from datetime import datetime from datetime import datetime
from enum import Enum
import psutil import psutil
from pubsub import pub from pubsub import pub
from sqlalchemy import Column, Integer, String, DateTime, JSON from sqlalchemy import Column, Integer, String, DateTime, JSON
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from lib.utilities.misc_helper import get_time_elapsed from src.utilities.misc_helper import get_time_elapsed
from src.utilities.status_utils import RenderStatus, string_to_status
logger = logging.getLogger() logger = logging.getLogger()
Base = declarative_base() Base = declarative_base()
class RenderStatus(Enum):
NOT_STARTED = "not_started"
RUNNING = "running"
COMPLETED = "completed"
CANCELLED = "cancelled"
ERROR = "error"
SCHEDULED = "scheduled"
WAITING_FOR_SUBJOBS = "waiting_for_subjobs"
CONFIGURING = "configuring"
UNDEFINED = "undefined"
def string_to_status(string):
for stat in RenderStatus:
if stat.value == string:
return stat
return RenderStatus.UNDEFINED
class BaseRenderWorker(Base): class BaseRenderWorker(Base):
__tablename__ = 'render_workers' __tablename__ = 'render_workers'
@@ -121,7 +102,7 @@ class BaseRenderWorker(Base):
@status.setter @status.setter
def status(self, new_status): def status(self, new_status):
if self._status != new_status.value: if self._status != new_status.value:
old_status = self._status old_status = self.status
self._status = new_status.value self._status = new_status.value
pub.sendMessage('status_change', job_id=self.id, old_status=old_status, new_status=new_status) pub.sendMessage('status_change', job_id=self.id, old_status=old_status, new_status=new_status)
@@ -186,7 +167,8 @@ class BaseRenderWorker(Base):
self.status = RenderStatus.RUNNING self.status = RenderStatus.RUNNING
self.start_time = datetime.now() self.start_time = datetime.now()
logger.info(f'Starting {self.engine.name()} {self.engine.version()} Render for {self.input_path} | Frame Count: {self.total_frames}') logger.info(f'Starting {self.engine.name()} {self.engine.version()} Render for {self.input_path} | '
f'Frame Count: {self.total_frames}')
self.__thread.start() self.__thread.start()
def run(self): def run(self):
@@ -207,7 +189,7 @@ class BaseRenderWorker(Base):
f.write(f"Running command: {' '.join(subprocess_cmds)}\n") f.write(f"Running command: {' '.join(subprocess_cmds)}\n")
for c in io.TextIOWrapper(self.__process.stdout, encoding="utf-8"): # or another encoding for c in io.TextIOWrapper(self.__process.stdout, encoding="utf-8"): # or another encoding
f.write(c) f.write(c)
logger.debug(f"{self.engine.name()}Worker: {c.strip()}") # logger.debug(f"{self.engine.name()}Worker: {c.strip()}")
self.last_output = c.strip() self.last_output = c.strip()
self._parse_stdout(c.strip()) self._parse_stdout(c.strip())
f.write('\n') f.write('\n')
@@ -220,7 +202,7 @@ class BaseRenderWorker(Base):
return return
if return_code: if return_code:
message = f"{self.engine.name()} render failed with return_code {return_code} after {self.time_elapsed()}" message = f"{self.engine.name()} render failed with code {return_code} after {self.time_elapsed()}"
logger.error(message) logger.error(message)
f.write(message) f.write(message)
self.status = RenderStatus.ERROR self.status = RenderStatus.ERROR
@@ -233,7 +215,7 @@ class BaseRenderWorker(Base):
f.write(message) f.write(message)
if self.children: if self.children:
from lib.distributed_job_manager import DistributedJobManager from src.distributed_job_manager import DistributedJobManager
DistributedJobManager.wait_for_subjobs(local_job=self) DistributedJobManager.wait_for_subjobs(local_job=self)
# Post Render Work # Post Render Work

View File

@@ -2,9 +2,9 @@
import re import re
from collections import Counter from collections import Counter
from lib.engines.blender_engine import Blender from src.workers.engines.blender_engine import Blender
from lib.utilities.ffmpeg_helper import image_sequence_to_video from src.utilities.ffmpeg_helper import image_sequence_to_video
from lib.workers.base_worker import * from src.workers.base_worker import *
class BlenderRenderWorker(BaseRenderWorker): class BlenderRenderWorker(BaseRenderWorker):
@@ -69,17 +69,6 @@ class BlenderRenderWorker(BaseRenderWorker):
samples = re.sub(r'[^\d/]', '', sample_string) samples = re.sub(r'[^\d/]', '', sample_string)
self.__frame_percent_complete = int(samples.split('/')[0]) / int(samples.split('/')[-1]) self.__frame_percent_complete = int(samples.split('/')[0]) / int(samples.split('/')[-1])
# Calculate rough percent based on cycles
# EEVEE
# 10-Apr-22 22:42:06 - RENDERER: Fra:0 Mem:857.99M (Peak 928.55M) | Time:00:03.96 | Rendering 1 / 65 samples
# 10-Apr-22 22:42:10 - RENDERER: Fra:0 Mem:827.09M (Peak 928.55M) | Time:00:07.92 | Rendering 26 / 64 samples
# 10-Apr-22 22:42:10 - RENDERER: Fra:0 Mem:827.09M (Peak 928.55M) | Time:00:08.17 | Rendering 51 / 64 samples
# 10-Apr-22 22:42:10 - RENDERER: Fra:0 Mem:827.09M (Peak 928.55M) | Time:00:08.31 | Rendering 64 / 64 samples
# CYCLES
# 10-Apr-22 22:43:22 - RENDERER: Fra:0 Mem:836.30M (Peak 1726.13M) | Time:00:01.56 | Remaining:00:30.65 | Mem:588.68M, Peak:588.68M | Scene, View Layer | Sample 1/150
# 10-Apr-22 22:43:43 - RENDERER: Fra:0 Mem:836.30M (Peak 1726.13M) | Time:00:22.01 | Remaining:00:03.36 | Mem:588.68M, Peak:588.68M | Scene, View Layer | Sample 129/150
if int(stats['frame']) > self.current_frame: if int(stats['frame']) > self.current_frame:
self.current_frame = int(stats['frame']) self.current_frame = int(stats['frame'])
logger.debug( logger.debug(

View File

@@ -1,7 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import re import re
from .base_worker import * import subprocess
from ..engines.ffmpeg_engine import FFMPEG
from src.workers.base_worker import BaseRenderWorker
from src.workers.engines.ffmpeg_engine import FFMPEG
class FFMPEGRenderWorker(BaseRenderWorker): class FFMPEGRenderWorker(BaseRenderWorker):
@@ -48,18 +50,3 @@ class FFMPEGRenderWorker(BaseRenderWorker):
time_elapsed = stats['time_elapsed'] time_elapsed = stats['time_elapsed']
elif "not found" in line: elif "not found" in line:
self.log_error(line) self.log_error(line)
if __name__ == '__main__':
print(FFMPEG.full_report())
# logging.basicConfig(format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S', level=logging.DEBUG)
#
# test_movie = '/Users/brettwilliams/Desktop/dark_knight_rises.mp4'
#
# r = FFMPEGRenderWorker(test_movie, '/Users/brettwilliams/Desktop/test-ffmpeg.mp4', args=['-c:v', 'libx265', '-vtag', 'hvc1'])
# # r = FFMPEGRenderer(test_movie, '/Users/brettwilliams/Desktop/dark_knight_rises-output.mp4')
# r.start()
# while r.is_running():
# time.sleep(1)

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from lib.client.dashboard_window import start_client from src.client.dashboard_window import start_client
if __name__ == '__main__': if __name__ == '__main__':
start_client() start_client()

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from lib.server.api_server import start_server from src.api_server import start_server
if __name__ == '__main__': if __name__ == '__main__':
start_server() start_server()