mirror of
				https://github.com/k4yt3x/video2x.git
				synced 2025-11-04 06:31:00 +01:00 
			
		
		
		
	added internationalization support
This commit is contained in:
		
							parent
							
								
									19e6d241d5
								
							
						
					
					
						commit
						b8472f155a
					
				@ -82,9 +82,9 @@ class Upscaler:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # create temp directories for extracted frames and upscaled frames
 | 
					        # create temp directories for extracted frames and upscaled frames
 | 
				
			||||||
        self.extracted_frames = pathlib.Path(tempfile.mkdtemp(dir=self.video2x_cache_directory))
 | 
					        self.extracted_frames = pathlib.Path(tempfile.mkdtemp(dir=self.video2x_cache_directory))
 | 
				
			||||||
        Avalon.debug_info(f'Extracted frames are being saved to: {self.extracted_frames}')
 | 
					        Avalon.debug_info(_('Extracted frames are being saved to: {}').format(self.extracted_frames))
 | 
				
			||||||
        self.upscaled_frames = pathlib.Path(tempfile.mkdtemp(dir=self.video2x_cache_directory))
 | 
					        self.upscaled_frames = pathlib.Path(tempfile.mkdtemp(dir=self.video2x_cache_directory))
 | 
				
			||||||
        Avalon.debug_info(f'Upscaled frames are being saved to: {self.upscaled_frames}')
 | 
					        Avalon.debug_info(_('Upscaled frames are being saved to: {}').format(self.upscaled_frames))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def cleanup_temp_directories(self):
 | 
					    def cleanup_temp_directories(self):
 | 
				
			||||||
        """delete temp directories when done
 | 
					        """delete temp directories when done
 | 
				
			||||||
