From ab0f12ce6b96fc9e4ec23f4f52bb0ba8d4b6bb54 Mon Sep 17 00:00:00 2001 From: GeoHaber <11169518+GeoHaber@users.noreply.github.com> Date: Mon, 16 Sep 2024 18:55:29 -0400 Subject: [PATCH] here and there some buns to spare Oy --- FFMpeg.py | 15 +++--- My_Utils.py | 133 ++++++++++++++++++++++++++------------------------ Trans_code.py | 15 ++++-- 3 files changed, 87 insertions(+), 76 deletions(-) diff --git a/FFMpeg.py b/FFMpeg.py index e6e8e34..9a40fed 100644 --- a/FFMpeg.py +++ b/FFMpeg.py @@ -463,7 +463,6 @@ def get_encoder_options(codec_name, is_10bit, bit_rate, use_hw_accel=False): @perf_monitor def parse_video(strm_in, de_bug=False, skip_it=False): ''' Parse and extract data from video streams ''' - msj = sys._getframe().f_code.co_name if de_bug: print(f" +{msj} Start: {TM.datetime.now():%T}") @@ -509,12 +508,13 @@ def parse_video(strm_in, de_bug=False, skip_it=False): else: # XXX: Estimate Average bits_per_pixel glb_totfrms = round(frm_rate * glb_vidolen) - max_vid_btrt = 4500000 - btrt = min( _vi_btrt, max_vid_btrt ) + max_vid_btrt = 4500000 msj = " 8" if (is_10bit := pix_fmt.endswith("10le")): msj = "10" + max_vid_btrt *= 1.25 + btrt = min( _vi_btrt, max_vid_btrt ) # Aspect Ratio Calculation original_ratio = vid_width / vid_heigh @@ -528,14 +528,13 @@ def parse_video(strm_in, de_bug=False, skip_it=False): ff_vid = ['-map', f'0:v:{indx}', f'-c:v:{indx}'] # Handle HEVC codec and bitrate adjustments - if codec_name == 'hevc' and _vi_btrt < max_vid_btrt: + if codec_name == 'hevc' and _vi_btrt <= max_vid_btrt: # Skip re-encoding if conditions are met extra += ' => Copy' - ff_vid.extend(['copy']) - # ff_vid.append('copy') + ff_vid.append('copy') else: # Re-encode if required (e.g., non-HEVC codec or bitrate exceeds max) - bitrate_action = 'Reduce BitRate' if _vi_btrt > max_vid_btrt else 'Reencode' + bitrate_action = 'Reduce BitRate' if _vi_btrt > max_vid_btrt else 'Reencode Hevc' extra += f' {bitrate_action}: {hm_sz(btrt):>6} ' encoder_options = get_encoder_options(codec_name, is_10bit, btrt, use_hw_accel) ff_vid.extend(encoder_options) @@ -842,7 +841,7 @@ def parse_extrd(streams_in, de_bug=False): ##>>============-------------------< End >------------------==============<<## @perf_monitor -def zabrain_run(input_file: str, mta_dta: Dict[str, any], de_bug: bool= False ) -> Tuple[bool, bool]: +def parse_finfo(input_file: str, mta_dta: Dict[str, any], de_bug: bool= False ) -> Tuple[bool, bool]: ''' Decide what based on streams info ''' msj = sys._getframe().f_code.co_name print(f" +{msj} Start: {TM.datetime.now():%T}") diff --git a/My_Utils.py b/My_Utils.py index 0a887fd..39f31da 100644 --- a/My_Utils.py +++ b/My_Utils.py @@ -285,66 +285,73 @@ def __exit__(self, exc_type, exc_value, traceback): class Spinner: - def __init__(self, spin_text="|/-o+\\", indent=0): - self.spinner_count = 0 - self.spin_text = spin_text - self.spin_length = len(spin_text) - self.prefix = " " * indent # Indentation string - self.last_message_length = 0 # To keep track of the length of the last printed message - self.cursor_hidden = False - - def hide_cursor(self): - if not self.cursor_hidden: - sys.stderr.write("\033[?25l") # Hide cursor - sys.stderr.flush() - self.cursor_hidden = True - - def show_cursor(self): - if self.cursor_hidden: - sys.stderr.write("\033[?25h") # Show cursor - sys.stderr.flush() - self.cursor_hidden = False - - def print_spin(self, extra: str = "") -> None: - """ - Prints a spinner in the console to indicate progress. - - Args: - extra (str): Additional text to display after the spinner. - """ - # Hide the cursor - self.hide_cursor() - - # Get terminal width - terminal_width = shutil.get_terminal_size().columns - - spin_char = self.spin_text[self.spinner_count % self.spin_length] - message = f"\r{self.prefix}| {spin_char} | {extra}" - - # Truncate the message if it's too long for the terminal - if len(message) > terminal_width: - message = message[:terminal_width - 1] # Truncate to fit the terminal width - - # Calculate the number of spaces needed to clear the previous message - clear_spaces = max(self.last_message_length - len(message), 0) - - # Print the spinner and the extra text, followed by enough spaces to clear any leftover characters - sys.stderr.write(f"{message}{' ' * clear_spaces}") - sys.stderr.flush() - - # Update the length of the last message - self.last_message_length = len(message) - - self.spinner_count += 1 - - def stop(self): - """ - Stops the spinner and shows the cursor. - """ - # Show the cursor - self.show_cursor() - sys.stderr.write("\n") # Move to the next line after stopping - sys.stderr.flush() + def __init__(self, spin_text="|/-o+\\", indent=0, delay=0.1): + self.spinner_count = 0 + self.spin_text = spin_text + self.spin_length = len(spin_text) + self.prefix = " " * indent # Indentation string + self.last_message_length = 0 # To keep track of the length of the last printed message + self.cursor_hidden = False + self.delay = delay # Delay between spinner updates + self.last_update_time = 0 + + def hide_cursor(self): + if not self.cursor_hidden: + sys.stderr.write("\033[?25l") # Hide cursor + sys.stderr.flush() + self.cursor_hidden = True + + def show_cursor(self): + if self.cursor_hidden: + sys.stderr.write("\033[?25h") # Show cursor + sys.stderr.flush() + self.cursor_hidden = False + + def abbreviate_path(self, path: str, max_length: int) -> str: + """Abbreviates a path to fit within the terminal width.""" + if len(path) <= max_length: + return path + else: + return f"{path[:max_length//2]}...{path[-max_length//2:]}" + + def print_spin(self, extra: str = "") -> None: + """Prints a spinner with optional extra text.""" + current_time = time.time() + if current_time - self.last_update_time < self.delay: + return # Skip updating the spinner if it's too soon + + self.last_update_time = current_time # Update the last update time + + # Hide the cursor + self.hide_cursor() + + # Get terminal width + terminal_width = shutil.get_terminal_size().columns + + # Abbreviate the extra text to fit the terminal + extra = self.abbreviate_path(extra, terminal_width - 10) + + spin_char = self.spin_text[self.spinner_count % self.spin_length] + message = f"\r{self.prefix}| {spin_char} | {extra}" + + # Calculate the number of spaces needed to clear the previous message + clear_spaces = max(self.last_message_length - len(message), 0) + + # Print the spinner and the extra text, followed by enough spaces to clear any leftover characters + sys.stderr.write(f"{message}{' ' * clear_spaces}") + sys.stderr.flush() + + # Update the length of the last message + self.last_message_length = len(message) + + self.spinner_count += 1 + + def stop(self): + """Stops the spinner and shows the cursor.""" + # Show the cursor + self.show_cursor() + sys.stderr.write("\n") # Move to the next line after stopping + sys.stderr.flush() ''' # Example usage: @@ -514,8 +521,8 @@ def copy_move(src: str, dst: str, keep_original: bool = False, verbose: bool = F - keep_original (bool, optional): If True, keep the original file. Defaults to False. - verbose (bool optional): If True print message. Defaults to False. """ - if verbose: - print(f"\ncopy_move called with src: {src}, dst: {dst}, keep_original: {keep_original}\n") +# if verbose: +# print(f"\ncopy_move called with src: {src}, dst: {dst}, keep_original: {keep_original}\n") if os.path.exists(dst) and os.path.samefile(src, dst): if not keep_original: @@ -531,7 +538,7 @@ def copy_move(src: str, dst: str, keep_original: bool = False, verbose: bool = F (action, transfer_func) = ("_Copy", shutil.copy2) if keep_original else ("_Move", shutil.move) transfer_func(src, dst) if verbose: - print(f"{action}: {src}\nTo : {dst}") + print(f"{action}: {src}\nTo: {dst}") return True except (PermissionError, IOError, OSError) as err: print(f"\ncopy_move Error: {err}\n{action}: {src} to {dst}") diff --git a/Trans_code.py b/Trans_code.py index 6530785..7a4d105 100644 --- a/Trans_code.py +++ b/Trans_code.py @@ -134,6 +134,8 @@ def clean_up(input_file: str, output_file: str, skip_it: bool, debug: bool) -> i @perf_monitor def process_file(file_info, cnt, fl_nmb ): + msj = sys._getframe().f_code.co_name + saved, procs, skipt, errod = 0, 0, 0, 0 str_t = time.perf_counter() file_p, file_s, ext, jsn_ou = file_info @@ -152,12 +154,12 @@ def process_file(file_info, cnt, fl_nmb ): try: # debug = True # DEBUG: - all_good, skip_it = zabrain_run(file_p, jsn_ou, debug) + all_good, skip_it = parse_finfo(file_p, jsn_ou, debug) if debug or ext != ".mp4": skip_it = False # print (f"\nFile: {file_p}\nFfmpeg: {all_good}\n") if skip_it: - print(f"\033[91m | Skip ffmpeg_run |\033[0m") + print(f"\033[91m >| {msj} |<\033[0m") skipt += 1 all_good = ffmpeg_run(file_p, all_good, skip_it, ffmpeg, de_bug) @@ -312,13 +314,16 @@ def handle_result(result): 'extension': 2, 'date': 3 # Sort by file modification date } + # Sorting by the key specified (name, size, extension, date) + sort_idx = sort_map.get(Sort_Key, 1) # Default to 'size' if Sort_Key is invalid +# sorted_list = sorted(_lst, key=lambda item: item[1], reverse=sort_order) + sorted_list = sorted(_lst, key=lambda item: item[sort_idx], reverse=sort_order) order = "Descending >" if sort_order else "Ascending <" - sortedfi = sorted(_lst, key=lambda item: item[1], reverse=sort_order) end_t = time.perf_counter() - print(f"\n Sort: {order}\n Scan: Done : {time.strftime('%H:%M:%S')}\tTotal: {hm_time(end_t - str_t)}\n") - return sortedfi + print(f"\n Sort: {order} Index: {Sort_Key}\n Scan: Done : {time.strftime('%H:%M:%S')}\tTotal: {hm_time(end_t - str_t)}\n") + return sorted_list ##==============------------------- End -------------------==============##