diff --git a/TheAnimeScripter.jsx b/TheAnimeScripter.jsx index 42d0ced7..40f545b6 100644 --- a/TheAnimeScripter.jsx +++ b/TheAnimeScripter.jsx @@ -491,7 +491,7 @@ var TheAnimeScripter = (function () { "ShuffleCugan-NCNN", "Span-NCNN", ], "Choose which model you want to utilize, read more in INFO, for AMD users choose DirectML or NCNN models"); - createDropdownField(panel1, "Interpolate Model", "Interpolate", ["Rife4.17", "Rife4.16-lite", "Rife4.15", "Rife4.15-lite", "Rife4.6", "Rife4.17-TensorRT", "Rife4.15-TensorRT", "Rife4.15-Lite-TensorRT", "Rife4.6-TensorRT", "Rife4.15-NCNN", "Rife4.15-Lite-NCNN", "Rife4.16-Lite-NCNN", "Rife4.6-NCNN", "GMFSS"], "Choose which interpolation model you want to utilize, read more in readme.txt, for AMD users choose DirectML or NCNN models, TensorRT is for NVIDIA RTX 2000 and above GPUs"); + createDropdownField(panel1, "Interpolate Model", "Interpolate", ["Rife4.17", "Rife4.17-Lite", "Rife4.16-Lite", "Rife4.15", "Rife4.15-Lite", "Rife4.6", "Rife4.17-TensorRT", "Rife4.15-TensorRT", "Rife4.15-Lite-TensorRT", "Rife4.6-TensorRT", "Rife4.16-Lite-NCNN", "Rife4.15-NCNN", "Rife4.15-Lite-NCNN", "Rife4.6-NCNN", "GMFSS"], "Choose which interpolation model you want to utilize, read more in readme.txt, for AMD users choose DirectML or NCNN models, TensorRT is for NVIDIA RTX 2000 and above GPUs"); createDropdownField(panel1, "Depth Model", "Depth", ["Small", "Base", "Large", "Small-TensorRT", "Base-TensorRT", "Large-TensorRT", "Small-DirectML", "Base-DirectML", "Large-DirectML"], "Choose which depth map model you want to utilize, ordered by speed, read more in INFO"); createDropdownField(panel1, "Encoder", "Encoder", ["X264", "X264_10Bit", "X264_Animation", "X264_Animation_10Bit", "X265", "X265_10Bit", "NVENC_H264", "NVENC_H265", "NVENC_H265_10Bit", "NVENC_AV1", "QSV_H264", "QSV_H265", "QSV_H265_10Bit", "H264_AMF", "HEVC_AMF", "HEVC_AMF_10Bit", "AV1"], "Choose which encoder you want to utilize, in no specific order, NVENC for NVidia GPUs, AMF for AMD GPUs and QSV for Intel iGPUs"); createDropdownField(panel1, "Resize Method", "Resize", ["Fast_Bilinear", "Bilinear", "Bicubic", "Experimental", "Neighbor", "Area", "Bicublin", "Gauss", "Sinc", "Lanczos", "Spline", "Spline16", "Spline36"], "Choose which resize method you want to utilize, For upscaling I would suggest Lanczos or Spline, for downscaling I would suggest Area or Bicubic"); diff --git a/gui.py b/gui.py index fd5da7b9..35ca84f1 100644 --- a/gui.py +++ b/gui.py @@ -40,7 +40,7 @@ ) logger = logging.getLogger(__name__) -TITLE = "The Anime Scripter - 1.8.3 (Alpha)" +TITLE = "The Anime Scripter - 1.8.5 (Alpha)" W, H = 1280, 720 if getattr(sys, "frozen", False): @@ -66,7 +66,6 @@ def __init__(self): self.createLayouts() self.createWidgets() - self.createDropdowns() self.settingsFile = os.path.join(os.getcwd(), "settings.json") loadSettings(self, self.settingsFile) @@ -80,43 +79,11 @@ def createLayouts(self): self.checkboxLayout = QVBoxLayout() self.outputLayout = QVBoxLayout() - def createDropdowns(self): - dropdowns = [ - ("Resize Method:", "Resize"), - ("Interpolate Method:", "Interpolation"), - ("Upscale Method:", "Upscaling"), - ("Denoise Method:", "Denoise"), - ("Dedup Method:", "Dedup"), - ("Depth Method:", "Depth"), - ("Encode Method:", "Encode"), - ] - - self.dropdowns = {} - for label, method in dropdowns: - dropdownLayout, dropdown = self.createLabeledDropdown( - label, dropdownsLabels(method) - ) - setattr(self, f"{method.lower()}MethodDropdown", dropdown) - self.dropdowns[method.lower()] = dropdownLayout - - checkboxes = [ - ("Keep Audio", "Enable or disable audio in the output file."), - ( - "Benchmark Mode", - "Benchmark mode will disable encoding and only monitor the performance of the script without the creation of an output file.", - ), - ] - - self.checkboxes = {} - for text, help_text in checkboxes: - checkbox = QCheckBox(text) - checkbox.setToolTip(help_text) - setattr(self, f"{text.replace(' ', '').lower()}Checkbox", checkbox) - self.checkboxes[text.replace(" ", "").lower()] = checkbox - def createWidgets(self): - self.checkboxInputLayout = QHBoxLayout() - + self.inputEntry = self.createPathWidgets("Input Path:", self.browseInput) + self.outputEntry = self.createPathWidgets("Output Path:", self.browseOutput) + + self.OptionLayout = QHBoxLayout() for option in [ "Resize", "Dedup", @@ -128,15 +95,16 @@ def createWidgets(self): "Depth", ]: self.createCheckbox(option) - + inputFields = [ ("Interpolate Factor:", 2, 100), ("Upscale Factor:", 2, 4), ("Resize Factor:", 1, 4), ] - + self.inputFieldsLayout = QVBoxLayout() - + self.inputFieldsLayout.setAlignment(Qt.AlignmentFlag.AlignTop) + for label, defaultValue, maxValue in inputFields: layout, entry = self.createInputField(label, defaultValue, maxValue) self.inputFieldsLayout.addLayout(layout) @@ -146,15 +114,11 @@ def createWidgets(self): self.interpolateFactorEntry = entry elif label == "Upscale Factor:": self.upscaleFactorEntry = entry - - self.checkboxInputLayout.addLayout(self.checkboxLayout) - self.checkboxInputLayout.addLayout(self.inputFieldsLayout) - - # Add settings to the options panel - mainSettings = QVBoxLayout() - mainSettings.setSpacing(10) - mainSettings.setAlignment(Qt.AlignmentFlag.AlignTop) - + + self.mainSettings = QVBoxLayout() + self.mainSettings.setSpacing(10) + self.mainSettings.setAlignment(Qt.AlignmentFlag.AlignTop) + dropdowns = [ ("Resize Method:", "Resize"), ("Interpolate Method:", "Interpolation"), @@ -164,26 +128,24 @@ def createWidgets(self): ("Depth Method:", "Depth"), ("Encode Method:", "Encode"), ] - + for label, method in dropdowns: dropdownLayout, dropdown = self.createLabeledDropdown( label, dropdownsLabels(method) ) setattr(self, f"{method.lower()}MethodDropdown", dropdown) - mainSettings.addLayout(dropdownLayout) - + self.mainSettings.addLayout(dropdownLayout) + self.encodeParamsLabel = QLabel() - mainSettings.addWidget(self.encodeParamsLabel) + self.mainSettings.addWidget(self.encodeParamsLabel) self.updateEncodeParamsLabel(self.encodeMethodDropdown.currentText()) self.encodeMethodDropdown.currentTextChanged.connect( self.updateEncodeParamsLabel ) - self.checkboxInputLayout.addLayout(mainSettings) - - extraSettings = QVBoxLayout() - extraSettings.setSpacing(10) - extraSettings.setAlignment(Qt.AlignmentFlag.AlignTop) - + + self.extraSettings = QVBoxLayout() + self.extraSettings.setAlignment(Qt.AlignmentFlag.AlignTop) + checkboxes = [ ( "Benchmark Mode", @@ -193,35 +155,41 @@ def createWidgets(self): "Scene Change Detection", "Enable or disable scene change detection, can impact performance but it will improve the quality of the output when interpolating.", ), + ( + "Rife Ensemble", + "Enable or disable RIFE ensemble, this can improve the quality of the interpolation at the cost of less performance.", + ), ] - + for text, help_text in checkboxes: checkbox = QCheckBox(text) checkbox.setToolTip(help_text) setattr(self, f"{text.replace(' ', '').lower()}Checkbox", checkbox) - extraSettings.addWidget(checkbox) - - self.checkboxInputLayout.addLayout(extraSettings) - - self.pathGroup = self.createGroup("Paths", self.pathLayout) - self.checkboxGroup = self.createGroup("Options", self.checkboxInputLayout) - self.outputGroup = self.createGroup("Log", self.outputLayout) - - self.inputEntry = self.createPathWidgets("Input Path:", self.browseInput) - self.outputEntry = self.createPathWidgets("Output Path:", self.browseOutput) - + self.extraSettings.addWidget(checkbox) + + self.OptionLayout.addLayout(self.checkboxLayout) + self.OptionLayout.addLayout(self.inputFieldsLayout) + self.OptionLayout.addLayout(self.mainSettings) + self.OptionLayout.addLayout(self.extraSettings) + self.OptionLayout.addStretch(1) + self.OptionLayout.setAlignment(Qt.AlignmentFlag.AlignTop) + + self.pathGroup = self.createGroup("Paths", self.pathLayout, 100) + self.checkboxGroup = self.createGroup("Options", self.OptionLayout) + self.outputGroup = self.createGroup("Log", self.outputLayout, 250) + self.outputWindow = QTextEdit() self.outputWindow.setReadOnly(True) self.outputLayout.addWidget(self.outputWindow) - + sys.stdout = StreamToTextEdit(self.outputWindow) sys.stderr = StreamToTextEdit(self.outputWindow) - + self.runButton = self.createButton("Run", self.runButtonOnClick) - + self.buttonLayout = QHBoxLayout() self.buttonLayout.addWidget(self.runButton) - + self.addWidgetsToLayout( self.layout, [self.pathGroup, self.checkboxGroup, self.outputGroup], 5 ) @@ -235,12 +203,13 @@ def createLabeledDropdown(self, label, options): dropdown.addItems(options) layout.addWidget(label) layout.addWidget(dropdown) - layout.addStretch(1) return layout, dropdown - def createGroup(self, title, layout): + def createGroup(self, title, layout, maxHeight=None): group = QGroupBox(title) group.setLayout(layout) + if maxHeight is not None: + group.setMaximumHeight(maxHeight) return group def runButtonOnClick(self): @@ -266,7 +235,7 @@ def createInputField(self, label, defaultValue, maxValue): entry = QLineEdit() entry.setText(str(defaultValue)) entry.setValidator(QIntValidator(0, maxValue)) - entry.setFixedWidth(30) + entry.setFixedWidth(50) entry.setAlignment(Qt.AlignmentFlag.AlignCenter) layout.addWidget(label) layout.addWidget(entry) @@ -275,6 +244,7 @@ def createInputField(self, label, defaultValue, maxValue): def createCheckbox(self, text): checkbox = QCheckBox(text) + self.checkboxLayout.setAlignment(Qt.AlignmentFlag.AlignTop) self.checkboxLayout.addWidget(checkbox) def createButton(self, text, slot): @@ -292,7 +262,7 @@ def browseInput(self): self, "Select Input File", "", - "Video Files (*.mp4 *.mkv *.mov *.avi);;All Files (*)", + "Video Files (*.mp4 *.mkv *.mov *.avi *.webm);;All Files (*)", ) if filePath: self.inputEntry.setText(filePath) diff --git a/main.py b/main.py index d0847c87..d188ef5c 100644 --- a/main.py +++ b/main.py @@ -39,7 +39,7 @@ else: mainPath = os.path.dirname(os.path.abspath(__file__)) -scriptVersion = "1.8.3" +scriptVersion = "1.8.5" warnings.filterwarnings("ignore") diff --git a/src/uiLogic.py b/src/uiLogic.py index 80d2e896..f1f4a846 100644 --- a/src/uiLogic.py +++ b/src/uiLogic.py @@ -3,6 +3,7 @@ import json import threading import logging +import time from PyQt6.QtWidgets import QCheckBox, QGraphicsOpacityEffect from PyQt6.QtCore import QPropertyAnimation, QEasingCurve @@ -93,7 +94,10 @@ def runCommand(self, mainPath, settingsFile) -> None: for option in loadSettingsFile: loweredOption = option.lower() - loweredOptionValue = str(loadSettingsFile[option]).lower() + + loweredOptionValue = str(loadSettingsFile[option]) + if "http" not in loweredOptionValue: + loweredOptionValue = loweredOptionValue.lower() if loweredOptionValue == "false": continue @@ -111,32 +115,10 @@ def runCommand(self, mainPath, settingsFile) -> None: command = " ".join(command) print(command) - def runSubprocess(command): - try: - process = subprocess.Popen( - command, - shell=True, - stdout=subprocess.PIPE, # Change this - stderr=subprocess.STDOUT, # And this - bufsize=1, - universal_newlines=True, - ) + def runCommandInTerminal(command): + os.system(f'start cmd /c "{command} & exit"') - def stream_output(): - for line in iter(process.stdout.readline, ''): - self.outputWindow.append(line.strip()) - process.stdout.close() - - threading.Thread(target=stream_output).start() - process.wait() - - except Exception as e: - self.outputWindow.append( - f"An error occurred while running the command, {e}" - ) - logging.error(f"An error occurred while running, {e}") - - threading.Thread(target=runSubprocess, args=(command,)).start() + threading.Thread(target=runCommandInTerminal, args=(command,), daemon=True).start() except Exception as e: @@ -193,6 +175,7 @@ def saveSettings(self, settingsFile): "resize_method": self.resizeMethodDropdown.currentText(), "benchmark": self.benchmarkmodeCheckbox.isChecked(), "scenechange": self.scenechangedetectionCheckbox.isChecked(), + "ensemble": self.rifeensembleCheckbox.isChecked(), } for i in range(self.checkboxLayout.count()): checkbox = self.checkboxLayout.itemAt(i).widget() @@ -204,7 +187,6 @@ def saveSettings(self, settingsFile): except Exception as e: self.outputWindow.append(f"An error occurred while saving settings, {e}") - def fadeIn(self, widget, duration=500): opacity_effect = QGraphicsOpacityEffect(widget) widget.setGraphicsEffect(opacity_effect) @@ -223,6 +205,9 @@ def dropdownsLabels(method): "ShuffleCugan", "Cugan", "Span", + "Compact", + "UltraCompact", + "SuperUltraCompact", "ShuffleCugan-TensorRT", "Span-TensorRT", "Compact-TensorRT", @@ -230,12 +215,16 @@ def dropdownsLabels(method): "SuperUltraCompact-TensorRT", "Cugan-DirectML", "Span-DirectML", + "Compact-DirectML", + "UltraCompact-DirectML", + "SuperUltraCompact-DirectML", "ShuffleCugan-NCNN", "Span-NCNN", ] case "Interpolation": return [ "Rife4.17", + "Rife4.17-Lite", "Rife4.16-Lite", "Rife4.15-Lite", "Rife4.15", @@ -253,7 +242,7 @@ def dropdownsLabels(method): case "Denoise": return ["DPIR", "SCUNet", "NAFNet", "Span"] case "Dedup": - return ["SSIM", "FFMPEG", "MSE", "SSIM-CUDA"] + return ["SSIM", "MSE", "SSIM-CUDA"] case "Depth": return ["Small", "Base", "Large", "Small-TensorRT", "Base-TensorRT", "Large-TensorRT", "Small-DirectML", "Base-DirectML", "Large-DirectML"] case "Encode":