def _pre_process(self):
        """
        Creates self.child_request.input_file file by re-encoding self._service_request.input_file. Without this
        re-encode, dandere2x isn't guaranteed to function correctly.
        """

        # Checks to see the video needs to be resized in order to conform to the block size. Applies the "DAR"
        # ffmpeg filter to 'pipe_video' in 'output_options.yaml' if the video was resized.
        resized_output_options = Dandere2xServiceInterface._check_and_fix_resolution(
            input_file=self._service_request.input_file,
            block_size=self._service_request.block_size,
            output_options_original=self._service_request.output_options)

        ffprobe_path = load_executable_paths_yaml()['ffprobe']
        ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

        # Re-encode the sent service_request into the child's input file, so that the child_request will operate on
        # "pre_processed.mkv", rather than self._service_request.input_file, which may not be a valid video file to
        # operate on.
        re_encode_video(ffmpeg_dir=ffmpeg_path,
                        ffprobe_dir=ffprobe_path,
                        output_options=resized_output_options,
                        input_file=self._service_request.input_file,
                        output_file=self.child_request.input_file)

        self.dandere2x_service = Dandere2xServiceThread(
            service_request=self.child_request)
Beispiel #2
0
def _check_and_fix_resolution(input_file: str, block_size: int,
                              output_options_original: dict) -> dict:
    """
    Returns a dictionary containing the output settings, taking into consideration if the video needs to be resized,
    and if it does, changes the pipe_video commands to include dar.
    """
    from dandere2x.dandere2xlib.utils.yaml_utils import load_executable_paths_yaml
    from dandere2x.dandere2xlib.wrappers.ffmpeg.ffmpeg import append_resize_filter_to_pre_process, \
        append_dar_filter_to_pipe_process
    from dandere2x.dandere2xlib.wrappers.ffmpeg.videosettings import VideoSettings
    import copy

    def valid_input_resolution(width: int, height: int, block_size: int):
        return width % block_size == 0 and height % block_size == 0

    new_output_options = copy.copy(output_options_original)

    # get meta-data from the video to do pre-processing
    ffprobe_path = load_executable_paths_yaml()['ffprobe']
    ffmpeg_path = load_executable_paths_yaml()['ffmpeg']
    video_settings = VideoSettings(ffprobe_path, ffmpeg_path, input_file)
    width, height = video_settings.width, video_settings.height

    if not valid_input_resolution(
            width=width, height=height, block_size=block_size):
        print("appending resize filter")
        append_resize_filter_to_pre_process(output_options=new_output_options,
                                            width=width,
                                            height=height,
                                            block_size=block_size)
        append_dar_filter_to_pipe_process(output_options=new_output_options,
                                          width=width,
                                          height=height)

    return new_output_options
Beispiel #3
0
    def _pre_process(self):

        ffprobe_path = load_executable_paths_yaml()['ffprobe']
        ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

        # Attempt to split the video up into N=3 distinct parts.
        divide_and_reencode_video(
            ffmpeg_path=ffmpeg_path,
            ffprobe_path=ffprobe_path,
            input_video=self._service_request.input_file,
            output_options=self._service_request.output_options,
            divide=3,
            output_dir=self._service_request.workspace)

        # Find all the split video files ffmpeg produced in the folder.
        divided_re_encoded_videos = glob.glob(
            os.path.join(self._service_request.workspace, "*.mkv"))

        # Create unique child_requests for each unique video, with the video being the input.
        for x in range(0, len(divided_re_encoded_videos)):
            child_request = copy.deepcopy(self._service_request)
            child_request.input_file = os.path.join(
                divided_re_encoded_videos[x])
            child_request.output_file = os.path.join(
                self._service_request.workspace, "non_migrated%d.mkv" % x)
            child_request.workspace = os.path.join(
                self._service_request.workspace, "subworkspace%d" % x)

            self._divided_videos_upscaled.append(child_request.output_file)
            self._child_threads.append(Dandere2xServiceThread(child_request))
