Lipsing / GUI.py
ibrahim313's picture
Upload 12 files
24bde82 verified
import tkinter as tk
from tkinter import filedialog, ttk
import configparser
import os
try:
with open('installed.txt', 'r') as file:
version = file.read()
except FileNotFoundError:
print("SyncKing-Kong does not appear to have installed correctly.")
print("Please try to install it again.")
print("https://github.com/anothermartz/Easy-Wav2Lip/issues")
input()
exit()
print("opening GUI")
runfile = 'run.txt'
if os.path.exists(runfile):
os.remove(runfile)
import webbrowser
def open_github_link(event):
webbrowser.open("https://github.com/anothermartz/Easy-Wav2Lip?tab=readme-ov-file#advanced-tweaking")
def read_config():
# Read the config.ini file
config = configparser.ConfigParser()
config.read("config.ini")
return config
def save_config(config):
# Save the updated config back to config.ini
with open("config.ini", "w") as config_file:
config.write(config_file)
def open_video_file():
file_path = filedialog.askopenfilename(title="Select a video file", filetypes=[("All files", "*.*")])
if file_path:
video_file_var.set(file_path)
def open_vocal_file():
file_path = filedialog.askopenfilename(title="Select a vocal file", filetypes=[("All files", "*.*")])
if file_path:
vocal_file_var.set(file_path)
# feathering
def validate_frame_preview(P):
if P == "":
return True # Allow empty input
try:
num = float(P)
if (num.is_integer()):
return True
except ValueError:
pass
return False
def start_syncking_kong():
print("Saving config")
config["OPTIONS"]["video_file"] = str(video_file_var.get())
config["OPTIONS"]["vocal_file"] = str(vocal_file_var.get())
config["OPTIONS"]["quality"] = str(quality_var.get())
config["OPTIONS"]["output_height"] = str(output_height_combobox.get())
config["OPTIONS"]["wav2lip_version"] = str(wav2lip_version_var.get())
config["OPTIONS"]["use_previous_tracking_data"] = str(use_previous_tracking_data_var.get())
config["OPTIONS"]["nosmooth"] = str(nosmooth_var.get())
config["OPTIONS"]["preview_window"] = str(preview_window_var.get())
config["PADDING"]["u"] = str(padding_vars["u"].get())
config["PADDING"]["d"] = str(padding_vars["d"].get())
config["PADDING"]["l"] = str(padding_vars["l"].get())
config["PADDING"]["r"] = str(padding_vars["r"].get())
config["MASK"]["size"] = str(size_var.get())
config["MASK"]["feathering"] = str(feathering_var.get())
config["MASK"]["mouth_tracking"] = str(mouth_tracking_var.get())
config["MASK"]["debug_mask"] = str(debug_mask_var.get())
config["OTHER"]["batch_process"] = str(batch_process_var.get())
config["OTHER"]["output_suffix"] = str(output_suffix_var.get())
config["OTHER"]["include_settings_in_suffix"] = str(include_settings_in_suffix_var.get())
config["OTHER"]["preview_settings"] = str(preview_settings_var.get())
config["OTHER"]["frame_to_preview"] = str(frame_to_preview_var.get())
save_config(config) # Save the updated config
with open("run.txt", "w") as f:
f.write("run")
exit()
# Add your logic here
root = tk.Tk()
root.title("SyncKing-Kong GUI")
root.geometry("800x720")
root.configure(bg="lightblue")
# Read the existing config.ini
config = read_config()
row=0
tk.Label(root, text=version, bg="lightblue").grid(row=row, column=0, sticky="w")
# Create a label for video file
row+=1
video_label = tk.Label(root, text="Video File Path:", bg="lightblue")
video_label.grid(row=row, column=0, sticky="e")
# Entry widget for video file path
video_file_var = tk.StringVar()
video_entry = tk.Entry(root, textvariable=video_file_var, width=80)
video_entry.grid(row=row, column=1, sticky="w")
# Create a button to open the file dialog
select_button = tk.Button(root, text="...", command=open_video_file)
select_button.grid(row=row, column=1, sticky="w", padx=490)
# Set the default value based on the existing config
video_file_var.set(config["OPTIONS"].get("video_file", ""))
row+=1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
# String input for vocal_file
row+=1
# Create a label for the input box
vocal_file_label = tk.Label(root, text="Vocal File Path:", bg="lightblue")
vocal_file_label.grid(row=row, column=0, sticky="e")
# Create an input box for the vocal file path
vocal_file_var = tk.StringVar()
vocal_file_entry = tk.Entry(root, textvariable=vocal_file_var, width=80)
vocal_file_entry.grid(row=row, column=1, sticky="w")
# Create a button to open the file dialog
select_button = tk.Button(root, text="...", command=open_vocal_file)
select_button.grid(row=row, column=1, sticky="w", padx=490)
# Set the initial value from the 'config' dictionary (if available)
vocal_file_var.set(config["OPTIONS"].get("vocal_file", ""))
row+=1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
# Dropdown box for quality options
row+=1
quality_label = tk.Label(root, text="Select Quality:", bg="lightblue")
quality_label.grid(row=row, column=0, sticky="e")
quality_options = ["Fast", "Improved", "Enhanced"]
quality_var = tk.StringVar()
quality_var.set(config["OPTIONS"].get("quality", "Improved"))
quality_dropdown = tk.OptionMenu(root, quality_var, *quality_options)
quality_dropdown.grid(row=row, column=1, sticky="w")
row+=1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
# Output height
row+=1
output_height_label = tk.Label(root, text="Output height:", bg="lightblue")
output_height_label.grid(row=row, column=0, sticky="e")
output_height_options = ["half resolution", "full resolution"]
output_height_combobox = ttk.Combobox(root, values=output_height_options)
output_height_combobox.set(config["OPTIONS"].get("output_height", "full resolution")) # Set default value
output_height_combobox.grid(row=row, column=1, sticky="w")
row+=1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
# Dropdown box for wav2lip version options
row+=1
wav2lip_version_label = tk.Label(root, text="Select Wav2Lip version:", bg="lightblue")
wav2lip_version_label.grid(row=row, column=0, sticky="e")
wav2lip_version_options = ["Wav2Lip", "Wav2Lip_GAN"]
wav2lip_version_var = tk.StringVar()
wav2lip_version_var.set(config["OPTIONS"].get("wav2lip_version", "Wav2Lip"))
wav2lip_version_dropdown = tk.OptionMenu(root, wav2lip_version_var, *wav2lip_version_options)
wav2lip_version_dropdown.grid(row=row, column=1, sticky="w")
row+=1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
# output_suffix
row+=1
output_suffix_label = tk.Label(root, text="Output File Suffix:", bg="lightblue")
output_suffix_label.grid(row=row, column=0, sticky="e")
output_suffix_var = tk.StringVar()
output_suffix_var.set(config["OTHER"].get("output_suffix", "_SyncKing-Kong"))
output_suffix_entry = output_suffix_entry = tk.Entry(root, textvariable=output_suffix_var, width=20)
output_suffix_entry.grid(row=row, column=1, sticky="w")
include_settings_in_suffix_var = tk.BooleanVar()
include_settings_in_suffix_var.set(config["OTHER"].get("include_settings_in_suffix", True)) # Set default value
include_settings_in_suffix_checkbox = tk.Checkbutton(root, text="Add Settings to Suffix", variable=include_settings_in_suffix_var, bg="lightblue")
include_settings_in_suffix_checkbox.grid(row=row, column=1, sticky="w", padx=130)
# batch_process
row+=1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
row+=1
batch_process_label = tk.Label(root, text="Batch Process:", bg="lightblue")
batch_process_label.grid(row=row, column=0, sticky="e")
batch_process_var = tk.BooleanVar()
batch_process_var.set(config["OTHER"].get("batch_process", True)) # Set default value
batch_process_checkbox = tk.Checkbutton(root, text="", variable=batch_process_var, bg="lightblue")
batch_process_checkbox.grid(row=row, column=1, sticky="w")
# Dropdown box for preview window options
row+=1
preview_window_label = tk.Label(root, text="Preview Window:", bg="lightblue")
preview_window_label.grid(row=row, column=0, sticky="e")
preview_window_options = ["Face", "Full", "Both", "None"]
preview_window_var = tk.StringVar()
preview_window_var.set(config["OPTIONS"].get("preview_window", "Face"))
preview_window_dropdown = tk.OptionMenu(root, preview_window_var, *preview_window_options)
preview_window_dropdown.grid(row=row, column=1, sticky="w")
row+=1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
# Button to start SyncKing-Kong
row+=1
start_button = tk.Button(root, text="Start SyncKing-Kong", command=start_syncking_kong, bg="#5af269", font=("Arial", 16))
start_button.grid(row=row, column=0, sticky="w", padx=290, columnspan=2)
row+=1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
row+=1
tk.Label(root, text="Advanced Tweaking:", bg="lightblue", font=("Arial", 16)).grid(row=row, column=0, sticky="w")
row+=1
# Create a label with a custom cursor
link = tk.Label(root, text="(Click here to see readme)", bg="lightblue", fg="blue", font=("Arial", 10), cursor="hand2")
link.grid(row=row, column=0)
# Bind the click event to the label
link.bind("<Button-1>", open_github_link)
# Process one frame only
preview_settings_var = tk.BooleanVar()
preview_settings_var.set(config["OTHER"].get("preview_settings", True)) # Set default value
preview_settings_checkbox = tk.Checkbutton(root, text="Process one frame only - Frame to process:", variable=preview_settings_var, bg="lightblue")
preview_settings_checkbox.grid(row=row, column=1, sticky="w")
frame_to_preview_var = tk.StringVar()
frame_to_preview_entry = tk.Entry(root, textvariable=frame_to_preview_var, validate="key", width=3, validatecommand=(root.register(validate_frame_preview), "%P"))
frame_to_preview_entry.grid(row=row, column=1, sticky="w", padx=255)
frame_to_preview_var.set(config["OTHER"].get("frame_to_preview", "100"))
# Checkbox for nosmooth option
row+=1
nosmooth_var = tk.BooleanVar()
nosmooth_var.set(config["OPTIONS"].get("nosmooth", True)) # Set default value
nosmooth_checkbox = tk.Checkbutton(root, text="nosmooth - unticking will smooth face detection between 5 frames", variable=nosmooth_var, bg="lightblue")
nosmooth_checkbox.grid(row=row, column=1, sticky="w")
# Checkbox for use_previous_tracking_data option
row+=1
use_previous_tracking_data_var = tk.BooleanVar()
use_previous_tracking_data_var.set(config["OPTIONS"].get("use_previous_tracking_data", True)) # Set default value
use_previous_tracking_data_checkbox = tk.Checkbutton(root, text="Keep previous face tracking data if using same video", variable=use_previous_tracking_data_var, bg="lightblue")
use_previous_tracking_data_checkbox.grid(row=row, column=1, sticky="w")
# padding
row+=1
tk.Label(root, text="Padding:", bg="lightblue", font=("Arial", 12)).grid(row=row, column=1, sticky="sw", pady=10)
row+=1
tk.Label(root, text="(Up, Down, Left, Right)", bg="lightblue").grid(row=row, column=1, rowspan=4, sticky="w", padx=100)
padding_vars = {}
# Create a list of padding labels and their corresponding keys
padding_labels = [("U:", "u"), ("D:", "d"), ("L:", "l"), ("R:", "r")]
# Validation function to allow only integers
def validate_integer(P):
if P == "" or P == "-" or P.lstrip("-").isdigit():
return True
return False
# Create the padding labels and entry widgets using a loop
for label_text, key in padding_labels:
label = tk.Label(root, text=label_text, bg="lightblue")
label.grid(row=row, column=1, sticky="w", padx=50)
# Create a StringVar for the current key
padding_var = tk.StringVar()
# Set validation to allow positive and negative integers
entry = tk.Entry(root, textvariable=padding_var, width=3, validate="key", validatecommand=(root.register(validate_integer), "%P"))
entry.grid(row=row, column=1, sticky="w", padx=70)
# Set the default value from the 'config' dictionary
padding_var.set(config["PADDING"].get(key, ""))
# Store the StringVar in the dictionary
padding_vars[key] = padding_var
# Increment the row
row += 1
tk.Label(root, text="", bg="lightblue").grid(row=row, column=0, sticky="w")
row+=1
# mask size
def validate_custom_number(P):
if P == "":
return True # Allow empty input
try:
num = float(P)
if 0 <= num <= 6 and (num.is_integer() or (num * 10) % 1 == 0):
return True
except ValueError:
pass
return False
row+=1
tk.Label(root, text="Mask settings:", bg="lightblue", font=("Arial", 12)).grid(row=row, column=1, sticky="sw")
row+=1
size_label = tk.Label(root, text="Mask size:", bg="lightblue", padx=50)
size_label.grid(row=row, column=1, sticky="w")
size_var = tk.StringVar()
size_entry = tk.Entry(root, textvariable=size_var, validate="key", width=3, validatecommand=(root.register(validate_custom_number), "%P"))
size_entry.grid(row=row, column=1, sticky="w", padx=120)
size_var.set(config["MASK"].get("size", "2.5"))
# feathering
def validate_feather(P):
if P == "":
return True # Allow empty input
try:
num = float(P)
if 0 <= num <= 3 and (num.is_integer()):
return True
except ValueError:
pass
return False
row+=1
feathering_label = tk.Label(root, text="Feathering:", bg="lightblue", padx=50)
feathering_label.grid(row=row, column=1, sticky="w")
feathering_var = tk.StringVar()
feathering_entry = tk.Entry(root, textvariable=feathering_var, validate="key", width=3, validatecommand=(root.register(validate_feather), "%P"))
feathering_entry.grid(row=row, column=1, sticky="w", padx=120)
feathering_var.set(config["MASK"].get("feathering", "2.5"))
# mouth_tracking
row+=1
mouth_tracking_var = tk.BooleanVar()
mouth_tracking_var.set(config["MASK"].get("mouth_tracking", True)) # Set default value
mouth_tracking_checkbox = tk.Checkbutton(root, text="track mouth for mask on every frame", variable=mouth_tracking_var, bg="lightblue", padx=50)
mouth_tracking_checkbox.grid(row=row, column=1, sticky="w")
# debug_mask
row+=1
debug_mask_var = tk.BooleanVar()
debug_mask_var.set(config["MASK"].get("debug_mask", True)) # Set default value
debug_mask_checkbox = tk.Checkbutton(root, text="highlight mask for debugging", variable=debug_mask_var, bg="lightblue", padx=50)
debug_mask_checkbox.grid(row=row, column=1, sticky="w")
# Increase spacing between all rows (uniformly)
for row in range(row):
root.rowconfigure(row, weight=1)
root.mainloop()