import tkinter as tk from tkinter import ttk, filedialog, messagebox import os from gui.video_item import VideoItem from core.video_processor import VideoProcessor from core.logger import Logger class MainWindow: def __init__(self, root): self.root = root self.root.title("Video Editor Pro") self.root.geometry("900x700") self.video_items = [] self.setup_ui() self.logger = Logger() def setup_ui(self): # Main frame main_frame = ttk.Frame(self.root, padding="10") main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) # Add files section files_frame = ttk.LabelFrame(main_frame, text="Видео файлы", padding="5") files_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10)) ttk.Button(files_frame, text="Добавить файлы", command=self.add_video_files).pack(side=tk.LEFT, padx=(0, 10)) ttk.Button(files_frame, text="Очистить все", command=self.clear_all).pack(side=tk.LEFT) # Scrollable frame for video items canvas = tk.Canvas(main_frame) scrollbar = ttk.Scrollbar(main_frame, orient="vertical", command=canvas.yview) self.scrollable_frame = ttk.Frame(canvas) self.scrollable_frame.bind( "", lambda e: canvas.configure(scrollregion=canvas.bbox("all")) ) canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw") canvas.configure(yscrollcommand=scrollbar.set) canvas.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S)) scrollbar.grid(row=1, column=1, sticky=(tk.N, tk.S)) # Output settings output_frame = ttk.LabelFrame(main_frame, text="Настройки вывода", padding="5") output_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(10, 0)) ttk.Label(output_frame, text="Формат:").grid(row=0, column=0, padx=(0, 5)) self.format_var = tk.StringVar(value="mp4") format_combo = ttk.Combobox(output_frame, textvariable=self.format_var, values=["mp4", "avi", "mov", "mkv"], state="readonly") format_combo.grid(row=0, column=1, padx=(0, 20)) ttk.Label(output_frame, text="Качество:").grid(row=0, column=2, padx=(0, 5)) self.quality_var = tk.StringVar(value="high") quality_combo = ttk.Combobox(output_frame, textvariable=self.quality_var, values=["low", "medium", "high"], state="readonly") quality_combo.grid(row=0, column=3, padx=(0, 20)) ttk.Button(output_frame, text="Выбрать папку для сохранения", command=self.select_output_dir).grid(row=0, column=4, padx=(0, 10)) self.output_dir_var = tk.StringVar(value=os.getcwd()) ttk.Label(output_frame, textvariable=self.output_dir_var).grid(row=0, column=5) # Process button ttk.Button(main_frame, text="Выполнить", command=self.process_videos, style="Accent.TButton").grid(row=3, column=0, pady=20) # Progress bar self.progress_var = tk.DoubleVar() self.progress_bar = ttk.Progressbar(main_frame, variable=self.progress_var, maximum=100) self.progress_bar.grid(row=4, column=0, columnspan=2, sticky=(tk.W, tk.E)) # Status label self.status_var = tk.StringVar(value="Готов к работе") ttk.Label(main_frame, textvariable=self.status_var).grid(row=5, column=0, columnspan=2) # Configure grid weights main_frame.columnconfigure(0, weight=1) main_frame.rowconfigure(1, weight=1) def add_video_files(self): files = filedialog.askopenfilenames( title="Выберите видео файлы", filetypes=[ ("Видео файлы", "*.mp4 *.avi *.mov *.mkv *.wmv *.flv *.webm"), ("Все файлы", "*.*") ] ) for file_path in files: video_item = VideoItem(self.scrollable_frame, file_path) video_item.pack(fill=tk.X, padx=5, pady=2) self.video_items.append(video_item) self.update_status(f"Добавлено файлов: {len(files)}") def clear_all(self): for item in self.video_items: item.destroy() self.video_items.clear() self.update_status("Все файлы удалены") def select_output_dir(self): directory = filedialog.askdirectory(title="Выберите папку для сохранения") if directory: self.output_dir_var.set(directory) def update_status(self, message): self.status_var.set(message) self.root.update() def process_videos(self): if not self.video_items: messagebox.showerror("Ошибка", "Добавьте хотя бы один видео файл") return # Collect video data video_data = [] for item in self.video_items: time_ranges = item.get_time_ranges() if not time_ranges: # Use entire video if no ranges specified time_ranges = [(0, item.get_duration())] video_data.append({ 'path': item.file_path, 'time_ranges': time_ranges }) output_format = self.format_var.get() output_quality = self.quality_var.get() output_dir = self.output_dir_var.get() try: processor = VideoProcessor() def progress_callback(progress, message): self.progress_var.set(progress * 100) self.update_status(message) output_path = processor.process_videos( video_data=video_data, output_dir=output_dir, output_format=output_format, quality=output_quality, progress_callback=progress_callback ) # Save log log_path = output_path.replace(f".{output_format}", "_log.txt") self.logger.save_log(log_path) self.update_status(f"Готово! Файл сохранен: {output_path}") messagebox.showinfo("Успех", f"Обработка завершена!\nФайл: {output_path}") except Exception as e: error_msg = f"Ошибка обработки: {str(e)}" self.update_status(error_msg) self.logger.log("ERROR", error_msg) messagebox.showerror("Ошибка", error_msg) finally: self.progress_var.set(0)