Beispiel #4
0
    def _setup_pipe(self) -> None:
        self.log.info("Setting up pipe Called")
        # load variables..
        output_no_sound = self.output_no_sound
        frame_rate = str(self.context.frame_rate)
        output_no_sound = output_no_sound
        ffmpeg_dir = load_executable_paths_yaml()['ffmpeg']
        dar = self.context.video_settings.dar

        # constructing the pipe command...
        ffmpeg_pipe_command = [ffmpeg_dir, "-r", frame_rate]

        options = get_options_from_section(
            self.context.service_request.output_options["ffmpeg"]["pipe_video"]
            ['output_options'],
            ffmpeg_command=True)
        for item in options:
            ffmpeg_pipe_command.append(item)

        ffmpeg_pipe_command.append("-r")
        ffmpeg_pipe_command.append(frame_rate)

        ffmpeg_pipe_command.append(output_no_sound)

        # Starting the Pipe Command
        console_output = open(
            self.context.console_output_dir + "pipe_output.txt", "w")
        console_output.write(str(ffmpeg_pipe_command))

        self.log.info("ffmpeg_pipe_command %s" % str(ffmpeg_pipe_command))
        self.ffmpeg_pipe_subprocess = subprocess.Popen(ffmpeg_pipe_command,
                                                       stdin=subprocess.PIPE,
                                                       stdout=console_output)
Beispiel #5
0
    def __init__(self, extracted_frames_dir: str, noised_frames_dir: str, frame_count):
        super().__init__()
        self.extracted_frames_dir = extracted_frames_dir
        self.noised_frames_dir = noised_frames_dir

        self.ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

        self.frame_count = frame_count
Beispiel #6
0
 def _on_completion(self):
     """
     Finishes the video up by migrating the audio tracks from the child's output file with the original input file.
     """
     ffmpeg_path = load_executable_paths_yaml()['ffmpeg']
     migrate_tracks_contextless(
         ffmpeg_dir=ffmpeg_path,
         no_audio=self.child_request.output_file,
         file_dir=self._service_request.input_file,
         output_file=self._service_request.output_file)
Beispiel #7
0
    def __init__(self, context: Dandere2xServiceContext,
                 controller: Dandere2xController):
        # implementation specific
        self.active_waifu2x_subprocess = None
        self.waifu2x_caffe_path = load_executable_paths_yaml()['waifu2x_caffe']

        assert get_operating_system() != "win32" or os.path.exists(self.waifu2x_caffe_path), \
            "%s does not exist!" % self.waifu2x_caffe_path

        super().__init__(context, controller)
        Thread.__init__(self, name="Waifu2x Thread")
Beispiel #8
0
    def __init__(self, input_video: str, extracted_frames_dir: str,
                 compressed_frames_dir: str, compressed_quality: int,
                 block_size: int, output_options_original: dict):

        ffprobe_path = load_executable_paths_yaml()['ffprobe']
        ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

        self.input_video = input_video
        self.extracted_frames_dir = extracted_frames_dir
        self.compressed_frames_dir = compressed_frames_dir

        self.compressed_quality = compressed_quality

        width, height = get_width_height(ffprobe_dir=ffprobe_path,
                                         input_video=input_video)
        self.cap = VideoFrameExtractor(Path(ffmpeg_path), Path(input_video),
                                       width, height, block_size,
                                       output_options_original)

        self.ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

        self.count = 1
Beispiel #9
0
    def __init__(self, service_request: Dandere2xServiceRequest):
        """
        Uses multiple Dandere2xServiceThread to upscale a given file. It does this by attempting to split the video
        up into equal parts, then migrating each upscaled-split video into one complete video file.
        """
        super().__init__(service_request=copy.deepcopy(service_request))

        assert is_file_video(ffprobe_dir=load_executable_paths_yaml()['ffprobe'],
                             input_video=self._service_request.input_file),\
            "%s is not a video file!" % self._service_request.input_file

        self._child_threads: List[Dandere2xServiceThread] = []
        self._divided_videos_upscaled: List[str] = []
