Merge pull request #137 from k4yt3x/2.10.0-anime4k

2.10.0 anime4k
This commit is contained in:
K4YT3X 2019-08-16 15:49:33 +00:00 committed by GitHub
commit 7a3af366f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 227 additions and 46 deletions

View File

@ -2,11 +2,11 @@
### Official Discussion Group (Telegram): https://t.me/video2x ### 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. 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`. 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 2. AMD GPU / Nvidia GPU
3. AMD GPU driver / Nvidia GPU driver / Nvidia CUDNN 3. AMD GPU driver / Nvidia GPU driver / Nvidia CUDNN
4. [**FFmpeg**](https://ffmpeg.zeranoe.com/builds/) 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 ## Recent Changes
### 2.10.0 (August 16, 2019)
- **Added support for [Anime4K](https://github.com/bloc97/Anime4K)**
### 2.9.0 (July 27, 2019) ### 2.9.0 (July 27, 2019)
- Changed file handling method from `os` to `pathlib` - 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) ### 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 . - Added automatic installation support for `Anime4K`
### Setup Script 1.3.0 (June 25, 2019)
- Added automatic installation support for `waifu2x-ncnn-vulkan`
## Description ## Description
@ -97,6 +101,10 @@ Download: https://ffmpeg.org/download.html
Download: https://github.com/lltcggie/waifu2x-caffe/releases 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 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 ### Installing Dependencies
@ -144,7 +152,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 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. Enlarge the video to 1920x1080 using CUDNN. You may also use the `-r/--ratio` option.
@ -168,7 +176,7 @@ python video2x.py -i sample_input.mp4 -o sample_output.mp4 -m gpu -r 2 -d waifu2
### CPU ### 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 ```shell
python video2x.py -i sample_input.mp4 -o sample_output.mp4 -m cpu --width=1920 --height=1080 python video2x.py -i sample_input.mp4 -o sample_output.mp4 -m cpu --width=1920 --height=1080
@ -241,6 +249,7 @@ This project relies on the following software and projects.
- [waifu2x-caffe](https://github.com/lltcggie/waifu2x-caffe) - [waifu2x-caffe](https://github.com/lltcggie/waifu2x-caffe)
- [waifu2x-converter-cpp](https://github.com/DeadSix27/waifu2x-converter-cpp) - [waifu2x-converter-cpp](https://github.com/DeadSix27/waifu2x-converter-cpp)
- [waifu2x-ncnn-vulkan](https://github.com/nihui/waifu2x-ncnn-vulkan) - [waifu2x-ncnn-vulkan](https://github.com/nihui/waifu2x-ncnn-vulkan)
- [Anime4K](https://github.com/bloc97/Anime4K)
## Special Thanks ## Special Thanks

92
bin/anime4k.py Normal file
View 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)

View File

@ -4,7 +4,7 @@
Name: Video2X FFmpeg Controller Name: Video2X FFmpeg Controller
Author: K4YT3X Author: K4YT3X
Date Created: Feb 24, 2018 Date Created: Feb 24, 2018
Last Modified: August 3, 2019 Last Modified: August 15, 2019
Description: This class handles all FFmpeg related operations. Description: This class handles all FFmpeg related operations.
""" """
@ -119,6 +119,8 @@ class Ffmpeg:
self.ffmpeg_binary self.ffmpeg_binary
] ]
execute.extend(self._read_configuration(phase='video_to_frames'))
execute.extend([ execute.extend([
'-i', '-i',
input_video input_video
@ -130,8 +132,6 @@ class Ffmpeg:
extracted_frames / f'extracted_%0d.{self.image_format}' extracted_frames / f'extracted_%0d.{self.image_format}'
]) ])
execute.extend(self._read_configuration(phase='video_to_frames'))
self._execute(execute) self._execute(execute)
def convert_video(self, framerate, resolution, upscaled_frames): def convert_video(self, framerate, resolution, upscaled_frames):
@ -152,6 +152,9 @@ class Ffmpeg:
resolution resolution
] ]
# read other options
execute.extend(self._read_configuration(phase='frames_to_video'))
# read FFmpeg input options # read FFmpeg input options
execute.extend(self._read_configuration(phase='frames_to_video', section='input_options')) execute.extend(self._read_configuration(phase='frames_to_video', section='input_options'))
@ -173,9 +176,6 @@ class Ffmpeg:
# read FFmpeg output options # read FFmpeg output options
execute.extend(self._read_configuration(phase='frames_to_video', section='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 # specify output file location
execute.extend([ execute.extend([
upscaled_frames / 'no_audio.mp4' upscaled_frames / 'no_audio.mp4'
@ -192,12 +192,17 @@ class Ffmpeg:
upscaled_frames {string} -- directory containing upscaled frames upscaled_frames {string} -- directory containing upscaled frames
""" """
execute = [ execute = [
self.ffmpeg_binary, self.ffmpeg_binary
]
execute.extend(self._read_configuration(phase='migrating_tracks'))
execute.extend([
'-i', '-i',
upscaled_frames / 'no_audio.mp4', upscaled_frames / 'no_audio.mp4',
'-i', '-i',
input_video input_video
] ])
execute.extend(self._read_configuration(phase='migrating_tracks', section='output_options')) execute.extend(self._read_configuration(phase='migrating_tracks', section='output_options'))
@ -205,8 +210,6 @@ class Ffmpeg:
output_video output_video
]) ])
execute.extend(self._read_configuration(phase='migrating_tracks'))
self._execute(execute) self._execute(execute)
def _read_configuration(self, phase, section=None): def _read_configuration(self, phase, section=None):
@ -277,9 +280,9 @@ class Ffmpeg:
Returns: Returns:
int -- execution return code int -- execution return code
""" """
Avalon.debug_info(f'Executing: {execute}')
# turn all list elements into string to avoid errors # turn all list elements into string to avoid errors
execute = [str(e) for e in execute] execute = [str(e) for e in execute]
Avalon.debug_info(f'Executing: {execute}')
return subprocess.run(execute, shell=True, check=True).returncode return subprocess.run(execute, shell=True, check=True).returncode

View File

@ -4,7 +4,7 @@
Name: Video2X Upscaler Name: Video2X Upscaler
Author: K4YT3X Author: K4YT3X
Date Created: December 10, 2018 Date Created: December 10, 2018
Last Modified: August 3, 2019 Last Modified: August 15, 2019
Dev: SAT3LL Dev: SAT3LL
@ -15,6 +15,7 @@ Licensed under the GNU General Public License Version 3 (GNU GPL v3),
""" """
# local imports # local imports
from anime4k import Anime4k
from exceptions import * from exceptions import *
from ffmpeg import Ffmpeg from ffmpeg import Ffmpeg
from image_cleaner import ImageCleaner from image_cleaner import ImageCleaner
@ -37,6 +38,8 @@ import traceback
from avalon_framework import Avalon from avalon_framework import Avalon
from tqdm import tqdm from tqdm import tqdm
AVAILABLE_DRIVERS = ['waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan', 'anime4k']
class Upscaler: class Upscaler:
""" An instance of this class is a upscaler that will """ An instance of this class is a upscaler that will
@ -156,7 +159,7 @@ class Upscaler:
self.upscaler_exceptions = [] self.upscaler_exceptions = []
# initialize waifu2x driver # initialize waifu2x driver
drivers = ['waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan'] drivers = AVAILABLE_DRIVERS
if self.waifu2x_driver not in drivers: if self.waifu2x_driver not in drivers:
raise UnrecognizedDriverError(f'Unrecognized waifu2x driver: {self.waifu2x_driver}') raise UnrecognizedDriverError(f'Unrecognized waifu2x driver: {self.waifu2x_driver}')
@ -176,6 +179,8 @@ class Upscaler:
self.progress_bar_exit_signal = True self.progress_bar_exit_signal = True
progress_bar.join() progress_bar.join()
return return
# drivers that are to be multi-threaded by video2x
else: else:
# create a container for all upscaler threads # create a container for all upscaler threads
upscaler_threads = [] upscaler_threads = []
@ -247,6 +252,15 @@ class Upscaler:
self.scale_ratio, self.scale_ratio,
self.upscaler_exceptions)) 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 # create thread
thread.name = thread_info[1] thread.name = thread_info[1]

