Optimize this to run as fast and as best as possible import tkinter as tk
from tkinter import filedialog, messagebox
import os
import subprocess
import shutil

def select_input_folders():
    selected_folders = []
    while True:
        folder = filedialog.askdirectory(title="Select Input Folder (Cancel to finish)")
        if folder:
            if folder not in selected_folders:
                selected_folders.append(folder)
                # Update the text widget
                input_text.insert(tk.END, folder + "\n")
            else:
                messagebox.showwarning("Duplicate Folder", f"The folder '{folder}' is already selected.")
        else:
            break
    # Store the selected folders
    input_folders_var.set(selected_folders)

def select_output_folder():
    folder = filedialog.askdirectory(title="Select Output Folder")
    if folder:
        output_folder_var.set(folder)
        output_entry.delete(0, tk.END)
        output_entry.insert(0, folder)

def sanitize_folder_name(name):
    """Sanitize the folder name to remove or replace problematic characters."""
    return "".join(c if c.isalnum() or c in (' ', '_', '-') else "_" for c in name).replace(" ", "_")

def process_videos():
    input_folders = input_folders_var.get()
    output_folder = output_folder_var.get()

    if not input_folders:
        messagebox.showerror("Error", "Please select at least one input folder.")
        return
    if not output_folder:
        messagebox.showerror("Error", "Please select an output folder.")
        return

    # Ensure the output directory exists
    os.makedirs(output_folder, exist_ok=True)

    # Disable the process button to prevent multiple clicks
    process_button.config(state=tk.DISABLED)
    process_button.update()

    # Iterate over each input folder and process videos
    for folder in input_folders:
        try:
            # Get the base name of the input folder
            base_name = os.path.basename(os.path.normpath(folder))
            sanitized_base = sanitize_folder_name(base_name)
            
            # Create a unique subdirectory in the output folder
            unique_output_dir = os.path.join(output_folder, f"{sanitized_base}_{base_name}")
            os.makedirs(unique_output_dir, exist_ok=True)
            
            # Run the video2image command with the unique output directory
            # Added '-f', 'jpg' to specify the output format as JPEG
            subprocess.run(['video2image', '-i', folder, '-o', unique_output_dir, '-f', 'jpg'], check=True)
        
        except subprocess.CalledProcessError as e:
            messagebox.showerror("Error", f"Failed to process folder: {folder}\nError: {e}")
            process_button.config(state=tk.NORMAL)
            return
        except Exception as ex:
            messagebox.showerror("Error", f"An unexpected error occurred while processing folder: {folder}\nError: {ex}")
            process_button.config(state=tk.NORMAL)
            return

    messagebox.showinfo("Success", "All videos have been successfully processed.")
    process_button.config(state=tk.NORMAL)

# Initialize the main window
root = tk.Tk()
root.title("Video to Image Converter")
root.geometry("600x400")
root.resizable(False, False)

# Variables to store folder paths
input_folders_var = tk.Variable(value=[])
output_folder_var = tk.StringVar()

# Frame for Input Folders
input_frame = tk.LabelFrame(root, text="Input Folders", padx=10, pady=10)
input_frame.pack(fill="both", expand="yes", padx=20, pady=10)

# Text widget to display selected input folders
input_text = tk.Text(input_frame, height=10, width=70, wrap=tk.WORD, state='normal')
input_text.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

# Scrollbar for the text widget
input_scroll = tk.Scrollbar(input_frame, command=input_text.yview)
input_scroll.pack(side=tk.RIGHT, fill=tk.Y)
input_text.config(yscrollcommand=input_scroll.set)

# Button to select input folders
select_input_button = tk.Button(root, text="Select Input Folders", command=select_input_folders)
select_input_button.pack(pady=5)

# Frame for Output Folder
output_frame = tk.LabelFrame(root, text="Output Folder", padx=10, pady=10)
output_frame.pack(fill="both", expand="yes", padx=20, pady=10)

# Entry widget to display selected output folder
output_entry = tk.Entry(output_frame, textvariable=output_folder_var, width=70, state='readonly')
output_entry.pack(side=tk.LEFT, padx=(0, 5), expand=True, fill=tk.X)

# Button to select output folder
select_output_button = tk.Button(output_frame, text="Select Output Folder", command=select_output_folder)
select_output_button.pack(side=tk.LEFT, padx=5)

# Process Button
process_button = tk.Button(root, text="Process Videos", command=process_videos, bg='green', fg='white', font=('Helvetica', 12, 'bold'))
process_button.pack(pady=20)

# Run the GUI loop
root.mainloop()