Esempio n. 1
0
def trim_video(context: Context, output_file: str):
    # load context

    input_file = context.input_file

    trim_video_command = [
        context.ffmpeg_dir, "-hwaccel", context.hwaccel, "-i", input_file
    ]

    trim_video_time = get_options_from_section(
        context.config_json["ffmpeg"]["trim_video"]["time"])

    for element in trim_video_time:
        trim_video_command.append(element)

    trim_video_options = \
        get_options_from_section(context.config_json["ffmpeg"]["trim_video"]["output_options"], ffmpeg_command=True)

    for element in trim_video_options:
        trim_video_command.append(element)

    trim_video_command.append(output_file)

    console_output = open(context.log_dir + "ffmpeg_trim_video_command.txt",
                          "w")
    console_output.write(str(trim_video_command))
    subprocess.call(trim_video_command,
                    shell=True,
                    stderr=console_output,
                    stdout=console_output)
Esempio n. 2
0
    def __init__(self, context: Context):
        # load context
        self.frame_count = context.frame_count
        self.waifu2x_vulkan_dir = context.waifu2x_ncnn_vulkan_file_path
        self.waifu2x_vulkan_path = context.waifu2x_ncnn_vulkan_path
        self.differences_dir = context.differences_dir
        self.upscaled_dir = context.upscaled_dir
        self.noise_level = context.noise_level
        self.scale_factor = context.scale_factor
        self.workspace = context.workspace
        self.context = context

        self.waifu2x_vulkan_upscale_frame = [
            self.waifu2x_vulkan_dir, "-i", "[input_file]", "-n",
            str(self.noise_level), "-s",
            str(self.scale_factor)
        ]

        waifu2x_vulkan_options = get_options_from_section(
            self.context.config_json["waifu2x_ncnn_vulkan"]["output_options"])

        # add custom options to waifu2x_vulkan
        for element in waifu2x_vulkan_options:
            self.waifu2x_vulkan_upscale_frame.append(element)

        self.waifu2x_vulkan_upscale_frame.extend(["-o", "[output_file]"])

        threading.Thread.__init__(self)
        logging.basicConfig(filename=self.workspace + 'waifu2x.log',
                            level=logging.INFO)
Esempio n. 3
0
    def __init__(self, context: Context):
        self.frame_count = context.frame_count
        self.waifu2x_caffe_cui_dir = context.waifu2x_caffe_cui_dir
        self.differences_dir = context.differences_dir
        self.upscaled_dir = context.upscaled_dir
        self.noise_level = context.noise_level
        self.scale_factor = context.scale_factor
        self.workspace = context.workspace
        self.context = context

        # Create Caffe Command
        self.waifu2x_caffe_upscale_frame = [
            self.waifu2x_caffe_cui_dir, "-i", "[input_file]", "-n",
            str(self.noise_level), "-s",
            str(self.scale_factor)
        ]

        waifu2x_caffe_options = get_options_from_section(
            context.config_json["waifu2x_caffe"]["output_options"])

        for element in waifu2x_caffe_options:
            self.waifu2x_caffe_upscale_frame.append(element)

        self.waifu2x_caffe_upscale_frame.extend(["-o", "[output_file]"])

        threading.Thread.__init__(self)
        logging.basicConfig(filename=self.workspace + 'waifu2x.log',
                            level=logging.INFO)
    def __init__(self, context: Context):
        # load context
        self.frame_count = context.frame_count
        self.waifu2x_converter_cpp_file_path = context.waifu2x_converter_cpp_file_path
        self.waifu2x_converter_cpp_path = context.waifu2x_converter_cpp_path
        self.residual_images_dir = context.residual_images_dir
        self.residual_upscaled_dir = context.residual_upscaled_dir
        self.noise_level = context.noise_level
        self.scale_factor = context.scale_factor
        self.workspace = context.workspace
        self.context = context

        self.waifu2x_conv_upscale_frame = [
            self.waifu2x_converter_cpp_file_path, "-i", "[input_file]",
            "--noise-level",
            str(self.noise_level), "--scale-ratio",
            str(self.scale_factor)
        ]

        waifu2x_conv_options = get_options_from_section(
            self.context.config_json["waifu2x_converter"]["output_options"])

        # add custom options to waifu2x_vulkan
        for element in waifu2x_conv_options:
            self.waifu2x_conv_upscale_frame.append(element)

        self.waifu2x_conv_upscale_frame.extend(["-o", "[output_file]"])

        threading.Thread.__init__(self)
        logging.basicConfig(filename=self.workspace + 'waifu2x.log',
                            level=logging.INFO)
