167 lines
6.6 KiB
Python
167 lines
6.6 KiB
Python
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(
|
||
"<Configure>",
|
||
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) |