View File

@ -51,6 +51,10 @@
"g": 0, "g": 0,
"j": "1:2:2" "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": {
"ffmpeg_path": "C:\\Users\\K4YT3X\\AppData\\Local\\video2x\\ffmpeg-latest-win64-static\\bin", "ffmpeg_path": "C:\\Users\\K4YT3X\\AppData\\Local\\video2x\\ffmpeg-latest-win64-static\\bin",
"video_to_frames": { "video_to_frames": {
@ -73,6 +77,7 @@
"-b:v": null, "-b:v": null,
"-pix_fmt": null "-pix_fmt": null
}, },
"-hwaccel": "auto",
"-y": true "-y": true
}, },
"migrating_tracks": { "migrating_tracks": {
@ -85,6 +90,7 @@
"-c": "copy", "-c": "copy",
"-pix_fmt": null "-pix_fmt": null
}, },
"-hwaccel": "auto",
"-y": true "-y": true
} }
}, },

View File

@ -13,7 +13,7 @@ __ __ _ _ ___ __ __
Name: Video2X Controller Name: Video2X Controller
Author: K4YT3X Author: K4YT3X
Date Created: Feb 24, 2018 Date Created: Feb 24, 2018
Last Modified: August 7, 2019 Last Modified: August 15, 2019
Dev: BrianPetkovsek Dev: BrianPetkovsek
Dev: SAT3LL Dev: SAT3LL
@ -44,6 +44,7 @@ smooth and edges sharp.
# local imports # local imports
from exceptions import * from exceptions import *
from upscaler import AVAILABLE_DRIVERS
from upscaler import Upscaler from upscaler import Upscaler
# built-in imports # built-in imports
@ -64,7 +65,7 @@ from avalon_framework import Avalon
import GPUtil import GPUtil
import psutil import psutil
VERSION = '2.9.0' VERSION = '2.10.0'
LEGAL_INFO = f'''Video2X Version: {VERSION} LEGAL_INFO = f'''Video2X Version: {VERSION}
Author: K4YT3X Author: K4YT3X
@ -104,7 +105,7 @@ def process_arguments():
# upscaler options # upscaler options
upscaler_options = parser.add_argument_group('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('-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('-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('-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.json')
@ -225,6 +226,10 @@ def absolutify_paths(config):
if not re.match('^[a-z]:', config['waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_path'], re.IGNORECASE): 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'] 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 # check ffmpeg path
if not re.match('^[a-z]:', config['ffmpeg']['ffmpeg_path'], re.IGNORECASE): if not re.match('^[a-z]:', config['ffmpeg']['ffmpeg_path'], re.IGNORECASE):
config['ffmpeg']['ffmpeg_path'] = current_directory / config['ffmpeg']['ffmpeg_path'] config['ffmpeg']['ffmpeg_path'] = current_directory / config['ffmpeg']['ffmpeg_path']
@ -275,8 +280,25 @@ if (args.width and not args.height) or (not args.width and args.height):
Avalon.error('You must specify both width and height') Avalon.error('You must specify both width and height')
raise ArgumentError('only one of width or height is specified') raise ArgumentError('only one of width or height is specified')
# check available memory # check available memory if driver is waifu2x-based
check_memory() 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 # read configurations from JSON
config = read_config(args.config) config = read_config(args.config)
@ -301,6 +323,12 @@ elif args.driver == 'waifu2x_ncnn_vulkan':
Avalon.error('Specified waifu2x_ncnn_vulkan directory doesn\'t exist') Avalon.error('Specified waifu2x_ncnn_vulkan directory doesn\'t exist')
Avalon.error('Please check the configuration file settings') Avalon.error('Please check the configuration file settings')
raise FileNotFoundError(waifu2x_settings['waifu2x_ncnn_vulkan_path']) 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 # read FFmpeg configuration
ffmpeg_settings = config['ffmpeg'] ffmpeg_settings = config['ffmpeg']

View File

@ -4,7 +4,7 @@
Name: Video2x GUI Name: Video2x GUI
Author: K4YT3X Author: K4YT3X
Date Created: July 27, 2019 Date Created: July 27, 2019
Last Modified: August 7, 2019 Last Modified: August 16, 2019
Description: GUI for Video2X Description: GUI for Video2X
""" """
@ -25,7 +25,7 @@ import threading
import time import time
import tkinter as tk import tkinter as tk
VERSION = '1.1.0' VERSION = '1.1.1'
LEGAL_INFO = f'''Video2X GUI Version: {VERSION} LEGAL_INFO = f'''Video2X GUI Version: {VERSION}
Author: K4YT3X Author: K4YT3X
@ -43,7 +43,8 @@ AVAILABLE_METHODS = {
AVAILABLE_DRIVERS = { AVAILABLE_DRIVERS = {
'Waifu2X Caffe': 'waifu2x_caffe', 'Waifu2X Caffe': 'waifu2x_caffe',
'Waifu2X Converter CPP': 'waifu2x_converter', 'Waifu2X Converter CPP': 'waifu2x_converter',
'Waifu2x NCNN Vulkan': 'waifu2x_ncnn_vulkan' 'Waifu2x NCNN Vulkan': 'waifu2x_ncnn_vulkan',
'Anime4K': 'anime4k'
} }
IMAGE_FORMATS = {'PNG', 'JPG'} IMAGE_FORMATS = {'PNG', 'JPG'}

View File

@ -5,7 +5,7 @@ Name: Video2X Setup Script
Author: K4YT3X Author: K4YT3X
Author: BrianPetkovsek Author: BrianPetkovsek
Date Created: November 28, 2018 Date Created: November 28, 2018
Last Modified: July 30, 2019 Last Modified: August 16, 2019
Dev: SAT3LL Dev: SAT3LL
@ -22,6 +22,7 @@ Installation Details:
- waifu2x-caffe: %LOCALAPPDATA%\\video2x\\waifu2x-caffe - waifu2x-caffe: %LOCALAPPDATA%\\video2x\\waifu2x-caffe
- waifu2x-cpp-converter: %LOCALAPPDATA%\\video2x\\waifu2x-converter-cpp - waifu2x-cpp-converter: %LOCALAPPDATA%\\video2x\\waifu2x-converter-cpp
- waifu2x_ncnn_vulkan: %LOCALAPPDATA%\\video2x\\waifu2x-ncnn-vulkan - waifu2x_ncnn_vulkan: %LOCALAPPDATA%\\video2x\\waifu2x-ncnn-vulkan
- anime4k: %LOCALAPPDATA%\\video2x\\anime4k
""" """
# built-in imports # built-in imports
@ -43,10 +44,11 @@ import zipfile
# later in the script. # later in the script.
# import requests # import requests
VERSION = '1.4.0' VERSION = '1.5.0'
# global static variables # global static variables
LOCALAPPDATA = pathlib.Path(os.getenv('localappdata')) LOCALAPPDATA = pathlib.Path(os.getenv('localappdata'))
DRIVER_OPTIONS = ['all', 'waifu2x_caffe', 'waifu2x_converter', 'waifu2x_ncnn_vulkan', 'anime4k']
def process_arguments(): def process_arguments():
@ -56,7 +58,7 @@ def process_arguments():
# video options # video options
general_options = parser.add_argument_group('General 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 # parse arguments
return parser.parse_args() return parser.parse_args()
@ -86,12 +88,15 @@ class Video2xSetup:
self._install_waifu2x_caffe() self._install_waifu2x_caffe()
self._install_waifu2x_converter_cpp() self._install_waifu2x_converter_cpp()
self._install_waifu2x_ncnn_vulkan() self._install_waifu2x_ncnn_vulkan()
self._install_anime4k()
elif self.driver == 'waifu2x_caffe': elif self.driver == 'waifu2x_caffe':
self._install_waifu2x_caffe() self._install_waifu2x_caffe()
elif self.driver == 'waifu2x_converter': elif self.driver == 'waifu2x_converter':
self._install_waifu2x_converter_cpp() self._install_waifu2x_converter_cpp()
elif self.driver == 'waifu2x_ncnn_vulkan': elif self.driver == 'waifu2x_ncnn_vulkan':
self._install_waifu2x_ncnn_vulkan() self._install_waifu2x_ncnn_vulkan()
elif self.driver == 'anime4k':
self._install_anime4k()
print('\nGenerating Video2X configuration file') print('\nGenerating Video2X configuration file')
self._generate_config() self._generate_config()
@ -137,7 +142,7 @@ class Video2xSetup:
import requests import requests
# Get latest release of waifu2x-caffe via GitHub API # 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']: for a in latest_release['assets']:
if 'waifu2x-caffe.zip' in a['browser_download_url']: if 'waifu2x-caffe.zip' in a['browser_download_url']:
@ -154,7 +159,7 @@ class Video2xSetup:
import requests import requests
# Get latest release of waifu2x-caffe via GitHub API # 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']: for a in latest_release['assets']:
if re.search(r'waifu2x-DeadSix27-win64_v[0-9]*\.zip', a['browser_download_url']): if re.search(r'waifu2x-DeadSix27-win64_v[0-9]*\.zip', a['browser_download_url']):
@ -171,7 +176,7 @@ class Video2xSetup:
import requests import requests
# Get latest release of waifu2x-ncnn-vulkan via Github API # 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']: for a in latest_release['assets']:
if re.search(r'waifu2x-ncnn-vulkan-\d*\.zip', a['browser_download_url']): if re.search(r'waifu2x-ncnn-vulkan-\d*\.zip', a['browser_download_url']):
@ -190,6 +195,26 @@ class Video2xSetup:
# rename the newly extracted directory # rename the newly extracted directory
(LOCALAPPDATA / 'video2x' / zipf.namelist()[0]).rename(waifu2x_ncnn_vulkan_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)
# extract and rename
with zipfile.ZipFile(anime4k_zip) as zipf:
zipf.extractall(LOCALAPPDATA / 'video2x' / 'anime4k')
def _generate_config(self): def _generate_config(self):
""" Generate video2x config """ Generate video2x config
""" """
@ -203,12 +228,15 @@ class Video2xSetup:
template_dict['waifu2x_caffe']['waifu2x_caffe_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-caffe' / 'waifu2x-caffe-cui.exe') 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_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['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': 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']['waifu2x_caffe_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-caffe' / 'waifu2x-caffe-cui.exe')
elif self.driver == 'waifu2x_converter': elif self.driver == 'waifu2x_converter':
template_dict['waifu2x_converter']['waifu2x_converter_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-converter-cpp') template_dict['waifu2x_converter']['waifu2x_converter_path'] = str(LOCALAPPDATA / 'video2x' / 'waifu2x-converter-cpp')
elif self.driver == 'waifu2x_ncnn_vulkan': 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']['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['ffmpeg']['ffmpeg_path'] = str(LOCALAPPDATA / 'video2x' / 'ffmpeg-latest-win64-static' / 'bin')
template_dict['video2x']['video2x_cache_directory'] = None template_dict['video2x']['video2x_cache_directory'] = None
@ -216,7 +244,7 @@ class Video2xSetup:
# Write configuration into file # Write configuration into file
with open('video2x.json', 'w') as config: with open('video2x.json', 'w') as config:
json.dump(template_dict, config, indent=4) json.dump(template_dict, config, indent=2)
config.close() config.close()