Esempio n. 5
0
def extract_frames(context: Context, input_file: str):
    input_frames_dir = context.input_frames_dir
    extension_type = context.extension_type
    output_file = input_frames_dir + "frame%01d" + extension_type
    logger = logging.getLogger(__name__)
    frame_rate = context.frame_rate

    extract_frames_command = [
        context.ffmpeg_dir, "-hwaccel", context.hwaccel, "-i", input_file
    ]

    extract_frames_options = \
        get_options_from_section(context.config_json["ffmpeg"]["video_to_frames"]['output_options'],
                                 ffmpeg_command=True)

    for element in extract_frames_options:
        extract_frames_command.append(element)

    extract_frames_command.append("-r")
    extract_frames_command.append(str(frame_rate))

    extract_frames_command.extend([output_file])

    logger.info("extracting frames")

    console_output = open(
        context.log_dir + "ffmpeg_extract_frames_console.txt", "w")
    console_output.write(str(extract_frames_command))
    subprocess.call(extract_frames_command,
                    shell=True,
                    stderr=console_output,
                    stdout=console_output)
Esempio n. 6
0
def create_video_from_specific_frames(context: Context, file_prefix,
                                      output_file, start_number,
                                      frames_per_video):
    # load context
    logger = context.logger
    extension_type = context.extension_type
    input_files = file_prefix + "%d" + extension_type

    video_from_frames_command = [
        context.ffmpeg_dir, "-start_number",
        str(start_number), "-hwaccel", context.hwaccel, "-framerate",
        str(context.frame_rate), "-i", input_files, "-vframes",
        str(frames_per_video), "-r",
        str(context.frame_rate)
    ]

    frame_to_video_option = get_options_from_section(
        context.config_json["ffmpeg"]["frames_to_video"]['output_options'],
        ffmpeg_command=True)

    for element in frame_to_video_option:
        video_from_frames_command.append(element)

    video_from_frames_command.extend([output_file])

    logger.info("running ffmpeg command: " + str(video_from_frames_command))

    console_output = open(context.log_dir + "video_from_frames_command.txt",
                          "w")
    console_output.write(str(video_from_frames_command))
    subprocess.call(video_from_frames_command,
                    shell=True,
                    stderr=console_output,
                    stdout=console_output)
Esempio n. 7
0
def concat_encoded_vids(context: Context, output_file: str):
    """
    Concatonate a video using 2) in this stackoverflow post.
    https://stackoverflow.com/questions/7333232/how-to-concatenate-two-mp4-files-using-ffmpeg

    The 'list.txt' should already exist, as it's produced in realtime_encoding.py
    """

    encoded_dir = context.encoded_dir

    text_file = encoded_dir + "list.txt"
    concat_videos_command = [
        context.ffmpeg_dir, "-f", "concat", "-safe", "0", "-hwaccel",
        context.hwaccel, "-i", text_file
    ]

    concat_videos_option = \
        get_options_from_section(context.config_json["ffmpeg"]["concat_videos"]['output_options'], ffmpeg_command=True)

    for element in concat_videos_option:
        concat_videos_command.append(element)

    concat_videos_command.extend([output_file])

    console_output = open(context.log_dir + "ffmpeg_concat_videos_command.txt",
                          "w")
    console_output.write((str(concat_videos_command)))
    subprocess.call(concat_videos_command,
                    shell=False,
                    stderr=console_output,
                    stdout=console_output)
Esempio n. 8
0
def migrate_tracks(context: Context, no_audio: str, file_dir: str,
                   output_file: str):
    """
    Add the audio tracks from the original video to the output video.
    """
    migrate_tracks_command = [
        context.ffmpeg_dir, "-i", no_audio, "-i", file_dir, "-map", "0:v:0?",
        "-map", "1?", "-c", "copy", "-map", "-1:v?"
    ]

    migrate_tracks_options = \
        get_options_from_section(context.config_json["ffmpeg"]["migrating_tracks"]['output_options'],
                                 ffmpeg_command=True)

    for element in migrate_tracks_options:
        migrate_tracks_command.append(element)

    migrate_tracks_command.extend([str(output_file)])

    console_output = open(context.log_dir + "migrate_tracks_command.txt", "w")
    console_output.write(str(migrate_tracks_command))
    subprocess.call(migrate_tracks_command,
                    shell=False,
                    stderr=console_output,
                    stdout=console_output)
