41 Commits

Author SHA1 Message Date
k4yt3x
5db2cfd2a3 added anime4k instructions 2020-01-12 03:32:25 -05:00
k4yt3x
652b9f34bd fixing #180 bug2 attempt 2 2020-01-04 17:03:16 -05:00
k4yt3x
f3c50ea728 fixing #180 bug2 2020-01-04 16:59:51 -05:00
k4yt3x
880087241d updated waifu2x-ncnn-vulkan path key for new config structure 2020-01-04 16:56:08 -05:00
k4yt3x
067e17290a 1.6.1 changed driver paths to 3.0.0 config style 2020-01-04 16:49:13 -05:00
k4yt3x
fc675e7899 updated copyright date 2020-01-04 16:48:37 -05:00
K4YT3X
2d81270e44 Set theme jekyll-theme-slate 2019-12-22 06:00:02 +00:00
K4YT3X
3ace2447c2 Create CNAME 2019-12-22 05:48:39 +00:00
K4YT3X
30b0e2c7bf Delete CNAME 2019-12-22 05:48:25 +00:00
k4yt3x
d54fea0310 enables available memory warning for Linux platform 2019-12-19 23:03:58 -05:00
k4yt3x
332055a4e5 fixed temp directory cleaning problem on exit 2019-12-11 22:20:01 -05:00
k4yt3x
19e17b1a8f updated platform information 2019-12-11 21:59:38 -05:00
k4yt3x
9e745fb747 video2x_gui 1.1.3: fixed driver path key name 2019-12-11 21:59:20 -05:00
K4YT3X
fd5edead7e Merge pull request #171 from YOUSIKI/master
Check platform correctly
2019-11-30 19:56:08 +00:00
YOUSIKI
aa7c0b3f12 Check platform correctly
Continue if running on win32.
Exit if running on other platforms.
2019-11-30 22:56:34 +08:00
k4yt3x
65cc4c6afb Merge branch '3.0.0' 2019-11-26 04:14:13 -05:00
k4yt3x
bd2da021bd updated README for 3.0.0 2019-11-26 04:12:04 -05:00
k4yt3x
7e888db7b2 formatted YAML file 2019-11-26 04:10:01 -05:00
k4yt3x
7726a86e35 added platform check, made PermissionError more obvious 2019-11-26 04:03:03 -05:00
K4YT3X
a0595136ab Create CNAME 2019-11-18 06:43:00 +00:00
K4YT3X
5c93a5a73b Delete CNAME 2019-11-18 06:42:54 +00:00
K4YT3X
7b9b87fa9b Create CNAME 2019-11-17 05:41:13 +00:00
k4yt3x
cb255da65c added missing sys library import 2019-11-16 02:54:25 -05:00
k4yt3x
d503325a62 changed YAML load to FullLoader to make it WIndows-compatible 2019-11-16 02:52:33 -05:00
k4yt3x
954233c238 changed default config path from JSON to YAML 2019-11-16 01:51:01 -05:00
k4yt3x
95416f68a8 make the GUI script YAML-compatible 2019-11-16 01:50:41 -05:00
k4yt3x
dce778b3bf 1.1.2 fixed repeated output file extensions 2019-11-15 22:40:48 -05:00
k4yt3x
c537dd726c changed YAML loader to Windows compatible FullLoader 2019-11-15 22:40:19 -05:00
k4yt3x
b1918a4a8a fixed pixel_formats print bug and subprocess execution bug 2019-11-15 02:39:27 -05:00
k4yt3x
7ae9618785 updated file modification date 2019-11-15 02:38:39 -05:00
k4yt3x
eb3d29103c fixed anime4k path key 2019-11-15 02:38:11 -05:00
k4yt3x
a188f6ebda 1.6.0 added support for YAML, better exception handling 2019-11-15 02:04:12 -05:00
k4yt3x
fd67dfca11 docstring modifications, added JDK warning 2019-11-15 02:03:44 -05:00
k4yt3x
b1f29f1098 fixed NCNN Vulkan driver argument error 2019-11-15 01:09:55 -05:00
k4yt3x
fe7c0c840d fixed type error for waifu2x-ncnn-vulkan argument 2019-10-24 21:33:05 -04:00
k4yt3x
dc2410d4da renaming variables, using YAML to replace JSON 2019-10-19 21:53:12 -04:00
k4yt3x
91ac512d57 remove .exe extension for Linux compatibility 2019-10-19 21:52:31 -04:00
k4yt3x
732288f075 renamed waifu2x_settings to driver_settings 2019-10-19 21:52:11 -04:00
k4yt3x
e812c228c3 updated file permissions 2019-10-19 21:51:18 -04:00
k4yt3x
9841fa9577 converted JSON config into YAML 2019-10-19 21:45:44 -04:00
k4yt3x
5391f59847 renamed bin to src since python isn't binary 2019-10-19 21:40:00 -04:00
17 changed files with 438 additions and 260 deletions

1
CNAME Normal file
View File

@@ -0,0 +1 @@
video2x.org

View File

