move to electron app & remove unnecessary code
This commit is contained in:
10
.desktop
10
.desktop
@@ -1,7 +1,7 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=FSR Image & Video Upscaler
|
||||
Comment=Upscale your videos and images with FSR
|
||||
Path=/opt/fsrimageupscaler
|
||||
Exec=/opt/fsrimageupscaler/fsrimagevideoupscaler
|
||||
Icon=fsrimageupscaler
|
||||
Name=Image & Video Upscaler
|
||||
Comment=Upscale your videos and images with different upscalers
|
||||
Path=/opt/imagevideoupscaler
|
||||
Exec=/opt/imagevideoupscaler/imagevideoupscaler
|
||||
Icon=imagevideoupscaler
|
||||
|
||||
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# FSRImageVideoUpscalerFrontend - .gitignore
|
||||
#
|
||||
# Created by Janis Hutz 05/24/2023, Licensed under the GPL V3 License
|
||||
# https://janishutz.com, development@janishutz.com
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# remove pycache
|
||||
__pycache__
|
||||
|
||||
# remove node_modules from repo
|
||||
node_modules
|
||||
3
.idea/.gitignore
generated
vendored
3
.idea/.gitignore
generated
vendored
@@ -1,3 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
8
.idea/FSRImageVideoUpscalerFrontend.iml
generated
8
.idea/FSRImageVideoUpscalerFrontend.iml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
8
.idea/FSRImageVideoUpscalerFrontendNew.iml
generated
8
.idea/FSRImageVideoUpscalerFrontendNew.iml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
6
.idea/inspectionProfiles/profiles_settings.xml
generated
@@ -1,6 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
4
.idea/misc.xml
generated
4
.idea/misc.xml
generated
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/FSRImageVideoUpscalerFrontendNew.iml" filepath="$PROJECT_DIR$/.idea/FSRImageVideoUpscalerFrontendNew.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,21 +0,0 @@
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5.QtWidgets import QApplication, QMainWindow
|
||||
|
||||
class FSRImageVideoUpscaler:
|
||||
def __init__(self):
|
||||
self.app = QApplication(sys.argv)
|
||||
self.window = QMainWindow()
|
||||
self.label = QtWidgets.QLabel(self.window)
|
||||
|
||||
def runapp(self):
|
||||
self.window.setGeometry(200, 200, 800, 600)
|
||||
self.window.setWindowTitle("FSR Image & Video upscaler")
|
||||
|
||||
self.label.setText("Hello World")
|
||||
self.label.move(300, 300)
|
||||
|
||||
|
||||
self.window.show()
|
||||
sys.exit(self.app.exec_())
|
||||
|
||||
FSRImageVideoUpscaler().runapp()
|
||||
281
dev/dump.txt
281
dev/dump.txt
@@ -1,281 +0,0 @@
|
||||
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 an 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=" File and settings check failed. \n Make sure to specify the same file extension in the output like in the input \n make sure that the entries you made as settings are valid! (4 >= scale >= 1) ")
|
||||
self.box = self.get_content_area()
|
||||
self.box.pack_start(self.label, True, True, 20)
|
||||
self.show_all()
|
||||
|
||||
|
||||
class HomeWindow(Gtk.Window):
|
||||
def __init__(self):
|
||||
super().__init__(title="Test")
|
||||
self.os_type = sys.platform
|
||||
self.save_file = ""
|
||||
self.open_file = ""
|
||||
# Spawn box
|
||||
self.main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
self.sub_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
self.orient_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
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
|
||||
self.hb = Gtk.HeaderBar()
|
||||
self.hb.set_show_close_button(True)
|
||||
self.hb.props.title = "FSR Image & Video Upscaler"
|
||||
self.set_titlebar(self.hb)
|
||||
|
||||
# Create filechooser button
|
||||
self.filechoosebutton = Gtk.Button(label="Choose Input File")
|
||||
self.filechoosebutton.connect("clicked", self.filechooser_clicked)
|
||||
self.box.pack_start(self.filechoosebutton, True, True, 0)
|
||||
|
||||
# Create output filechooser button
|
||||
self.opfchooserbutton = Gtk.Button(label="Choose Output File")
|
||||
self.opfchooserbutton.connect("clicked", self.opfilechooser_clicked)
|
||||
self.box.pack_start(self.opfchooserbutton, True, True, 0)
|
||||
|
||||
# Create start button
|
||||
self.start_button = Gtk.Button(label="Start upscaling")
|
||||
self.start_button.connect("clicked", self.start_clicked)
|
||||
self.box.pack_start(self.start_button, True, True, 0)
|
||||
|
||||
# Create Input File label
|
||||
self.ip_file_label = Gtk.Label(label="Choose input file")
|
||||
|
||||
# Create Output File label
|
||||
self.op_file_label = Gtk.Label(label="Choose output file")
|
||||
|
||||
# Pack File labels
|
||||
self.filebox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
|
||||
self.filebox.pack_start(self.ip_file_label, True, True, 10)
|
||||
self.filebox.pack_start(self.op_file_label, True, True, 10)
|
||||
|
||||
# QualitySelect
|
||||
self.title = Gtk.Label(label="Upscaling Multiplier Presets")
|
||||
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, 10)
|
||||
|
||||
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\nNOTE that factors greater than 2 are not recommended!\nFactors greater than 4 will not run!")
|
||||
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, 10)
|
||||
|
||||
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")
|
||||
|
||||
# Details
|
||||
self.details = Gtk.Label(label="Ready")
|
||||
|
||||
# Separator
|
||||
self.separator = Gtk.Separator().new(Gtk.Orientation.HORIZONTAL)
|
||||
|
||||
# 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.top_box.pack_start(self.details, True, True, 0)
|
||||
self.top_box.pack_start(self.separator, True, False, 0)
|
||||
|
||||
|
||||
self.orient_box.pack_start(self.filebox, True, True, 0)
|
||||
self.orient_box.pack_start(self.box, True, True, 0)
|
||||
self.sub_box.pack_start(self.orient_box, True, True, 30)
|
||||
self.main_box.pack_start(self.top_box, True, True, 0)
|
||||
self.main_box.pack_end(self.sub_box, True, True, 5)
|
||||
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):
|
||||
self.filechooserdialog = Gtk.FileChooserDialog(title="Choose input file", action=Gtk.FileChooserAction.OPEN)
|
||||
self.filechooserdialog.add_buttons(
|
||||
Gtk.STOCK_CANCEL,
|
||||
Gtk.ResponseType.CANCEL,
|
||||
Gtk.STOCK_OPEN,
|
||||
Gtk.ResponseType.OK,
|
||||
)
|
||||
self.response = self.filechooserdialog.run()
|
||||
if self.response == Gtk.ResponseType.OK:
|
||||
self.ip_file_label.set_text(self.filechooserdialog.get_filename())
|
||||
self.open_file = self.filechooserdialog.get_filename()
|
||||
elif self.response == Gtk.ResponseType.CANCEL:
|
||||
pass
|
||||
self.filechooserdialog.destroy()
|
||||
|
||||
def opfilechooser_clicked(self, widget):
|
||||
self.filechooserdialog_save = Gtk.FileChooserDialog(title="Choose output file", action=Gtk.FileChooserAction.SAVE)
|
||||
Gtk.FileChooser.set_do_overwrite_confirmation(self.filechooserdialog_save, True)
|
||||
if self.os_type == "linux":
|
||||
Gtk.FileChooser.set_current_folder(self.filechooserdialog_save, "/home")
|
||||
elif self.os_type == "win32":
|
||||
Gtk.FileChooser.set_current_folder(self.filechooserdialog_save, "%HOMEPATH%")
|
||||
else:
|
||||
pass
|
||||
if str(self.open_file)[len(self.open_file) - 4:] == ".mp4":
|
||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "video.mp4")
|
||||
elif str(self.open_file)[len(self.open_file) - 4:] == ".mkv":
|
||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "video.mkv")
|
||||
elif str(self.open_file)[len(self.open_file) - 4:] == ".png":
|
||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "image.png")
|
||||
elif str(self.open_file)[len(self.open_file) - 4:] == ".jpg":
|
||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "image.jpg")
|
||||
elif str(self.open_file)[len(self.open_file) - 4:] == ".jpeg":
|
||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "image.jpeg")
|
||||
else:
|
||||
Gtk.FileChooser.set_current_name(self.filechooserdialog_save, "")
|
||||
self.filechooserdialog_save.add_buttons(
|
||||
Gtk.STOCK_CANCEL,
|
||||
Gtk.ResponseType.CANCEL,
|
||||
Gtk.STOCK_SAVE,
|
||||
Gtk.ResponseType.OK,
|
||||
)
|
||||
self.response = self.filechooserdialog_save.run()
|
||||
if self.response == Gtk.ResponseType.OK:
|
||||
self.op_file_label.set_text(self.filechooserdialog_save.get_filename())
|
||||
self.save_file = self.filechooserdialog_save.get_filename()
|
||||
elif self.response == Gtk.ResponseType.CANCEL:
|
||||
pass
|
||||
self.filechooserdialog_save.destroy()
|
||||
|
||||
def info_button(self):
|
||||
self.info_dialog = Gtk.Dialog()
|
||||
self.remove_event = Gtk.Button(label="Don't show again")
|
||||
self.info_dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
||||
self.info_dialog.set_default_size(150, 100)
|
||||
self.box = self.info_dialog.get_content_area()
|
||||
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. \n\n\n click \"ok\" to start upscaling")
|
||||
self.box.pack_start(self.label, True, True, 0)
|
||||
self.info_dialog.show_all()
|
||||
self.info_response = self.info_dialog.run()
|
||||
self.info_dialog.destroy()
|
||||
|
||||
def start_clicked(self, widget):
|
||||
self.respawn = True
|
||||
try:
|
||||
if self.scaler.is_alive():
|
||||
self.respawn = False
|
||||
else:
|
||||
self.respawn = True
|
||||
|
||||
except AttributeError:
|
||||
self.respawn = True
|
||||
|
||||
if self.respawn:
|
||||
if str(self.open_file) != "" and str(self.save_file) != "":
|
||||
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"
|
||||
if self.custom_quality_selector.get_text()[len(self.custom_quality_selector.get_text()) - 1] == "x":
|
||||
self.q = f"{self.custom_quality_selector.get_text()} {self.custom_quality_selector.get_text()}"
|
||||
else:
|
||||
self.q = f"{self.custom_quality_selector.get_text()}x {self.custom_quality_selector.get_text()}x"
|
||||
else:
|
||||
self.quality_selected = "default"
|
||||
self.q = str(arg.get(self.output))
|
||||
self.go = True
|
||||
if self.go:
|
||||
self.details.set_text("Starting upscaling process")
|
||||
print("\n\nStarting upscaling process!\n\n")
|
||||
self.info_button()
|
||||
if self.info_response == Gtk.ResponseType.OK:
|
||||
self.details.set_text("Upscaling")
|
||||
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,)
|
||||
)
|
||||
self.scaler.start()
|
||||
elif self.info_response == Gtk.ResponseType.CANCEL:
|
||||
self.details.set_text("Ready")
|
||||
print("aborted")
|
||||
else:
|
||||
raise Exception
|
||||
else:
|
||||
self.details.set_text("File-checks failed! Please check your entries!")
|
||||
print("File-checks unsuccessful. Please check your entries!")
|
||||
self.checkerror()
|
||||
else:
|
||||
self.details.set_text("No file specified!")
|
||||
print("no file specified")
|
||||
self.fileerror()
|
||||
else:
|
||||
self.runningerror()
|
||||
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.set_default_size(800, 600)
|
||||
win.connect("destroy", Gtk.main_quit)
|
||||
win.show_all()
|
||||
Gtk.main()
|
||||
@@ -1,19 +0,0 @@
|
||||
import bin.lib.ffmpeg
|
||||
|
||||
ffmpeg = bin.lib.ffmpeg
|
||||
|
||||
|
||||
class MetaDataParser:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def get_metadata(self, filepath):
|
||||
return ffmpeg.probe(str(filepath))["streams"]
|
||||
|
||||
|
||||
videometa = MetaDataParser().get_metadata("/mnt/storage/SORTED/Videos/OBS_Rec/Behalten/2019-12-19 18-21-36.mp4").pop(0)
|
||||
duration = videometa.get("duration")
|
||||
frames = videometa.get("nb_frames")
|
||||
framerate = float(frames) / float(duration)
|
||||
print(framerate)
|
||||
print(videometa)
|
||||
BIN
dev/logo.xcf
BIN
dev/logo.xcf
Binary file not shown.
@@ -1,4 +0,0 @@
|
||||
import os
|
||||
|
||||
test = f"ffmpeg"
|
||||
os.system(test)
|
||||
4
frontend/.browserslistrc
Normal file
4
frontend/.browserslistrc
Normal file
@@ -0,0 +1,4 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
not ie 11
|
||||
17
frontend/.eslintrc.js
Normal file
17
frontend/.eslintrc.js
Normal file
@@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
'extends': [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended'
|
||||
],
|
||||
parserOptions: {
|
||||
parser: '@babel/eslint-parser'
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||
}
|
||||
}
|
||||
23
frontend/.gitignore
vendored
Normal file
23
frontend/.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
24
frontend/README.md
Normal file
24
frontend/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# imagevideoupscaler
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
5
frontend/babel.config.js
Normal file
5
frontend/babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
||||
19
frontend/jsconfig.json
Normal file
19
frontend/jsconfig.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"module": "esnext",
|
||||
"baseUrl": "./",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
}
|
||||
}
|
||||
19533
frontend/package-lock.json
generated
Normal file
19533
frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
25
frontend/package.json
Normal file
25
frontend/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "imagevideoupscaler",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.8.3",
|
||||
"vue": "^3.2.13",
|
||||
"vue-router": "^4.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
"@babel/eslint-parser": "^7.12.16",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3"
|
||||
}
|
||||
}
|
||||
BIN
frontend/public/favicon.ico
Normal file
BIN
frontend/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
17
frontend/public/index.html
Normal file
17
frontend/public/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
30
frontend/src/App.vue
Normal file
30
frontend/src/App.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<nav>
|
||||
<router-link to="/">Home</router-link> |
|
||||
<router-link to="/about">About</router-link>
|
||||
</nav>
|
||||
<router-view/>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
#app {
|
||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
nav {
|
||||
padding: 30px;
|
||||
}
|
||||
|
||||
nav a {
|
||||
font-weight: bold;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
nav a.router-link-exact-active {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
BIN
frontend/src/assets/logo.png
Normal file
BIN
frontend/src/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
59
frontend/src/components/HelloWorld.vue
Normal file
59
frontend/src/components/HelloWorld.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
5
frontend/src/main.js
Normal file
5
frontend/src/main.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
|
||||
createApp(App).use(router).mount('#app')
|
||||
25
frontend/src/router/index.js
Normal file
25
frontend/src/router/index.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: HomeView
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
name: 'about',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(process.env.BASE_URL),
|
||||
routes
|
||||
})
|
||||
|
||||
export default router
|
||||
5
frontend/src/views/AboutView.vue
Normal file
5
frontend/src/views/AboutView.vue
Normal file
@@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div class="about">
|
||||
<h1>This is an about page</h1>
|
||||
</div>
|
||||
</template>
|
||||
18
frontend/src/views/HomeView.vue
Normal file
18
frontend/src/views/HomeView.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<img alt="Vue logo" src="../assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
import HelloWorld from '@/components/HelloWorld.vue'
|
||||
|
||||
export default {
|
||||
name: 'HomeView',
|
||||
components: {
|
||||
HelloWorld
|
||||
}
|
||||
}
|
||||
</script>
|
||||
4
frontend/vue.config.js
Normal file
4
frontend/vue.config.js
Normal file
@@ -0,0 +1,4 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: true
|
||||
})
|
||||
@@ -5,7 +5,7 @@ block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['fsrimagevideoupscaler.py'],
|
||||
['imagevideoupscaler-cli.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[('config', 'config')],
|
||||
@@ -26,7 +26,7 @@ exe = EXE(
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name='FSR Image & Video Upscaler',
|
||||
name='Image & Video Upscaler',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
@@ -46,5 +46,5 @@ coll = COLLECT(
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name='fsrimagevideoupscaler',
|
||||
name='imagevideoupscaler-cli',
|
||||
)
|
||||
@@ -1,169 +0,0 @@
|
||||
"""
|
||||
* FSRImageVideoUpscalerFrontend - fsrimagevideoupscaler.py
|
||||
*
|
||||
* Created by Janis Hutz 03/14/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
*
|
||||
*
|
||||
"""
|
||||
|
||||
import sys
|
||||
import bin.handler
|
||||
import multiprocessing
|
||||
import bin.checks
|
||||
import bin.arg_assembly
|
||||
|
||||
arg = bin.arg_assembly.ArgAssembly()
|
||||
checks = bin.checks.Checks()
|
||||
handler = bin.handler.Handler()
|
||||
|
||||
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QFileDialog, QComboBox, QHBoxLayout, QVBoxLayout, QWidget
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
|
||||
class HomeWindow(QMainWindow):
|
||||
def __init__( self, parent=None ):
|
||||
super( HomeWindow, self ).__init__( parent )
|
||||
self.os_type = sys.platform
|
||||
self.save_file = ""
|
||||
self.open_file = ""
|
||||
|
||||
box = QVBoxLayout();
|
||||
actionsBox = QHBoxLayout();
|
||||
|
||||
widget = QWidget();
|
||||
actionsWidget = QWidget();
|
||||
|
||||
self.button = QPushButton( 'Input file' );
|
||||
self.button.clicked.connect( self.filechooser_clicked );
|
||||
self.button_out = QPushButton( 'Output file' );
|
||||
self.button_out.clicked.connect( self.opfilechooser_clicked );
|
||||
self.button_run = QPushButton( 'Upscale' );
|
||||
self.button_run.clicked.connect( self.info_button );
|
||||
|
||||
self.qualitySelector = QComboBox();
|
||||
self.qualitySelector.addItems( ['2x', '1.7x', '1.5x', '1.3x', 'Custom (will respect value below)' ] );
|
||||
|
||||
actionsBox.addWidget( self.button );
|
||||
actionsBox.addWidget( self.button_out );
|
||||
actionsBox.addWidget( self.button_run );
|
||||
actionsWidget.setLayout( actionsBox );
|
||||
|
||||
box.addWidget( self.qualitySelector );
|
||||
box.addWidget( actionsWidget );
|
||||
widget.setLayout( box );
|
||||
|
||||
self.setCentralWidget( widget );
|
||||
|
||||
self.setWindowTitle( 'FSRImageVideoUpscalerFrontend' );
|
||||
|
||||
|
||||
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 ):
|
||||
self.open_file = QFileDialog.getOpenFileName( self, 'Open input file', '', 'Image & Video files (*.jpg *.png *.mp4 *.mkv *.jpeg)' );
|
||||
|
||||
|
||||
def opfilechooser_clicked( self ):
|
||||
self.path = '';
|
||||
|
||||
if str( self.open_file )[len(self.open_file) - 4:] == '.mp4':
|
||||
self.path = 'video.mp4';
|
||||
elif str( self.open_file )[len(self.open_file) - 4:] == '.mkv':
|
||||
self.path = 'video.mkv';
|
||||
elif str( self.open_file )[len(self.open_file) - 4:] == '.png':
|
||||
self.path = 'image.png';
|
||||
elif str( self.open_file )[len(self.open_file) - 4:] == '.jpg':
|
||||
self.path = 'image.jpg';
|
||||
elif str( self.open_file )[len(self.open_file) - 4:] == '.jpeg':
|
||||
self.path = 'image.jpeg';
|
||||
|
||||
self.open_file_out = QFileDialog.getOpenFileName( self, 'Select output file', '', 'Image & Video files (*.jpg *.png *.mp4 *.mkv *.jpeg)' );
|
||||
|
||||
def info_button(self):
|
||||
self.fileMissingErrorDialog = QDialog( self );
|
||||
self.fileMissingErrorDialog.setWindowTitle( 'Upscaling! This process might take a LONG time!' );
|
||||
self.fileMissingErrorDialog.exec();
|
||||
self.start_clicked();
|
||||
|
||||
def start_clicked(self):
|
||||
self.respawn = True
|
||||
try:
|
||||
if self.scaler.is_alive():
|
||||
self.respawn = False
|
||||
else:
|
||||
self.respawn = True
|
||||
|
||||
except AttributeError:
|
||||
self.respawn = True
|
||||
|
||||
if self.respawn:
|
||||
if str(self.open_file) != "" and str(self.save_file) != "":
|
||||
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"
|
||||
if self.custom_quality_selector.get_text()[len(self.custom_quality_selector.get_text()) - 1] == "x":
|
||||
self.q = f"{self.custom_quality_selector.get_text()} {self.custom_quality_selector.get_text()}"
|
||||
else:
|
||||
self.q = f"{self.custom_quality_selector.get_text()}x {self.custom_quality_selector.get_text()}x"
|
||||
else:
|
||||
self.quality_selected = "default"
|
||||
self.q = str(arg.get(self.output))
|
||||
self.go = True
|
||||
if self.go:
|
||||
self.details.set_text("Starting upscaling process")
|
||||
print("\n\nStarting upscaling process!\n\n")
|
||||
self.info_button()
|
||||
if self.info_response == Gtk.ResponseType.OK:
|
||||
self.details.set_text("Upscaling")
|
||||
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,)
|
||||
)
|
||||
self.scaler.start()
|
||||
elif self.info_response == Gtk.ResponseType.CANCEL:
|
||||
self.details.set_text("Ready")
|
||||
print("aborted")
|
||||
else:
|
||||
raise Exception
|
||||
else:
|
||||
self.details.set_text("File-checks failed! Please check your entries!")
|
||||
print("File-checks unsuccessful. Please check your entries!")
|
||||
self.checkerror()
|
||||
else:
|
||||
self.details.set_text("No file specified!")
|
||||
print("no file specified")
|
||||
self.fileerror()
|
||||
else:
|
||||
self.runningerror()
|
||||
print("Already running!")
|
||||
|
||||
def runningerror(self):
|
||||
self.runningerrordialog = ErrorDialogRunning(self)
|
||||
self.runningerrordialog.run()
|
||||
self.runningerrordialog.destroy()
|
||||
|
||||
def fileerror(self):
|
||||
self.fileMissingErrorDialog = QDialog( self );
|
||||
self.fileMissingErrorDialog.setWindowTitle( 'Missing file selection! Please ensure you have selected both an input and output file!' );
|
||||
self.fileMissingErrorDialog.exec();
|
||||
|
||||
def checkerror(self):
|
||||
self.checkerrordialog = ErrorDialogCheckFail(self)
|
||||
self.checkerrordialog.run()
|
||||
self.checkerrordialog.destroy()
|
||||
|
||||
|
||||
app = QApplication( sys.argv );
|
||||
ex = HomeWindow();
|
||||
ex.show();
|
||||
sys.exit( app.exec_() );
|
||||
27
package.json
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "imagevideoupscaler",
|
||||
"version": "1.0.0",
|
||||
"description": "A frontend to upscale your videos and images using different upscale engines",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/simplePCBuilding/FSRImageVideoUpscalerFrontend.git"
|
||||
},
|
||||
"keywords": [
|
||||
"upscaler",
|
||||
"electron",
|
||||
"python",
|
||||
"frontend",
|
||||
"videos",
|
||||
"images"
|
||||
],
|
||||
"author": "Janis Hutz",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"bugs": {
|
||||
"url": "https://github.com/simplePCBuilding/FSRImageVideoUpscalerFrontend/issues"
|
||||
},
|
||||
"homepage": "https://github.com/simplePCBuilding/FSRImageVideoUpscalerFrontend#readme"
|
||||
}
|
||||
Reference in New Issue
Block a user