108 lines
3.9 KiB
Python
108 lines
3.9 KiB
Python
import tkinter as tk
|
||
from tkinter import ttk
|
||
import os
|
||
from moviepy.editor import VideoFileClip
|
||
|
||
|
||
class VideoItem(ttk.Frame):
|
||
def __init__(self, parent, file_path):
|
||
super().__init__(parent)
|
||
self.file_path = file_path
|
||
self.time_ranges = []
|
||
self.setup_ui()
|
||
|
||
def setup_ui(self):
|
||
# File info
|
||
file_name = os.path.basename(self.file_path)
|
||
ttk.Label(self, text=file_name, font=('Arial', 9, 'bold')).grid(row=0, column=0, sticky=tk.W)
|
||
|
||
# Duration info
|
||
try:
|
||
with VideoFileClip(self.file_path) as clip:
|
||
duration = clip.duration
|
||
duration_str = self.format_time(duration)
|
||
ttk.Label(self, text=f"Длительность: {duration_str}").grid(row=1, column=0, sticky=tk.W)
|
||
except:
|
||
duration_str = "Неизвестно"
|
||
ttk.Label(self, text="Ошибка чтения файла").grid(row=1, column=0, sticky=tk.W)
|
||
|
||
# Time ranges frame
|
||
ranges_frame = ttk.LabelFrame(self, text="Временные диапазоны")
|
||
ranges_frame.grid(row=2, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=5)
|
||
|
||
self.ranges_container = ttk.Frame(ranges_frame)
|
||
self.ranges_container.pack(fill=tk.X, padx=5, pady=5)
|
||
|
||
# Add range button
|
||
ttk.Button(ranges_frame, text="+ Добавить диапазон",
|
||
command=self.add_time_range).pack(pady=5)
|
||
|
||
# Buttons
|
||
ttk.Button(self, text="Удалить",
|
||
command=self.destroy).grid(row=0, column=2, rowspan=2, padx=5)
|
||
|
||
self.columnconfigure(0, weight=1)
|
||
|
||
def format_time(self, seconds):
|
||
hours = int(seconds // 3600)
|
||
minutes = int((seconds % 3600) // 60)
|
||
seconds = int(seconds % 60)
|
||
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
|
||
|
||
def add_time_range(self, start_time=0, end_time=0):
|
||
range_frame = ttk.Frame(self.ranges_container)
|
||
range_frame.pack(fill=tk.X, pady=2)
|
||
|
||
ttk.Label(range_frame, text="От:").pack(side=tk.LEFT)
|
||
start_var = tk.StringVar(value=self.format_time(start_time))
|
||
start_entry = ttk.Entry(range_frame, textvariable=start_var, width=8)
|
||
start_entry.pack(side=tk.LEFT, padx=(0, 10))
|
||
|
||
ttk.Label(range_frame, text="До:").pack(side=tk.LEFT)
|
||
end_var = tk.StringVar(value=self.format_time(end_time))
|
||
end_entry = ttk.Entry(range_frame, textvariable=end_var, width=8)
|
||
end_entry.pack(side=tk.LEFT, padx=(0, 10))
|
||
|
||
def remove_range():
|
||
range_frame.destroy()
|
||
self.time_ranges = [r for r in self.time_ranges if r['frame'] != range_frame]
|
||
|
||
ttk.Button(range_frame, text="×", width=3,
|
||
command=remove_range).pack(side=tk.LEFT)
|
||
|
||
self.time_ranges.append({
|
||
'frame': range_frame,
|
||
'start_var': start_var,
|
||
'end_var': end_var
|
||
})
|
||
|
||
def get_time_ranges(self):
|
||
ranges = []
|
||
for range_data in self.time_ranges:
|
||
try:
|
||
start_time = self.parse_time(range_data['start_var'].get())
|
||
end_time = self.parse_time(range_data['end_var'].get())
|
||
|
||
if start_time < end_time:
|
||
ranges.append((start_time, end_time))
|
||
except:
|
||
continue
|
||
return ranges
|
||
|
||
def parse_time(self, time_str):
|
||
parts = time_str.split(':')
|
||
if len(parts) == 3: # HH:MM:SS
|
||
hours, minutes, seconds = map(int, parts)
|
||
return hours * 3600 + minutes * 60 + seconds
|
||
elif len(parts) == 2: # MM:SS
|
||
minutes, seconds = map(int, parts)
|
||
return minutes * 60 + seconds
|
||
else: # SS
|
||
return int(time_str)
|
||
|
||
def get_duration(self):
|
||
try:
|
||
with VideoFileClip(self.file_path) as clip:
|
||
return clip.duration
|
||
except:
|
||
return 0 |