Beispiel #10
0
    def _setup_pipe(self) -> None:
        self.log.info("Setting up pipe Called")
        # load variables..
        output_no_sound = self.output_no_sound
        frame_rate = str(self.context.frame_rate)
        output_no_sound = output_no_sound
        ffmpeg_dir = load_executable_paths_yaml()['ffmpeg']
        dar = self.context.video_settings.dar

        # constructing the pipe command...
        ffmpeg_pipe_command = [ffmpeg_dir]

        # walrus operator go brrrr
        if (hw_accel := self.context.service_request.output_options["ffmpeg"]["pipe_video"]["-hwaccel"]) is not None:
            ffmpeg_pipe_command.append("-hwaccel")
            ffmpeg_pipe_command.append(hw_accel)
Beispiel #11
0
    def __init__(self,
                 input_video: str,
                 extracted_frames_dir: str,
                 compressed_frames_dir: str,
                 compressed_quality: int):

        self.input_video = input_video
        self.extracted_frames_dir = extracted_frames_dir
        self.compressed_frames_dir = compressed_frames_dir

        self.compressed_quality = compressed_quality
        self.cap = cv2.VideoCapture(self.input_video)

        self.ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

        self.count = 1
Beispiel #12
0
    def __init__(self, context: Dandere2xServiceContext,
                 controller: Dandere2xController):
        threading.Thread.__init__(self, name="Dandere2xCpp")
        self.context = context
        self.controller = controller

        self.dandere2x_cpp_subprocess = None
        self.log = logging.getLogger()

        dandere2x_cpp_dir = load_executable_paths_yaml()['dandere2x_cpp']
        self.exec_command = [
            dandere2x_cpp_dir, self.context.service_request.workspace,
            str(self.context.frame_count),
            str(self.context.service_request.block_size),
            str(self.context.step_size), "r",
            str(1), ".jpg"
        ]
Beispiel #13
0
    def _on_completion(self):
        """
        Converts all self._divided_videos_upscaled into one big video, then migrates the original audio into this
        service request's output file.
        """
        ffmpeg_path = load_executable_paths_yaml()['ffmpeg']
        no_audio = os.path.join(self._service_request.workspace, "noaudio.mkv")
        concat_n_videos(ffmpeg_dir=ffmpeg_path,
                        temp_file_dir=self._service_request.workspace,
                        console_output_dir=self._service_request.workspace,
                        list_of_files=self._divided_videos_upscaled,
                        output_file=no_audio)

        migrate_tracks_contextless(
            ffmpeg_dir=ffmpeg_path,
            no_audio=no_audio,
            file_dir=self._service_request.input_file,
            output_file=self._service_request.output_file)
Beispiel #14
0
    def __init__(self, context: Dandere2xServiceContext,
                 controller: Dandere2xController):
        threading.Thread.__init__(self, name="Dandere2xCpp")
        self.context = context
        self.controller = controller

        self.dandere2x_cpp_subprocess = None
        self.log = logging.getLogger()

        dandere2x_cpp_dir = load_executable_paths_yaml()['dandere2x_cpp']
        self.exec_command = [
            dandere2x_cpp_dir, self.context.service_request.workspace,
            str(self.context.frame_count),
            str(self.context.service_request.block_size),
            self.context.dandere2x_cpp_block_matching_arg,
            self.context.dandere2x_cpp_evaluator_arg,
            str(self.context.service_request.quality_minimum),
            str(self.context.bleed)
        ]
    def __init__(self, service_request: Dandere2xServiceRequest):
        """
        Uses a single Dandere2xServiceThread object to upscale a video file.

        Args:
            service_request: Dandere2xServiceRequest object.
        """
        super().__init__(service_request=copy.deepcopy(service_request))

        assert is_file_video(ffprobe_dir=load_executable_paths_yaml()['ffprobe'],
                             input_video=self._service_request.input_file),\
            "%s is not a video file!" % self._service_request.input_file

        self.child_request = copy.deepcopy(service_request)
        self.child_request.input_file = os.path.join(service_request.workspace,
                                                     "pre_processed.mkv")
        self.child_request.output_file = os.path.join(
            service_request.workspace, "non_migrated.mkv")
        self.child_request.workspace = os.path.join(service_request.workspace,
                                                    "subworkspace")
        self.dandere2x_service = None
