added quality options and fixed bugs
This commit is contained in:
15
bin/arg_assembly.py
Normal file
15
bin/arg_assembly.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class ArgAssembly:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get(self, quality):
|
||||||
|
if quality == "2x":
|
||||||
|
return "Performance"
|
||||||
|
elif quality == "1.7x":
|
||||||
|
return "Balanced"
|
||||||
|
elif quality == "1.5x":
|
||||||
|
return "Quality"
|
||||||
|
elif quality == "1.3x":
|
||||||
|
return "UltraQuality"
|
||||||
|
else:
|
||||||
|
raise Exception
|
||||||
41
bin/checks.py
Normal file
41
bin/checks.py
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
class Checks:
|
||||||
|
def __init__(self):
|
||||||
|
self.custom_quality = 0.0
|
||||||
|
self.i_file_extension = ""
|
||||||
|
|
||||||
|
def perform(self, quality_selection, custom_quality, input_filepath, output_filepath):
|
||||||
|
# Call this function to perform entry checks.
|
||||||
|
# Returns True if all checks passed, False if one or more not passed.
|
||||||
|
if self.quality_checks(quality_selection, custom_quality) and self.file_checks(input_filepath, output_filepath):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def quality_checks(self, quality_sel, custom_q):
|
||||||
|
if quality_sel != "Custom (will respect value below)":
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
self.custom_quality = float(custom_q)
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def file_checks(self, i_fp, o_fp):
|
||||||
|
self.i_file_extension = str(i_fp)[len(i_fp) - 4:]
|
||||||
|
if self.i_file_extension == ".png" or self.i_file_extension == ".jpg":
|
||||||
|
pass
|
||||||
|
elif self.i_file_extension == "jpeg":
|
||||||
|
if str(i_fp)[len(i_fp) - 5:] == ".jpeg":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
elif self.i_file_extension == ".mp4" or self.i_file_extension == ".mkv":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if str(i_fp)[len(i_fp) - 4:] == str(o_fp)[len(o_fp) - 4:]:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
@@ -47,7 +47,7 @@ class Handler:
|
|||||||
if str(filepath)[len(filepath) - 4:] == ".mp4" or str(filepath)[len(filepath) - 4:] == ".mkv":
|
if str(filepath)[len(filepath) - 4:] == ".mp4" or str(filepath)[len(filepath) - 4:] == ".mkv":
|
||||||
print("upscaling video")
|
print("upscaling video")
|
||||||
self.video_scaling(ffmpegpath, fsrpath, filepath, quality_mode, quality_setting, output_path)
|
self.video_scaling(ffmpegpath, fsrpath, filepath, quality_mode, quality_setting, output_path)
|
||||||
elif str(filepath)[len(filepath) - 4:] == ".JPG" or str(filepath)[len(filepath) - 4:] == ".png" or str(filepath)[len(filepath) - 4:] == ".jpg":
|
elif str(filepath)[len(filepath) - 4:] == ".JPG" or str(filepath)[len(filepath) - 4:] == ".png" or str(filepath)[len(filepath) - 4:] == ".jpg" or str(filepath)[len(filepath) - 5:] == ".jpeg":
|
||||||
print("upscaling image")
|
print("upscaling image")
|
||||||
self.photo_scaling(fsrpath, filepath, quality_mode, quality_setting, output_path)
|
self.photo_scaling(fsrpath, filepath, quality_mode, quality_setting, output_path)
|
||||||
else:
|
else:
|
||||||
@@ -192,8 +192,11 @@ class Handler:
|
|||||||
|
|
||||||
# get Video's audio
|
# get Video's audio
|
||||||
print("Retrieving Video's audio to append")
|
print("Retrieving Video's audio to append")
|
||||||
os.remove(f"{self.tmppath}audio.aac")
|
try:
|
||||||
os.remove(f"{output_path}")
|
os.remove(f"{self.tmppath}audio.aac")
|
||||||
|
os.remove(f"{output_path}")
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
if self.os_type == "linux":
|
if self.os_type == "linux":
|
||||||
self.command = f"ffmpeg -i {self.filepath} -vn -acodec copy {self.tmppath}audio.aac"
|
self.command = f"ffmpeg -i {self.filepath} -vn -acodec copy {self.tmppath}audio.aac"
|
||||||
elif self.os_type == "win32":
|
elif self.os_type == "win32":
|
||||||
|
|||||||
@@ -10,14 +10,65 @@
|
|||||||
import gi
|
import gi
|
||||||
import bin.handler
|
import bin.handler
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
import bin.checks
|
||||||
|
import bin.arg_assembly
|
||||||
|
|
||||||
gi.require_version("Gtk", "3.0")
|
gi.require_version("Gtk", "3.0")
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
|
|
||||||
|
|
||||||
|
arg = bin.arg_assembly.ArgAssembly()
|
||||||
|
checks = bin.checks.Checks()
|
||||||
handler = bin.handler.Handler()
|
handler = bin.handler.Handler()
|
||||||
|
|
||||||
|
|
||||||
|
class ProgressIndicator(Gtk.Dialog):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__(title="Upscaling", transient_for=parent, flags=0)
|
||||||
|
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
||||||
|
self.set_default_size(150, 100)
|
||||||
|
self.spinner = Gtk.Spinner()
|
||||||
|
self.label = Gtk.Label(label=" Upscaling. This process will take long (if a Video). \n Duration depends on your Hardware and length and resolution of video \n You may see the output of the app, if you switch to the other window that is behind it. ")
|
||||||
|
self.box = self.get_content_area()
|
||||||
|
self.box.pack_start(self.label, True, True, 20)
|
||||||
|
self.box.pack_start(self.spinner, True, True, 20)
|
||||||
|
self.spinner.start()
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorDialogFileMissing(Gtk.Dialog):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__(title="Error", transient_for=parent, flags=0)
|
||||||
|
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
||||||
|
self.set_default_size(150, 100)
|
||||||
|
self.label = Gtk.Label(label=" No file specified. Please select a input AND output file! ")
|
||||||
|
self.box = self.get_content_area()
|
||||||
|
self.box.pack_start(self.label, True, True, 20)
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorDialogRunning(Gtk.Dialog):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__(title="Error", transient_for=parent, flags=0)
|
||||||
|
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
||||||
|
self.set_default_size(150, 100)
|
||||||
|
self.label = Gtk.Label(label=" You are already upscaling. Please wait for the current job to finish! ")
|
||||||
|
self.box = self.get_content_area()
|
||||||
|
self.box.pack_start(self.label, True, True, 20)
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorDialogCheckFail(Gtk.Dialog):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__(title="Error", transient_for=parent, flags=0)
|
||||||
|
self.add_buttons(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
||||||
|
self.set_default_size(150, 100)
|
||||||
|
self.label = Gtk.Label(label=" Filechecks failed. Make sure to specify the same file extension in the output like in the input ")
|
||||||
|
self.box = self.get_content_area()
|
||||||
|
self.box.pack_start(self.label, True, True, 20)
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
|
||||||
class HomeWindow(Gtk.Window):
|
class HomeWindow(Gtk.Window):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__(title="Test")
|
super().__init__(title="Test")
|
||||||
@@ -28,6 +79,9 @@ class HomeWindow(Gtk.Window):
|
|||||||
self.main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
self.main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
self.sub_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
self.sub_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||||
self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||||
|
self.top_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
self.quality_select_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||||
|
self.custom_quality_selector_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||||
|
|
||||||
# Headerbar
|
# Headerbar
|
||||||
self.hb = Gtk.HeaderBar()
|
self.hb = Gtk.HeaderBar()
|
||||||
@@ -50,15 +104,54 @@ class HomeWindow(Gtk.Window):
|
|||||||
self.start_button.connect("clicked", self.start_clicked)
|
self.start_button.connect("clicked", self.start_clicked)
|
||||||
self.box.pack_start(self.start_button, True, True, 0)
|
self.box.pack_start(self.start_button, True, True, 0)
|
||||||
|
|
||||||
# Title
|
# QualitySelect
|
||||||
self.title = Gtk.Label(label="Test")
|
self.title = Gtk.Label(label="Upscaling Multiplier Presets")
|
||||||
self.title.set_text("FSR Image & Video Upscaler")
|
self.qualities = Gtk.ListStore(str)
|
||||||
|
self.qualities.append(["2x"])
|
||||||
|
self.qualities.append(["1.7x"])
|
||||||
|
self.qualities.append(["1.5x"])
|
||||||
|
self.qualities.append(["1.3x"])
|
||||||
|
self.qualities.append(["Custom (will respect value below)"])
|
||||||
|
self.quality_select = Gtk.ComboBox.new_with_model(self.qualities)
|
||||||
|
self.text_renderer = Gtk.CellRendererText()
|
||||||
|
self.quality_select.pack_start(self.text_renderer, True)
|
||||||
|
self.quality_select.add_attribute(self.text_renderer, "text", 0)
|
||||||
|
self.quality_select.connect("changed", self.on_quality_change)
|
||||||
|
self.quality_select_shrink = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
self.quality_select_shrink.pack_start(self.quality_select, True, False, 30)
|
||||||
|
|
||||||
|
self.quality_select_box.pack_start(self.title, True, True, 0)
|
||||||
|
self.quality_select_box.pack_start(self.quality_select_shrink, True, True, 20)
|
||||||
|
|
||||||
|
# Custom Quality Selector
|
||||||
|
self.custom_quality_selector_title = Gtk.Label(label="Custom Upscaling Multiplier")
|
||||||
|
self.custom_quality_selector_shrink = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
self.custom_quality_selector = Gtk.Entry()
|
||||||
|
self.custom_quality_selector_shrink.pack_start(self.custom_quality_selector, True, False, 30)
|
||||||
|
|
||||||
|
self.custom_quality_selector_box.pack_start(self.custom_quality_selector_title, True, True, 0)
|
||||||
|
self.custom_quality_selector_box.pack_start(self.custom_quality_selector_shrink, True, True, 20)
|
||||||
|
|
||||||
|
# Info
|
||||||
|
self.infos = Gtk.Label(label="Settings")
|
||||||
|
|
||||||
|
# Packing boxes
|
||||||
|
self.top_box.pack_start(self.infos, True, True, 0)
|
||||||
|
self.top_box.pack_start(self.quality_select_box, True, True, 0)
|
||||||
|
self.top_box.pack_start(self.custom_quality_selector_box, True, True, 0)
|
||||||
|
|
||||||
self.sub_box.pack_start(self.box, True, True, 30)
|
self.sub_box.pack_start(self.box, True, True, 30)
|
||||||
self.main_box.pack_start(self.title, True, True, 0)
|
self.main_box.pack_start(self.top_box, True, True, 20)
|
||||||
self.main_box.pack_end(self.sub_box, True, True, 20)
|
self.main_box.pack_end(self.sub_box, True, True, 20)
|
||||||
self.add(self.main_box)
|
self.add(self.main_box)
|
||||||
|
|
||||||
|
def on_quality_change(self, quality):
|
||||||
|
# get data from quality changer
|
||||||
|
self.tree_iter = quality.get_active_iter()
|
||||||
|
if self.tree_iter is not None:
|
||||||
|
self.model = quality.get_model()
|
||||||
|
self.output = self.model[self.tree_iter][0]
|
||||||
|
|
||||||
def filechooser_clicked(self, widget):
|
def filechooser_clicked(self, widget):
|
||||||
self.filechooserdialog = Gtk.FileChooserDialog(title="Choose input file", action=Gtk.FileChooserAction.OPEN)
|
self.filechooserdialog = Gtk.FileChooserDialog(title="Choose input file", action=Gtk.FileChooserAction.OPEN)
|
||||||
self.filechooserdialog.add_buttons(
|
self.filechooserdialog.add_buttons(
|
||||||
@@ -94,22 +187,64 @@ class HomeWindow(Gtk.Window):
|
|||||||
self.filechooserdialog_save.destroy()
|
self.filechooserdialog_save.destroy()
|
||||||
|
|
||||||
def start_clicked(self, widget):
|
def start_clicked(self, widget):
|
||||||
if str(self.open_file) != "" and str(self.save_file) != "":
|
self.respawn = True
|
||||||
print("ok")
|
try:
|
||||||
self.go = True
|
if self.scaler.is_alive():
|
||||||
if self.go:
|
self.respawn = False
|
||||||
self.scaler = multiprocessing.Process(name="scaler",
|
else:
|
||||||
target=handler.handler,
|
self.respawn = True
|
||||||
args=("./bin/lib/FidelityFX_CLI.exe",
|
|
||||||
self.open_file,
|
except AttributeError:
|
||||||
"default",
|
self.respawn = True
|
||||||
"Quality",
|
|
||||||
self.save_file,
|
if self.respawn:
|
||||||
"./bin/lib/ffmpeg.exe")
|
if str(self.open_file) != "" and str(self.save_file) != "":
|
||||||
)
|
print("ok")
|
||||||
self.scaler.start()
|
if checks.perform(self.output, self.custom_quality_selector.get_text(), self.open_file, self.save_file):
|
||||||
|
if self.output == "Custom (will respect value below)":
|
||||||
|
self.quality_selected = "custom"
|
||||||
|
self.q = f"{self.custom_quality_selector.get_text()} {self.custom_quality_selector.get_text()}"
|
||||||
|
else:
|
||||||
|
self.quality_selected = "default"
|
||||||
|
self.q = str(arg.get(self.output))
|
||||||
|
self.go = True
|
||||||
|
if self.go:
|
||||||
|
self.pr_i = ProgressIndicator(self)
|
||||||
|
self.pr_i.run()
|
||||||
|
self.pr_i.destroy()
|
||||||
|
self.scaler = multiprocessing.Process(name="scaler",
|
||||||
|
target=handler.handler,
|
||||||
|
args=("./bin/lib/FidelityFX_CLI.exe",
|
||||||
|
self.open_file,
|
||||||
|
self.quality_selected,
|
||||||
|
self.q,
|
||||||
|
self.save_file,
|
||||||
|
"./bin/lib/ffmpeg.exe")
|
||||||
|
)
|
||||||
|
self.scaler.start()
|
||||||
|
else:
|
||||||
|
print("File-checks unsuccessful. Please check your entries!")
|
||||||
|
self.checkerror()
|
||||||
|
else:
|
||||||
|
print("no file specified")
|
||||||
|
self.fileerror()
|
||||||
else:
|
else:
|
||||||
print("no file specified")
|
print("Already running!")
|
||||||
|
|
||||||
|
def runningerror(self):
|
||||||
|
self.runningerrordialog = ErrorDialogRunning(self)
|
||||||
|
self.runningerrordialog.run()
|
||||||
|
self.runningerrordialog.destroy()
|
||||||
|
|
||||||
|
def fileerror(self):
|
||||||
|
self.fileerrordialog = ErrorDialogFileMissing(self)
|
||||||
|
self.fileerrordialog.run()
|
||||||
|
self.fileerrordialog.destroy()
|
||||||
|
|
||||||
|
def checkerror(self):
|
||||||
|
self.checkerrordialog = ErrorDialogCheckFail(self)
|
||||||
|
self.checkerrordialog.run()
|
||||||
|
self.checkerrordialog.destroy()
|
||||||
|
|
||||||
|
|
||||||
win = HomeWindow()
|
win = HomeWindow()
|
||||||
|
|||||||
Reference in New Issue
Block a user