import sys import os import webbrowser import customtkinter as ctk import tkinter as tk from typing import Callable, Tuple import cv2 from PIL import Image, ImageOps import modules.globals import modules.metadata from modules.face_analyser import get_one_face from modules.capturer import get_video_frame, get_video_frame_total from modules.processors.frame.core import get_frame_processors_modules from modules.utilities import is_image, is_video, resolve_relative_path ROOT = None ROOT_HEIGHT = 700 ROOT_WIDTH = 800 PREVIEW = None PREVIEW_MAX_HEIGHT = 700 PREVIEW_MAX_WIDTH = 1200 RECENT_DIRECTORY_SOURCE = None RECENT_DIRECTORY_TARGET = None RECENT_DIRECTORY_OUTPUT = None preview_label = None preview_slider = None source_label = None target_label = None status_label = None img_ft, vid_ft = modules.globals.file_types def init(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.CTk: global ROOT, PREVIEW ROOT = create_root(start, destroy) PREVIEW = create_preview(ROOT) return ROOT def create_root(start: Callable[[], None], destroy: Callable[[], None]) -> ctk.CTk: global source_label, target_label, status_label ctk.deactivate_automatic_dpi_awareness() ctk.set_appearance_mode('system') ctk.set_default_color_theme(resolve_relative_path('ui.json')) root = ctk.CTk() root.minsize(ROOT_WIDTH, ROOT_HEIGHT) root.title(f'{modules.metadata.name} {modules.metadata.version} {modules.metadata.edition}') root.configure() root.protocol('WM_DELETE_WINDOW', lambda: destroy()) source_label = ctk.CTkLabel(root, text=None) source_label.place(relx=0.1, rely=0.1, relwidth=0.3, relheight=0.25) target_label = ctk.CTkLabel(root, text=None) target_label.place(relx=0.6, rely=0.1, relwidth=0.3, relheight=0.25) select_face_button = ctk.CTkButton(root, text='Select a face', cursor='hand2', command=lambda: select_source_path()) select_face_button.place(relx=0.1, rely=0.3, relwidth=0.3, relheight=0.1) select_target_button = ctk.CTkButton(root, text='Select a target', cursor='hand2', command=lambda: select_target_path()) select_target_button.place(relx=0.6, rely=0.3, relwidth=0.3, relheight=0.1) keep_fps_value = ctk.BooleanVar(value=modules.globals.keep_fps) keep_fps_checkbox = ctk.CTkSwitch(root, text='Keep fps', variable=keep_fps_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_fps', not modules.globals.keep_fps)) keep_fps_checkbox.place(relx=0.1, rely=0.5) keep_frames_value = ctk.BooleanVar(value=modules.globals.keep_frames) keep_frames_switch = ctk.CTkSwitch(root, text='Keep frames', variable=keep_frames_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_frames', keep_frames_value.get())) keep_frames_switch.place(relx=0.1, rely=0.55) # for FRAME PROCESSOR ENHANCER tumbler: enhancer_value = ctk.BooleanVar(value=modules.globals.fp_ui['face_enhancer']) enhancer_switch = ctk.CTkSwitch(root, text='Face Enhancer', variable=enhancer_value, cursor='hand2', command=lambda: update_tumbler('face_enhancer',enhancer_value.get())) enhancer_switch.place(relx=0.1, rely=0.6) remote_process_value = ctk.BooleanVar(value=modules.globals.fp_ui['remote_processor']) remote_process_switch = ctk.CTkSwitch(root, text='Remote Processor', variable=remote_process_value, cursor='hand2', command=lambda: update_tumbler('remote_processor',remote_process_value.get())) remote_process_switch.place(relx=0.1, rely=0.65) def on_text_change(event=None): setattr(modules.globals, 'pull_addr', text_box_addr_in.get("1.0", tk.END).strip()) def on_text_change_out(event=None): setattr(modules.globals, 'push_addr', text_box_addr_out.get("1.0", tk.END).strip()) def on_text_change_out_two(event=None): setattr(modules.globals, 'push_addr_two', text_box_addr_out_t.get("1.0", tk.END).strip()) keep_audio_value = ctk.BooleanVar(value=modules.globals.keep_audio) keep_audio_switch = ctk.CTkSwitch(root, text='Keep audio', variable=keep_audio_value, cursor='hand2', command=lambda: setattr(modules.globals, 'keep_audio', keep_audio_value.get())) keep_audio_switch.place(relx=0.6, rely=0.5) many_faces_value = ctk.BooleanVar(value=modules.globals.many_faces) many_faces_switch = ctk.CTkSwitch(root, text='Many faces', variable=many_faces_value, cursor='hand2', command=lambda: setattr(modules.globals, 'many_faces', many_faces_value.get())) many_faces_switch.place(relx=0.6, rely=0.55) nsfw_value = ctk.BooleanVar(value=modules.globals.nsfw) nsfw_switch = ctk.CTkSwitch(root, text='NSFW', variable=nsfw_value, cursor='hand2', command=lambda: setattr(modules.globals, 'nsfw', nsfw_value.get())) nsfw_switch.place(relx=0.6, rely=0.6) #Label a text box label = ctk.CTkLabel(root, text="In:") label.place(relx=0.1, rely=0.72, anchor=tk.E) #Label a text box label = ctk.CTkLabel(root, text="OutS:") label.place(relx=0.6, rely=0.72, anchor=tk.E) # Create a text box text_box_addr_in = ctk.CTkTextbox(root, width=200, height=10) text_box_addr_in.place(relx=0.1, rely=0.7) text_box_addr_in.bind("", on_text_change) # Create a text box text_box_addr_out = ctk.CTkTextbox(root, width=100, height=10) text_box_addr_out.place(relx=0.6, rely=0.7) text_box_addr_out.bind("", on_text_change_out) # Create a text box text_box_addr_out_t = ctk.CTkTextbox(root, width=100, height=10) text_box_addr_out_t.place(relx=0.8, rely=0.7) text_box_addr_out_t.bind("", on_text_change_out_two) start_button = ctk.CTkButton(root, text='Start', cursor='hand2', command=lambda: select_output_path(start)) start_button.place(relx=0.15, rely=0.75, relwidth=0.2, relheight=0.05) stop_button = ctk.CTkButton(root, text='Destroy', cursor='hand2', command=lambda: destroy()) stop_button.place(relx=0.4, rely=0.75, relwidth=0.2, relheight=0.05) preview_button = ctk.CTkButton(root, text='Preview', cursor='hand2', command=lambda: toggle_preview()) preview_button.place(relx=0.65, rely=0.75, relwidth=0.2, relheight=0.05) live_button = ctk.CTkButton(root, text='Live', cursor='hand2', command=lambda: webcam_preview()) live_button.place(relx=0.40, rely=0.85, relwidth=0.2, relheight=0.05) status_label = ctk.CTkLabel(root, text=None, justify='center') status_label.place(relx=0.1, rely=0.9, relwidth=0.8) donate_label = ctk.CTkLabel(root, text='Deep Live Cam', justify='center', cursor='hand2') donate_label.place(relx=0.1, rely=0.95, relwidth=0.8) donate_label.configure(text_color=ctk.ThemeManager.theme.get('URL').get('text_color')) donate_label.bind('