mirror of
https://github.com/k4yt3x/video2x.git
synced 2025-03-03 21:12:13 +00:00
upgraded input QLineEdit to QTableView
This commit is contained in:
parent
d12f2a3888
commit
f2943802cb
@ -4,7 +4,7 @@
|
|||||||
Name: Video2X Upscaler
|
Name: Video2X Upscaler
|
||||||
Author: K4YT3X
|
Author: K4YT3X
|
||||||
Date Created: December 10, 2018
|
Date Created: December 10, 2018
|
||||||
Last Modified: May 7, 2020
|
Last Modified: May 8, 2020
|
||||||
|
|
||||||
Description: This file contains the Upscaler class. Each
|
Description: This file contains the Upscaler class. Each
|
||||||
instance of the Upscaler class is an upscaler on an image or
|
instance of the Upscaler class is an upscaler on an image or
|
||||||
@ -30,9 +30,7 @@ import queue
|
|||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import threading
|
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
@ -71,8 +69,8 @@ class Upscaler:
|
|||||||
|
|
||||||
def __init__(self, input_path, output_path, driver_settings, ffmpeg_settings):
|
def __init__(self, input_path, output_path, driver_settings, ffmpeg_settings):
|
||||||
# mandatory arguments
|
# mandatory arguments
|
||||||
self.input_path = input_path
|
self.input = input_path
|
||||||
self.output_path = output_path
|
self.output = output_path
|
||||||
self.driver_settings = driver_settings
|
self.driver_settings = driver_settings
|
||||||
self.ffmpeg_settings = ffmpeg_settings
|
self.ffmpeg_settings = ffmpeg_settings
|
||||||
|
|
||||||
@ -134,20 +132,30 @@ class Upscaler:
|
|||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
def _check_arguments(self):
|
def _check_arguments(self):
|
||||||
|
if isinstance(self.input, list):
|
||||||
|
if self.output.exists() and not self.output.is_dir():
|
||||||
|
Avalon.error(_('Input and output path type mismatch'))
|
||||||
|
Avalon.error(_('Input is multiple files but output is not directory'))
|
||||||
|
raise ArgumentError('input output path type mismatch')
|
||||||
|
for input_path in self.input:
|
||||||
|
if not input_path.is_file() and not input_path.is_dir():
|
||||||
|
Avalon.error(_('Input path {} is neither a file nor a directory'.format(input_path)))
|
||||||
|
raise FileNotFoundError(f'{input_path} is neither file nor directory')
|
||||||
|
|
||||||
# if input is a file
|
# if input is a file
|
||||||
if self.input_path.is_file():
|
elif self.input.is_file():
|
||||||
if self.output_path.is_dir():
|
if self.output.is_dir():
|
||||||
Avalon.error(_('Input and output path type mismatch'))
|
Avalon.error(_('Input and output path type mismatch'))
|
||||||
Avalon.error(_('Input is single file but output is directory'))
|
Avalon.error(_('Input is single file but output is directory'))
|
||||||
raise ArgumentError('input output path type mismatch')
|
raise ArgumentError('input output path type mismatch')
|
||||||
if not re.search(r'.*\..*$', str(self.output_path)):
|
if not re.search(r'.*\..*$', str(self.output)):
|
||||||
Avalon.error(_('No suffix found in output file path'))
|
Avalon.error(_('No suffix found in output file path'))
|
||||||
Avalon.error(_('Suffix must be specified for FFmpeg'))
|
Avalon.error(_('Suffix must be specified for FFmpeg'))
|
||||||
raise ArgumentError('no output video suffix specified')
|
raise ArgumentError('no output video suffix specified')
|
||||||
|
|
||||||
# if input is a directory
|
# if input is a directory
|
||||||
elif self.input_path.is_dir():
|
elif self.input.is_dir():
|
||||||
if self.output_path.is_file():
|
if self.output.is_file():
|
||||||
Avalon.error(_('Input and output path type mismatch'))
|
Avalon.error(_('Input and output path type mismatch'))
|
||||||
Avalon.error(_('Input is directory but output is existing single file'))
|
Avalon.error(_('Input is directory but output is existing single file'))
|
||||||
raise ArgumentError('input output path type mismatch')
|
raise ArgumentError('input output path type mismatch')
|
||||||
@ -155,7 +163,7 @@ class Upscaler:
|
|||||||
# if input is neither
|
# if input is neither
|
||||||
else:
|
else:
|
||||||
Avalon.error(_('Input path is neither a file nor a directory'))
|
Avalon.error(_('Input path is neither a file nor a directory'))
|
||||||
raise FileNotFoundError(f'{self.input_path} is neither file nor directory')
|
raise FileNotFoundError(f'{self.input} is neither file nor directory')
|
||||||
|
|
||||||
# check Fmpeg settings
|
# check Fmpeg settings
|
||||||
ffmpeg_path = pathlib.Path(self.ffmpeg_settings['ffmpeg_path'])
|
ffmpeg_path = pathlib.Path(self.ffmpeg_settings['ffmpeg_path'])
|
||||||
@ -259,32 +267,32 @@ class Upscaler:
|
|||||||
# if the driver being used is waifu2x-caffe
|
# if the driver being used is waifu2x-caffe
|
||||||
if self.driver == 'waifu2x_caffe':
|
if self.driver == 'waifu2x_caffe':
|
||||||
self.process_pool.append(driver.upscale(process_directory,
|
self.process_pool.append(driver.upscale(process_directory,
|
||||||
self.upscaled_frames,
|
self.upscaled_frames,
|
||||||
self.scale_ratio,
|
self.scale_ratio,
|
||||||
self.scale_width,
|
self.scale_width,
|
||||||
self.scale_height,
|
self.scale_height,
|
||||||
self.image_format,
|
self.image_format,
|
||||||
self.bit_depth))
|
self.bit_depth))
|
||||||
|
|
||||||
# if the driver being used is waifu2x-converter-cpp
|
# if the driver being used is waifu2x-converter-cpp
|
||||||
elif self.driver == 'waifu2x_converter_cpp':
|
elif self.driver == 'waifu2x_converter_cpp':
|
||||||
self.process_pool.append(driver.upscale(process_directory,
|
self.process_pool.append(driver.upscale(process_directory,
|
||||||
self.upscaled_frames,
|
self.upscaled_frames,
|
||||||
self.scale_ratio,
|
self.scale_ratio,
|
||||||
self.processes,
|
self.processes,
|
||||||
self.image_format))
|
self.image_format))
|
||||||
|
|
||||||
# if the driver being used is waifu2x-ncnn-vulkan
|
# if the driver being used is waifu2x-ncnn-vulkan
|
||||||
elif self.driver == 'waifu2x_ncnn_vulkan':
|
elif self.driver == 'waifu2x_ncnn_vulkan':
|
||||||
self.process_pool.append(driver.upscale(process_directory,
|
self.process_pool.append(driver.upscale(process_directory,
|
||||||
self.upscaled_frames,
|
self.upscaled_frames,
|
||||||
self.scale_ratio))
|
self.scale_ratio))
|
||||||
|
|
||||||
# if the driver being used is srmd_ncnn_vulkan
|
# if the driver being used is srmd_ncnn_vulkan
|
||||||
elif self.driver == 'srmd_ncnn_vulkan':
|
elif self.driver == 'srmd_ncnn_vulkan':
|
||||||
self.process_pool.append(driver.upscale(process_directory,
|
self.process_pool.append(driver.upscale(process_directory,
|
||||||
self.upscaled_frames,
|
self.upscaled_frames,
|
||||||
self.scale_ratio))
|
self.scale_ratio))
|
||||||
|
|
||||||
# start progress bar in a different thread
|
# start progress bar in a different thread
|
||||||
Avalon.debug_info(_('Starting progress monitor'))
|
Avalon.debug_info(_('Starting progress monitor'))
|
||||||
@ -390,18 +398,34 @@ class Upscaler:
|
|||||||
# define processing queue
|
# define processing queue
|
||||||
processing_queue = queue.Queue()
|
processing_queue = queue.Queue()
|
||||||
|
|
||||||
|
# if input is a list of files
|
||||||
|
if isinstance(self.input, list):
|
||||||
|
# make output directory if it doesn't exist
|
||||||
|
self.output.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
for input_path in self.input:
|
||||||
|
|
||||||
|
if input_path.is_file():
|
||||||
|
output_video = self.output / input_path.name
|
||||||
|
processing_queue.put((input_path.absolute(), output_video.absolute()))
|
||||||
|
|
||||||
|
elif input_path.is_dir():
|
||||||
|
for input_video in [f for f in input_path.iterdir() if f.is_file()]:
|
||||||
|
output_video = self.output / input_video.name
|
||||||
|
processing_queue.put((input_video.absolute(), output_video.absolute()))
|
||||||
|
|
||||||
# if input specified is single file
|
# if input specified is single file
|
||||||
if self.input_path.is_file():
|
elif self.input.is_file():
|
||||||
Avalon.info(_('Upscaling single video file: {}').format(self.input_path))
|
Avalon.info(_('Upscaling single video file: {}').format(self.input))
|
||||||
processing_queue.put((self.input_path.absolute(), self.output_path.absolute()))
|
processing_queue.put((self.input.absolute(), self.output.absolute()))
|
||||||
|
|
||||||
# if input specified is a directory
|
# if input specified is a directory
|
||||||
elif self.input_path.is_dir():
|
elif self.input.is_dir():
|
||||||
|
|
||||||
# make output directory if it doesn't exist
|
# make output directory if it doesn't exist
|
||||||
self.output_path.mkdir(parents=True, exist_ok=True)
|
self.output.mkdir(parents=True, exist_ok=True)
|
||||||
for input_video in [f for f in self.input_path.iterdir() if f.is_file()]:
|
for input_video in [f for f in self.input.iterdir() if f.is_file()]:
|
||||||
output_video = self.output_path / input_video.name
|
output_video = self.output / input_video.name
|
||||||
processing_queue.put((input_video.absolute(), output_video.absolute()))
|
processing_queue.put((input_video.absolute(), output_video.absolute()))
|
||||||
|
|
||||||
while not processing_queue.empty():
|
while not processing_queue.empty():
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
Creator: Video2X GUI
|
Creator: Video2X GUI
|
||||||
Author: K4YT3X
|
Author: K4YT3X
|
||||||
Date Created: May 5, 2020
|
Date Created: May 5, 2020
|
||||||
Last Modified: May 7, 2020
|
Last Modified: May 8, 2020
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
@ -14,7 +14,6 @@ from upscaler import Upscaler
|
|||||||
import contextlib
|
import contextlib
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import time
|
import time
|
||||||
@ -22,9 +21,10 @@ import traceback
|
|||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
# third-party imports
|
# third-party imports
|
||||||
from PyQt5 import QtWidgets, QtGui
|
from PyQt5 import QtGui, uic
|
||||||
from PyQt5 import uic
|
from PyQt5.QtCore import *
|
||||||
from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, QRunnable, QThreadPool
|
from PyQt5.QtWidgets import *
|
||||||
|
# QObject, pyqtSlot, pyqtSignal, QRunnable, QThreadPool, QAbstractTableModel, Qt
|
||||||
|
|
||||||
VERSION = '2.0.0'
|
VERSION = '2.0.0'
|
||||||
|
|
||||||
@ -42,6 +42,7 @@ AVAILABLE_DRIVERS = {
|
|||||||
'Anime4KCPP': 'anime4kcpp'
|
'Anime4KCPP': 'anime4kcpp'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def resource_path(relative_path: str) -> pathlib.Path:
|
def resource_path(relative_path: str) -> pathlib.Path:
|
||||||
try:
|
try:
|
||||||
base_path = pathlib.Path(sys._MEIPASS)
|
base_path = pathlib.Path(sys._MEIPASS)
|
||||||
@ -56,6 +57,7 @@ class WorkerSignals(QObject):
|
|||||||
interrupted = pyqtSignal()
|
interrupted = pyqtSignal()
|
||||||
finished = pyqtSignal()
|
finished = pyqtSignal()
|
||||||
|
|
||||||
|
|
||||||
class ProgressBarWorker(QRunnable):
|
class ProgressBarWorker(QRunnable):
|
||||||
def __init__(self, fn, *args, **kwargs):
|
def __init__(self, fn, *args, **kwargs):
|
||||||
super(ProgressBarWorker, self).__init__()
|
super(ProgressBarWorker, self).__init__()
|
||||||
@ -72,6 +74,7 @@ class ProgressBarWorker(QRunnable):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class UpscalerWorker(QRunnable):
|
class UpscalerWorker(QRunnable):
|
||||||
|
|
||||||
def __init__(self, fn, *args, **kwargs):
|
def __init__(self, fn, *args, **kwargs):
|
||||||
@ -99,7 +102,50 @@ class UpscalerWorker(QRunnable):
|
|||||||
self.signals.finished.emit()
|
self.signals.finished.emit()
|
||||||
|
|
||||||
|
|
||||||
class Video2XMainWindow(QtWidgets.QMainWindow):
|
class InputTableModel(QAbstractTableModel):
|
||||||
|
def __init__(self, data):
|
||||||
|
super(InputTableModel, self).__init__()
|
||||||
|
self._data = data
|
||||||
|
|
||||||
|
def data(self, index, role):
|
||||||
|
if role == Qt.DisplayRole:
|
||||||
|
|
||||||
|
if index.column() == 0:
|
||||||
|
return str(self._data[index.row()].absolute())
|
||||||
|
else:
|
||||||
|
if self._data[index.row()].is_file():
|
||||||
|
return 'File'
|
||||||
|
elif self._data[index.row()].is_dir():
|
||||||
|
return 'Folder'
|
||||||
|
else:
|
||||||
|
return 'Unknown'
|
||||||
|
|
||||||
|
def rowCount(self, index):
|
||||||
|
return len(self._data)
|
||||||
|
|
||||||
|
def columnCount(self, index):
|
||||||
|
return 2
|
||||||
|
|
||||||
|
def removeRow(self, index):
|
||||||
|
self._data.pop(index)
|
||||||
|
|
||||||
|
def headerData(self, section, orientation, role):
|
||||||
|
# section is the index of the column/row.
|
||||||
|
if role != Qt.DisplayRole:
|
||||||
|
return None
|
||||||
|
|
||||||
|
horizontal_headers = ['File Path', 'Type']
|
||||||
|
|
||||||
|
# return the correspondign header
|
||||||
|
if orientation == Qt.Horizontal:
|
||||||
|
return horizontal_headers[section]
|
||||||
|
|
||||||
|
# simply return the line number
|
||||||
|
if orientation == Qt.Vertical:
|
||||||
|
return str(section)
|
||||||
|
|
||||||
|
|
||||||
|
class Video2XMainWindow(QMainWindow):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@ -114,131 +160,147 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
self.setWindowIcon(QtGui.QIcon(self.video2x_icon_path))
|
self.setWindowIcon(QtGui.QIcon(self.video2x_icon_path))
|
||||||
|
|
||||||
# menu bar
|
# menu bar
|
||||||
self.action_exit = self.findChild(QtWidgets.QAction, 'actionExit')
|
self.action_exit = self.findChild(QAction, 'actionExit')
|
||||||
self.action_exit.triggered.connect(sys.exit)
|
self.action_exit.triggered.connect(sys.exit)
|
||||||
|
|
||||||
self.action_about = self.findChild(QtWidgets.QAction, 'actionAbout')
|
self.action_about = self.findChild(QAction, 'actionAbout')
|
||||||
self.action_about.triggered.connect(lambda: self.show_message(LEGAL_INFO, custom_icon=QtGui.QPixmap(self.video2x_icon_path)))
|
self.action_about.triggered.connect(lambda: self.show_message(LEGAL_INFO, custom_icon=QtGui.QPixmap(self.video2x_icon_path)))
|
||||||
|
|
||||||
# main tab
|
# main tab
|
||||||
# select input file/folder
|
# select input file/folder
|
||||||
self.input_line_edit = self.findChild(QtWidgets.QLineEdit, 'inputLineEdit')
|
self.input_table_view = self.findChild(QTableView, 'inputTableView')
|
||||||
self.enable_line_edit_file_drop(self.input_line_edit)
|
self.input_table_view.dragEnterEvent = self.dragEnterEvent
|
||||||
self.input_select_file_button = self.findChild(QtWidgets.QPushButton, 'inputSelectFileButton')
|
self.input_table_view.dropEvent = self.dropEvent
|
||||||
self.input_select_file_button.clicked.connect(self.select_input_file)
|
|
||||||
self.input_select_folder_button = self.findChild(QtWidgets.QPushButton, 'inputSelectFolderButton')
|
|
||||||
self.input_select_folder_button.clicked.connect(self.select_input_folder)
|
|
||||||
|
|
||||||
|
# initialize data in table
|
||||||
|
self.input_table_data = []
|
||||||
|
self.input_table_model = InputTableModel(self.input_table_data)
|
||||||
|
self.input_table_view.setModel(self.input_table_model)
|
||||||
|
# stretch file path and fill columns horizontally
|
||||||
|
self.input_table_view.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch)
|
||||||
|
|
||||||
|
# input table buttons
|
||||||
|
self.input_select_file_button = self.findChild(QPushButton, 'inputSelectFileButton')
|
||||||
|
self.input_select_file_button.clicked.connect(self.select_input_file)
|
||||||
|
self.input_select_folder_button = self.findChild(QPushButton, 'inputSelectFolderButton')
|
||||||
|
self.input_select_folder_button.clicked.connect(self.select_input_folder)
|
||||||
|
self.input_delete_selected_button = self.findChild(QPushButton, 'inputDeleteSelectedButton')
|
||||||
|
self.input_delete_selected_button.clicked.connect(self.input_table_delete_selected)
|
||||||
|
self.input_clear_all_button = self.findChild(QPushButton, 'inputClearAllButton')
|
||||||
|
self.input_clear_all_button.clicked.connect(self.input_table_clear_all)
|
||||||
|
|
||||||
|
# other paths selection
|
||||||
# select output file/folder
|
# select output file/folder
|
||||||
self.output_line_edit = self.findChild(QtWidgets.QLineEdit, 'outputLineEdit')
|
self.output_line_edit = self.findChild(QLineEdit, 'outputLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.output_line_edit)
|
self.enable_line_edit_file_drop(self.output_line_edit)
|
||||||
self.output_select_file_button = self.findChild(QtWidgets.QPushButton, 'outputSelectFileButton')
|
self.output_line_edit.setText(str((pathlib.Path().cwd() / 'output').absolute()))
|
||||||
|
self.output_select_file_button = self.findChild(QPushButton, 'outputSelectFileButton')
|
||||||
self.output_select_file_button.clicked.connect(self.select_output_file)
|
self.output_select_file_button.clicked.connect(self.select_output_file)
|
||||||
self.output_select_folder_button = self.findChild(QtWidgets.QPushButton, 'outputSelectFolderButton')
|
self.output_select_folder_button = self.findChild(QPushButton, 'outputSelectFolderButton')
|
||||||
self.output_select_folder_button.clicked.connect(self.select_output_folder)
|
self.output_select_folder_button.clicked.connect(self.select_output_folder)
|
||||||
|
|
||||||
# config file
|
# config file
|
||||||
self.config_line_edit = self.findChild(QtWidgets.QLineEdit, 'configLineEdit')
|
self.config_line_edit = self.findChild(QLineEdit, 'configLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.config_line_edit)
|
self.enable_line_edit_file_drop(self.config_line_edit)
|
||||||
self.config_line_edit.setText(str((pathlib.Path(__file__).parent / 'video2x.yaml').absolute()))
|
self.config_line_edit.setText(str((pathlib.Path(__file__).parent / 'video2x.yaml').absolute()))
|
||||||
self.config_select_file_button = self.findChild(QtWidgets.QPushButton, 'configSelectButton')
|
self.config_select_file_button = self.findChild(QPushButton, 'configSelectButton')
|
||||||
self.config_select_file_button.clicked.connect(self.select_config_file)
|
self.config_select_file_button.clicked.connect(self.select_config_file)
|
||||||
|
|
||||||
# cache directory
|
# cache directory
|
||||||
self.cache_line_edit = self.findChild(QtWidgets.QLineEdit, 'cacheLineEdit')
|
self.cache_line_edit = self.findChild(QLineEdit, 'cacheLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.cache_line_edit)
|
self.enable_line_edit_file_drop(self.cache_line_edit)
|
||||||
self.cache_select_folder_button = self.findChild(QtWidgets.QPushButton, 'cacheSelectFolderButton')
|
self.cache_select_folder_button = self.findChild(QPushButton, 'cacheSelectFolderButton')
|
||||||
self.cache_select_folder_button.clicked.connect(self.select_cache_folder)
|
self.cache_select_folder_button.clicked.connect(self.select_cache_folder)
|
||||||
|
|
||||||
# express settings
|
# express settings
|
||||||
self.driver_combo_box = self.findChild(QtWidgets.QComboBox, 'driverComboBox')
|
self.driver_combo_box = self.findChild(QComboBox, 'driverComboBox')
|
||||||
self.driver_combo_box.currentTextChanged.connect(self.update_gui_for_driver)
|
self.driver_combo_box.currentTextChanged.connect(self.update_gui_for_driver)
|
||||||
self.processes_spin_box = self.findChild(QtWidgets.QSpinBox, 'processesSpinBox')
|
self.processes_spin_box = self.findChild(QSpinBox, 'processesSpinBox')
|
||||||
self.scale_ratio_double_spin_box = self.findChild(QtWidgets.QDoubleSpinBox, 'scaleRatioDoubleSpinBox')
|
self.scale_ratio_double_spin_box = self.findChild(QDoubleSpinBox, 'scaleRatioDoubleSpinBox')
|
||||||
self.preserve_frames_check_box = self.findChild(QtWidgets.QCheckBox, 'preserveFramesCheckBox')
|
self.preserve_frames_check_box = self.findChild(QCheckBox, 'preserveFramesCheckBox')
|
||||||
|
|
||||||
# progress bar and start/stop controls
|
# progress bar and start/stop controls
|
||||||
self.progress_bar = self.findChild(QtWidgets.QProgressBar, 'progressBar')
|
self.progress_bar = self.findChild(QProgressBar, 'progressBar')
|
||||||
self.time_elapsed_label = self.findChild(QtWidgets.QLabel, 'timeElapsedLabel')
|
self.time_elapsed_label = self.findChild(QLabel, 'timeElapsedLabel')
|
||||||
self.time_remaining_label = self.findChild(QtWidgets.QLabel, 'timeRemainingLabel')
|
self.time_remaining_label = self.findChild(QLabel, 'timeRemainingLabel')
|
||||||
self.rate_label = self.findChild(QtWidgets.QLabel, 'rateLabel')
|
self.rate_label = self.findChild(QLabel, 'rateLabel')
|
||||||
self.start_button = self.findChild(QtWidgets.QPushButton, 'startButton')
|
self.start_button = self.findChild(QPushButton, 'startButton')
|
||||||
self.start_button.clicked.connect(self.start)
|
self.start_button.clicked.connect(self.start)
|
||||||
self.stop_button = self.findChild(QtWidgets.QPushButton, 'stopButton')
|
self.stop_button = self.findChild(QPushButton, 'stopButton')
|
||||||
self.stop_button.clicked.connect(self.stop)
|
self.stop_button.clicked.connect(self.stop)
|
||||||
|
|
||||||
# driver settings
|
# driver settings
|
||||||
# waifu2x-caffe
|
# waifu2x-caffe
|
||||||
self.waifu2x_caffe_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'waifu2xCaffePathLineEdit')
|
self.waifu2x_caffe_path_line_edit = self.findChild(QLineEdit, 'waifu2xCaffePathLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.waifu2x_caffe_path_line_edit)
|
self.enable_line_edit_file_drop(self.waifu2x_caffe_path_line_edit)
|
||||||
self.waifu2x_caffe_path_select_button = self.findChild(QtWidgets.QPushButton, 'waifu2xCaffePathSelectButton')
|
self.waifu2x_caffe_path_select_button = self.findChild(QPushButton, 'waifu2xCaffePathSelectButton')
|
||||||
self.waifu2x_caffe_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_caffe_path_line_edit))
|
self.waifu2x_caffe_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_caffe_path_line_edit))
|
||||||
self.waifu2x_caffe_mode_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xCaffeModeComboBox')
|
self.waifu2x_caffe_mode_combo_box = self.findChild(QComboBox, 'waifu2xCaffeModeComboBox')
|
||||||
self.waifu2x_caffe_noise_level_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeNoiseLevelSpinBox')
|
self.waifu2x_caffe_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeNoiseLevelSpinBox')
|
||||||
self.waifu2x_caffe_process_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xCaffeProcessComboBox')
|
self.waifu2x_caffe_process_combo_box = self.findChild(QComboBox, 'waifu2xCaffeProcessComboBox')
|
||||||
self.waifu2x_caffe_model_combobox = self.findChild(QtWidgets.QComboBox, 'waifu2xCaffeModelComboBox')
|
self.waifu2x_caffe_model_combobox = self.findChild(QComboBox, 'waifu2xCaffeModelComboBox')
|
||||||
self.waifu2x_caffe_crop_size_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeCropSizeSpinBox')
|
self.waifu2x_caffe_crop_size_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeCropSizeSpinBox')
|
||||||
self.waifu2x_caffe_output_quality_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeOutputQualitySpinBox')
|
self.waifu2x_caffe_output_quality_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeOutputQualitySpinBox')
|
||||||
self.waifu2x_caffe_output_depth_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeOutputDepthSpinBox')
|
self.waifu2x_caffe_output_depth_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeOutputDepthSpinBox')
|
||||||
self.waifu2x_caffe_batch_size_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeBatchSizeSpinBox')
|
self.waifu2x_caffe_batch_size_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeBatchSizeSpinBox')
|
||||||
self.waifu2x_caffe_gpu_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xCaffeGpuSpinBox')
|
self.waifu2x_caffe_gpu_spin_box = self.findChild(QSpinBox, 'waifu2xCaffeGpuSpinBox')
|
||||||
self.waifu2x_caffe_tta_check_box = self.findChild(QtWidgets.QCheckBox, 'waifu2xCaffeTtaCheckBox')
|
self.waifu2x_caffe_tta_check_box = self.findChild(QCheckBox, 'waifu2xCaffeTtaCheckBox')
|
||||||
|
|
||||||
# waifu2x-converter-cpp
|
# waifu2x-converter-cpp
|
||||||
self.waifu2x_converter_cpp_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'waifu2xConverterCppPathLineEdit')
|
self.waifu2x_converter_cpp_path_line_edit = self.findChild(QLineEdit, 'waifu2xConverterCppPathLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.waifu2x_converter_cpp_path_line_edit)
|
self.enable_line_edit_file_drop(self.waifu2x_converter_cpp_path_line_edit)
|
||||||
self.waifu2x_converter_cpp_path_edit_button = self.findChild(QtWidgets.QPushButton, 'waifu2xConverterCppPathSelectButton')
|
self.waifu2x_converter_cpp_path_edit_button = self.findChild(QPushButton, 'waifu2xConverterCppPathSelectButton')
|
||||||
self.waifu2x_converter_cpp_path_edit_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_converter_cpp_path_line_edit))
|
self.waifu2x_converter_cpp_path_edit_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_converter_cpp_path_line_edit))
|
||||||
self.waifu2x_converter_cpp_png_compression_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xConverterCppPngCompressionSpinBox')
|
self.waifu2x_converter_cpp_png_compression_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppPngCompressionSpinBox')
|
||||||
self.waifu2x_converter_cpp_processor_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xConverterCppProcessorSpinBox')
|
self.waifu2x_converter_cpp_processor_spin_box = self.findChild(QSpinBox, 'waifu2xConverterCppProcessorSpinBox')
|
||||||
self.waifu2x_converter_cpp_model_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xConverterCppModelComboBox')
|
self.waifu2x_converter_cpp_model_combo_box = self.findChild(QComboBox, 'waifu2xConverterCppModelComboBox')
|
||||||
self.waifu2x_converter_cpp_mode_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xConverterCppModeComboBox')
|
self.waifu2x_converter_cpp_mode_combo_box = self.findChild(QComboBox, 'waifu2xConverterCppModeComboBox')
|
||||||
self.waifu2x_converter_cpp_disable_gpu_check_box = self.findChild(QtWidgets.QCheckBox, 'disableGpuCheckBox')
|
self.waifu2x_converter_cpp_disable_gpu_check_box = self.findChild(QCheckBox, 'disableGpuCheckBox')
|
||||||
self.waifu2x_converter_cpp_tta_check_box = self.findChild(QtWidgets.QCheckBox, 'ttaCheckBox')
|
self.waifu2x_converter_cpp_tta_check_box = self.findChild(QCheckBox, 'ttaCheckBox')
|
||||||
|
|
||||||
# waifu2x-ncnn-vulkan
|
# waifu2x-ncnn-vulkan
|
||||||
self.waifu2x_ncnn_vulkan_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'waifu2xNcnnVulkanPathLineEdit')
|
self.waifu2x_ncnn_vulkan_path_line_edit = self.findChild(QLineEdit, 'waifu2xNcnnVulkanPathLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.waifu2x_ncnn_vulkan_path_line_edit)
|
self.enable_line_edit_file_drop(self.waifu2x_ncnn_vulkan_path_line_edit)
|
||||||
self.waifu2x_ncnn_vulkan_path_select_button = self.findChild(QtWidgets.QPushButton, 'waifu2xNcnnVulkanPathSelectButton')
|
self.waifu2x_ncnn_vulkan_path_select_button = self.findChild(QPushButton, 'waifu2xNcnnVulkanPathSelectButton')
|
||||||
self.waifu2x_ncnn_vulkan_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_ncnn_vulkan_path_line_edit))
|
self.waifu2x_ncnn_vulkan_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.waifu2x_ncnn_vulkan_path_line_edit))
|
||||||
self.waifu2x_ncnn_vulkan_noise_level_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xNcnnVulkanNoiseLevelSpinBox')
|
self.waifu2x_ncnn_vulkan_noise_level_spin_box = self.findChild(QSpinBox, 'waifu2xNcnnVulkanNoiseLevelSpinBox')
|
||||||
self.waifu2x_ncnn_vulkan_tile_size_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xNcnnVulkanTileSizeSpinBox')
|
self.waifu2x_ncnn_vulkan_tile_size_spin_box = self.findChild(QSpinBox, 'waifu2xNcnnVulkanTileSizeSpinBox')
|
||||||
self.waifu2x_ncnn_vulkan_model_combo_box = self.findChild(QtWidgets.QComboBox, 'waifu2xNcnnVulkanModelComboBox')
|
self.waifu2x_ncnn_vulkan_model_combo_box = self.findChild(QComboBox, 'waifu2xNcnnVulkanModelComboBox')
|
||||||
self.waifu2x_ncnn_vulkan_gpu_id_spin_box = self.findChild(QtWidgets.QSpinBox, 'waifu2xNcnnVulkanGpuIdSpinBox')
|
self.waifu2x_ncnn_vulkan_gpu_id_spin_box = self.findChild(QSpinBox, 'waifu2xNcnnVulkanGpuIdSpinBox')
|
||||||
self.waifu2x_ncnn_vulkan_jobs_line_edit = self.findChild(QtWidgets.QLineEdit, 'waifu2xNcnnVulkanJobsLineEdit')
|
self.waifu2x_ncnn_vulkan_jobs_line_edit = self.findChild(QLineEdit, 'waifu2xNcnnVulkanJobsLineEdit')
|
||||||
self.waifu2x_ncnn_vulkan_tta_check_box = self.findChild(QtWidgets.QCheckBox, 'waifu2xNcnnVulkanTtaCheckBox')
|
self.waifu2x_ncnn_vulkan_tta_check_box = self.findChild(QCheckBox, 'waifu2xNcnnVulkanTtaCheckBox')
|
||||||
|
|
||||||
# srmd-ncnn-vulkan
|
# srmd-ncnn-vulkan
|
||||||
self.srmd_ncnn_vulkan_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'srmdNcnnVulkanPathLineEdit')
|
self.srmd_ncnn_vulkan_path_line_edit = self.findChild(QLineEdit, 'srmdNcnnVulkanPathLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.srmd_ncnn_vulkan_path_line_edit)
|
self.enable_line_edit_file_drop(self.srmd_ncnn_vulkan_path_line_edit)
|
||||||
self.srmd_ncnn_vulkan_path_select_button = self.findChild(QtWidgets.QPushButton, 'srmdNcnnVulkanPathSelectButton')
|
self.srmd_ncnn_vulkan_path_select_button = self.findChild(QPushButton, 'srmdNcnnVulkanPathSelectButton')
|
||||||
self.srmd_ncnn_vulkan_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.srmd_ncnn_vulkan_path_line_edit))
|
self.srmd_ncnn_vulkan_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.srmd_ncnn_vulkan_path_line_edit))
|
||||||
self.srmd_ncnn_vulkan_noise_level_spin_box = self.findChild(QtWidgets.QSpinBox, 'srmdNcnnVulkanNoiseLevelSpinBox')
|
self.srmd_ncnn_vulkan_noise_level_spin_box = self.findChild(QSpinBox, 'srmdNcnnVulkanNoiseLevelSpinBox')
|
||||||
self.srmd_ncnn_vulkan_tile_size_spin_box = self.findChild(QtWidgets.QSpinBox, 'srmdNcnnVulkanTileSizeSpinBox')
|
self.srmd_ncnn_vulkan_tile_size_spin_box = self.findChild(QSpinBox, 'srmdNcnnVulkanTileSizeSpinBox')
|
||||||
self.srmd_ncnn_vulkan_model_combo_box = self.findChild(QtWidgets.QComboBox, 'srmdNcnnVulkanModelComboBox')
|
self.srmd_ncnn_vulkan_model_combo_box = self.findChild(QComboBox, 'srmdNcnnVulkanModelComboBox')
|
||||||
self.srmd_ncnn_vulkan_gpu_id_spin_box = self.findChild(QtWidgets.QSpinBox, 'srmdNcnnVulkanGpuIdSpinBox')
|
self.srmd_ncnn_vulkan_gpu_id_spin_box = self.findChild(QSpinBox, 'srmdNcnnVulkanGpuIdSpinBox')
|
||||||
self.srmd_ncnn_vulkan_jobs_line_edit = self.findChild(QtWidgets.QLineEdit, 'srmdNcnnVulkanJobsLineEdit')
|
self.srmd_ncnn_vulkan_jobs_line_edit = self.findChild(QLineEdit, 'srmdNcnnVulkanJobsLineEdit')
|
||||||
self.srmd_ncnn_vulkan_tta_check_box = self.findChild(QtWidgets.QCheckBox, 'srmdNcnnVulkanTtaCheckBox')
|
self.srmd_ncnn_vulkan_tta_check_box = self.findChild(QCheckBox, 'srmdNcnnVulkanTtaCheckBox')
|
||||||
|
|
||||||
# anime4k
|
# anime4k
|
||||||
self.anime4kcpp_path_line_edit = self.findChild(QtWidgets.QLineEdit, 'anime4kCppPathLineEdit')
|
self.anime4kcpp_path_line_edit = self.findChild(QLineEdit, 'anime4kCppPathLineEdit')
|
||||||
self.enable_line_edit_file_drop(self.anime4kcpp_path_line_edit)
|
self.enable_line_edit_file_drop(self.anime4kcpp_path_line_edit)
|
||||||
self.anime4kcpp_path_select_button = self.findChild(QtWidgets.QPushButton, 'anime4kCppPathSelectButton')
|
self.anime4kcpp_path_select_button = self.findChild(QPushButton, 'anime4kCppPathSelectButton')
|
||||||
self.anime4kcpp_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.anime4kcpp_path_line_edit))
|
self.anime4kcpp_path_select_button.clicked.connect(lambda: self.select_driver_binary_path(self.anime4kcpp_path_line_edit))
|
||||||
self.anime4kcpp_passes_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPassesSpinBox')
|
self.anime4kcpp_passes_spin_box = self.findChild(QSpinBox, 'anime4kCppPassesSpinBox')
|
||||||
self.anime4kcpp_push_color_count_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPushColorCountSpinBox')
|
self.anime4kcpp_push_color_count_spin_box = self.findChild(QSpinBox, 'anime4kCppPushColorCountSpinBox')
|
||||||
self.anime4kcpp_strength_color_spin_box = self.findChild(QtWidgets.QDoubleSpinBox, 'anime4kCppStrengthColorSpinBox')
|
self.anime4kcpp_strength_color_spin_box = self.findChild(QDoubleSpinBox, 'anime4kCppStrengthColorSpinBox')
|
||||||
self.anime4kcpp_strength_gradient_spin_box = self.findChild(QtWidgets.QDoubleSpinBox, 'anime4kCppStrengthGradientSpinBox')
|
self.anime4kcpp_strength_gradient_spin_box = self.findChild(QDoubleSpinBox, 'anime4kCppStrengthGradientSpinBox')
|
||||||
self.anime4kcpp_threads_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppThreadsSpinBox')
|
self.anime4kcpp_threads_spin_box = self.findChild(QSpinBox, 'anime4kCppThreadsSpinBox')
|
||||||
self.anime4kcpp_pre_filters_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPreFiltersSpinBox')
|
self.anime4kcpp_pre_filters_spin_box = self.findChild(QSpinBox, 'anime4kCppPreFiltersSpinBox')
|
||||||
self.anime4kcpp_post_filters_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPostFiltersSpinBox')
|
self.anime4kcpp_post_filters_spin_box = self.findChild(QSpinBox, 'anime4kCppPostFiltersSpinBox')
|
||||||
self.anime4kcpp_platform_id_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppPlatformIdSpinBox')
|
self.anime4kcpp_platform_id_spin_box = self.findChild(QSpinBox, 'anime4kCppPlatformIdSpinBox')
|
||||||
self.anime4kcpp_device_id_spin_box = self.findChild(QtWidgets.QSpinBox, 'anime4kCppDeviceIdSpinBox')
|
self.anime4kcpp_device_id_spin_box = self.findChild(QSpinBox, 'anime4kCppDeviceIdSpinBox')
|
||||||
self.anime4kcpp_codec_combo_box = self.findChild(QtWidgets.QComboBox, 'anime4kCppCodecComboBox')
|
self.anime4kcpp_codec_combo_box = self.findChild(QComboBox, 'anime4kCppCodecComboBox')
|
||||||
self.anime4kcpp_fast_mode_check_box = self.findChild(QtWidgets.QCheckBox, 'anime4kCppFastModeCheckBox')
|
self.anime4kcpp_fast_mode_check_box = self.findChild(QCheckBox, 'anime4kCppFastModeCheckBox')
|
||||||
self.anime4kcpp_pre_processing_check_box = self.findChild(QtWidgets.QCheckBox, 'anime4kCppPreProcessingCheckBox')
|
self.anime4kcpp_pre_processing_check_box = self.findChild(QCheckBox, 'anime4kCppPreProcessingCheckBox')
|
||||||
self.anime4kcpp_post_processing_check_box = self.findChild(QtWidgets.QCheckBox, 'anime4kCppPostProcessingCheckBox')
|
self.anime4kcpp_post_processing_check_box = self.findChild(QCheckBox, 'anime4kCppPostProcessingCheckBox')
|
||||||
self.anime4kcpp_gpu_mode_check_box = self.findChild(QtWidgets.QCheckBox, 'anime4kCppGpuModeCheckBox')
|
self.anime4kcpp_gpu_mode_check_box = self.findChild(QCheckBox, 'anime4kCppGpuModeCheckBox')
|
||||||
|
|
||||||
# load configurations
|
# load configurations
|
||||||
self.load_configurations()
|
self.load_configurations()
|
||||||
@ -250,11 +312,15 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
event.ignore()
|
event.ignore()
|
||||||
|
|
||||||
def dropEvent(self, event):
|
def dropEvent(self, event):
|
||||||
input_path = pathlib.Path(event.mimeData().urls()[0].toLocalFile())
|
input_paths = [pathlib.Path(u.toLocalFile()) for u in event.mimeData().urls()]
|
||||||
self.input_line_edit.setText(str(input_path.absolute()))
|
for path in input_paths:
|
||||||
self.generate_output_path(input_path)
|
if (path.is_file() or path.is_dir()) and not self.input_table_path_exists(path):
|
||||||
|
self.input_table_data.append(path)
|
||||||
|
|
||||||
def enable_line_edit_file_drop(self, line_edit: QtWidgets.QLineEdit):
|
self.update_input_table()
|
||||||
|
self.update_output_path()
|
||||||
|
|
||||||
|
def enable_line_edit_file_drop(self, line_edit: QLineEdit):
|
||||||
line_edit.dragEnterEvent = self.dragEnterEvent
|
line_edit.dragEnterEvent = self.dragEnterEvent
|
||||||
line_edit.dropEvent = lambda event: line_edit.setText(str(pathlib.Path(event.mimeData().urls()[0].toLocalFile()).absolute()))
|
line_edit.dropEvent = lambda event: line_edit.setText(str(pathlib.Path(event.mimeData().urls()[0].toLocalFile()).absolute()))
|
||||||
|
|
||||||
@ -279,7 +345,7 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
|
|
||||||
# if file doesn't exist, return
|
# if file doesn't exist, return
|
||||||
if not config_file_path.is_file():
|
if not config_file_path.is_file():
|
||||||
QtWidgets.QErrorMessage(self).showMessage('Video2X configuration file not found, please specify manually.')
|
QErrorMessage(self).showMessage('Video2X configuration file not found, please specify manually.')
|
||||||
return
|
return
|
||||||
|
|
||||||
# read configuration dict from config file
|
# read configuration dict from config file
|
||||||
@ -438,19 +504,50 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
else:
|
else:
|
||||||
self.processes_spin_box.setValue(1)
|
self.processes_spin_box.setValue(1)
|
||||||
|
|
||||||
|
def update_input_table(self):
|
||||||
|
# HACK: use insertRow, removeRow and signals
|
||||||
|
del self.input_table_model
|
||||||
|
self.input_table_model = InputTableModel(self.input_table_data)
|
||||||
|
self.input_table_view.setModel(self.input_table_model)
|
||||||
|
|
||||||
|
def input_table_delete_selected(self):
|
||||||
|
items_to_delete = []
|
||||||
|
for index in [i.row() for i in self.input_table_view.selectedIndexes()]:
|
||||||
|
items_to_delete.append(self.input_table_data[index])
|
||||||
|
|
||||||
|
for item in items_to_delete:
|
||||||
|
self.input_table_data.remove(item)
|
||||||
|
self.update_input_table()
|
||||||
|
|
||||||
|
def input_table_clear_all(self):
|
||||||
|
self.input_table_data = []
|
||||||
|
self.update_input_table()
|
||||||
|
|
||||||
|
def input_table_path_exists(self, input_path):
|
||||||
|
for path in self.input_table_data:
|
||||||
|
# not using Path.samefile since file may not exist
|
||||||
|
if str(path.absolute()) == str(input_path.absolute()):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def select_file(self, *args, **kwargs) -> pathlib.Path:
|
def select_file(self, *args, **kwargs) -> pathlib.Path:
|
||||||
file_selected = QtWidgets.QFileDialog.getOpenFileName(self, *args, **kwargs)
|
file_selected = QFileDialog.getOpenFileName(self, *args, **kwargs)
|
||||||
if not isinstance(file_selected, tuple) or file_selected[0] == '':
|
if not isinstance(file_selected, tuple) or file_selected[0] == '':
|
||||||
return None
|
return None
|
||||||
return pathlib.Path(file_selected[0])
|
return pathlib.Path(file_selected[0])
|
||||||
|
|
||||||
def select_folder(self, *args, **kwargs) -> pathlib.Path:
|
def select_folder(self, *args, **kwargs) -> pathlib.Path:
|
||||||
folder_selected = QtWidgets.QFileDialog.getExistingDirectory(self, *args, **kwargs)
|
folder_selected = QFileDialog.getExistingDirectory(self, *args, **kwargs)
|
||||||
if folder_selected == '':
|
if folder_selected == '':
|
||||||
return None
|
return None
|
||||||
return pathlib.Path(folder_selected)
|
return pathlib.Path(folder_selected)
|
||||||
|
|
||||||
def generate_output_path(self, input_path: pathlib.Path):
|
def update_output_path(self):
|
||||||
|
# if there is more than one input
|
||||||
|
if len(self.input_table_data) != 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
input_path = self.input_table_data[0]
|
||||||
# give up if input path doesn't exist or isn't a file or a directory
|
# give up if input path doesn't exist or isn't a file or a directory
|
||||||
if not input_path.exists() or not (input_path.is_file() or input_path.is_dir()):
|
if not input_path.exists() or not (input_path.is_file() or input_path.is_dir()):
|
||||||
return
|
return
|
||||||
@ -466,23 +563,27 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
if input_path.is_file():
|
if input_path.is_file():
|
||||||
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}.mp4')
|
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}.mp4')
|
||||||
elif input_path.is_dir():
|
elif input_path.is_dir():
|
||||||
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_file_id}')
|
output_path = input_path.parent / pathlib.Path(f'{input_path.stem}_output_{output_path_id}')
|
||||||
output_path_id += 1
|
output_path_id += 1
|
||||||
|
|
||||||
if not output_path.exists():
|
if not output_path.exists():
|
||||||
self.output_line_edit.setText(str(output_path.absolute()))
|
self.output_line_edit.setText(str(output_path.absolute()))
|
||||||
|
|
||||||
def select_input_file(self):
|
def select_input_file(self):
|
||||||
if (input_file := self.select_file('Select Input File')) is None:
|
if ((input_file := self.select_file('Select Input File')) is None or
|
||||||
|
self.input_table_path_exists(input_file)):
|
||||||
return
|
return
|
||||||
self.generate_output_path(input_file)
|
self.input_table_data.append(input_file)
|
||||||
self.input_line_edit.setText(str(input_file.absolute()))
|
self.update_output_path()
|
||||||
|
self.update_input_table()
|
||||||
|
|
||||||
def select_input_folder(self):
|
def select_input_folder(self):
|
||||||
if (input_folder := self.select_folder('Select Input Folder')) is None:
|
if ((input_folder := self.select_folder('Select Input Folder')) is None or
|
||||||
|
self.input_table_path_exists(input_folder)):
|
||||||
return
|
return
|
||||||
self.generate_output_path(input_folder)
|
self.input_table_data.append(input_folder)
|
||||||
self.input_line_edit.setText(str(input_folder.absolute()))
|
self.update_output_path()
|
||||||
|
self.update_input_table()
|
||||||
|
|
||||||
def select_output_file(self):
|
def select_output_file(self):
|
||||||
if (output_file := self.select_file('Select Output File')) is None:
|
if (output_file := self.select_file('Select Output File')) is None:
|
||||||
@ -511,15 +612,15 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
driver_line_edit.setText(str(driver_binary_path.absolute()))
|
driver_line_edit.setText(str(driver_binary_path.absolute()))
|
||||||
|
|
||||||
def show_error(self, message: str):
|
def show_error(self, message: str):
|
||||||
QtWidgets.QErrorMessage(self).showMessage(message.replace('\n', '<br>'))
|
QErrorMessage(self).showMessage(message.replace('\n', '<br>'))
|
||||||
|
|
||||||
def show_message(self, message: str, custom_icon=None):
|
def show_message(self, message: str, custom_icon=None):
|
||||||
message_box = QtWidgets.QMessageBox()
|
message_box = QMessageBox()
|
||||||
message_box.setWindowTitle('Message')
|
message_box.setWindowTitle('Message')
|
||||||
if custom_icon:
|
if custom_icon:
|
||||||
message_box.setIconPixmap(custom_icon.scaled(64, 64))
|
message_box.setIconPixmap(custom_icon.scaled(64, 64))
|
||||||
else:
|
else:
|
||||||
message_box.setIcon(QtWidgets.QMessageBox.Information)
|
message_box.setIcon(QMessageBox.Information)
|
||||||
message_box.setText(message)
|
message_box.setText(message)
|
||||||
message_box.exec_()
|
message_box.exec_()
|
||||||
|
|
||||||
@ -542,9 +643,9 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
progress_percentage = 0
|
progress_percentage = 0
|
||||||
|
|
||||||
progress_callback.emit((progress_percentage,
|
progress_callback.emit((progress_percentage,
|
||||||
self.upscaler.total_frames_upscaled,
|
self.upscaler.total_frames_upscaled,
|
||||||
self.upscaler.total_frames,
|
self.upscaler.total_frames,
|
||||||
upscale_begin_time))
|
upscale_begin_time))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# upscale process will stop at 99%
|
# upscale process will stop at 99%
|
||||||
@ -580,14 +681,17 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
self.begin_time = time.time()
|
self.begin_time = time.time()
|
||||||
|
|
||||||
# resolve input and output directories from GUI
|
# resolve input and output directories from GUI
|
||||||
if self.input_line_edit.text().strip() == '':
|
if len(self.input_table_data) == 0:
|
||||||
self.show_error('Input path not specified')
|
self.show_error('Input path unspecified')
|
||||||
return
|
return
|
||||||
if self.output_line_edit.text().strip() == '':
|
if self.output_line_edit.text().strip() == '':
|
||||||
self.show_error('Output path not specified')
|
self.show_error('Output path unspecified')
|
||||||
return
|
return
|
||||||
|
|
||||||
input_directory = pathlib.Path(os.path.expandvars(self.input_line_edit.text()))
|
if len(self.input_table_data) == 1:
|
||||||
|
input_directory = self.input_table_data[0]
|
||||||
|
else:
|
||||||
|
input_directory = self.input_table_data
|
||||||
output_directory = pathlib.Path(os.path.expandvars(self.output_line_edit.text()))
|
output_directory = pathlib.Path(os.path.expandvars(self.output_line_edit.text()))
|
||||||
|
|
||||||
# load driver settings from GUI
|
# load driver settings from GUI
|
||||||
@ -658,7 +762,7 @@ class Video2XMainWindow(QtWidgets.QMainWindow):
|
|||||||
|
|
||||||
# this file shouldn't be imported
|
# this file shouldn't be imported
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
window = Video2XMainWindow()
|
window = Video2XMainWindow()
|
||||||
window.show()
|
window.show()
|
||||||
app.exec_()
|
app.exec_()
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>691</width>
|
<width>718</width>
|
||||||
<height>503</height>
|
<height>668</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="acceptDrops">
|
<property name="acceptDrops">
|
||||||
@ -16,7 +16,7 @@
|
|||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Video2X GUI</string>
|
<string>Video2X GUI</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralWidget">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
<number>5</number>
|
<number>5</number>
|
||||||
@ -79,154 +79,160 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="fileSelectionVerticalLayout">
|
<widget class="QGroupBox" name="inputSelectionGroupBox">
|
||||||
<item>
|
<property name="title">
|
||||||
<layout class="QHBoxLayout" name="inputHorizontalLayout">
|
<string>Input Selection</string>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QLabel" name="inputLabel">
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
<property name="minimumSize">
|
<item>
|
||||||
<size>
|
<widget class="QTableView" name="inputTableView"/>
|
||||||
<width>63</width>
|
</item>
|
||||||
<height>0</height>
|
<item>
|
||||||
</size>
|
<layout class="QHBoxLayout" name="inputButtonsHorizontalLayout">
|
||||||
</property>
|
<item>
|
||||||
<property name="lineWidth">
|
<widget class="QPushButton" name="inputSelectFileButton">
|
||||||
<number>1</number>
|
<property name="enabled">
|
||||||
</property>
|
<bool>true</bool>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Input</string>
|
<property name="text">
|
||||||
</property>
|
<string>Select File</string>
|
||||||
<property name="wordWrap">
|
</property>
|
||||||
<bool>false</bool>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="margin">
|
<item>
|
||||||
<number>0</number>
|
<widget class="QPushButton" name="inputSelectFolderButton">
|
||||||
</property>
|
<property name="text">
|
||||||
</widget>
|
<string>Select Folder</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
</widget>
|
||||||
<widget class="QLineEdit" name="inputLineEdit"/>
|
</item>
|
||||||
</item>
|
<item>
|
||||||
<item>
|
<widget class="QPushButton" name="inputDeleteSelectedButton">
|
||||||
<widget class="QPushButton" name="inputSelectFileButton">
|
<property name="text">
|
||||||
<property name="enabled">
|
<string>Delete Selected</string>
|
||||||
<bool>true</bool>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
<property name="text">
|
</item>
|
||||||
<string>Select File</string>
|
<item>
|
||||||
</property>
|
<widget class="QPushButton" name="inputClearAllButton">
|
||||||
</widget>
|
<property name="text">
|
||||||
</item>
|
<string>Clear All</string>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QPushButton" name="inputSelectFolderButton">
|
</widget>
|
||||||
<property name="text">
|
</item>
|
||||||
<string>Select Folder</string>
|
</layout>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
</layout>
|
||||||
</item>
|
</widget>
|
||||||
</layout>
|
</item>
|
||||||
</item>
|
<item>
|
||||||
<item>
|
<widget class="QGroupBox" name="otherPathsSelectionGroupBox">
|
||||||
<layout class="QHBoxLayout" name="outputHorizontalLayout">
|
<property name="title">
|
||||||
<item>
|
<string>Other Paths Selection</string>
|
||||||
<widget class="QLabel" name="outputLabel">
|
</property>
|
||||||
<property name="sizePolicy">
|
<layout class="QVBoxLayout" name="verticalLayout_9">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<item>
|
||||||
<horstretch>0</horstretch>
|
<layout class="QHBoxLayout" name="outputHorizontalLayout">
|
||||||
<verstretch>0</verstretch>
|
<item>
|
||||||
</sizepolicy>
|
<widget class="QLabel" name="outputLabel">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
<property name="minimumSize">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<size>
|
<horstretch>0</horstretch>
|
||||||
<width>63</width>
|
<verstretch>0</verstretch>
|
||||||
<height>0</height>
|
</sizepolicy>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="minimumSize">
|
||||||
<property name="text">
|
<size>
|
||||||
<string>Output</string>
|
<width>63</width>
|
||||||
</property>
|
<height>0</height>
|
||||||
</widget>
|
</size>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="text">
|
||||||
<widget class="QLineEdit" name="outputLineEdit"/>
|
<string>Output</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
</widget>
|
||||||
<widget class="QPushButton" name="outputSelectFileButton">
|
</item>
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Select File</string>
|
<widget class="QLineEdit" name="outputLineEdit"/>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="outputSelectFileButton">
|
||||||
<item>
|
<property name="text">
|
||||||
<widget class="QPushButton" name="outputSelectFolderButton">
|
<string>Select File</string>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Select Folder</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="outputSelectFolderButton">
|
||||||
</layout>
|
<property name="text">
|
||||||
</item>
|
<string>Select Folder</string>
|
||||||
<item>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="configHorizontalLayout">
|
</widget>
|
||||||
<item>
|
</item>
|
||||||
<widget class="QLabel" name="configLabel">
|
</layout>
|
||||||
<property name="sizePolicy">
|
</item>
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
<item>
|
||||||
<horstretch>0</horstretch>
|
<layout class="QHBoxLayout" name="configHorizontalLayout">
|
||||||
<verstretch>0</verstretch>
|
<item>
|
||||||
</sizepolicy>
|
<widget class="QLabel" name="configLabel">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
<property name="minimumSize">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<size>
|
<horstretch>0</horstretch>
|
||||||
<width>63</width>
|
<verstretch>0</verstretch>
|
||||||
<height>0</height>
|
</sizepolicy>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="minimumSize">
|
||||||
<property name="text">
|
<size>
|
||||||
<string>Config</string>
|
<width>63</width>
|
||||||
</property>
|
<height>0</height>
|
||||||
</widget>
|
</size>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="text">
|
||||||
<widget class="QLineEdit" name="configLineEdit"/>
|
<string>Config</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
</widget>
|
||||||
<widget class="QPushButton" name="configSelectButton">
|
</item>
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Select</string>
|
<widget class="QLineEdit" name="configLineEdit"/>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="configSelectButton">
|
||||||
</layout>
|
<property name="text">
|
||||||
</item>
|
<string>Select</string>
|
||||||
<item>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="cacheHorizontalLayout">
|
</widget>
|
||||||
<item>
|
</item>
|
||||||
<widget class="QLabel" name="cacheLabel">
|
</layout>
|
||||||
<property name="minimumSize">
|
</item>
|
||||||
<size>
|
<item>
|
||||||
<width>63</width>
|
<layout class="QHBoxLayout" name="cacheHorizontalLayout">
|
||||||
<height>0</height>
|
<item>
|
||||||
</size>
|
<widget class="QLabel" name="cacheLabel">
|
||||||
</property>
|
<property name="minimumSize">
|
||||||
<property name="text">
|
<size>
|
||||||
<string>Cache Folder</string>
|
<width>63</width>
|
||||||
</property>
|
<height>0</height>
|
||||||
</widget>
|
</size>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="text">
|
||||||
<widget class="QLineEdit" name="cacheLineEdit"/>
|
<string>Cache Folder</string>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
</widget>
|
||||||
<widget class="QPushButton" name="cacheSelectFolderButton">
|
</item>
|
||||||
<property name="text">
|
<item>
|
||||||
<string>Select Folder</string>
|
<widget class="QLineEdit" name="cacheLineEdit"/>
|
||||||
</property>
|
</item>
|
||||||
</widget>
|
<item>
|
||||||
</item>
|
<widget class="QPushButton" name="cacheSelectFolderButton">
|
||||||
</layout>
|
<property name="text">
|
||||||
</item>
|
<string>Select Folder</string>
|
||||||
</layout>
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="expressSettingsGroupBox">
|
<widget class="QGroupBox" name="expressSettingsGroupBox">
|
||||||
@ -1344,7 +1350,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>691</width>
|
<width>718</width>
|
||||||
<height>21</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
Loading…
Reference in New Issue
Block a user