Beispiel #16
0
from dandere2x.dandere2xlib.utils.yaml_utils import load_executable_paths_yaml
from dandere2x.dandere2xlib.wrappers.ffmpeg.ffmpeg import apply_noise_to_image

ffmpeg_path = load_executable_paths_yaml()['ffmpeg']

import time

start = time.time()

apply_noise_to_image(
    ffmpeg_dir=ffmpeg_path,
    input_image=r"C:\Users\Tyler\Desktop\3.3\workspace\ffmpeg_test\output1.jpg",
    output_file=
    r"C:\Users\Tyler\Desktop\3.3\workspace\ffmpeg_test\output_noise_python.jpg"
)

end = time.time()
print(end - start)
Beispiel #17
0
    def __init__(self, service_request: Dandere2xServiceRequest):
        """

        Creates struct-like object that serves as a set of constants and directories dandere2x will use. Once this is
        instantiated, it's to be treated as 'effectively final' meaning that none of the variables will
        change after they're declared.

        Most dandere2x-core functions will require a Dandere2xServiceContext object in order for it to run.

        Args:
            service_request: A service_request, which may be produced by the program or the user.
        """

        self.service_request = service_request

        # Directories and Paths
        self.input_frames_dir = os.path.join(service_request.workspace,
                                             "inputs") + os.path.sep
        self.noised_input_frames_dir = os.path.join(
            service_request.workspace, "noised_inputs") + os.path.sep
        self.residual_images_dir = os.path.join(
            service_request.workspace, "residual_images") + os.path.sep
        self.residual_upscaled_dir = os.path.join(
            service_request.workspace, "residual_upscaled") + os.path.sep
        self.residual_data_dir = os.path.join(service_request.workspace,
                                              "residual_data") + os.path.sep
        self.pframe_data_dir = os.path.join(service_request.workspace,
                                            "pframe_data") + os.path.sep
        self.merged_dir = os.path.join(service_request.workspace,
                                       "merged") + os.path.sep
        self.fade_data_dir = os.path.join(service_request.workspace,
                                          "fade_data") + os.path.sep
        self.debug_dir = os.path.join(service_request.workspace,
                                      "debug") + os.path.sep
        self.console_output_dir = os.path.join(service_request.workspace,
                                               "console_output") + os.path.sep
        self.compressed_static_dir = os.path.join(
            service_request.workspace, "compressed_static") + os.path.sep
        self.encoded_dir = os.path.join(service_request.workspace,
                                        "encoded") + os.path.sep
        self.temp_image_folder = os.path.join(
            service_request.workspace, "temp_image_folder") + os.path.sep
        self.log_dir = os.path.join(service_request.workspace,
                                    "log_dir") + os.path.sep

        self.directories = {
            self.input_frames_dir, self.noised_input_frames_dir,
            self.residual_images_dir, self.residual_upscaled_dir,
            self.merged_dir, self.residual_data_dir, self.pframe_data_dir,
            self.debug_dir, self.console_output_dir,
            self.compressed_static_dir, self.fade_data_dir, self.encoded_dir,
            self.temp_image_folder, self.log_dir
        }

        ffprobe_path = load_executable_paths_yaml()['ffprobe']
        ffmpeg_path = load_executable_paths_yaml()['ffmpeg']
        video_settings = VideoSettings(
            ffprobe_dir=ffprobe_path,
            ffmpeg_dir=ffmpeg_path,
            video_file=self.service_request.input_file)
        self.video_settings = video_settings
        self.width, self.height = video_settings.width, video_settings.height
        self.frame_count = video_settings.frame_count
        self.frame_rate = video_settings.frame_rate

        # todo static-ish settings < add to a yaml somewhere >
        self.bleed = self.service_request.output_options["dandere2x"]["bleed"]
        self.temp_image = self.temp_image_folder + "tempimage.jpg"
        self.debug = False
        self.step_size = 4
        self.max_frames_ahead = 100

        # Dandere2xCPP
        self.dandere2x_cpp_block_matching_arg = self.service_request.output_options[
            "dandere2x_cpp"]["block_matching_arg"]
        self.dandere2x_cpp_evaluator_arg = self.service_request.output_options[
            "dandere2x_cpp"]["evaluator_arg"]