mirror of
https://github.com/k4yt3x/video2x.git
synced 2026-02-07 13:04:53 +08:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6180ccd9b2 | ||
|
|
e10315f89e | ||
|
|
6521e071ce | ||
|
|
a685e91b14 | ||
|
|
9d72bad314 | ||
|
|
2b63b5f0a6 | ||
|
|
9c84228c17 | ||
|
|
f9bb191336 | ||
|
|
7a3af366f8 | ||
|
|
d4223f93ec | ||
|
|
c5c764a91f | ||
|
|
ba6472c9fc | ||
|
|
dc1244580f | ||
|
|
0347d05127 | ||
|
|
45f5bf91e6 | ||
|
|
5e78beabcf | ||
|
|
6c5b7ea17f | ||
|
|
d9610abae0 | ||
|
|
47471352ba | ||
|
|
969cfe5c0d | ||
|
|
e12db41213 | ||
|
|
7a69d58e28 | ||
|
|
ad6308d385 | ||
|
|
8c3a85ac42 | ||
|
|
db603062e9 | ||
|
|
807276fcc3 | ||
|
|
9be46f7d62 | ||
|
|
f42a8ab71f | ||
|
|
e3b2624977 |
5
.github/ISSUE_TEMPLATE/bug-report.md
vendored
5
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -11,10 +11,11 @@ assignees: K4YT3X
|
||||
|
||||
|Module|Version|
|
||||
|-|-|
|
||||
|`video2x`||
|
||||
|`ffmpeg`||
|
||||
|`Video2X`||
|
||||
|`FFmpeg`||
|
||||
|`waifu2x-caffe`||
|
||||
|`waifu2x-converter-cpp`||
|
||||
|`waifu2x-ncnn-vulkan`||
|
||||
|
||||
## Symptom
|
||||
|
||||
|
||||
45
README.md
45
README.md
@@ -2,11 +2,11 @@
|
||||
|
||||
### Official Discussion Group (Telegram): https://t.me/video2x
|
||||
|
||||
## Download Builds (beta)
|
||||
## Download Builds
|
||||
|
||||
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.
|
||||
|
||||
The **`full`** package provides all packages that will possibly be needed by `Video2X`, including `FFmpeg`, `waifu2x-caffe`, `waifu2x-converter-cpp`, and `waifu2x-ncnn-vulkan`. The config file (`video2x.json`) is also already configured for the environment. All you need to do is just to launch `video2x.exe`.
|
||||
The **`full`** package provides all packages that will possibly be needed by `Video2X`, including `FFmpeg`, `waifu2x-caffe`, `waifu2x-converter-cpp`, `waifu2x-ncnn-vulkan`, and `Anime4K`. The config file (`video2x.json`) is also already configured for the environment. All you need to do is just to launch `video2x.exe`.
|
||||
|
||||
The **`light`** package provides only the most basic functions of `Video2X`. Only `video2x.exe`, `video2x_setup.exe` and `video2x.json` are included. To setup dependencies (e.g. `FFmpeg` and `Waifu2X`) automatically, simply launch `video2x_setup.exe`.
|
||||
|
||||
@@ -18,10 +18,18 @@ Component names that are **bolded** can be automatically downloaded and configur
|
||||
2. AMD GPU / Nvidia GPU
|
||||
3. AMD GPU driver / Nvidia GPU driver / Nvidia CUDNN
|
||||
4. [**FFmpeg**](https://ffmpeg.zeranoe.com/builds/)
|
||||
5. [**waifu2x-caffe**](https://github.com/lltcggie/waifu2x-caffe/releases) / [**waifu2x-converter-cpp**](https://github.com/DeadSix27/waifu2x-converter-cpp/releases) / [**waifu2x-ncnn-vulkan**](https://github.com/nihui/waifu2x-ncnn-vulkan)
|
||||
5. One of the following drivers
|
||||
- [**waifu2x-caffe**](https://github.com/lltcggie/waifu2x-caffe/releases)
|
||||
- [**waifu2x-converter-cpp**](https://github.com/DeadSix27/waifu2x-converter-cpp/releases)
|
||||
- [**waifu2x-ncnn-vulkan**](https://github.com/nihui/waifu2x-ncnn-vulkan)
|
||||
- [**Anime4K**](https://github.com/bloc97/Anime4K)
|
||||
|
||||
## Recent Changes
|
||||
|
||||
### 2.10.0 (August 16, 2019)
|
||||
|
||||
- **Added support for [Anime4K](https://github.com/bloc97/Anime4K)**
|
||||
|
||||
### 2.9.0 (July 27, 2019)
|
||||
|
||||
- Changed file handling method from `os` to `pathlib`
|
||||
@@ -35,15 +43,11 @@ Component names that are **bolded** can be automatically downloaded and configur
|
||||
|
||||
### 2.8.0 (June 25, 2019)
|
||||
|
||||
- Added support for [waifu2x-ncnn-vulkan](https://github.com/nihui/waifu2x-ncnn-vulkan)
|
||||
- **Added support for [waifu2x-ncnn-vulkan](https://github.com/nihui/waifu2x-ncnn-vulkan)**
|
||||
|
||||
### 2.7.1 (April 18, 2019)
|
||||
### Setup Script 1.5.0 (August 16, 2019)
|
||||
|
||||
- Fixed video2x custom temp folder bug found by @cr08 .
|
||||
|
||||
### Setup Script 1.3.0 (June 25, 2019)
|
||||
|
||||
- Added automatic installation support for `waifu2x-ncnn-vulkan`
|
||||
- Added automatic installation support for `Anime4K`
|
||||
|
||||
## Description
|
||||
|
||||
@@ -61,6 +65,8 @@ Clip is from trailer of animated movie "千と千尋の神隠し". Copyright bel
|
||||
|
||||
## Screenshot
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
---
|
||||
@@ -89,14 +95,18 @@ If you have any questions, first try visiting our [Q&A](https://github.com/k4yt3
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Python 3**
|
||||
- **Python 3**
|
||||
Download: https://www.python.org/downloads/windows/
|
||||
- **FFmpeg Windows Build**
|
||||
Download: https://ffmpeg.org/download.html
|
||||
- **waifu2x-caffe** (for Nvidia CUDA/CUDNN)
|
||||
- **FFmpeg Windows Build**
|
||||
Download: https://ffmpeg.org/download.html
|
||||
- **waifu2x-caffe** (for Nvidia CUDA/CUDNN)
|
||||
Download: https://github.com/lltcggie/waifu2x-caffe/releases
|
||||
- **waifu2x-converter-cpp** (required for AMD, OpenCL and OpenGL processing)
|
||||
- **waifu2x-converter-cpp** (required for AMD, OpenCL and OpenGL processing)
|
||||
Download: https://github.com/DeadSix27/waifu2x-converter-cpp/releases
|
||||
- **waifu2x-ncnn-vulkan**
|
||||
Download: https://github.com/nihui/waifu2x-ncnn-vulkan/releases
|
||||
- **Anime4K**
|
||||
Download: https://github.com/bloc97/Anime4K/releases
|
||||
|
||||
### Installing Dependencies
|
||||
|
||||
@@ -144,7 +154,7 @@ Enlarge the video to 1920x1080 using CUDA. You may also use the `-r/--ratio` opt
|
||||
python video2x.py -i sample_input.mp4 -o sample_output.mp4 -m gpu --width=1920 --height=1080
|
||||
```
|
||||
|
||||
### Nvidia CNDNN
|
||||
### Nvidia CUDNN
|
||||
|
||||
Enlarge the video to 1920x1080 using CUDNN. You may also use the `-r/--ratio` option.
|
||||
|
||||
@@ -168,7 +178,7 @@ python video2x.py -i sample_input.mp4 -o sample_output.mp4 -m gpu -r 2 -d waifu2
|
||||
|
||||
### CPU
|
||||
|
||||
Enlarge the video to 1920x1080 using the CPU. You may also use the `-r/--ratio` option. This is potentially much slower than using a GPU. The configuration file for this method is similar to the previous methods.
|
||||
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.
|
||||
|
||||
```shell
|
||||
python video2x.py -i sample_input.mp4 -o sample_output.mp4 -m cpu --width=1920 --height=1080
|
||||
@@ -241,6 +251,7 @@ This project relies on the following software and projects.
|
||||
- [waifu2x-caffe](https://github.com/lltcggie/waifu2x-caffe)
|
||||
- [waifu2x-converter-cpp](https://github.com/DeadSix27/waifu2x-converter-cpp)
|
||||
- [waifu2x-ncnn-vulkan](https://github.com/nihui/waifu2x-ncnn-vulkan)
|
||||
- [Anime4K](https://github.com/bloc97/Anime4K)
|
||||
|
||||
## Special Thanks
|
||||
|
||||
|
||||
92
bin/anime4k.py
Normal file
92
bin/anime4k.py
Normal file
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Name: Anime4K Driver
|
||||
Author: K4YT3X
|
||||
Date Created: August 15, 2019
|
||||
Last Modified: August 15, 2019
|
||||
|
||||
Description: This class is a high-level wrapper
|
||||
for Anime4k.
|
||||
"""
|
||||
|
||||
# built-in imports
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
# third-party imports
|
||||
from avalon_framework import Avalon
|
||||
|
||||
|
||||
class Anime4k:
|
||||
"""This class communicates with Anime4K engine
|
||||
|
||||
An object will be created for this class, containing information
|
||||
about the binary address and the processing method. When being called
|
||||
by the main program, other detailed information will be passed to
|
||||
the upscale function.
|
||||
"""
|
||||
|
||||
def __init__(self, waifu2x_settings):
|
||||
self.waifu2x_settings = waifu2x_settings
|
||||
self.print_lock = threading.Lock()
|
||||
|
||||
def upscale(self, input_directory, output_directory, scale_ratio, upscaler_exceptions, push_strength=None, push_grad_strength=None):
|
||||
""" Anime4K wrapper
|
||||
|
||||
Arguments:
|
||||
file_in {string} -- input file path
|
||||
file_out {string} -- output file path
|
||||
|
||||
Keyword Arguments:
|
||||
scale {int} -- scale ratio (default: {None})
|
||||
push_strength {int} -- residual push strength (default: {None})
|
||||
push_grad_strength {int} -- residual gradient push strength (default: {None})
|
||||
|
||||
Returns:
|
||||
subprocess.Popen.returncode -- command line return value of execution
|
||||
"""
|
||||
try:
|
||||
# return value is the sum of all execution return codes
|
||||
return_value = 0
|
||||
|
||||
# get a list lof all image files in input_directory
|
||||
extracted_frame_files = [f for f in input_directory.iterdir() if str(f).lower().endswith('.png') or str(f).lower().endswith('.jpg')]
|
||||
|
||||
# upscale each image in input_directory
|
||||
for image in extracted_frame_files:
|
||||
|
||||
execute = [
|
||||
self.waifu2x_settings['java_path'],
|
||||
'-jar',
|
||||
self.waifu2x_settings['anime4k_path'],
|
||||
str(image.absolute()),
|
||||
str(output_directory / image.name),
|
||||
str(scale_ratio)
|
||||
]
|
||||
|
||||
# optional arguments
|
||||
kwargs = [
|
||||
'push_strength',
|
||||
'push_grad_strength'
|
||||
]
|
||||
|
||||
# if optional argument specified, append value to execution list
|
||||
for arg in kwargs:
|
||||
if locals()[arg] is not None:
|
||||
execute.extend([locals([arg])])
|
||||
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'Executing: {execute}', )
|
||||
self.print_lock.release()
|
||||
return_value += subprocess.run(execute, check=True).returncode
|
||||
|
||||
# print thread exiting message
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Thread {threading.current_thread().name} exiting')
|
||||
self.print_lock.release()
|
||||
|
||||
# return command execution return code
|
||||
return return_value
|
||||
except Exception as e:
|
||||
upscaler_exceptions.append(e)
|
||||
@@ -4,14 +4,13 @@
|
||||
Name: Video2X FFmpeg Controller
|
||||
Author: K4YT3X
|
||||
Date Created: Feb 24, 2018
|
||||
Last Modified: July 27, 2019
|
||||
Last Modified: August 15, 2019
|
||||
|
||||
Description: This class handles all FFmpeg related operations.
|
||||
"""
|
||||
|
||||
# built-in imports
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import subprocess
|
||||
|
||||
@@ -119,6 +118,8 @@ class Ffmpeg:
|
||||
self.ffmpeg_binary
|
||||
]
|
||||
|
||||
execute.extend(self._read_configuration(phase='video_to_frames'))
|
||||
|
||||
execute.extend([
|
||||
'-i',
|
||||
input_video
|
||||
@@ -130,8 +131,6 @@ class Ffmpeg:
|
||||
extracted_frames / f'extracted_%0d.{self.image_format}'
|
||||
])
|
||||
|
||||
execute.extend(self._read_configuration(phase='video_to_frames'))
|
||||
|
||||
self._execute(execute)
|
||||
|
||||
def convert_video(self, framerate, resolution, upscaled_frames):
|
||||
@@ -152,6 +151,9 @@ class Ffmpeg:
|
||||
resolution
|
||||
]
|
||||
|
||||
# read other options
|
||||
execute.extend(self._read_configuration(phase='frames_to_video'))
|
||||
|
||||
# read FFmpeg input options
|
||||
execute.extend(self._read_configuration(phase='frames_to_video', section='input_options'))
|
||||
|
||||
@@ -159,8 +161,7 @@ class Ffmpeg:
|
||||
# Dev: SAT3LL
|
||||
# rename all .png.png suffixes to .png
|
||||
import re
|
||||
import shutil
|
||||
regex = re.compile(r'\.png\.png$')
|
||||
regex = re.compile(r'\.png\.png$', re.IGNORECASE)
|
||||
for frame_name in upscaled_frames.iterdir():
|
||||
(upscaled_frames / frame_name).rename(upscaled_frames / regex.sub('.png', str(frame_name)))
|
||||
# END WORKAROUND
|
||||
@@ -174,9 +175,6 @@ class Ffmpeg:
|
||||
# read FFmpeg output options
|
||||
execute.extend(self._read_configuration(phase='frames_to_video', section='output_options'))
|
||||
|
||||
# read other options
|
||||
execute.extend(self._read_configuration(phase='frames_to_video'))
|
||||
|
||||
# specify output file location
|
||||
execute.extend([
|
||||
upscaled_frames / 'no_audio.mp4'
|
||||
@@ -193,12 +191,17 @@ class Ffmpeg:
|
||||
upscaled_frames {string} -- directory containing upscaled frames
|
||||
"""
|
||||
execute = [
|
||||
self.ffmpeg_binary,
|
||||
self.ffmpeg_binary
|
||||
]
|
||||
|
||||
execute.extend(self._read_configuration(phase='migrating_tracks'))
|
||||
|
||||
execute.extend([
|
||||
'-i',
|
||||
upscaled_frames / 'no_audio.mp4',
|
||||
'-i',
|
||||
input_video
|
||||
]
|
||||
])
|
||||
|
||||
execute.extend(self._read_configuration(phase='migrating_tracks', section='output_options'))
|
||||
|
||||
@@ -206,8 +209,6 @@ class Ffmpeg:
|
||||
output_video
|
||||
])
|
||||
|
||||
execute.extend(self._read_configuration(phase='migrating_tracks'))
|
||||
|
||||
self._execute(execute)
|
||||
|
||||
def _read_configuration(self, phase, section=None):
|
||||
@@ -278,9 +279,9 @@ class Ffmpeg:
|
||||
Returns:
|
||||
int -- execution return code
|
||||
"""
|
||||
Avalon.debug_info(f'Executing: {execute}')
|
||||
|
||||
# turn all list elements into string to avoid errors
|
||||
execute = [str(e) for e in execute]
|
||||
|
||||
Avalon.debug_info(f'Executing: {execute}')
|
||||
|
||||
return subprocess.run(execute, shell=True, check=True).returncode
|
||||
|
||||
@@ -12,7 +12,6 @@ that have already been upscaled.
|
||||
"""
|
||||
|
||||
# built-in imports
|
||||
import os
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Name: Video2X Upscaler
|
||||
Author: K4YT3X
|
||||
Date Created: December 10, 2018
|
||||
Last Modified: July 27, 2019
|
||||
Last Modified: August 21, 2019
|
||||
|
||||
Dev: SAT3LL
|
||||
|
||||
@@ -15,6 +15,7 @@ Licensed under the GNU General Public License Version 3 (GNU GPL v3),
|
||||
"""
|
||||
|
||||
# local imports
|
||||
from anime4k import Anime4k
|
||||
from exceptions import *
|
||||
from ffmpeg import Ffmpeg
|
||||
from image_cleaner import ImageCleaner
|
||||
@@ -24,6 +25,7 @@ from waifu2x_ncnn_vulkan import Waifu2xNcnnVulkan
|
||||
|
||||
# built-in imports
|
||||
from fractions import Fraction
|
||||
import contextlib
|
||||
import copy
|
||||
import pathlib
|
||||
import re
|
||||
@@ -37,6 +39,8 @@ import traceback
|
||||
from avalon_framework import Avalon
|
||||
from tqdm import tqdm
|
||||
|
||||
AVAILABLE_DRIVERS = ['waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan', 'anime4k']
|
||||
|
||||
|
||||
class Upscaler:
|
||||
""" An instance of this class is a upscaler that will
|
||||
@@ -122,7 +126,7 @@ class Upscaler:
|
||||
previous_cycle_frames = 0
|
||||
while not self.progress_bar_exit_signal:
|
||||
|
||||
try:
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
self.total_frames_upscaled = len([f for f in self.upscaled_frames.iterdir() if str(f)[-4:] == f'.{self.image_format}'])
|
||||
delta = self.total_frames_upscaled - previous_cycle_frames
|
||||
previous_cycle_frames = self.total_frames_upscaled
|
||||
@@ -131,10 +135,8 @@ class Upscaler:
|
||||
if self.total_frames_upscaled >= self.total_frames:
|
||||
return
|
||||
|
||||
# adds the detla into the progress bar
|
||||
# adds the delta into the progress bar
|
||||
progress_bar.update(delta)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
@@ -156,7 +158,7 @@ class Upscaler:
|
||||
self.upscaler_exceptions = []
|
||||
|
||||
# initialize waifu2x driver
|
||||
drivers = ['waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan']
|
||||
drivers = AVAILABLE_DRIVERS
|
||||
if self.waifu2x_driver not in drivers:
|
||||
raise UnrecognizedDriverError(f'Unrecognized waifu2x driver: {self.waifu2x_driver}')
|
||||
|
||||
@@ -170,12 +172,14 @@ class Upscaler:
|
||||
|
||||
w2.upscale(self.extracted_frames, self.upscaled_frames, self.scale_ratio, self.threads, self.image_format, self.upscaler_exceptions)
|
||||
for image in [f for f in self.upscaled_frames.iterdir() if f.is_file()]:
|
||||
renamed = re.sub(f'_\[.*-.*\]\[x(\d+(\.\d+)?)\]\.{self.image_format}', f'.{self.image_format}', image)
|
||||
renamed = re.sub(f'_\[.*-.*\]\[x(\d+(\.\d+)?)\]\.{self.image_format}', f'.{self.image_format}', str(image))
|
||||
(self.upscaled_frames / image).rename(self.upscaled_frames / renamed)
|
||||
|
||||
self.progress_bar_exit_signal = True
|
||||
progress_bar.join()
|
||||
return
|
||||
|
||||
# drivers that are to be multi-threaded by video2x
|
||||
else:
|
||||
# create a container for all upscaler threads
|
||||
upscaler_threads = []
|
||||
@@ -247,6 +251,15 @@ class Upscaler:
|
||||
self.scale_ratio,
|
||||
self.upscaler_exceptions))
|
||||
|
||||
# if the driver being used is anime4k
|
||||
elif self.waifu2x_driver == 'anime4k':
|
||||
w2 = Anime4k(copy.deepcopy(self.waifu2x_settings))
|
||||
thread = threading.Thread(target=w2.upscale,
|
||||
args=(thread_info[0],
|
||||
self.upscaled_frames,
|
||||
self.scale_ratio,
|
||||
self.upscaler_exceptions))
|
||||
|
||||
# create thread
|
||||
thread.name = thread_info[1]
|
||||
|
||||
|
||||
@@ -41,15 +41,19 @@
|
||||
},
|
||||
"waifu2x_ncnn_vulkan": {
|
||||
"waifu2x_ncnn_vulkan_path": "C:\\Users\\K4YT3X\\AppData\\Local\\video2x\\waifu2x-ncnn-vulkan\\waifu2x-ncnn-vulkan.exe",
|
||||
"input": null,
|
||||
"output": null,
|
||||
"noise-level": 2,
|
||||
"scale-ratio": null,
|
||||
"tile-size": 200,
|
||||
"model-path": null,
|
||||
"gpu": 0,
|
||||
"load-proc-save_threads": null,
|
||||
"verbose": null
|
||||
"v": null,
|
||||
"i": null,
|
||||
"o": null,
|
||||
"n": 2,
|
||||
"s": 2,
|
||||
"t": 400,
|
||||
"m": "models-cunet",
|
||||
"g": 0,
|
||||
"j": "1:2:2"
|
||||
},
|
||||
"anime4k": {
|
||||
"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",
|
||||
@@ -73,6 +77,7 @@
|
||||
"-b:v": null,
|
||||
"-pix_fmt": null
|
||||
},
|
||||
"-hwaccel": "auto",
|
||||
"-y": true
|
||||
},
|
||||
"migrating_tracks": {
|
||||
@@ -85,6 +90,7 @@
|
||||
"-c": "copy",
|
||||
"-pix_fmt": null
|
||||
},
|
||||
"-hwaccel": "auto",
|
||||
"-y": true
|
||||
}
|
||||
},
|
||||
|
||||
101
bin/video2x.py
101
bin/video2x.py
@@ -13,7 +13,7 @@ __ __ _ _ ___ __ __
|
||||
Name: Video2X Controller
|
||||
Author: K4YT3X
|
||||
Date Created: Feb 24, 2018
|
||||
Last Modified: July 27, 2019
|
||||
Last Modified: August 29, 2019
|
||||
|
||||
Dev: BrianPetkovsek
|
||||
Dev: SAT3LL
|
||||
@@ -44,13 +44,13 @@ smooth and edges sharp.
|
||||
|
||||
# local imports
|
||||
from exceptions import *
|
||||
from upscaler import AVAILABLE_DRIVERS
|
||||
from upscaler import Upscaler
|
||||
|
||||
# built-in imports
|
||||
import argparse
|
||||
import glob
|
||||
import contextlib
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import shutil
|
||||
@@ -64,7 +64,22 @@ from avalon_framework import Avalon
|
||||
import GPUtil
|
||||
import psutil
|
||||
|
||||
VERSION = '2.9.0'
|
||||
VERSION = '2.10.0'
|
||||
|
||||
LEGAL_INFO = f'''Video2X Version: {VERSION}
|
||||
Author: K4YT3X
|
||||
License: GNU GPL v3
|
||||
Github Page: https://github.com/k4yt3x/video2x
|
||||
Contact: k4yt3x@k4yt3x.com'''
|
||||
|
||||
LOGO = r'''
|
||||
__ __ _ _ ___ __ __
|
||||
\ \ / / (_) | | |__ \ \ \ / /
|
||||
\ \ / / _ __| | ___ ___ ) | \ V /
|
||||
\ \/ / | | / _` | / _ \ / _ \ / / > <
|
||||
\ / | | | (_| | | __/ | (_) | / /_ / . \
|
||||
\/ |_| \__,_| \___| \___/ |____| /_/ \_\
|
||||
'''
|
||||
|
||||
# each thread might take up to 2.5 GB during initialization.
|
||||
# (system memory, not to be confused with GPU memory)
|
||||
@@ -89,7 +104,7 @@ def process_arguments():
|
||||
# upscaler options
|
||||
upscaler_options = parser.add_argument_group('Upscaler Options')
|
||||
upscaler_options.add_argument('-m', '--method', help='upscaling method', action='store', default='gpu', choices=['cpu', 'gpu', 'cudnn'])
|
||||
upscaler_options.add_argument('-d', '--driver', help='waifu2x driver', action='store', default='waifu2x_caffe', choices=['waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan'])
|
||||
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')
|
||||
@@ -111,18 +126,9 @@ def process_arguments():
|
||||
|
||||
def print_logo():
|
||||
"""print video2x logo"""
|
||||
logo = r'''
|
||||
__ __ _ _ ___ __ __
|
||||
\ \ / / (_) | | |__ \ \ \ / /
|
||||
\ \ / / _ __| | ___ ___ ) | \ V /
|
||||
\ \/ / | | / _` | / _ \ / _ \ / / > <
|
||||
\ / | | | (_| | | __/ | (_) | / /_ / . \
|
||||
\/ |_| \__,_| \___| \___/ |____| /_/ \_\
|
||||
'''
|
||||
print(logo)
|
||||
print('\n Video2X Video Enlarger')
|
||||
spaces = ((44 - len(f'Version {VERSION}')) // 2) * ' '
|
||||
print(f'{Avalon.FM.BD}\n{spaces} Version {VERSION}\n{Avalon.FM.RST}')
|
||||
print(LOGO)
|
||||
print(f'\n{"Video2X Video Enlarger".rjust(40, " ")}')
|
||||
print(f'\n{Avalon.FM.BD}{f"Version {VERSION}".rjust(36, " ")}{Avalon.FM.RST}\n')
|
||||
|
||||
|
||||
def check_memory():
|
||||
@@ -145,12 +151,10 @@ def check_memory():
|
||||
Avalon.warning('Nvidia-smi not available, skipping available memory check')
|
||||
Avalon.warning('If you experience error \"cudaSuccess out of memory\", try reducing number of threads you\'re using')
|
||||
else:
|
||||
try:
|
||||
with contextlib.suppress(ValueError):
|
||||
# "0" is GPU ID. Both waifu2x drivers use the first GPU available, therefore only 0 makes sense
|
||||
gpu_memory_available = (GPUtil.getGPUs()[0].memoryTotal - GPUtil.getGPUs()[0].memoryUsed) / 1024
|
||||
memory_status.append(('GPU', gpu_memory_available))
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
# go though each checkable memory type and check availability
|
||||
for memory_type, memory_available in memory_status:
|
||||
@@ -218,6 +222,10 @@ def absolutify_paths(config):
|
||||
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']
|
||||
|
||||
# check anime4k path
|
||||
if not re.match('^[a-z]:', config['anime4k']['anime4k_path'], re.IGNORECASE):
|
||||
config['anime4k']['anime4k_path'] = current_directory / config['anime4k']['anime4k_path']
|
||||
|
||||
# check ffmpeg path
|
||||
if not re.match('^[a-z]:', config['ffmpeg']['ffmpeg_path'], re.IGNORECASE):
|
||||
config['ffmpeg']['ffmpeg_path'] = current_directory / config['ffmpeg']['ffmpeg_path']
|
||||
@@ -245,11 +253,7 @@ args = process_arguments()
|
||||
|
||||
# display version and lawful informaition
|
||||
if args.version:
|
||||
print(f'Video2X Version: {VERSION}')
|
||||
print('Author: K4YT3X')
|
||||
print('License: GNU GPL v3')
|
||||
print('Github Page: https://github.com/k4yt3x/video2x')
|
||||
print('Contact: k4yt3x@k4yt3x.com')
|
||||
print(LEGAL_INFO)
|
||||
exit(0)
|
||||
|
||||
# arguments sanity check
|
||||
@@ -259,9 +263,9 @@ if not args.input:
|
||||
if not args.output:
|
||||
Avalon.error('You must specify output video file/directory path')
|
||||
raise ArgumentError('output video path not specified')
|
||||
if (args.driver == 'waifu2x_converter' or args.driver == 'waifu2x_ncnn_vulkan') and args.width and args.height:
|
||||
Avalon.error('Waifu2x Converter CPP/NCNN accepts only scaling ratio')
|
||||
raise ArgumentError('waifu2x-converter supports only scaling ratio')
|
||||
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()):
|
||||
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')
|
||||
@@ -272,8 +276,25 @@ if (args.width and not args.height) or (not args.width and args.height):
|
||||
Avalon.error('You must specify both width and height')
|
||||
raise ArgumentError('only one of width or height is specified')
|
||||
|
||||
# check available memory
|
||||
check_memory()
|
||||
# check available memory if driver is waifu2x-based
|
||||
if args.driver in ['waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan']:
|
||||
check_memory()
|
||||
|
||||
# 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):
|
||||
while True:
|
||||
try:
|
||||
threads = Avalon.gets('Amount of threads to use [5]: ')
|
||||
args.threads = int(threads)
|
||||
break
|
||||
except ValueError:
|
||||
if threads == '':
|
||||
args.threads = 5
|
||||
break
|
||||
else:
|
||||
Avalon.error(f'{threads} is not a valid integer')
|
||||
|
||||
# read configurations from JSON
|
||||
config = read_config(args.config)
|
||||
@@ -298,6 +319,12 @@ elif args.driver == 'waifu2x_ncnn_vulkan':
|
||||
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'])
|
||||
|
||||
# read FFmpeg configuration
|
||||
ffmpeg_settings = config['ffmpeg']
|
||||
@@ -353,7 +380,7 @@ try:
|
||||
Avalon.error('Input and output path type mismatch')
|
||||
Avalon.error('Input is single file but output is directory')
|
||||
raise Exception('input output path type mismatch')
|
||||
if not re.search('.*\..*$', str(args.output)):
|
||||
if not re.search(r'.*\..*$', str(args.output)):
|
||||
Avalon.error('No suffix found in output file path')
|
||||
Avalon.error('Suffix must be specified for FFmpeg')
|
||||
raise Exception('No suffix specified')
|
||||
@@ -380,9 +407,13 @@ try:
|
||||
elif args.input.is_dir():
|
||||
# upscale videos in a directory
|
||||
Avalon.info(f'Upscaling videos in directory: {args.input}')
|
||||
|
||||
# make output directory if it doesn't exist
|
||||
args.output.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for input_video in [f for f in args.input.iterdir() if f.is_file()]:
|
||||
output_video = args.output / input_video
|
||||
upscaler = Upscaler(input_video=args.input / input_video, output_video=output_video, method=args.method, waifu2x_settings=waifu2x_settings, ffmpeg_settings=ffmpeg_settings)
|
||||
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)
|
||||
|
||||
# set optional options
|
||||
upscaler.waifu2x_driver = args.driver
|
||||
@@ -409,8 +440,6 @@ except Exception:
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
# remove Video2X cache directory
|
||||
try:
|
||||
with contextlib.suppress(FileNotFoundError):
|
||||
if not preserve_frames:
|
||||
shutil.rmtree(video2x_cache_directory)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Name: Video2x GUI
|
||||
Author: K4YT3X
|
||||
Date Created: July 27, 2019
|
||||
Last Modified: July 27, 2019
|
||||
Last Modified: August 17, 2019
|
||||
|
||||
Description: GUI for Video2X
|
||||
"""
|
||||
@@ -23,14 +23,18 @@ import pathlib
|
||||
import tempfile
|
||||
import threading
|
||||
import time
|
||||
import tkinter as tk
|
||||
|
||||
VERSION = '1.0.0'
|
||||
VERSION = '1.1.1'
|
||||
|
||||
LEGAL_INFO = f'''Video2X GUI Version: {VERSION}
|
||||
Author: K4YT3X
|
||||
License: GNU GPL v3
|
||||
Github Page: https://github.com/k4yt3x/video2x
|
||||
Contact: k4yt3x@k4yt3x.com'''
|
||||
|
||||
# global static variables
|
||||
|
||||
AVAILABLE_METHODS = {'GPU': 'gpu',
|
||||
AVAILABLE_METHODS = {
|
||||
'GPU': 'gpu',
|
||||
'CUDNN': 'cudnn',
|
||||
'CPU': 'cpu'
|
||||
}
|
||||
@@ -38,7 +42,8 @@ AVAILABLE_METHODS = {'GPU': 'gpu',
|
||||
AVAILABLE_DRIVERS = {
|
||||
'Waifu2X Caffe': 'waifu2x_caffe',
|
||||
'Waifu2X Converter CPP': 'waifu2x_converter',
|
||||
'Waifu2x NCNN Vulkan': 'waifu2x_ncnn_vulkan'
|
||||
'Waifu2x NCNN Vulkan': 'waifu2x_ncnn_vulkan',
|
||||
'Anime4K': 'anime4k'
|
||||
}
|
||||
|
||||
IMAGE_FORMATS = {'PNG', 'JPG'}
|
||||
@@ -52,10 +57,25 @@ class Video2xGui():
|
||||
|
||||
# create main window
|
||||
self.main_window = Tk()
|
||||
self.main_window.title('Video2X GUI')
|
||||
self.main_window.title(f'Video2X GUI {VERSION}')
|
||||
self.main_frame = Frame()
|
||||
self.main_frame.pack(fill=BOTH, expand=True)
|
||||
|
||||
# add menu bar
|
||||
self.menu_bar = Menu(self.main_frame)
|
||||
|
||||
# file menu
|
||||
self.file_menu = Menu(self.menu_bar, tearoff=0)
|
||||
self.file_menu.add_command(label='Exit', command=self.main_frame.quit)
|
||||
self.menu_bar.add_cascade(label='File', menu=self.file_menu)
|
||||
|
||||
# help menu
|
||||
self.help_menu = Menu(self.menu_bar, tearoff=0)
|
||||
self.help_menu.add_command(label='About', command=self._display_help)
|
||||
self.menu_bar.add_cascade(label='Help', menu=self.help_menu)
|
||||
|
||||
self.main_window.config(menu=self.menu_bar)
|
||||
|
||||
# file frame
|
||||
self.file_frame = Frame(self.main_frame)
|
||||
self.file_frame.pack(fill=X, padx=5, pady=5, expand=True)
|
||||
@@ -164,6 +184,9 @@ class Video2xGui():
|
||||
|
||||
self.main_frame.mainloop()
|
||||
|
||||
def _display_help(self):
|
||||
messagebox.showinfo('About', LEGAL_INFO)
|
||||
|
||||
def _launch_upscaling(self):
|
||||
|
||||
# prevent launching multiple instances
|
||||
@@ -178,8 +201,8 @@ class Video2xGui():
|
||||
if self.output_file.get() == '':
|
||||
messagebox.showerror('Error', 'You must specify output video file/directory path')
|
||||
return
|
||||
if (self.driver.get() == 'waifu2x_converter' or self.driver.get() == 'waifu2x_ncnn_vulkan') and self.width.get() and self.height.get():
|
||||
messagebox.showerror('Error', 'Waifu2x Converter CPP/NCNN accepts only scaling ratio')
|
||||
if (self.driver.get() in ['Waifu2X Converter CPP', 'Waifu2x NCNN Vulkan', 'Anime4K']) and self.width.get() and self.height.get():
|
||||
messagebox.showerror('Error', f'Selected driver \"{self.driver.get()}\" accepts only scaling ratio')
|
||||
return
|
||||
if self.driver.get() == 'waifu2x_ncnn_vulkan' and (self.scale_ratio.get() > 2 or not self.scale_ratio.get().is_integer()):
|
||||
messagebox.showerror('Error', 'Scaling ratio must be 1 or 2 for waifu2x_ncnn_vulkan')
|
||||
@@ -201,6 +224,9 @@ class Video2xGui():
|
||||
|
||||
def _upscale(self):
|
||||
|
||||
# start timer
|
||||
begin_time = time.time()
|
||||
|
||||
# read configuration file
|
||||
config = read_config('video2x.json')
|
||||
config = absolutify_paths(config)
|
||||
@@ -218,14 +244,21 @@ class Video2xGui():
|
||||
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'])
|
||||
|
||||
# read FFmpeg configuration
|
||||
ffmpeg_settings = config['ffmpeg']
|
||||
|
||||
# load video2x settings
|
||||
image_format = config['video2x']['image_format'].lower()
|
||||
preserve_frames = config['video2x']['preserve_frames']
|
||||
@@ -289,12 +322,11 @@ class Video2xGui():
|
||||
self.upscaler.cleanup_temp_directories()
|
||||
|
||||
# show message when upscaling completes
|
||||
messagebox.showinfo('Info', 'Upscaling Completed')
|
||||
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
|
||||
|
||||
@@ -317,7 +349,17 @@ class Video2xGui():
|
||||
|
||||
def _select_input(self):
|
||||
self.input_file.set(askopenfilename(title='Select Input File'))
|
||||
self.output_file.set(f'{self.input_file.get()}_output.mp4')
|
||||
|
||||
# try to set an output file name automatically
|
||||
output_file = pathlib.Path(f'{self.input_file.get()}_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_id += 1
|
||||
|
||||
if not output_file.exists():
|
||||
self.output_file.set(str(output_file))
|
||||
|
||||
def _select_output(self):
|
||||
self.output_file.set(asksaveasfilename(title='Select Output File'))
|
||||
|
||||
@@ -5,7 +5,7 @@ Name: Video2X Setup Script
|
||||
Author: K4YT3X
|
||||
Author: BrianPetkovsek
|
||||
Date Created: November 28, 2018
|
||||
Last Modified: July 30, 2019
|
||||
Last Modified: August 20, 2019
|
||||
|
||||
Dev: SAT3LL
|
||||
|
||||
@@ -22,10 +22,12 @@ Installation Details:
|
||||
- waifu2x-caffe: %LOCALAPPDATA%\\video2x\\waifu2x-caffe
|
||||
- waifu2x-cpp-converter: %LOCALAPPDATA%\\video2x\\waifu2x-converter-cpp
|
||||
- waifu2x_ncnn_vulkan: %LOCALAPPDATA%\\video2x\\waifu2x-ncnn-vulkan
|
||||
- anime4k: %LOCALAPPDATA%\\video2x\\anime4k
|
||||
"""
|
||||
|
||||
# built-in imports
|
||||
import argparse
|
||||
import contextlib
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
@@ -43,10 +45,11 @@ import zipfile
|
||||
# later in the script.
|
||||
# import requests
|
||||
|
||||
VERSION = '1.4.0'
|
||||
VERSION = '1.5.0'
|
||||
|
||||
# global static variables
|
||||
LOCALAPPDATA = pathlib.Path(os.getenv('localappdata'))
|
||||
DRIVER_OPTIONS = ['all', 'waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan', 'anime4k']
|
||||
|
||||
|
||||
def process_arguments():
|
||||
@@ -56,7 +59,7 @@ def process_arguments():
|
||||
|
||||
# video options
|
||||
general_options = parser.add_argument_group('General Options')
|
||||
general_options.add_argument('-d', '--driver', help='driver to download and configure', action='store', choices=['all', 'waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan'], default='all')
|
||||
general_options.add_argument('-d', '--driver', help='driver to download and configure', action='store', choices=DRIVER_OPTIONS, default='all')
|
||||
|
||||
# parse arguments
|
||||
return parser.parse_args()
|
||||
@@ -79,19 +82,22 @@ class Video2xSetup:
|
||||
print('\nInstalling Python libraries')
|
||||
self._install_python_requirements()
|
||||
|
||||
print('\nInstalling FFMPEG')
|
||||
print('\nInstalling FFmpeg')
|
||||
self._install_ffmpeg()
|
||||
|
||||
if self.driver == 'all':
|
||||
self._install_waifu2x_caffe()
|
||||
self._install_waifu2x_converter_cpp()
|
||||
self._install_waifu2x_ncnn_vulkan()
|
||||
self._install_anime4k()
|
||||
elif self.driver == 'waifu2x_caffe':
|
||||
self._install_waifu2x_caffe()
|
||||
elif self.driver == 'waifu2x_converter':
|
||||
self._install_waifu2x_converter_cpp()
|
||||
elif self.driver == 'waifu2x_ncnn_vulkan':
|
||||
self._install_waifu2x_ncnn_vulkan()
|
||||
elif self.driver == 'anime4k':
|
||||
self._install_anime4k()
|
||||
|
||||
print('\nGenerating Video2X configuration file')
|
||||
self._generate_config()
|
||||
@@ -137,7 +143,7 @@ class Video2xSetup:
|
||||
import requests
|
||||
|
||||
# Get latest release of waifu2x-caffe via GitHub API
|
||||
latest_release = json.loads(requests.get('https://api.github.com/repos/lltcggie/waifu2x-caffe/releases/latest').content.decode('utf-8'))
|
||||
latest_release = requests.get('https://api.github.com/repos/lltcggie/waifu2x-caffe/releases/latest').json()
|
||||
|
||||
for a in latest_release['assets']:
|
||||
if 'waifu2x-caffe.zip' in a['browser_download_url']:
|
||||
@@ -154,7 +160,7 @@ class Video2xSetup:
|
||||
import requests
|
||||
|
||||
# Get latest release of waifu2x-caffe via GitHub API
|
||||
latest_release = json.loads(requests.get('https://api.github.com/repos/DeadSix27/waifu2x-converter-cpp/releases/latest').content.decode('utf-8'))
|
||||
latest_release = requests.get('https://api.github.com/repos/DeadSix27/waifu2x-converter-cpp/releases/latest').json()
|
||||
|
||||
for a in latest_release['assets']:
|
||||
if re.search(r'waifu2x-DeadSix27-win64_v[0-9]*\.zip', a['browser_download_url']):
|
||||
@@ -171,7 +177,7 @@ class Video2xSetup:
|
||||
import requests
|
||||
|
||||
# Get latest release of waifu2x-ncnn-vulkan via Github API
|
||||
latest_release = json.loads(requests.get('https://api.github.com/repos/nihui/waifu2x-ncnn-vulkan/releases/latest').content.decode('utf-8'))
|
||||
latest_release = requests.get('https://api.github.com/repos/nihui/waifu2x-ncnn-vulkan/releases/latest').json()
|
||||
|
||||
for a in latest_release['assets']:
|
||||
if re.search(r'waifu2x-ncnn-vulkan-\d*\.zip', a['browser_download_url']):
|
||||
@@ -190,6 +196,34 @@ class Video2xSetup:
|
||||
# rename the newly extracted directory
|
||||
(LOCALAPPDATA / 'video2x' / zipf.namelist()[0]).rename(waifu2x_ncnn_vulkan_directory)
|
||||
|
||||
def _install_anime4k(self):
|
||||
""" Install Anime4K
|
||||
"""
|
||||
print('\nInstalling Anime4K')
|
||||
|
||||
"""
|
||||
import requests
|
||||
|
||||
# get latest release of Anime4K via Github API
|
||||
# at the time of writing this portion, Anime4K doesn't yet have a stable release
|
||||
# therefore releases/latest won't work
|
||||
latest_release = requests.get('https://api.github.com/repos/bloc97/Anime4K/releases').json()[0]
|
||||
|
||||
for a in latest_release['assets']:
|
||||
if 'Anime4K_Java.zip' in a['browser_download_url']:
|
||||
anime4k_zip = download(a['browser_download_url'], tempfile.gettempdir())
|
||||
self.trash.append(anime4k_zip)
|
||||
"""
|
||||
|
||||
# since Java pre-compiled release has been removed from download
|
||||
# page, we use this cached version as a temporary solution
|
||||
anime4k_zip = download('https://files.flexio.org/Resources/anime4k.zip', tempfile.gettempdir())
|
||||
self.trash.append(anime4k_zip)
|
||||
|
||||
# extract and rename
|
||||
with zipfile.ZipFile(anime4k_zip) as zipf:
|
||||
zipf.extractall(LOCALAPPDATA / 'video2x' / 'anime4k')
|
||||
|
||||
def _generate_config(self):
|
||||
""" Generate video2x config
|
||||
"""
|
||||
@@ -203,12 +237,15 @@ class Video2xSetup:
|
||||
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')
|
||||
elif self.driver == 'waifu2x_caffe':
|
||||
template_dict['waifu2x_caffe']['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')
|
||||
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')
|
||||
elif self.driver == 'anime4k':
|
||||
template_dict['anime4k']['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
|
||||
@@ -216,7 +253,7 @@ class Video2xSetup:
|
||||
|
||||
# Write configuration into file
|
||||
with open('video2x.json', 'w') as config:
|
||||
json.dump(template_dict, config, indent=4)
|
||||
json.dump(template_dict, config, indent=2)
|
||||
config.close()
|
||||
|
||||
|
||||
@@ -238,10 +275,8 @@ def download(url, save_path, chunk_size=4096):
|
||||
file_name = None
|
||||
if 'content-disposition' in stream.headers:
|
||||
disposition = stream.headers['content-disposition']
|
||||
try:
|
||||
with contextlib.suppress(IndexError):
|
||||
file_name = re.findall("filename=(.+)", disposition)[0].strip('"')
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
if file_name is None:
|
||||
# output_file = f'{save_path}\\{stream.url.split("/")[-1]}'
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Name: Waifu2x Caffe Driver
|
||||
Author: K4YT3X
|
||||
Date Created: Feb 24, 2018
|
||||
Last Modified: July 27, 2019
|
||||
Last Modified: August 3, 2019
|
||||
|
||||
Description: This class is a high-level wrapper
|
||||
for waifu2x-caffe.
|
||||
@@ -67,9 +67,9 @@ class Waifu2xCaffe:
|
||||
self.print_lock.release()
|
||||
|
||||
# list to be executed
|
||||
execute = []
|
||||
# initialize the list with waifu2x binary path as the first element
|
||||
execute = [str(self.waifu2x_settings['waifu2x_caffe_path'])]
|
||||
|
||||
execute.append(self.waifu2x_settings['waifu2x_caffe_path'])
|
||||
for key in self.waifu2x_settings.keys():
|
||||
|
||||
value = self.waifu2x_settings[key]
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Name: Waifu2x Converter CPP Driver
|
||||
Author: K4YT3X
|
||||
Date Created: February 8, 2019
|
||||
Last Modified: July 27, 2019
|
||||
Last Modified: August 3, 2019
|
||||
|
||||
Description: This class is a high-level wrapper
|
||||
for waifu2x-converter-cpp.
|
||||
@@ -48,15 +48,6 @@ class Waifu2xConverter:
|
||||
# overwrite config file settings
|
||||
self.waifu2x_settings['input'] = input_directory
|
||||
self.waifu2x_settings['output'] = output_directory
|
||||
|
||||
# temporary fix for https://github.com/DeadSix27/waifu2x-converter-cpp/issues/109
|
||||
"""
|
||||
self.waifu2x_settings['i'] = input_directory
|
||||
self.waifu2x_settings['o'] = output_directory
|
||||
self.waifu2x_settings['input'] = None
|
||||
self.waifu2x_settings['output'] = None
|
||||
"""
|
||||
|
||||
self.waifu2x_settings['scale-ratio'] = scale_ratio
|
||||
self.waifu2x_settings['jobs'] = jobs
|
||||
self.waifu2x_settings['output-format'] = image_format
|
||||
@@ -72,7 +63,8 @@ class Waifu2xConverter:
|
||||
self.print_lock.release()
|
||||
|
||||
# list to be executed
|
||||
execute = []
|
||||
# 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')]
|
||||
|
||||
for key in self.waifu2x_settings.keys():
|
||||
|
||||
@@ -80,7 +72,7 @@ class Waifu2xConverter:
|
||||
|
||||
# the key doesn't need to be passed in this case
|
||||
if key == 'waifu2x_converter_path':
|
||||
execute.append(pathlib.Path(str(value)) / 'waifu2x-converter-cpp.exe')
|
||||
continue
|
||||
|
||||
# null or None means that leave this option out (keep default)
|
||||
elif value is None or value is False:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
Name: Waifu2x NCNN Vulkan Driver
|
||||
Author: SAT3LL
|
||||
Date Created: June 26, 2019
|
||||
Last Modified: July 27, 2019
|
||||
Last Modified: August 3, 2019
|
||||
|
||||
Dev: K4YT3X
|
||||
|
||||
@@ -52,61 +52,42 @@ class Waifu2xNcnnVulkan:
|
||||
|
||||
try:
|
||||
# overwrite config file settings
|
||||
self.waifu2x_settings['input'] = input_directory
|
||||
self.waifu2x_settings['output'] = output_directory
|
||||
self.waifu2x_settings['i'] = input_directory
|
||||
self.waifu2x_settings['o'] = output_directory
|
||||
self.waifu2x_settings['s'] = scale_ratio
|
||||
|
||||
# print thread start message
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Thread {threading.current_thread().name} started')
|
||||
self.print_lock.release()
|
||||
|
||||
# waifu2x_ncnn_vulkan does not have long-opts, we'll have a dictionary that maps "our" config long-opt
|
||||
# names to their short opts
|
||||
waifu2x_ncnn_vulkan_opt_flag = {
|
||||
'input': '-i',
|
||||
'output': '-o',
|
||||
'noise-level': '-n',
|
||||
'scale-ratio': '-s',
|
||||
'tile-size': '-t',
|
||||
'model-path': '-m',
|
||||
'gpu': '-g',
|
||||
'load-proc-save_threads': '-j',
|
||||
'verbose': '-v'
|
||||
}
|
||||
# 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 = [self.waifu2x_settings['waifu2x_ncnn_vulkan_path']]
|
||||
for key in self.waifu2x_settings.keys():
|
||||
|
||||
value = self.waifu2x_settings[key]
|
||||
if key == 'waifu2x_ncnn_vulkan_path':
|
||||
continue
|
||||
elif key == 'input':
|
||||
execute.append(waifu2x_ncnn_vulkan_opt_flag[key])
|
||||
execute.append(input_directory)
|
||||
elif key == 'output':
|
||||
execute.append(waifu2x_ncnn_vulkan_opt_flag[key])
|
||||
execute.append(output_directory)
|
||||
elif key == 'scale-ratio':
|
||||
execute.append(waifu2x_ncnn_vulkan_opt_flag[key])
|
||||
# waifu2x_ncnn_vulkan does not accept an arbitrary scale ratio, max is 2
|
||||
if scale_ratio == 1:
|
||||
execute.append('1')
|
||||
else:
|
||||
execute.append('2')
|
||||
# allow upper if cases to take precedence
|
||||
elif value is None or value is False:
|
||||
|
||||
# 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:
|
||||
continue
|
||||
else:
|
||||
execute.append(waifu2x_ncnn_vulkan_opt_flag[key])
|
||||
if len(key) == 1:
|
||||
execute.append(f'-{key}')
|
||||
else:
|
||||
execute.append(f'--{key}')
|
||||
execute.append(str(value))
|
||||
|
||||
Avalon.debug_info(f'Executing: {execute}')
|
||||
subprocess.run(execute, check=True, stderr=subprocess.DEVNULL)
|
||||
completed_command = subprocess.run(execute, check=True)
|
||||
|
||||
# print thread exiting message
|
||||
self.print_lock.acquire()
|
||||
Avalon.debug_info(f'[upscaler] Thread {threading.current_thread().name} exiting')
|
||||
self.print_lock.release()
|
||||
|
||||
return 0
|
||||
# return command execution return code
|
||||
return completed_command.returncode
|
||||
except Exception as e:
|
||||
upscaler_exceptions.append(e)
|
||||
|
||||
Reference in New Issue
Block a user