@ -94,35 +94,35 @@ class Upscaler:
 | 
				
			|||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    # avalon framework cannot be used if python is shutting down
 | 
					                    # avalon framework cannot be used if python is shutting down
 | 
				
			||||||
                    # therefore, plain print is used
 | 
					                    # therefore, plain print is used
 | 
				
			||||||
                    print(f'Cleaning up cache directory: {directory}')
 | 
					                    print(_('Cleaning up cache directory: {}').format(directory))
 | 
				
			||||||
                    shutil.rmtree(directory)
 | 
					                    shutil.rmtree(directory)
 | 
				
			||||||
                except (OSError, FileNotFoundError):
 | 
					                except (OSError, FileNotFoundError):
 | 
				
			||||||
                    print(f'Unable to delete: {directory}')
 | 
					                    print(_('Unable to delete: {}').format(directory))
 | 
				
			||||||
                    traceback.print_exc()
 | 
					                    traceback.print_exc()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _check_arguments(self):
 | 
					    def _check_arguments(self):
 | 
				
			||||||
        # check if arguments are valid / all necessary argument
 | 
					        # check if arguments are valid / all necessary argument
 | 
				
			||||||
        # values are specified
 | 
					        # values are specified
 | 
				
			||||||
        if not self.input_video:
 | 
					        if not self.input_video:
 | 
				
			||||||
            Avalon.error('You must specify input video file/directory path')
 | 
					            Avalon.error(_('You must specify input video file/directory path'))
 | 
				
			||||||
            raise ArgumentError('input video path not specified')
 | 
					            raise ArgumentError('input video path not specified')
 | 
				
			||||||
        if not self.output_video:
 | 
					        if not self.output_video:
 | 
				
			||||||
            Avalon.error('You must specify output video file/directory path')
 | 
					            Avalon.error(_('You must specify output video file/directory path'))
 | 
				
			||||||
            raise ArgumentError('output video path not specified')
 | 
					            raise ArgumentError('output video path not specified')
 | 
				
			||||||
        if (self.driver in ['waifu2x_converter', 'waifu2x_ncnn_vulkan', 'anime4k']) and self.scale_width and self.scale_height:
 | 
					        if (self.driver in ['waifu2x_converter', 'waifu2x_ncnn_vulkan', 'anime4k']) and self.scale_width and self.scale_height:
 | 
				
			||||||
            Avalon.error('Selected driver accepts only scaling ratio')
 | 
					            Avalon.error(_('Selected driver accepts only scaling ratio'))
 | 
				
			||||||
            raise ArgumentError('selected driver supports only scaling ratio')
 | 
					            raise ArgumentError('selected driver supports only scaling ratio')
 | 
				
			||||||
        if self.driver == 'waifu2x_ncnn_vulkan' and self.scale_ratio is not None and (self.scale_ratio > 2 or not self.scale_ratio.is_integer()):
 | 
					        if self.driver == 'waifu2x_ncnn_vulkan' and self.scale_ratio is not None and (self.scale_ratio > 2 or not self.scale_ratio.is_integer()):
 | 
				
			||||||
            Avalon.error('Scaling ratio must be 1 or 2 for waifu2x_ncnn_vulkan')
 | 
					            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')
 | 
					            raise ArgumentError('scaling ratio must be 1 or 2 for waifu2x_ncnn_vulkan')
 | 
				
			||||||
        if self.driver == 'srmd_ncnn_vulkan' and self.scale_ratio is not None and (self.scale_ratio not in [2, 3, 4]):
 | 
					        if self.driver == 'srmd_ncnn_vulkan' and self.scale_ratio is not None and (self.scale_ratio not in [2, 3, 4]):
 | 
				
			||||||
            Avalon.error('Scaling ratio must be one of 2, 3 or 4 for srmd_ncnn_vulkan')
 | 
					            Avalon.error(_('Scaling ratio must be one of 2, 3 or 4 for srmd_ncnn_vulkan'))
 | 
				
			||||||
            raise ArgumentError('scaling ratio must be one of 2, 3 or 4 for srmd_ncnn_vulkan')
 | 
					            raise ArgumentError('scaling ratio must be one of 2, 3 or 4 for srmd_ncnn_vulkan')
 | 
				
			||||||
        if (self.scale_width or self.scale_height) and self.scale_ratio:
 | 
					        if (self.scale_width or self.scale_height) and self.scale_ratio:
 | 
				
			||||||
            Avalon.error('You can only specify either scaling ratio or output width and height')
 | 
					            Avalon.error(_('You can only specify either scaling ratio or output width and height'))
 | 
				
			||||||
            raise ArgumentError('both scaling ration and width/height specified')
 | 
					            raise ArgumentError('both scaling ration and width/height specified')
 | 
				
			||||||
        if (self.scale_width and not self.scale_height) or (not self.scale_width and self.scale_height):
 | 
					        if (self.scale_width and not self.scale_height) or (not self.scale_width and self.scale_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')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _progress_bar(self, extracted_frames_directories):
 | 
					    def _progress_bar(self, extracted_frames_directories):
 | 
				
			||||||
@ -139,7 +139,7 @@ class Upscaler:
 | 
				
			|||||||
        for directory in extracted_frames_directories:
 | 
					        for directory in extracted_frames_directories:
 | 
				
			||||||
            self.total_frames += len([f for f in directory.iterdir() if str(f).lower().endswith(self.image_format.lower())])
 | 
					            self.total_frames += len([f for f in directory.iterdir() if str(f).lower().endswith(self.image_format.lower())])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        with tqdm(total=self.total_frames, ascii=True, desc='Upscaling Progress') as progress_bar:
 | 
					        with tqdm(total=self.total_frames, ascii=True, desc=_('Upscaling Progress')) as progress_bar:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # tqdm update method adds the value to the progress
 | 
					            # tqdm update method adds the value to the progress
 | 
				
			||||||
            # bar instead of setting the value. Therefore, a delta
 | 
					            # bar instead of setting the value. Therefore, a delta
 | 
				
			||||||
@ -176,7 +176,7 @@ class Upscaler:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        # initialize waifu2x driver
 | 
					        # initialize waifu2x driver
 | 
				
			||||||
        if self.driver not in AVAILABLE_DRIVERS:
 | 
					        if self.driver not in AVAILABLE_DRIVERS:
 | 
				
			||||||
            raise UnrecognizedDriverError(f'Unrecognized driver: {self.driver}')
 | 
					            raise UnrecognizedDriverError(_('Unrecognized driver: {}').format(self.driver))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # create a container for all upscaler processes
 | 
					        # create a container for all upscaler processes
 | 
				
			||||||
        upscaler_processes = []
 | 
					        upscaler_processes = []
 | 
				
			||||||
@ -255,15 +255,15 @@ class Upscaler:
 | 
				
			|||||||
        progress_bar.start()
 | 
					        progress_bar.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # create the clearer and start it
 | 
					        # create the clearer and start it
 | 
				
			||||||
        Avalon.debug_info('Starting upscaled image cleaner')
 | 
					        Avalon.debug_info(_('Starting upscaled image cleaner'))
 | 
				
			||||||
        image_cleaner = ImageCleaner(self.extracted_frames, self.upscaled_frames, len(upscaler_processes))
 | 
					        image_cleaner = ImageCleaner(self.extracted_frames, self.upscaled_frames, len(upscaler_processes))
 | 
				
			||||||
        image_cleaner.start()
 | 
					        image_cleaner.start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # wait for all process to exit
 | 
					        # wait for all process to exit
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            Avalon.debug_info('Main process waiting for subprocesses to exit')
 | 
					            Avalon.debug_info(_('Main process waiting for subprocesses to exit'))
 | 
				
			||||||
            for process in upscaler_processes:
 | 
					            for process in upscaler_processes:
 | 
				
			||||||
                Avalon.debug_info(f'Subprocess {process.pid} exited with code {process.wait()}')
 | 
					                Avalon.debug_info(_('Subprocess {} exited with code {}').format(process.pid, process.wait()))
 | 
				
			||||||
        except (KeyboardInterrupt, SystemExit):
 | 
					        except (KeyboardInterrupt, SystemExit):
 | 
				
			||||||
            Avalon.warning('Exit signal received')
 | 
					            Avalon.warning('Exit signal received')
 | 
				
			||||||
            Avalon.warning('Killing processes')
 | 
					            Avalon.warning('Killing processes')
 | 
				
			||||||
@ -271,7 +271,7 @@ class Upscaler:
 | 
				
			|||||||
                process.terminate()
 | 
					                process.terminate()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # cleanup and exit with exit code 1
 | 
					            # cleanup and exit with exit code 1
 | 
				
			||||||
            Avalon.debug_info('Killing upscaled image cleaner')
 | 
					            Avalon.debug_info(_('Killing upscaled image cleaner'))
 | 
				
			||||||
            image_cleaner.stop()
 | 
					            image_cleaner.stop()
 | 
				
			||||||
            self.progress_bar_exit_signal = True
 | 
					            self.progress_bar_exit_signal = True
 | 
				
			||||||
            sys.exit(1)
 | 
					            sys.exit(1)
 | 
				
			||||||
@ -284,7 +284,7 @@ class Upscaler:
 | 
				
			|||||||
                (self.upscaled_frames / image).rename(self.upscaled_frames / renamed)
 | 
					                (self.upscaled_frames / image).rename(self.upscaled_frames / renamed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # upscaling done, kill the clearer
 | 
					        # upscaling done, kill the clearer
 | 
				
			||||||
        Avalon.debug_info('Killing upscaled image cleaner')
 | 
					        Avalon.debug_info(_('Killing upscaled image cleaner'))
 | 
				
			||||||
        image_cleaner.stop()
 | 
					        image_cleaner.stop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # pass exit signal to progress bar thread
 | 
					        # pass exit signal to progress bar thread
 | 
				
			||||||
@ -310,10 +310,10 @@ class Upscaler:
 | 
				
			|||||||
            # append FFmpeg path to the end of PATH
 | 
					            # append FFmpeg path to the end of PATH
 | 
				
			||||||
            # Anime4KCPP will then use FFmpeg to migrate audio tracks
 | 
					            # Anime4KCPP will then use FFmpeg to migrate audio tracks
 | 
				
			||||||
            os.environ['PATH'] += f';{self.ffmpeg_settings["ffmpeg_path"]}'
 | 
					            os.environ['PATH'] += f';{self.ffmpeg_settings["ffmpeg_path"]}'
 | 
				
			||||||
            Avalon.info('Starting to upscale extracted images')
 | 
					            Avalon.info(_('Starting to upscale extracted images'))
 | 
				
			||||||
            driver = Anime4kCpp(self.driver_settings)
 | 
					            driver = Anime4kCpp(self.driver_settings)
 | 
				
			||||||
            driver.upscale(self.input_video, self.output_video, self.scale_ratio, self.processes).wait()
 | 
					            driver.upscale(self.input_video, self.output_video, self.scale_ratio, self.processes).wait()
 | 
				
			||||||
            Avalon.info('Upscaling completed')
 | 
					            Avalon.info(_('Upscaling completed'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            self.create_temp_directories()
 | 
					            self.create_temp_directories()
 | 
				
			||||||
@ -321,7 +321,7 @@ class Upscaler:
 | 
				
			|||||||
            # initialize objects for ffmpeg and waifu2x-caffe
 | 
					            # initialize objects for ffmpeg and waifu2x-caffe
 | 
				
			||||||
            fm = Ffmpeg(self.ffmpeg_settings, self.image_format)
 | 
					            fm = Ffmpeg(self.ffmpeg_settings, self.image_format)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Avalon.info('Reading video information')
 | 
					            Avalon.info(_('Reading video information'))
 | 
				
			||||||
            video_info = fm.get_video_info(self.input_video)
 | 
					            video_info = fm.get_video_info(self.input_video)
 | 
				
			||||||
            # analyze original video with ffprobe and retrieve framerate
 | 
					            # analyze original video with ffprobe and retrieve framerate
 | 
				
			||||||
            # width, height = info['streams'][0]['width'], info['streams'][0]['height']
 | 
					            # width, height = info['streams'][0]['width'], info['streams'][0]['height']
 | 
				
			||||||
@ -335,7 +335,7 @@ class Upscaler:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            # exit if no video stream found
 | 
					            # exit if no video stream found
 | 
				
			||||||
            if video_stream_index is None:
 | 
					            if video_stream_index is None:
 | 
				
			||||||
                Avalon.error('Aborting: No video stream found')
 | 
					                Avalon.error(_('Aborting: No video stream found'))
 | 
				
			||||||
                raise StreamNotFoundError('no video stream found')
 | 
					                raise StreamNotFoundError('no video stream found')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # extract frames from video
 | 
					            # extract frames from video
 | 
				
			||||||
@ -352,10 +352,10 @@ class Upscaler:
 | 
				
			|||||||
            try:
 | 
					            try:
 | 
				
			||||||
                self.bit_depth = pixel_formats[fm.pixel_format]
 | 
					                self.bit_depth = pixel_formats[fm.pixel_format]
 | 
				
			||||||
            except KeyError:
 | 
					            except KeyError:
 | 
				
			||||||
                Avalon.error(f'Unsupported pixel format: {fm.pixel_format}')
 | 
					                Avalon.error(_('Unsupported pixel format: {}').format(fm.pixel_format))
 | 
				
			||||||
                raise UnsupportedPixelError(f'unsupported pixel format {fm.pixel_format}')
 | 
					                raise UnsupportedPixelError(f'unsupported pixel format {fm.pixel_format}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Avalon.info(f'Framerate: {framerate}')
 | 
					            Avalon.info(_('Framerate: {}').format(framerate))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # width/height will be coded width/height x upscale factor
 | 
					            # width/height will be coded width/height x upscale factor
 | 
				
			||||||
            if self.scale_ratio:
 | 
					            if self.scale_ratio:
 | 
				
			||||||
@ -365,19 +365,19 @@ class Upscaler:
 | 
				
			|||||||
                self.scale_height = int(self.scale_ratio * original_height)
 | 
					                self.scale_height = int(self.scale_ratio * original_height)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # upscale images one by one using waifu2x
 | 
					            # upscale images one by one using waifu2x
 | 
				
			||||||
            Avalon.info('Starting to upscale extracted images')
 | 
					            Avalon.info(_('Starting to upscale extracted images'))
 | 
				
			||||||
            self._upscale_frames()
 | 
					            self._upscale_frames()
 | 
				
			||||||
            Avalon.info('Upscaling completed')
 | 
					            Avalon.info(_('Upscaling completed'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # frames to Video
 | 
					            # frames to Video
 | 
				
			||||||
            Avalon.info('Converting extracted frames into video')
 | 
					            Avalon.info(_('Converting extracted frames into video'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # use user defined output size
 | 
					            # use user defined output size
 | 
				
			||||||
            fm.convert_video(framerate, f'{self.scale_width}x{self.scale_height}', self.upscaled_frames)
 | 
					            fm.convert_video(framerate, f'{self.scale_width}x{self.scale_height}', self.upscaled_frames)
 | 
				
			||||||
            Avalon.info('Conversion completed')
 | 
					            Avalon.info(_('Conversion completed'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # migrate audio tracks and subtitles
 | 
					            # migrate audio tracks and subtitles
 | 
				
			||||||
            Avalon.info('Migrating audio tracks and subtitles to upscaled video')
 | 
					            Avalon.info(_('Migrating audio tracks and subtitles to upscaled video'))
 | 
				
			||||||
            fm.migrate_audio_tracks_subtitles(self.input_video, self.output_video, self.upscaled_frames)
 | 
					            fm.migrate_audio_tracks_subtitles(self.input_video, self.output_video, self.upscaled_frames)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # destroy temp directories
 | 
					            # destroy temp directories
 | 
				
			||||||
 | 
				
			|||||||
@ -55,7 +55,9 @@ from upscaler import Upscaler
 | 
				
			|||||||
# built-in imports
 | 
					# built-in imports
 | 
				
			||||||
import argparse
 | 
					import argparse
 | 
				
			||||||
import contextlib
 | 
					import contextlib
 | 
				
			||||||
 | 
					import gettext
 | 
				
			||||||
import importlib
 | 
					import importlib
 | 
				
			||||||
 | 
					import locale
 | 
				
			||||||
import pathlib
 | 
					import pathlib
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
import shutil
 | 
					import shutil
 | 
				
			||||||
@ -68,14 +70,24 @@ import yaml
 | 
				
			|||||||
# third-party imports
 | 
					# third-party imports
 | 
				
			||||||
from avalon_framework import Avalon
 | 
					from avalon_framework import Avalon
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# internationalization constants
 | 
				
			||||||
 | 
					DOMAIN = 'video2x'
 | 
				
			||||||
 | 
					LOCALE_DIRECTORY = pathlib.Path(__file__).parent.absolute() / 'locale'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# getting default locale settings
 | 
				
			||||||
 | 
					default_locale, encoding = locale.getdefaultlocale()
 | 
				
			||||||
 | 
					language = gettext.translation(DOMAIN, LOCALE_DIRECTORY, [default_locale], fallback=True)
 | 
				
			||||||
 | 
					language.install()
 | 
				
			||||||
 | 
					_ = language.gettext
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VERSION = '4.0.0'
 | 
					VERSION = '4.0.0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LEGAL_INFO = f'''Video2X Version: {VERSION}
 | 
					LEGAL_INFO = _('''Video2X Version: {}
 | 
				
			||||||
Author: K4YT3X
 | 
					Author: K4YT3X
 | 
				
			||||||
License: GNU GPL v3
 | 
					License: GNU GPL v3
 | 
				
			||||||
Github Page: https://github.com/k4yt3x/video2x
 | 
					Github Page: https://github.com/k4yt3x/video2x
 | 
				
			||||||
Contact: k4yt3x@k4yt3x.com'''
 | 
					Contact: k4yt3x@k4yt3x.com''').format(VERSION)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LOGO = r'''
 | 
					LOGO = r'''
 | 
				
			||||||
    __      __  _       _                  ___   __   __
 | 
					    __      __  _       _                  ___   __   __
 | 
				
			||||||
@ -90,23 +102,24 @@ LOGO = r'''
 | 
				
			|||||||
def parse_arguments():
 | 
					def parse_arguments():
 | 
				
			||||||
    """ parse CLI arguments
 | 
					    """ parse CLI arguments
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    parser = argparse.ArgumentParser(prog='video2x', formatter_class=argparse.ArgumentDefaultsHelpFormatter)
 | 
					    parser = argparse.ArgumentParser(prog='video2x', formatter_class=argparse.ArgumentDefaultsHelpFormatter, add_help=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # video options
 | 
					    # video options
 | 
				
			||||||
    general_options = parser.add_argument_group('General Options')
 | 
					    general_options = parser.add_argument_group(_('General Options'))
 | 
				
			||||||
    general_options.add_argument('-i', '--input', type=pathlib.Path, help='source video file/directory')
 | 
					    general_options.add_argument('-h', '--help', action='help', help=_('show this help message and exit'))
 | 
				
			||||||
    general_options.add_argument('-o', '--output', type=pathlib.Path, help='output video file/directory')
 | 
					    general_options.add_argument('-i', '--input', type=pathlib.Path, help=_('source video file/directory'))
 | 
				
			||||||
    general_options.add_argument('-c', '--config', type=pathlib.Path, help='video2x config file location', action='store',
 | 
					    general_options.add_argument('-o', '--output', type=pathlib.Path, help=_('output video file/directory'))
 | 
				
			||||||
 | 
					    general_options.add_argument('-c', '--config', type=pathlib.Path, help=_('video2x config file path'), action='store',
 | 
				
			||||||
                                 default=pathlib.Path(__file__).parent.absolute() / 'video2x.yaml')
 | 
					                                 default=pathlib.Path(__file__).parent.absolute() / 'video2x.yaml')
 | 
				
			||||||
    general_options.add_argument('-d', '--driver', help='upscaling driver', choices=AVAILABLE_DRIVERS, default='waifu2x_caffe')
 | 
					    general_options.add_argument('-d', '--driver', help=_('upscaling driver'), choices=AVAILABLE_DRIVERS, default='waifu2x_caffe')
 | 
				
			||||||
    general_options.add_argument('-p', '--processes', help='number of processes to use for upscaling', action='store', type=int, default=1)
 | 
					    general_options.add_argument('-p', '--processes', help=_('number of processes to use for upscaling'), action='store', type=int, default=1)
 | 
				
			||||||
    general_options.add_argument('-v', '--version', help='display version, lawful information and exit', action='store_true')
 | 
					    general_options.add_argument('-v', '--version', help=_('display version, lawful information and exit'), action='store_true')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # scaling options
 | 
					    # scaling options
 | 
				
			||||||
    scaling_options = parser.add_argument_group('Scaling Options')
 | 
					    scaling_options = parser.add_argument_group(_('Scaling Options'))
 | 
				
			||||||
    scaling_options.add_argument('--width', help='output video width', action='store', type=int)
 | 
					    scaling_options.add_argument('--width', help=_('output video width'), action='store', type=int)
 | 
				
			||||||
    scaling_options.add_argument('--height', help='output video height', action='store', type=int)
 | 
					    scaling_options.add_argument('--height', help=_('output video height'), action='store', type=int)
 | 
				
			||||||
    scaling_options.add_argument('-r', '--ratio', help='scaling ratio', action='store', type=float)
 | 
					    scaling_options.add_argument('-r', '--ratio', help=_('scaling ratio'), action='store', type=float)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # if no driver arguments are specified
 | 
					    # if no driver arguments are specified
 | 
				
			||||||
    if '--' not in sys.argv:
 | 
					    if '--' not in sys.argv:
 | 
				
			||||||
@ -146,7 +159,7 @@ def read_config(config_file: pathlib.Path) -> dict:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# this is not a library
 | 
					# this is not a library
 | 
				
			||||||
if __name__ != '__main__':
 | 
					if __name__ != '__main__':
 | 
				
			||||||
    Avalon.error('This file cannot be imported')
 | 
					    Avalon.error(_('This file cannot be imported'))
 | 
				
			||||||
    raise ImportError(f'{__file__} cannot be imported')
 | 
					    raise ImportError(f'{__file__} cannot be imported')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# print video2x logo
 | 
					# print video2x logo
 | 
				
			||||||
@ -176,8 +189,8 @@ if driver_args is not None:
 | 
				
			|||||||
# check if driver path exists
 | 
					# check if driver path exists
 | 
				
			||||||
if not pathlib.Path(driver_settings['path']).exists():
 | 
					if not pathlib.Path(driver_settings['path']).exists():
 | 
				
			||||||
    if not pathlib.Path(f'{driver_settings["path"]}.exe').exists():
 | 
					    if not pathlib.Path(f'{driver_settings["path"]}.exe').exists():
 | 
				
			||||||
        Avalon.error('Specified driver executable directory doesn\'t exist')
 | 
					        Avalon.error(_('Specified driver executable directory doesn\'t exist'))
 | 
				
			||||||
        Avalon.error('Please check the configuration file settings')
 | 
					        Avalon.error(_('Please check the configuration file settings'))
 | 
				
			||||||
        raise FileNotFoundError(driver_settings['path'])
 | 
					        raise FileNotFoundError(driver_settings['path'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# read FFmpeg configuration
 | 
					# read FFmpeg configuration
 | 
				
			||||||
@ -194,20 +207,20 @@ else:
 | 
				
			|||||||
    video2x_cache_directory = pathlib.Path(tempfile.gettempdir()) / 'video2x'
 | 
					    video2x_cache_directory = pathlib.Path(tempfile.gettempdir()) / 'video2x'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if video2x_cache_directory.exists() and not video2x_cache_directory.is_dir():
 | 
					if video2x_cache_directory.exists() and not video2x_cache_directory.is_dir():
 | 
				
			||||||
    Avalon.error('Specified cache directory is a file/link')
 | 
					    Avalon.error(_('Specified cache directory is a file/link'))
 | 
				
			||||||
    raise FileExistsError('Specified cache directory is a file/link')
 | 
					    raise FileExistsError('Specified cache directory is a file/link')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# if cache directory doesn't exist
 | 
					# if cache directory doesn't exist
 | 
				
			||||||
# ask the user if it should be created
 | 
					# ask the user if it should be created
 | 
				
			||||||
elif not video2x_cache_directory.exists():
 | 
					elif not video2x_cache_directory.exists():
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        Avalon.debug_info(f'Creating cache directory {video2x_cache_directory}')
 | 
					        Avalon.debug_info(_('Creating cache directory {}').format(video2x_cache_directory))
 | 
				
			||||||
        video2x_cache_directory.mkdir(parents=True, exist_ok=True)
 | 
					        video2x_cache_directory.mkdir(parents=True, exist_ok=True)
 | 
				
			||||||
    # there can be a number of exceptions here
 | 
					    # there can be a number of exceptions here
 | 
				
			||||||
    # PermissionError, FileExistsError, etc.
 | 
					    # PermissionError, FileExistsError, etc.
 | 
				
			||||||
    # therefore, we put a catch-them-all here
 | 
					    # therefore, we put a catch-them-all here
 | 
				
			||||||
    except Exception as exception:
 | 
					    except Exception as exception:
 | 
				
			||||||
        Avalon.error(f'Unable to create {video2x_cache_directory}')
 | 
					        Avalon.error(_('Unable to create {}').format(video2x_cache_directory))
 | 
				
			||||||
        raise exception
 | 
					        raise exception
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -220,16 +233,16 @@ try:
 | 
				
			|||||||
    if video2x_args.input.is_file():
 | 
					    if video2x_args.input.is_file():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # upscale single video file
 | 
					        # upscale single video file
 | 
				
			||||||
        Avalon.info(f'Upscaling single video file: {video2x_args.input}')
 | 
					        Avalon.info(_('Upscaling single video file: {}').format(video2x_args.input))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # check for input output format mismatch
 | 
					        # check for input output format mismatch
 | 
				
			||||||
        if video2x_args.output.is_dir():
 | 
					        if video2x_args.output.is_dir():
 | 
				
			||||||
            Avalon.error('Input and output path type mismatch')
 | 
					            Avalon.error(_('Input and output path type mismatch'))
 | 
				
			||||||
            Avalon.error('Input is single file but output is directory')
 | 
					            Avalon.error(_('Input is single file but output is directory'))
 | 
				
			||||||
            raise Exception('input output path type mismatch')
 | 
					            raise Exception('input output path type mismatch')
 | 
				
			||||||
        if not re.search(r'.*\..*$', str(video2x_args.output)):
 | 
					        if not re.search(r'.*\..*$', str(video2x_args.output)):
 | 
				
			||||||
            Avalon.error('No suffix found in output file path')
 | 
					            Avalon.error(_('No suffix found in output file path'))
 | 
				
			||||||
            Avalon.error('Suffix must be specified for FFmpeg')
 | 
					            Avalon.error(_('Suffix must be specified for FFmpeg'))
 | 
				
			||||||
            raise Exception('No suffix specified')
 | 
					            raise Exception('No suffix specified')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        upscaler = Upscaler(input_video=video2x_args.input,
 | 
					        upscaler = Upscaler(input_video=video2x_args.input,
 | 
				
			||||||
@ -253,7 +266,7 @@ try:
 | 
				
			|||||||
    # if input specified is a directory
 | 
					    # if input specified is a directory
 | 
				
			||||||
    elif video2x_args.input.is_dir():
 | 
					    elif video2x_args.input.is_dir():
 | 
				
			||||||
        # upscale videos in a directory
 | 
					        # upscale videos in a directory
 | 
				
			||||||
        Avalon.info(f'Upscaling videos in directory: {video2x_args.input}')
 | 
					        Avalon.info(_('Upscaling videos in directory: {}').format(video2x_args.input))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # make output directory if it doesn't exist
 | 
					        # make output directory if it doesn't exist
 | 
				
			||||||
        video2x_args.output.mkdir(parents=True, exist_ok=True)
 | 
					        video2x_args.output.mkdir(parents=True, exist_ok=True)
 | 
				
			||||||
@ -278,13 +291,13 @@ try:
 | 
				
			|||||||
            # run upscaler
 | 
					            # run upscaler
 | 
				
			||||||
            upscaler.run()
 | 
					            upscaler.run()
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        Avalon.error('Input path is neither a file nor a directory')
 | 
					        Avalon.error(_('Input path is neither a file nor a directory'))
 | 
				
			||||||
        raise FileNotFoundError(f'{video2x_args.input} is neither file nor directory')
 | 
					        raise FileNotFoundError(f'{video2x_args.input} is neither file nor directory')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Avalon.info(f'Program completed, taking {round((time.time() - begin_time), 5)} seconds')
 | 
					    Avalon.info(_('Program completed, taking {} seconds').format(round((time.time() - begin_time), 5)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
except Exception:
 | 
					except Exception:
 | 
				
			||||||
    Avalon.error('An exception has occurred')
 | 
					    Avalon.error(_('An exception has occurred'))
 | 
				
			||||||
    traceback.print_exc()
 | 
					    traceback.print_exc()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # try cleaning up temp directories
 | 
					    # try cleaning up temp directories
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user