Esempio n. 9
0
def concat_encoded_vids(context: Context, output_file: str):
    text_file = context.workspace + "encoded\\list.txt"
    concat_videos_command = [
        context.ffmpeg_dir, "-f", "concat", "-safe", "0", "-hwaccel",
        context.hwaccel, "-i", text_file
    ]

    concat_videos_option = \
        get_options_from_section(context.config_json["ffmpeg"]["concat_videos"]['output_options'], ffmpeg_command=True)

    for element in concat_videos_option:
        concat_videos_command.append(element)

    concat_videos_command.extend([output_file])

    console_output = open(context.log_dir + "ffmpeg_concat_videos_command.txt",
                          "w")
    console_output.write((str(concat_videos_command)))
    subprocess.call(concat_videos_command,
                    shell=True,
                    stderr=console_output,
                    stdout=console_output)
Esempio n. 10
0
    def __init__(self, config_json_unparsed: json):
        """
        Create all the needed values that will be used in various parts of dandere2x. A lot of these values
        are derived from external files, such as the json, ffmpeg and ffprobe, or are joined from directories.

        Having all the variables here allows dandere2x the values needed to be global, but at the same time not really.
        """

        self.this_folder = None

        # load 'this folder' in a pyinstaller friendly way
        if getattr(sys, 'frozen', False):
            self.this_folder = os.path.dirname(sys.executable)
        elif __file__:
            self.this_folder = os.path.dirname(__file__)

        self.this_folder = pathlib.Path(self.this_folder)

        # Parse the unparsed config into a parsed (../externals -> C:/this_folder/externals)
        self.config_json = absolutify_json(config_json_unparsed,
                                           str(self.this_folder.absolute()),
                                           absolutify_key="..")

        ################################
        #  setup all the directories.. #
        ################################

        # side note - for vulkan and converter, we need to know the path of the file in order for it to run correctly,
        # hence why we have two variables for them
        self.waifu2x_converter_cpp_path = self.config_json[
            'waifu2x_converter']['waifu2x_converter_path']
        self.waifu2x_converter_file_name = self.config_json[
            'waifu2x_converter']['waifu2x_converter_file_name']
        self.waifu2x_converter_cpp_file_path = os.path.join(
            self.waifu2x_converter_cpp_path, self.waifu2x_converter_file_name)

        self.waifu2x_ncnn_vulkan_path = self.config_json[
            'waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_path']
        self.waifu2x_ncnn_vulkan_file_name = self.config_json[
            'waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_file_name']
        self.waifu2x_ncnn_vulkan_file_path = os.path.join(
            self.waifu2x_ncnn_vulkan_path, self.waifu2x_ncnn_vulkan_file_name)

        self.waifu2x_caffe_cui_dir = pathlib.Path(
            self.config_json['waifu2x_caffe']['waifu2x_caffe_path'])

        self.workspace = self.config_json['dandere2x']['developer_settings'][
            'workspace']
        self.workspace_use_temp = self.config_json['dandere2x'][
            'developer_settings']['workspace_use_temp']

        # if we're using a temporary workspace, assign workspace to be in the temp folder
        if self.workspace_use_temp:
            self.workspace = os.path.join(pathlib.Path(tempfile.gettempdir()),
                                          'dandere2x') + os.path.sep

        # setup directories
        self.input_frames_dir = self.workspace + "inputs" + os.path.sep
        self.residual_images_dir = self.workspace + "residual_images" + os.path.sep
        self.residual_upscaled_dir = self.workspace + "residual_upscaled" + os.path.sep
        self.correction_data_dir = self.workspace + "correction_data" + os.path.sep
        self.merged_dir = self.workspace + "merged" + os.path.sep
        self.residual_data_dir = self.workspace + "residual_data" + os.path.sep
        self.pframe_data_dir = self.workspace + "pframe_data" + os.path.sep
        self.fade_data_dir = self.workspace + "fade_data" + os.path.sep
        self.debug_dir = self.workspace + "debug" + os.path.sep
        self.log_dir = self.workspace + "logs" + os.path.sep
        self.compressed_static_dir = self.workspace + "compressed_static" + os.path.sep
        self.compressed_moving_dir = self.workspace + "compressed_moving" + os.path.sep
        self.encoded_dir = self.workspace + "encoded" + os.path.sep
        self.temp_image_folder = self.workspace + "temp_image_folder" + os.path.sep

        # put all the directories that need to be created into a list for creation / deleting.
        self.directories = {
            self.workspace, self.input_frames_dir, self.correction_data_dir,
            self.residual_images_dir, self.residual_upscaled_dir,
            self.merged_dir, self.residual_data_dir, self.pframe_data_dir,
            self.debug_dir, self.log_dir, self.compressed_static_dir,
            self.compressed_moving_dir, self.fade_data_dir, self.encoded_dir,
            self.temp_image_folder
        }

        self.ffmpeg_dir = self.config_json['ffmpeg']['ffmpeg_path']
        self.ffprobe_dir = self.config_json['ffmpeg']['ffprobe_path']
        self.hwaccel = self.config_json['ffmpeg']['-hwaccel']

        ################################
        # Load Dandere2x User Settings #
        ################################

        # User Settings
        self.block_size = self.config_json['dandere2x']['usersettings'][
            'block_size']
        self.quality_minimum = self.config_json['dandere2x']['usersettings'][
            'quality_minimum']
        self.waifu2x_type = self.config_json['dandere2x']['usersettings'][
            'waifu2x_type']
        self.noise_level = self.config_json['dandere2x']['usersettings'][
            'denoise_level']
        self.scale_factor = self.config_json['dandere2x']['usersettings'][
            'scale_factor']
        self.input_file = self.config_json['dandere2x']['usersettings'][
            'input_file']
        self.output_file = self.config_json['dandere2x']['usersettings'][
            'output_file']

        # Developer Settings
        self.quality_moving_ratio = self.config_json['dandere2x'][
            'developer_settings']['quality_moving_ratio']
        self.step_size = self.config_json['dandere2x']['developer_settings'][
            'step_size']
        self.bleed = self.config_json['dandere2x']['developer_settings'][
            'bleed']
        self.extension_type = self.config_json['dandere2x'][
            'developer_settings']['extension_type']
        self.debug = self.config_json['dandere2x']['developer_settings'][
            'debug']
        self.dandere2x_cpp_dir = self.config_json['dandere2x'][
            'developer_settings']['dandere2x_cpp_dir']
        self.correction_block_size = 2

        # Real Time Encoding
        self.realtime_encoding_enabled = self.config_json['dandere2x'][
            'developer_settings']['realtime_encoding'][
                'realtime_encoding_enabled']
        self.realtime_encoding_delete_files = self.config_json['dandere2x'][
            'developer_settings']['realtime_encoding'][
                'realtime_encoding_delete_files']
        self.realtime_encoding_seconds_per_video = \
        self.config_json['dandere2x']['developer_settings']['realtime_encoding']['realtime_encoding_seconds_per_video']

        ################################
        #       Video Settings         #
        ################################

        # find out if the user trimmed a video by checking the time part of the json. IF theres nothing there,
        # then the user didn't trim anything
        self.user_trim_video = False
        find_out_if_trim = get_options_from_section(
            self.config_json["ffmpeg"]["trim_video"]['time'])

        if find_out_if_trim:
            self.user_trim_video = True

        # load the needed video settings
        self.video_settings = VideoSettings(self.ffprobe_dir, self.input_file)

        self.frame_rate = math.ceil(self.video_settings.frame_rate)
        self.width = self.video_settings.width
        self.height = self.video_settings.height
        self.frame_count = 0