@@ -2,7 +2,7 @@
### Official Discussion Group (Telegram): https://t.me/video2x
## Download Builds
## Download Builds (Windows)
You can go to the [releases page](https://github.com/k4yt3x/video2x/releases) to download the latest builds of `Video2X`. The exe files will require no Python or Python module installation.
@@ -14,7 +14,7 @@ The **`light`** package provides only the most basic functions of `Video2X`. Onl
Component names that are **bolded** can be automatically downloaded and configured with the `video2x_setup.py` script.
1. Operating System: Windows
1. Operating System: Windows / Linux
2. AMD GPU / Nvidia GPU
3. AMD GPU driver / Nvidia GPU driver / Nvidia CUDNN
4. [**FFmpeg**](https://ffmpeg.zeranoe.com/builds/)
@@ -26,6 +26,13 @@ Component names that are **bolded** can be automatically downloaded and configur
## Recent Changes
### 3.0.0 (November 26, 2019)
- Linux compatibility
- Configuration file changed to YAML format
- You may still use a JSON-formatted config file. To do so, please specify `-c video2x.json`.
- Other code clean-up and optimization
### 2.10.0 (August 16, 2019)
- **Added support for [Anime4K](https://github.com/bloc97/Anime4K)**
@@ -36,18 +43,10 @@ Component names that are **bolded** can be automatically downloaded and configur
- Removed f_string dependency and support for legacy versions of Python
- Organized file import statements
### 2.8.1 (July 9, 2019)
### Setup Script 1.6.0 (November 26, 2019)
- Added automatic pixel format detection
- Added automatic color bit depth detection
### 2.8.0 (June 25, 2019)
- **Added support for [waifu2x-ncnn-vulkan](https://github.com/nihui/waifu2x-ncnn-vulkan)**
### Setup Script 1.5.0 (August 16, 2019)
- Added automatic installation support for `Anime4K`
- Added compatibility for new YAML configuration file
- Added better exception handling
## Description
@@ -176,6 +175,14 @@ python video2x.py -i sample_input.mp4 -o sample_output.mp4 -m gpu -r 2 -d waifu2
python video2x.py -i sample_input.mp4 -o sample_output.mp4 -m gpu -r 2 -d waifu2x_ncnn_vulkan
```
### Anime4K
Enlarge the video by 2 times using Anime4K. **Remember to install and configure [JRE 12](https://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase12-5440181.html) path in the configuration file.**
```shell
python video2x.py -i sample_input.mp4 -o sample_output.mp4 -r 2 -d anime4k
```
### CPU
Enlarge the video to 1920x1080 using the CPU. You may also use the `-r/--ratio` option. **waifu2x-based upscalers potentially run much slower than using a GPU, but Anime4K is more CPU-dependant**. The configuration file for this method is similar to the previous methods.
@@ -241,7 +248,7 @@ https://www.gnu.org/licenses/gpl-3.0.txt
![GPLv3 Icon](https://www.gnu.org/graphics/gplv3-127x51.png)
(C) 2018-2019 K4YT3X
(C) 2018-2020 K4YT3X
## Credits

1
_config.yml Normal file
View File

@@ -0,0 +1 @@
theme: jekyll-theme-slate

10
bin/anime4k.py → src/anime4k.py Normal file → Executable file
View File

@@ -4,7 +4,7 @@
Name: Anime4K Driver
Author: K4YT3X
Date Created: August 15, 2019
Last Modified: August 15, 2019
Last Modified: November 15, 2019
Description: This class is a high-level wrapper
for Anime4k.
@@ -27,8 +27,8 @@ class Anime4k:
the upscale function.
"""
def __init__(self, waifu2x_settings):
self.waifu2x_settings = waifu2x_settings
def __init__(self, driver_settings):
self.driver_settings = driver_settings
self.print_lock = threading.Lock()
def upscale(self, input_directory, output_directory, scale_ratio, upscaler_exceptions, push_strength=None, push_grad_strength=None):
@@ -57,9 +57,9 @@ class Anime4k:
for image in extracted_frame_files:
execute = [
self.waifu2x_settings['java_path'],
self.driver_settings['java_path'],
'-jar',
self.waifu2x_settings['anime4k_path'],
self.driver_settings['path'],
str(image.absolute()),
str(output_directory / image.name),
str(scale_ratio)

0
bin/exceptions.py → src/exceptions.py Normal file → Executable file
View File

10
bin/ffmpeg.py → src/ffmpeg.py Normal file → Executable file
View File

@@ -4,7 +4,7 @@
Name: Video2X FFmpeg Controller
Author: K4YT3X
Date Created: Feb 24, 2018
Last Modified: August 15, 2019
Last Modified: November 15, 2019
Description: This class handles all FFmpeg related operations.
"""
@@ -30,8 +30,8 @@ class Ffmpeg:
self.ffmpeg_settings = ffmpeg_settings
self.ffmpeg_path = pathlib.Path(self.ffmpeg_settings['ffmpeg_path'])
self.ffmpeg_binary = self.ffmpeg_path / 'ffmpeg.exe'
self.ffmpeg_probe_binary = self.ffmpeg_path / 'ffprobe.exe'
self.ffmpeg_binary = self.ffmpeg_path / 'ffmpeg'
self.ffmpeg_probe_binary = self.ffmpeg_path / 'ffprobe'
self.image_format = image_format
self.pixel_format = None
@@ -67,7 +67,7 @@ class Ffmpeg:
pass
# print pixel formats for debugging
Avalon.debug_info(pixel_formats)
Avalon.debug_info(str(pixel_formats))
return pixel_formats
@@ -284,4 +284,4 @@ class Ffmpeg:
Avalon.debug_info(f'Executing: {execute}')
return subprocess.run(execute, shell=True, check=True).returncode
return subprocess.run(execute, check=True).returncode

0
bin/image_cleaner.py → src/image_cleaner.py Normal file → Executable file
View File

View File

@@ -2,5 +2,6 @@ avalon_framework
colorama
GPUtil
psutil
pyyaml
requests
tqdm

16
bin/upscaler.py → src/upscaler.py Normal file → Executable file
View File

@@ -4,7 +4,7 @@
Name: Video2X Upscaler
Author: K4YT3X
Date Created: December 10, 2018
Last Modified: August 21, 2019
Last Modified: December 11, 2019
Dev: SAT3LL
@@ -51,12 +51,12 @@ class Upscaler:
ArgumentError -- if argument is not valid
"""
def __init__(self, input_video, output_video, method, waifu2x_settings, ffmpeg_settings):
def __init__(self, input_video, output_video, method, driver_settings, ffmpeg_settings):
# mandatory arguments
self.input_video = input_video
self.output_video = output_video
self.method = method
self.waifu2x_settings = waifu2x_settings
self.driver_settings = driver_settings
self.ffmpeg_settings = ffmpeg_settings
# optional arguments
@@ -82,7 +82,7 @@ class Upscaler:
"""delete temp directories when done
"""
if not self.preserve_frames:
for directory in [self.extracted_frames, self.upscaled_frames]:
for directory in [self.extracted_frames, self.upscaled_frames, self.video2x_cache_directory]:
try:
# avalon framework cannot be used if python is shutting down
# therefore, plain print is used
@@ -165,7 +165,7 @@ class Upscaler:
# it's easier to do multi-threading with waifu2x_converter
# the number of threads can be passed directly to waifu2x_converter
if self.waifu2x_driver == 'waifu2x_converter':
w2 = Waifu2xConverter(self.waifu2x_settings, self.model_dir)
w2 = Waifu2xConverter(self.driver_settings, self.model_dir)
progress_bar = threading.Thread(target=self._progress_bar, args=([self.extracted_frames],))
progress_bar.start()
@@ -222,7 +222,7 @@ class Upscaler:
# create a separate w2 instance for each thread
if self.waifu2x_driver == 'waifu2x_caffe':
w2 = Waifu2xCaffe(copy.deepcopy(self.waifu2x_settings), self.method, self.model_dir, self.bit_depth)
w2 = Waifu2xCaffe(copy.deepcopy(self.driver_settings), self.method, self.model_dir, self.bit_depth)
if self.scale_ratio:
thread = threading.Thread(target=w2.upscale,
args=(thread_info[0],
@@ -244,7 +244,7 @@ class Upscaler:
# if the driver being used is waifu2x_ncnn_vulkan
elif self.waifu2x_driver == 'waifu2x_ncnn_vulkan':
w2 = Waifu2xNcnnVulkan(copy.deepcopy(self.waifu2x_settings))
w2 = Waifu2xNcnnVulkan(copy.deepcopy(self.driver_settings))
thread = threading.Thread(target=w2.upscale,
args=(thread_info[0],
self.upscaled_frames,
@@ -253,7 +253,7 @@ class Upscaler:
# if the driver being used is anime4k
elif self.waifu2x_driver == 'anime4k':
w2 = Anime4k(copy.deepcopy(self.waifu2x_settings))
w2 = Anime4k(copy.deepcopy(self.driver_settings))
thread = threading.Thread(target=w2.upscale,
args=(thread_info[0],
self.upscaled_frames,

103
bin/video2x.py → src/video2x.py Normal file → Executable file
View File

@@ -11,17 +11,17 @@ __ __ _ _ ___ __ __
Name: Video2X Controller
Author: K4YT3X
Creator: K4YT3X
Date Created: Feb 24, 2018
Last Modified: August 29, 2019
Last Modified: January 4, 2020
Dev: BrianPetkovsek
Dev: SAT3LL
Editor: BrianPetkovsek
Editor: SAT3LL
Licensed under the GNU General Public License Version 3 (GNU GPL v3),
available at: https://www.gnu.org/licenses/gpl-3.0.txt
(C) 2018-2019 K4YT3X
(C) 2018 - 2020 K4YT3X
Video2X is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -50,7 +50,6 @@ from upscaler import Upscaler
# built-in imports
import argparse
import contextlib
import json
import pathlib
import re
import shutil
@@ -58,13 +57,15 @@ import sys
import tempfile
import time
import traceback
import yaml
# third-party imports
from avalon_framework import Avalon
import GPUtil
import psutil
VERSION = '2.10.0'
VERSION = '3.0.0'
LEGAL_INFO = f'''Video2X Version: {VERSION}
Author: K4YT3X
@@ -87,7 +88,7 @@ SYS_MEM_PER_THREAD = 2.5
GPU_MEM_PER_THREAD = 3.5
def process_arguments():
def parse_arguments():
"""Processes CLI arguments
This function parses all arguments
@@ -107,7 +108,7 @@ def process_arguments():
upscaler_options.add_argument('-d', '--driver', help='upscaling driver', action='store', default='waifu2x_caffe', choices=AVAILABLE_DRIVERS)
upscaler_options.add_argument('-y', '--model_dir', type=pathlib.Path, help='directory containing model JSON files', action='store')
upscaler_options.add_argument('-t', '--threads', help='number of threads to use for upscaling', action='store', type=int, default=1)
upscaler_options.add_argument('-c', '--config', type=pathlib.Path, help='video2x config file location', action='store', default=pathlib.Path(sys.argv[0]).parent.absolute() / 'video2x.json')
upscaler_options.add_argument('-c', '--config', type=pathlib.Path, help='video2x config file location', action='store', default=pathlib.Path(sys.argv[0]).parent.absolute() / 'video2x.yaml')
upscaler_options.add_argument('-b', '--batch', help='enable batch mode (select all default values to questions)', action='store_true')
# scaling options
@@ -144,7 +145,7 @@ def check_memory():
# check if Nvidia-smi is available
# GPUtil requires nvidia-smi.exe to interact with GPU
if args.method == 'gpu' or args.method == 'cudnn':
if args.method in ['gpu', 'cudnn']:
if not (shutil.which('nvidia-smi') or
pathlib.Path(r'C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe').is_file()):
# Nvidia System Management Interface not available
@@ -186,14 +187,18 @@ def check_memory():
Avalon.warning('Proceed with caution')
def read_config(config_file):
""" Reads configuration file
def read_config(config_file: pathlib.Path) -> dict:
""" read video2x configurations from config file
Returns a dictionary read by JSON.
Arguments:
config_file {pathlib.Path} -- video2x configuration file pathlib.Path
Returns:
dict -- dictionary of video2x configuration
"""
with open(config_file, 'r') as raw_config:
config = json.load(raw_config)
return config
with open(config_file, 'r') as config:
return yaml.load(config, Loader=yaml.FullLoader)
def absolutify_paths(config):
@@ -248,13 +253,13 @@ if __name__ != '__main__':
# print video2x logo
print_logo()
# process CLI arguments
args = process_arguments()
# parse command line arguments
args = parse_arguments()
# display version and lawful informaition
if args.version:
print(LEGAL_INFO)
exit(0)
sys.exit(0)
# arguments sanity check
if not args.input:
@@ -266,7 +271,7 @@ if not args.output:
if (args.driver in ['waifu2x_converter', 'waifu2x_ncnn_vulkan', 'anime4k']) and args.width and args.height:
Avalon.error('Selected driver accepts only scaling ratio')
raise ArgumentError('selected driver supports only scaling ratio')
if args.driver == 'waifu2x_ncnn_vulkan' and (args.ratio > 2 or not args.ratio.is_integer()):
if args.driver == 'waifu2x_ncnn_vulkan' and args.ratio is not None and (args.ratio > 2 or not args.ratio.is_integer()):
Avalon.error('Scaling ratio must be 1 or 2 for waifu2x_ncnn_vulkan')
raise ArgumentError('scaling ratio must be 1 or 2 for waifu2x_ncnn_vulkan')
if (args.width or args.height) and args.ratio:
@@ -283,48 +288,38 @@ if args.driver in ['waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan']:
# anime4k runs significantly faster with more threads
if args.driver == 'anime4k' and args.threads <= 1:
Avalon.warning('Anime4K runs significantly faster with more threads')
if Avalon.ask('Use more threads of Anime4K?', True):
if Avalon.ask('Use more threads of Anime4K?', default=True, batch=args.batch):
while True:
try:
threads = Avalon.gets('Amount of threads to use [5]: ')
threads = Avalon.gets('Amount of threads to use [5]: ', default=5, batch=args.batch)
args.threads = int(threads)
break
except ValueError:
if threads == '':
args.threads = 5
break
else:
Avalon.error(f'{threads} is not a valid integer')
Avalon.error(f'{threads} is not a valid integer')
# read configurations from JSON
# read configurations from configuration file
config = read_config(args.config)
config = absolutify_paths(config)
# config = absolutify_paths(config)
# load waifu2x configuration
if args.driver == 'waifu2x_caffe':
waifu2x_settings = config['waifu2x_caffe']
if not pathlib.Path(waifu2x_settings['waifu2x_caffe_path']).is_file():
Avalon.error('Specified waifu2x-caffe directory doesn\'t exist')
driver_settings = config[args.driver]
# check if driver path exists
if not pathlib.Path(driver_settings['path']).is_file():
if not pathlib.Path(f'{driver_settings["path"]}.exe').is_file():
Avalon.error('Specified driver executable directory doesn\'t exist')
Avalon.error('Please check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['waifu2x_caffe_path'])
elif args.driver == 'waifu2x_converter':
waifu2x_settings = config['waifu2x_converter']
if not pathlib.Path(waifu2x_settings['waifu2x_converter_path']).is_dir():
Avalon.error('Specified waifu2x-converter-cpp directory doesn\'t exist')
Avalon.error('Please check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['waifu2x_converter_path'])
elif args.driver == 'waifu2x_ncnn_vulkan':
waifu2x_settings = config['waifu2x_ncnn_vulkan']
if not pathlib.Path(waifu2x_settings['waifu2x_ncnn_vulkan_path']).is_file():
Avalon.error('Specified waifu2x_ncnn_vulkan directory doesn\'t exist')
Avalon.error('Please check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['waifu2x_ncnn_vulkan_path'])
elif args.driver == 'anime4k':
waifu2x_settings = config['anime4k']
if not pathlib.Path(waifu2x_settings['anime4k_path']).is_file():
Avalon.error('Specified anime4k directory doesn\'t exist')
Avalon.error('Please check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['anime4k_path'])
raise FileNotFoundError(driver_settings['path'])
# if the driver is Anime4K, check if JDK 12 is installed
if args.driver == 'anime4k':
if not pathlib.Path('C:/Program Files/Java/jdk-12.0.2/bin/java.exe').is_file():
Avalon.warning('Cannot find JDK 12 at its default installation location')
Avalon.warning('Please ensure you have JDK 12 installed and configured')
# read FFmpeg configuration
ffmpeg_settings = config['ffmpeg']
@@ -385,7 +380,7 @@ try:
Avalon.error('Suffix must be specified for FFmpeg')
raise Exception('No suffix specified')
upscaler = Upscaler(input_video=args.input, output_video=args.output, method=args.method, waifu2x_settings=waifu2x_settings, ffmpeg_settings=ffmpeg_settings)
upscaler = Upscaler(input_video=args.input, output_video=args.output, method=args.method, driver_settings=driver_settings, ffmpeg_settings=ffmpeg_settings)
# set optional options
upscaler.waifu2x_driver = args.driver
@@ -413,7 +408,7 @@ try:
for input_video in [f for f in args.input.iterdir() if f.is_file()]:
output_video = args.output / input_video.name
upscaler = Upscaler(input_video=input_video, output_video=output_video, method=args.method, waifu2x_settings=waifu2x_settings, ffmpeg_settings=ffmpeg_settings)
upscaler = Upscaler(input_video=input_video, output_video=output_video, method=args.method, driver_settings=driver_settings, ffmpeg_settings=ffmpeg_settings)
# set optional options
upscaler.waifu2x_driver = args.driver
@@ -435,9 +430,15 @@ try:
raise FileNotFoundError(f'{args.input} is neither file nor directory')
Avalon.info(f'Program completed, taking {round((time.time() - begin_time), 5)} seconds')
except Exception:
Avalon.error('An exception has occurred')
traceback.print_exc()
# try cleaning up temp directories
with contextlib.suppress(Exception):
upscaler.cleanup_temp_directories()
finally:
# remove Video2X cache directory
with contextlib.suppress(FileNotFoundError):

89
src/video2x.yaml Normal file
View File

@@ -0,0 +1,89 @@
---
waifu2x_caffe:
path: C:\Users\K4YT3X\AppData\Local\video2x\waifu2x-caffe\waifu2x-caffe-cui
input_extention_list:
output_extention:
mode: noise_scale
scale_ratio:
scale_width:
scale_height:
noise_level: 3
process: gpu
crop_size: 128
output_quality: -1
output_depth: 8
batch_size: 1
gpu: 0
tta: 0
input_path:
output_path:
model_dir:
crop_w:
crop_h:
waifu2x_converter:
path: C:\Users\K4YT3X\AppData\Local\video2x\waifu2x-converter-cpp
output-format:
png-compression:
image-quality:
block-size:
disable-gpu:
force-OpenCL:
processor:
jobs:
model-dir:
scale-ratio:
noise-level: 3
mode: noise-scale
silent: true
output:
input:
waifu2x_ncnn_vulkan:
path: C:\Users\K4YT3X\AppData\Local\video2x\waifu2x-ncnn-vulkan\waifu2x-ncnn-vulkan
v:
i:
o:
n: 2
s: 2
t: 400
m: models-cunet
g: 0
j: "1:2:2"
anime4k:
path: C:\Users\K4YT3X\AppData\Local\video2x\anime4k\Anime4K.jar
java_path: C:\Program Files\Java\jdk-12.0.2\bin\java.exe
ffmpeg:
ffmpeg_path: C:\Users\K4YT3X\AppData\Local\video2x\ffmpeg-latest-win64-static\bin
video_to_frames:
output_options:
"-qscale:v":
"-pix_fmt": rgba64be
"-hwaccel": auto
"-y": true
frames_to_video:
input_options:
"-qscale:v":
"-qscale:a":
"-f": image2
output_options:
"-vcodec": libx264
"-crf": 17
"-b:v":
"-pix_fmt":
"-hwaccel": auto
"-y": true
migrating_tracks:
output_options:
"-map":
- 0:v?
- 1:a?
- 1:s?
- 1:d?
- 1:t?
"-c": copy
"-pix_fmt":
"-hwaccel": auto
"-y": true
video2x:
video2x_cache_directory:
image_format: png
preserve_frames: false

252
bin/video2x_gui.py → src/video2x_gui.py Normal file → Executable file
View File

@@ -1,12 +1,12 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Name: Video2x GUI
Creator: Video2X GUI
Author: K4YT3X
Date Created: July 27, 2019
Last Modified: August 17, 2019
Last Modified: December 11, 2019
Description: GUI for Video2X
Description: A simple GUI for Video2X made with tkinter.
"""
# local imports
@@ -18,13 +18,17 @@ from tkinter import *
from tkinter import messagebox
from tkinter import ttk
from tkinter.filedialog import *
import json
import contextlib
import pathlib
import sys
import tempfile
import threading
import time
import yaml
VERSION = '1.1.1'
VERSION = '1.1.3'
VIDEO2X_CONFIG = pathlib.Path(sys.argv[0]).parent.absolute() / 'video2x.yaml'
LEGAL_INFO = f'''Video2X GUI Version: {VERSION}
Author: K4YT3X
@@ -48,6 +52,46 @@ AVAILABLE_DRIVERS = {
IMAGE_FORMATS = {'PNG', 'JPG'}
DEMUXER_EXTENSIONS = {'3dostr', '4xm', 'aa', 'aac', 'ac3', 'acm', 'act',
'adf', 'adp', 'ads', 'adx', 'aea', 'afc', 'aiff', 'aix', 'alaw',
'alias_pix', 'alsa', 'amr', 'amrnb', 'amrwb', 'anm', 'apc', 'ape',
'apng', 'aptx', 'aptx_hd', 'aqtitle', 'asf', 'asf_o', 'ass', 'ast',
'au', 'avi', 'avisynth', 'avr', 'avs', 'avs2', 'bethsoftvid', 'bfi',
'bfstm', 'bin', 'bink', 'bit', 'bmp_pipe', 'bmv', 'boa', 'brender_pix',
'brstm', 'c93', 'caf', 'cavsvideo', 'cdg', 'cdxl', 'cine', 'codec2',
'codec2raw', 'concat', 'dash', 'data', 'daud', 'dcstr', 'dds_pipe',
'dfa', 'dirac', 'dnxhd', 'dpx_pipe', 'dsf', 'dsicin', 'dss', 'dts',
'dtshd', 'dv', 'dvbsub', 'dvbtxt', 'dxa', 'ea', 'ea_cdata', 'eac3',
'epaf', 'exr_pipe', 'f32be', 'f32le', 'f64be', 'f64le', 'fbdev',
'ffmetadata', 'film_cpk', 'filmstrip', 'fits', 'flac', 'flic', 'flv',
'frm', 'fsb', 'g722', 'g723_1', 'g726', 'g726le', 'g729', 'gdv', 'genh',
'gif', 'gsm', 'gxf', 'h261', 'h263', 'h264', 'hevc', 'hls', 'applehttp',
'hnm', 'ico', 'idcin', 'idf', 'iec61883', 'iff', 'ilbc', 'image2',
'image2pipe', 'ingenient', 'ipmovie', 'ircam', 'iss', 'iv8', 'ivf',
'ivr', 'j2k_pipe', 'jack', 'jacosub', 'jpeg_pipe', 'jpegls_pipe',
'jv', 'kmsgrab', 'lavfi', 'libcdio', 'libdc1394', 'libgme', 'libopenmpt',
'live_flv', 'lmlm4', 'loas', 'lrc', 'lvf', 'lxf', 'm4v', 'matroska', 'webm',
'mgsts', 'microdvd', 'mjpeg', 'mjpeg_2000', 'mlp', 'mlv', 'mm', 'mmf',
'mov', 'mp4', 'm4a', '3gp', '3g2', 'mj2', 'mp3', 'mpc', 'mpc8', 'mpeg',
'mpegts', 'mpegtsraw', 'mpegvideo', 'mpjpeg', 'mpl2', 'mpsub', 'msf',
'msnwctcp', 'mtaf', 'mtv', 'mulaw', 'musx', 'mv', 'mvi', 'mxf', 'mxg',
'nc', 'nistsphere', 'nsp', 'nsv', 'nut', 'nuv', 'ogg', 'oma', 'openal',
'oss', 'paf', 'pam_pipe', 'pbm_pipe', 'pcx_pipe', 'pgm_pipe', 'pgmyuv_pipe',
'pictor_pipe', 'pjs', 'pmp', 'png_pipe', 'ppm_pipe', 'psd_pipe', 'psxstr',
'pulse', 'pva', 'pvf', 'qcp', 'qdraw_pipe', 'r3d', 'rawvideo', 'realtext',
'redspark', 'rl2', 'rm', 'roq', 'rpl', 'rsd', 'rso', 'rtp', 'rtsp',
's16be', 's16le', 's24be', 's24le', 's32be', 's32le', 's337m', 's8',
'sami', 'sap', 'sbc', 'sbg', 'scc', 'sdp', 'sdr2', 'sds', 'sdx', 'ser',
'sgi_pipe', 'shn', 'siff', 'sln', 'smjpeg', 'smk', 'smush', 'sndio',
'sol', 'sox', 'spdif', 'srt', 'stl', 'subviewer', 'subviewer1', 'sunrast_pipe',
'sup', 'svag', 'svg_pipe', 'swf', 'tak', 'tedcaptions', 'thp', 'tiertexseq',
'tiff_pipe', 'tmv', 'truehd', 'tta', 'tty', 'txd', 'ty', 'u16be', 'u16le',
'u24be', 'u24le', 'u32be', 'u32le', 'u8', 'v210', 'v210x', 'vag', 'vc1',
'vc1test', 'vidc', 'video4linux2', 'v4l2', 'vivo', 'vmd', 'vobsub', 'voc',
'vpk', 'vplayer', 'vqf', 'w64', 'wav', 'wc3movie', 'webm_dash_manifest',
'webp_pipe', 'webvtt', 'wsaud', 'wsd', 'wsvqa', 'wtv', 'wv', 'wve', 'x11grab',
'xa', 'xbin', 'xmv', 'xpm_pipe', 'xvag', 'xwd_pipe', 'xwma', 'yop', 'yuv4mpegpipe'}
class Video2xGui():
@@ -161,7 +205,7 @@ class Video2xGui():
# preserve frames
self.preserve_frames = BooleanVar(self.options_left)
self.preserve_frames.set(True)
self.preserve_frames.set(False)
Label(self.options_right, text='Preserve Frames', relief=RIDGE, width=15).grid(row=3, column=0, padx=2, pady=3)
preserve_frames_menu = OptionMenu(self.options_right, self.preserve_frames, *{True, False})
preserve_frames_menu.grid(row=3, column=1, padx=2, pady=3, sticky=W)
@@ -224,108 +268,104 @@ class Video2xGui():
def _upscale(self):
# start timer
begin_time = time.time()
try:
# start timer
begin_time = time.time()
# read configuration file
config = read_config('video2x.json')
config = absolutify_paths(config)
# read configuration file
config = read_config(VIDEO2X_CONFIG)
config = absolutify_paths(config)
input_file = pathlib.Path(self.input_file.get())
output_file = pathlib.Path(self.output_file.get())
driver = AVAILABLE_DRIVERS[self.driver.get()]
input_file = pathlib.Path(self.input_file.get())
output_file = pathlib.Path(self.output_file.get())
driver = AVAILABLE_DRIVERS[self.driver.get()]
if driver == 'waifu2x_caffe':
waifu2x_settings = config['waifu2x_caffe']
if not pathlib.Path(waifu2x_settings['waifu2x_caffe_path']).is_file():
messagebox.showerror('Error', 'Specified waifu2x-caffe directory doesn\'t exist\nPlease check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['waifu2x_caffe_path'])
elif driver == 'waifu2x_converter':
waifu2x_settings = config['waifu2x_converter']
if not pathlib.Path(waifu2x_settings['waifu2x_converter_path']).is_dir():
messagebox.showerror('Error', 'Specified waifu2x-converter-cpp directory doesn\'t exist\nPlease check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['waifu2x_converter_path'])
elif driver == 'waifu2x_ncnn_vulkan':
waifu2x_settings = config['waifu2x_ncnn_vulkan']
if not pathlib.Path(waifu2x_settings['waifu2x_ncnn_vulkan_path']).is_file():
messagebox.showerror('Error', 'Specified waifu2x_ncnn_vulkan directory doesn\'t exist\nPlease check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['waifu2x_ncnn_vulkan_path'])
elif driver == 'anime4k':
waifu2x_settings = config['anime4k']
if not pathlib.Path(waifu2x_settings['anime4k_path']).is_file():
messagebox.showerror('Error', 'Specified Anime4K directory doesn\'t exist\nPlease check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['anime4k_path'])
# load specified driver's config into driver_settings
driver_settings = config[driver]
# read FFmpeg configuration
ffmpeg_settings = config['ffmpeg']
# if executable doesn't exist, show warning
if not pathlib.Path(driver_settings['path']).is_file() and not pathlib.Path(f'{driver_settings["path"]}.exe').is_file():
messagebox.showerror('Error', 'Specified driver directory doesn\'t exist\nPlease check the configuration file settings')
raise FileNotFoundError(driver_settings['path'])
# load video2x settings
image_format = config['video2x']['image_format'].lower()
preserve_frames = config['video2x']['preserve_frames']
# read FFmpeg configuration
ffmpeg_settings = config['ffmpeg']
# load cache directory
if isinstance(config['video2x']['video2x_cache_directory'], str):
video2x_cache_directory = pathlib.Path(config['video2x']['video2x_cache_directory'])
else:
video2x_cache_directory = pathlib.Path(tempfile.gettempdir()) / 'video2x'
# load video2x settings
image_format = config['video2x']['image_format'].lower()
preserve_frames = config['video2x']['preserve_frames']
if video2x_cache_directory.exists() and not video2x_cache_directory.is_dir():
messagebox.showerror('Error', 'Specified cache directory is a file/link')
raise FileExistsError('Specified cache directory is a file/link')
elif not video2x_cache_directory.exists():
# try creating the cache directory
if messagebox.askyesno('Question', f'Specified cache directory {video2x_cache_directory} does not exist\nCreate directory?'):
try:
video2x_cache_directory.mkdir(parents=True, exist_ok=True)
# there can be a number of exceptions here
# PermissionError, FileExistsError, etc.
# therefore, we put a catch-them-all here
except Exception as e:
messagebox.showerror('Error', f'Unable to create {video2x_cache_directory}\nAborting...')
raise e
# load cache directory
if isinstance(config['video2x']['video2x_cache_directory'], str):
video2x_cache_directory = pathlib.Path(config['video2x']['video2x_cache_directory'])
else:
raise FileNotFoundError('Could not create cache directory')
video2x_cache_directory = pathlib.Path(tempfile.gettempdir()) / 'video2x'
# load more settings from gui
width = self.width.get()
height = self.height.get()
scale_ratio = self.scale_ratio.get()
image_format = self.image_format.get()
threads = self.threads.get()
method = AVAILABLE_METHODS[self.method.get()]
preserve_frames = self.preserve_frames.get()
if video2x_cache_directory.exists() and not video2x_cache_directory.is_dir():
messagebox.showerror('Error', 'Specified cache directory is a file/link')
raise FileExistsError('Specified cache directory is a file/link')
self.upscaler = Upscaler(input_video=input_file, output_video=output_file, method=method, waifu2x_settings=waifu2x_settings, ffmpeg_settings=ffmpeg_settings)
elif not video2x_cache_directory.exists():
# try creating the cache directory
if messagebox.askyesno('Question', f'Specified cache directory {video2x_cache_directory} does not exist\nCreate directory?'):
try:
video2x_cache_directory.mkdir(parents=True, exist_ok=True)
# set optional options
self.upscaler.waifu2x_driver = driver
self.upscaler.scale_width = width
self.upscaler.scale_height = height
self.upscaler.scale_ratio = scale_ratio
self.upscaler.model_dir = None
self.upscaler.threads = threads
self.upscaler.video2x_cache_directory = video2x_cache_directory
self.upscaler.image_format = image_format
self.upscaler.preserve_frames = preserve_frames
# there can be a number of exceptions here
# PermissionError, FileExistsError, etc.
# therefore, we put a catch-them-all here
except Exception as e:
messagebox.showerror('Error', f'Unable to create {video2x_cache_directory}\nAborting...')
raise e
else:
raise FileNotFoundError('Could not create cache directory')
# run upscaler
self.upscaler.create_temp_directories()
# load more settings from gui
width = self.width.get()
height = self.height.get()
scale_ratio = self.scale_ratio.get()
image_format = self.image_format.get()
threads = self.threads.get()
method = AVAILABLE_METHODS[self.method.get()]
preserve_frames = self.preserve_frames.get()
# start progress bar
progress_bar = threading.Thread(target=self._progress_bar)
progress_bar.start()
self.upscaler = Upscaler(input_video=input_file, output_video=output_file, method=method, driver_settings=driver_settings, ffmpeg_settings=ffmpeg_settings)
# start upscaling
self.upscaler.run()
self.upscaler.cleanup_temp_directories()
# set optional options
self.upscaler.waifu2x_driver = driver
self.upscaler.scale_width = width
self.upscaler.scale_height = height
self.upscaler.scale_ratio = scale_ratio
self.upscaler.model_dir = None
self.upscaler.threads = threads
self.upscaler.video2x_cache_directory = video2x_cache_directory
self.upscaler.image_format = image_format
self.upscaler.preserve_frames = preserve_frames
# run upscaler
self.upscaler.create_temp_directories()
# start progress bar
progress_bar = threading.Thread(target=self._progress_bar)
progress_bar.start()
# start upscaling
self.upscaler.run()
self.upscaler.cleanup_temp_directories()
# show message when upscaling completes
messagebox.showinfo('Info', f'Upscaling Completed\nTime Taken: {round((time.time() - begin_time), 5)} seconds')
self.progress_bar['value'] = 100
self.running = False
self.start_button_text.set('Start')
except Exception as e:
messagebox.showerror('Error', f'Upscaler ran into an error:\n{e}')
# try cleaning up temp directories
with contextlib.suppress(Exception):
self.upscaler.cleanup_temp_directories()
# show message when upscaling completes
messagebox.showinfo('Info', f'Upscaling Completed\nTime Taken: {round((time.time() - begin_time), 5)} seconds')
self.progress_bar['value'] = 100
self.running = False
self.start_button_text.set('Start')
def _progress_bar(self):
""" This method prints a progress bar
@@ -350,12 +390,18 @@ class Video2xGui():
def _select_input(self):
self.input_file.set(askopenfilename(title='Select Input File'))
# remove input file extension
input_filename = str(self.input_file.get())
for extension in DEMUXER_EXTENSIONS:
if input_filename.endswith(f'.{extension}'):
input_filename = input_filename[:-1 - len(extension)]
# try to set an output file name automatically
output_file = pathlib.Path(f'{self.input_file.get()}_output.mp4')
output_file = pathlib.Path(f'{input_filename}_output.mp4')
output_file_id = 0
while output_file.is_file() and output_file_id <= 10:
output_file = pathlib.Path(f'{self.input_file.get()}_output_{output_file_id}.mp4')
output_file = pathlib.Path(f'{input_filename}_output_{output_file_id}.mp4')
output_file_id += 1
if not output_file.exists():
@@ -368,10 +414,10 @@ class Video2xGui():
def read_config(config_file):
""" Reads configuration file
Returns a dictionary read by JSON.
Returns a dictionary read by parsing Video2X config.
"""
with open(config_file, 'r') as raw_config:
config = json.load(raw_config)
config = yaml.load(raw_config, Loader=yaml.FullLoader)
return config
@@ -390,16 +436,16 @@ def absolutify_paths(config):
current_directory = pathlib.Path(sys.argv[0]).parent.absolute()
# check waifu2x-caffe path
if not re.match('^[a-z]:', config['waifu2x_caffe']['waifu2x_caffe_path'], re.IGNORECASE):
config['waifu2x_caffe']['waifu2x_caffe_path'] = current_directory / config['waifu2x_caffe']['waifu2x_caffe_path']
if not re.match('^[a-z]:', config['waifu2x_caffe']['path'], re.IGNORECASE):
config['waifu2x_caffe']['path'] = current_directory / config['waifu2x_caffe']['path']
# check waifu2x-converter-cpp path
if not re.match('^[a-z]:', config['waifu2x_converter']['waifu2x_converter_path'], re.IGNORECASE):
config['waifu2x_converter']['waifu2x_converter_path'] = current_directory / config['waifu2x_converter']['waifu2x_converter_path']
if not re.match('^[a-z]:', config['waifu2x_converter']['path'], re.IGNORECASE):
config['waifu2x_converter']['path'] = current_directory / config['waifu2x_converter']['path']
# check waifu2x_ncnn_vulkan path
if not re.match('^[a-z]:', config['waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_path'], re.IGNORECASE):
config['waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_path'] = current_directory / config['waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_path']
if not re.match('^[a-z]:', config['waifu2x_ncnn_vulkan']['path'], re.IGNORECASE):
config['waifu2x_ncnn_vulkan']['path'] = current_directory / config['waifu2x_ncnn_vulkan']['path']
# check ffmpeg path
if not re.match('^[a-z]:', config['ffmpeg']['ffmpeg_path'], re.IGNORECASE):

91
bin/video2x_setup.py → src/video2x_setup.py Normal file → Executable file
View File

@@ -2,17 +2,12 @@
# -*- coding: utf-8 -*-
"""
Name: Video2X Setup Script
Author: K4YT3X
Author: BrianPetkovsek
Creator: K4YT3X
Date Created: November 28, 2018
Last Modified: August 20, 2019
Last Modified: January 4, 2020
Dev: SAT3LL
Licensed under the GNU General Public License Version 3 (GNU GPL v3),
available at: https://www.gnu.org/licenses/gpl-3.0.txt
(C) 2018-2019 K4YT3X
Editor: BrianPetkovsek
Editor: SAT3LL
Description: This script helps installing all dependencies of video2x
and generates a configuration for it.
@@ -26,9 +21,9 @@ Installation Details:
"""
# built-in imports
from datetime import timedelta
import argparse
import contextlib
import json
import os
import pathlib
import re
@@ -36,6 +31,7 @@ import shutil
import subprocess
import sys
import tempfile
import time
import traceback
import urllib
import zipfile
@@ -45,14 +41,15 @@ import zipfile
# later in the script.
# import requests
VERSION = '1.5.0'
VERSION = '1.6.1'
# global static variables
LOCALAPPDATA = pathlib.Path(os.getenv('localappdata'))
VIDEO2X_CONFIG = pathlib.Path(sys.argv[0]).parent.absolute() / 'video2x.yaml'
DRIVER_OPTIONS = ['all', 'waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan', 'anime4k']
def process_arguments():
def parse_arguments():
"""Processes CLI arguments
"""
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
@@ -227,34 +224,35 @@ class Video2xSetup:
def _generate_config(self):
""" Generate video2x config
"""
# Open current video2x.json file as template
with open('video2x.json', 'r') as template:
template_dict = json.load(template)
import yaml
# open current video2x configuration file as template
with open(VIDEO2X_CONFIG, 'r') as template:
template_dict = yaml.load(template, Loader=yaml.FullLoader)
template.close()
# configure only the specified drivers
if self.driver == 'all':
template_dict['waifu2x_caffe']['waifu2x_caffe_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-caffe' / 'waifu2x-caffe-cui.exe')
template_dict['waifu2x_converter']['waifu2x_converter_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-converter-cpp')
template_dict['waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-ncnn-vulkan' / 'waifu2x-ncnn-vulkan.exe')
template_dict['anime4k']['anime4k_path'] = str(LOCALAPPDATA / 'video2x' / 'anime4k' / 'Anime4K.jar')
template_dict['waifu2x_caffe']['path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-caffe' / 'waifu2x-caffe-cui.exe')
template_dict['waifu2x_converter']['path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-converter-cpp')
template_dict['waifu2x_ncnn_vulkan']['path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-ncnn-vulkan' / 'waifu2x-ncnn-vulkan.exe')
template_dict['anime4k']['path'] = str(LOCALAPPDATA / 'video2x' / 'anime4k' / 'Anime4K.jar')
elif self.driver == 'waifu2x_caffe':
template_dict['waifu2x_caffe']['waifu2x_caffe_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-caffe' / 'waifu2x-caffe-cui.exe')
template_dict['waifu2x_caffe']['path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-caffe' / 'waifu2x-caffe-cui.exe')
elif self.driver == 'waifu2x_converter':
template_dict['waifu2x_converter']['waifu2x_converter_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-converter-cpp')
template_dict['waifu2x_converter']['path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-converter-cpp')
elif self.driver == 'waifu2x_ncnn_vulkan':
template_dict['waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-ncnn-vulkan' / 'waifu2x-ncnn-vulkan.exe')
template_dict['waifu2x_ncnn_vulkan']['path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-ncnn-vulkan' / 'waifu2x-ncnn-vulkan.exe')
elif self.driver == 'anime4k':
template_dict['anime4k']['anime4k_path'] = str(LOCALAPPDATA / 'video2x' / 'anime4k' / 'Anime4K.jar')
template_dict['anime4k']['path'] = str(LOCALAPPDATA / 'video2x' / 'anime4k' / 'Anime4K.jar')
template_dict['ffmpeg']['ffmpeg_path'] = str(LOCALAPPDATA / 'video2x' / 'ffmpeg-latest-win64-static' / 'bin')
template_dict['video2x']['video2x_cache_directory'] = None
template_dict['video2x']['preserve_frames'] = False
# Write configuration into file
with open('video2x.json', 'w') as config:
json.dump(template_dict, config, indent=2)
config.close()
# write configuration into file
with open(VIDEO2X_CONFIG, 'w') as config:
yaml.dump(template_dict, config)
def download(url, save_path, chunk_size=4096):
@@ -321,7 +319,20 @@ def pip_install(file):
if __name__ == '__main__':
try:
args = process_arguments()
# set default exit code
EXIT_CODE = 0
# get start time
start_time = time.time()
# check platform
if sys.platform != 'win32':
print('This script is currently only compatible with Windows')
EXIT_CODE = 1
sys.exit(1)
# parse command line arguments
args = parse_arguments()
print('Video2X Setup Script')
print(f'Version: {VERSION}')
@@ -335,8 +346,20 @@ if __name__ == '__main__':
setup = Video2xSetup(args.driver, download_python_modules)
setup.run()
print('\nScript finished successfully')
except Exception:
except SystemExit:
pass
# if PermissionError is raised
# user needs to run this with higher privilege
except PermissionError:
traceback.print_exc()
print('You might have insufficient privilege for this script to run')
print('Try running this script with Administrator privileges')
EXIT_CODE = 1
# for any exception in the script
except Exception:
traceback.print_exc()
print('An error has occurred')
print('Video2X Automatic Setup has failed')
@@ -348,4 +371,12 @@ if __name__ == '__main__':
traceback.print_exc()
print('An error occurred while trying to cleanup files')
exit(1)
EXIT_CODE = 1
# regardless if script finishes successfully or not
# print script execution summary
finally:
print('Script finished')
print(f'Time taken: {timedelta(seconds=round(time.time() - start_time))}')
input('Press [ENTER] to exit script')
sys.exit(EXIT_CODE)

32
bin/waifu2x_caffe.py → src/waifu2x_caffe.py Normal file → Executable file
View File

@@ -4,7 +4,7 @@
Name: Waifu2x Caffe Driver
Author: K4YT3X
Date Created: Feb 24, 2018
Last Modified: August 3, 2019
Last Modified: October 6, 2019
Description: This class is a high-level wrapper
for waifu2x-caffe.
@@ -27,11 +27,11 @@ class Waifu2xCaffe:
the upscale function.
"""
def __init__(self, waifu2x_settings, process, model_dir, bit_depth):
self.waifu2x_settings = waifu2x_settings
self.waifu2x_settings['process'] = process
self.waifu2x_settings['model_dir'] = model_dir
self.waifu2x_settings['output_depth'] = bit_depth
def __init__(self, driver_settings, process, model_dir, bit_depth):
self.driver_settings = driver_settings
self.driver_settings['process'] = process
self.driver_settings['model_dir'] = model_dir
self.driver_settings['output_depth'] = bit_depth
# arguments passed through command line overwrites config file values
self.process = process
@@ -50,16 +50,16 @@ class Waifu2xCaffe:
try:
# overwrite config file settings
self.waifu2x_settings['input_path'] = input_directory
self.waifu2x_settings['output_path'] = output_directory
self.driver_settings['input_path'] = input_directory
self.driver_settings['output_path'] = output_directory
if scale_ratio:
self.waifu2x_settings['scale_ratio'] = scale_ratio
self.driver_settings['scale_ratio'] = scale_ratio
elif scale_width and scale_height:
self.waifu2x_settings['scale_width'] = scale_width
self.waifu2x_settings['scale_height'] = scale_height
self.driver_settings['scale_width'] = scale_width
self.driver_settings['scale_height'] = scale_height
self.waifu2x_settings['output_extention'] = image_format
self.driver_settings['output_extention'] = image_format
# print thread start message
self.print_lock.acquire()
@@ -68,14 +68,14 @@ class Waifu2xCaffe:
# list to be executed
# initialize the list with waifu2x binary path as the first element
execute = [str(self.waifu2x_settings['waifu2x_caffe_path'])]
execute = [str(self.driver_settings['path'])]
for key in self.waifu2x_settings.keys():
for key in self.driver_settings.keys():
value = self.waifu2x_settings[key]
value = self.driver_settings[key]
# is executable key or null or None means that leave this option out (keep default)
if key == 'waifu2x_caffe_path' or value is None or value is False:
if key == 'path' or value is None or value is False:
continue
else:
if len(key) == 1:

30
bin/waifu2x_converter.py → src/waifu2x_converter.py Normal file → Executable file
View File

@@ -4,7 +4,7 @@
Name: Waifu2x Converter CPP Driver
Author: K4YT3X
Date Created: February 8, 2019
Last Modified: August 3, 2019
Last Modified: October 6, 2019
Description: This class is a high-level wrapper
for waifu2x-converter-cpp.
@@ -28,9 +28,9 @@ class Waifu2xConverter:
the upscale function.
"""
def __init__(self, waifu2x_settings, model_dir):
self.waifu2x_settings = waifu2x_settings
self.waifu2x_settings['model_dir'] = model_dir
def __init__(self, driver_settings, model_dir):
self.driver_settings = driver_settings
self.driver_settings['model_dir'] = model_dir
self.print_lock = threading.Lock()
def upscale(self, input_directory, output_directory, scale_ratio, jobs, image_format, upscaler_exceptions):
@@ -46,16 +46,16 @@ class Waifu2xConverter:
try:
# overwrite config file settings
self.waifu2x_settings['input'] = input_directory
self.waifu2x_settings['output'] = output_directory
self.waifu2x_settings['scale-ratio'] = scale_ratio
self.waifu2x_settings['jobs'] = jobs
self.waifu2x_settings['output-format'] = image_format
self.driver_settings['input'] = input_directory
self.driver_settings['output'] = output_directory
self.driver_settings['scale-ratio'] = scale_ratio
self.driver_settings['jobs'] = jobs
self.driver_settings['output-format'] = image_format
# models_rgb must be specified manually for waifu2x-converter-cpp
# if it's not specified in the arguments, create automatically
if self.waifu2x_settings['model-dir'] is None:
self.waifu2x_settings['model-dir'] = pathlib.Path(self.waifu2x_settings['waifu2x_converter_path']) / 'models_rgb'
if self.driver_settings['model-dir'] is None:
self.driver_settings['model-dir'] = pathlib.Path(self.driver_settings['waifu2x_converter_path']) / 'models_rgb'
# print thread start message
self.print_lock.acquire()
@@ -64,14 +64,14 @@ class Waifu2xConverter:
# list to be executed
# initialize the list with waifu2x binary path as the first element
execute = [str(pathlib.Path(self.waifu2x_settings['waifu2x_converter_path']) / 'waifu2x-converter-cpp.exe')]
execute = [str(pathlib.Path(self.driver_settings['path']) / 'waifu2x-converter-cpp.exe')]
for key in self.waifu2x_settings.keys():
for key in self.driver_settings.keys():
value = self.waifu2x_settings[key]
value = self.driver_settings[key]
# the key doesn't need to be passed in this case
if key == 'waifu2x_converter_path':
if key == 'path':
continue
# null or None means that leave this option out (keep default)

View File

@@ -2,11 +2,12 @@
# -*- coding: utf-8 -*-
"""
Name: Waifu2x NCNN Vulkan Driver
Author: SAT3LL
Creator: SAT3LL
Date Created: June 26, 2019
Last Modified: August 3, 2019
Last Modified: November 15, 2019
Dev: K4YT3X
Editor: K4YT3X
Last Modified: January 4, 2020
Description: This class is a high-level wrapper
for waifu2x_ncnn_vulkan.
@@ -30,14 +31,14 @@ class Waifu2xNcnnVulkan:
the upscale function.
"""
def __init__(self, waifu2x_settings):
self.waifu2x_settings = waifu2x_settings
def __init__(self, driver_settings):
self.driver_settings = driver_settings
# arguments passed through command line overwrites config file values
# waifu2x_ncnn_vulkan can't find its own model directory if its not in the current dir
# so change to it
os.chdir(os.path.join(self.waifu2x_settings['waifu2x_ncnn_vulkan_path'], '..'))
os.chdir(os.path.join(self.driver_settings['path'], '..'))
self.print_lock = threading.Lock()
@@ -52,9 +53,9 @@ class Waifu2xNcnnVulkan:
try:
# overwrite config file settings
self.waifu2x_settings['i'] = input_directory
self.waifu2x_settings['o'] = output_directory
self.waifu2x_settings['s'] = scale_ratio
self.driver_settings['i'] = input_directory
self.driver_settings['o'] = output_directory
self.driver_settings['s'] = int(scale_ratio)
# print thread start message
self.print_lock.acquire()
@@ -63,14 +64,14 @@ class Waifu2xNcnnVulkan:
# list to be executed
# initialize the list with waifu2x binary path as the first element
execute = [str(self.waifu2x_settings['waifu2x_ncnn_vulkan_path'])]
execute = [str(self.driver_settings['path'])]
for key in self.waifu2x_settings.keys():
for key in self.driver_settings.keys():
value = self.waifu2x_settings[key]
value = self.driver_settings[key]
# is executable key or null or None means that leave this option out (keep default)
if key == 'waifu2x_ncnn_vulkan_path' or value is None or value is False:
if key == 'path' or value is None or value is False:
continue
else:
if len(key) == 1: