Exemple #1
0
    def run(self):
        """ Main controller for Video2X

        This function controls the flow of video conversion
        and handles all necessary functions.
        """

        # parse arguments for waifu2x
        # check argument sanity
        self._check_arguments()

        # convert paths to absolute paths
        self.input_video = self.input_video.absolute()
        self.output_video = self.output_video.absolute()

        # drivers that have native support for video processing
        if self.driver == 'anime4kcpp':
            # append FFmpeg path to the end of PATH
            # Anime4KCPP will then use FFmpeg to migrate audio tracks
            os.environ['PATH'] += f';{self.ffmpeg_settings["ffmpeg_path"]}'
            Avalon.info(_('Starting to upscale extracted images'))

            # import and initialize Anime4KCPP wrapper
            DriverWrapperMain = getattr(
                importlib.import_module('wrappers.anime4kcpp'), 'WrapperMain')
            driver = DriverWrapperMain(copy.deepcopy(self.driver_settings))

            # run Anime4KCPP
            driver.upscale(self.input_video, self.output_video,
                           self.scale_ratio, self.processes).wait()
            Avalon.info(_('Upscaling completed'))

        else:
            self.create_temp_directories()

            # initialize objects for ffmpeg and waifu2x-caffe
            fm = Ffmpeg(self.ffmpeg_settings, self.image_format)

            Avalon.info(_('Reading video information'))
            video_info = fm.get_video_info(self.input_video)
            # analyze original video with ffprobe and retrieve framerate
            # width, height = info['streams'][0]['width'], info['streams'][0]['height']

            # find index of video stream
            video_stream_index = None
            for stream in video_info['streams']:
                if stream['codec_type'] == 'video':
                    video_stream_index = stream['index']
                    break

            # exit if no video stream found
            if video_stream_index is None:
                Avalon.error(_('Aborting: No video stream found'))
                raise StreamNotFoundError('no video stream found')

            # extract frames from video
            fm.extract_frames(self.input_video, self.extracted_frames)

            # get average frame rate of video stream
            framerate = float(
                Fraction(video_info['streams'][video_stream_index]
                         ['avg_frame_rate']))
            fm.pixel_format = video_info['streams'][video_stream_index][
                'pix_fmt']

            # get a dict of all pixel formats and corresponding bit depth
            pixel_formats = fm.get_pixel_formats()

            # try getting pixel format's corresponding bti depth
            try:
                self.bit_depth = pixel_formats[fm.pixel_format]
            except KeyError:
                Avalon.error(
                    _('Unsupported pixel format: {}').format(fm.pixel_format))
                raise UnsupportedPixelError(
                    f'unsupported pixel format {fm.pixel_format}')

            Avalon.info(_('Framerate: {}').format(framerate))

            # width/height will be coded width/height x upscale factor
            if self.scale_ratio:
                original_width = video_info['streams'][video_stream_index][
                    'width']
                original_height = video_info['streams'][video_stream_index][
                    'height']
                self.scale_width = int(self.scale_ratio * original_width)
                self.scale_height = int(self.scale_ratio * original_height)

            # upscale images one by one using waifu2x
            Avalon.info(_('Starting to upscale extracted images'))
            self._upscale_frames()
            Avalon.info(_('Upscaling completed'))

            # frames to Video
            Avalon.info(_('Converting extracted frames into video'))

            # use user defined output size
            fm.convert_video(framerate,
                             f'{self.scale_width}x{self.scale_height}',
                             self.upscaled_frames)
            Avalon.info(_('Conversion completed'))

            # migrate audio tracks and subtitles
            Avalon.info(
                _('Migrating audio tracks and subtitles to upscaled video'))
            fm.migrate_audio_tracks_subtitles(self.input_video,
                                              self.output_video,
                                              self.upscaled_frames)

            # destroy temp directories
            self.cleanup_temp_directories()
Exemple #2
0
    def run(self):
        """ Main controller for Video2X

        This function controls the flow of video conversion
        and handles all necessary functions.
        """

        # external stop signal when called in a thread
        self.stop_signal = False

        # define process pool to contain processes
        self.process_pool = []

        # parse arguments for waifu2x
        # check argument sanity
        self._check_arguments()

        # define processing queue
        processing_queue = queue.Queue()

        # if input specified is single file
        if self.input_path.is_file():
            Avalon.info(_('Upscaling single video file: {}').format(self.input_path))
            processing_queue.put((self.input_path.absolute(), self.output_path.absolute()))

        # if input specified is a directory
        elif self.input_path.is_dir():

            # make output directory if it doesn't exist
            self.output_path.mkdir(parents=True, exist_ok=True)
            for input_video in [f for f in self.input_path.iterdir() if f.is_file()]:
                output_video = self.output_path / input_video.name
                processing_queue.put((input_video.absolute(), output_video.absolute()))

        while not processing_queue.empty():
            input_video, output_video = processing_queue.get()
            # drivers that have native support for video processing
            if self.driver == 'anime4kcpp':
                # append FFmpeg path to the end of PATH
                # Anime4KCPP will then use FFmpeg to migrate audio tracks
                os.environ['PATH'] += f';{self.ffmpeg_settings["ffmpeg_path"]}'
                Avalon.info(_('Starting to upscale extracted images'))

                # import and initialize Anime4KCPP wrapper
                DriverWrapperMain = getattr(importlib.import_module('wrappers.anime4kcpp'), 'WrapperMain')
                driver = DriverWrapperMain(copy.deepcopy(self.driver_settings))

                # run Anime4KCPP
                self.process_pool.append(driver.upscale(input_video, output_video, self.scale_ratio, self.processes))
                self._wait()
                Avalon.info(_('Upscaling completed'))

            else:
                try:
                    self.create_temp_directories()

                    # initialize objects for ffmpeg and waifu2x-caffe
                    fm = Ffmpeg(self.ffmpeg_settings, self.image_format)

                    Avalon.info(_('Reading video information'))
                    video_info = fm.get_video_info(input_video)
                    # analyze original video with ffprobe and retrieve framerate
                    # width, height = info['streams'][0]['width'], info['streams'][0]['height']

                    # find index of video stream
                    video_stream_index = None
                    for stream in video_info['streams']:
                        if stream['codec_type'] == 'video':
                            video_stream_index = stream['index']
                            break

                    # exit if no video stream found
                    if video_stream_index is None:
                        Avalon.error(_('Aborting: No video stream found'))
                        raise StreamNotFoundError('no video stream found')

                    # extract frames from video
                    self.process_pool.append((fm.extract_frames(input_video, self.extracted_frames)))
                    self._wait()

                    # get average frame rate of video stream
                    framerate = float(Fraction(video_info['streams'][video_stream_index]['avg_frame_rate']))
                    fm.pixel_format = video_info['streams'][video_stream_index]['pix_fmt']

                    # get a dict of all pixel formats and corresponding bit depth
                    pixel_formats = fm.get_pixel_formats()

                    # try getting pixel format's corresponding bti depth
                    try:
                        self.bit_depth = pixel_formats[fm.pixel_format]
                    except KeyError:
                        Avalon.error(_('Unsupported pixel format: {}').format(fm.pixel_format))
                        raise UnsupportedPixelError(f'unsupported pixel format {fm.pixel_format}')

                    Avalon.info(_('Framerate: {}').format(framerate))

                    # width/height will be coded width/height x upscale factor
                    if self.scale_ratio:
                        original_width = video_info['streams'][video_stream_index]['width']
                        original_height = video_info['streams'][video_stream_index]['height']
                        self.scale_width = int(self.scale_ratio * original_width)
                        self.scale_height = int(self.scale_ratio * original_height)

                    # upscale images one by one using waifu2x
                    Avalon.info(_('Starting to upscale extracted images'))
                    self._upscale_frames()
                    Avalon.info(_('Upscaling completed'))

                    # frames to Video
                    Avalon.info(_('Converting extracted frames into video'))

                    # use user defined output size
                    self.process_pool.append(fm.convert_video(framerate, f'{self.scale_width}x{self.scale_height}', self.upscaled_frames))
                    self._wait()
                    Avalon.info(_('Conversion completed'))

                    # migrate audio tracks and subtitles
                    Avalon.info(_('Migrating audio tracks and subtitles to upscaled video'))
                    self.process_pool.append(fm.migrate_audio_tracks_subtitles(input_video, output_video, self.upscaled_frames))
                    self._wait()

                    # destroy temp directories
                    self.cleanup_temp_directories()

                except (Exception, KeyboardInterrupt, SystemExit) as e:
                    with contextlib.suppress(ValueError):
                        self.cleanup_temp_directories()
                    raise e