Esempio n. 11
0
    def __init__(self, config_json_unparsed: json):

        # load 'this folder' in a pyinstaller friendly way
        self.this_folder = None

        if getattr(sys, 'frozen', False):
            self.this_folder = os.path.dirname(sys.executable)
        elif __file__:
            self.this_folder = os.path.dirname(__file__)

        self.this_folder = pathlib.Path(self.this_folder)

        # We need the json to be absolute, meaning ".." --> this.folder
        # This allows Dandere2x to be somewhat portable on different systems

        self.config_json = absolutify_json(config_json_unparsed, str(self.this_folder.absolute()), absolutify_key="..")

        ################################
        #  setup all the directories.. #
        ################################

        # side note - for vulkan and converter, we need to know the path of the file in order for it to run correctly,
        # hence why we have two variables for them
        self.waifu2x_converter_cpp_path = self.config_json['waifu2x_converter']['waifu2x_converter_path']
        self.waifu2x_converter_cpp_dir = os.path.join(self.waifu2x_converter_cpp_path, "waifu2x-converter-cpp.exe")

        self.waifu2x_vulkan_path = self.config_json['waifu2x_ncnn_vulkan']['waifu2x_ncnn_vulkan_path']
        self.waifu2x_vulkan_dir = os.path.join(self.waifu2x_vulkan_path, "waifu2x-ncnn-vulkan.exe")

        self.waifu2x_caffe_cui_dir = pathlib.Path(self.config_json['waifu2x_caffe']['waifu2x_caffe_path'])

        self.workspace = self.config_json['dandere2x']['developer_settings']['workspace']
        self.workspace_use_temp = self.config_json['dandere2x']['developer_settings']['workspace_use_temp']

        # if we're using a temporary workspace, assign workspace to be in the temp folder
        if self.workspace_use_temp:
            self.workspace = os.path.join(pathlib.Path(tempfile.gettempdir()), 'dandere2x') + "\\"

        # setup directories
        self.input_frames_dir = self.workspace + "inputs" + os.path.sep
        self.differences_dir = self.workspace + "differences" + os.path.sep
        self.upscaled_dir = self.workspace + "upscaled" + os.path.sep
        self.correction_data_dir = self.workspace + "correction_data" + os.path.sep
        self.merged_dir = self.workspace + "merged" + os.path.sep
        self.inversion_data_dir = self.workspace + "inversion_data" + os.path.sep
        self.pframe_data_dir = self.workspace + "pframe_data" + os.path.sep
        self.fade_data_dir = self.workspace + "fade_data" + os.path.sep
        self.debug_dir = self.workspace + "debug" + os.path.sep
        self.log_dir = self.workspace + "logs" + os.path.sep
        self.compressed_static_dir = self.workspace + "compressed_static" + os.path.sep
        self.compressed_moving_dir = self.workspace + "compressed_moving" + os.path.sep
        self.encoded_dir = self.workspace + "encoded" + os.path.sep
        self.temp_image_folder = self.workspace + "temp_image_folder" + os.path.sep

        self.ffmpeg_dir = self.config_json['ffmpeg']['ffmpeg_path']
        self.ffprobe_dir = self.config_json['ffmpeg']['ffprobe_path']
        self.hwaccel = self.config_json['ffmpeg']['-hwaccel']

        ################################
        # Load Dandere2x User Settings #
        ################################

        # User Settings
        self.block_size = self.config_json['dandere2x']['usersettings']['block_size']
        self.quality_minimum = self.config_json['dandere2x']['usersettings']['quality_minimum']
        self.waifu2x_type = self.config_json['dandere2x']['usersettings']['waifu2x_type']
        self.noise_level = self.config_json['dandere2x']['usersettings']['denoise_level']
        self.scale_factor = self.config_json['dandere2x']['usersettings']['scale_factor']
        self.input_file = self.config_json['dandere2x']['usersettings']['input_file']
        self.output_file = self.config_json['dandere2x']['usersettings']['output_file']

        # Developer Settings

        self.quality_moving_ratio = self.config_json['dandere2x']['developer_settings']['quality_moving_ratio']
        self.step_size = self.config_json['dandere2x']['developer_settings']['step_size']
        self.bleed = self.config_json['dandere2x']['developer_settings']['bleed']
        self.extension_type = self.config_json['dandere2x']['developer_settings']['extension_type']
        self.debug = self.config_json['dandere2x']['developer_settings']['debug']
        self.dandere2x_cpp_dir = self.config_json['dandere2x']['developer_settings']['dandere2x_cpp_dir']
        self.correction_block_size = 2

        # Real Time Encoding

        self.realtime_encoding_enabled = self.config_json['dandere2x']['developer_settings']['realtime_encoding'][
            'realtime_encoding_enabled']
        self.realtime_encoding_delete_files = self.config_json['dandere2x']['developer_settings']['realtime_encoding'][
            'realtime_encoding_delete_files']
        self.realtime_encoding_seconds_per_video = \
        self.config_json['dandere2x']['developer_settings']['realtime_encoding']['realtime_encoding_seconds_per_video']

        ################################
        #       Video Settings         #
        ################################

        # find out if the user trimmed a video by checking the time part of the json. IF theres nothing there,
        # then the user didn't trim anything
        self.user_trim_video = False
        find_out_if_trim = get_options_from_section(self.config_json["ffmpeg"]["trim_video"]['time'])

        if find_out_if_trim:
            self.user_trim_video = True

        self.video_settings = VideoSettings(self.ffprobe_dir, self.input_file)

        self.frame_rate = math.ceil(self.video_settings.frame_rate)
        self.width = self.video_settings.width
        self.height = self.video_settings.height
        self.frame_count = 0