INIT
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import logging
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Logger:
|
||||
def __init__(self):
|
||||
self.log_messages = []
|
||||
|
||||
def log(self, level, message):
|
||||
"""Добавление сообщения в лог"""
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
log_entry = f"[{timestamp}] [{level}] {message}"
|
||||
self.log_messages.append(log_entry)
|
||||
print(log_entry) # Также выводим в консоль
|
||||
|
||||
def save_log(self, file_path):
|
||||
"""Сохранение лога в файл"""
|
||||
try:
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
f.write("VIDEO EDITOR PROCESSING LOG\n")
|
||||
f.write("=" * 50 + "\n")
|
||||
f.write(f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
|
||||
f.write("=" * 50 + "\n\n")
|
||||
|
||||
for log_entry in self.log_messages:
|
||||
f.write(log_entry + "\n")
|
||||
|
||||
self.log("INFO", f"Лог сохранен: {file_path}")
|
||||
except Exception as e:
|
||||
self.log("ERROR", f"Ошибка сохранения лога: {str(e)}")
|
||||
|
||||
def clear_log(self):
|
||||
"""Очистка лога"""
|
||||
self.log_messages.clear()
|
||||
@@ -0,0 +1,111 @@
|
||||
import os
|
||||
from moviepy.editor import VideoFileClip, concatenate_videoclips
|
||||
import tempfile
|
||||
from datetime import datetime
|
||||
from core.logger import Logger
|
||||
|
||||
|
||||
class VideoProcessor:
|
||||
def __init__(self):
|
||||
self.logger = Logger()
|
||||
|
||||
def process_videos(self, video_data, output_dir, output_format="mp4",
|
||||
quality="high", progress_callback=None):
|
||||
"""
|
||||
Основной метод обработки видео
|
||||
"""
|
||||
self.logger.log("INFO", f"Начало обработки {len(video_data)} видео файлов")
|
||||
|
||||
clips = []
|
||||
total_steps = sum(len(data['time_ranges']) for data in video_data) + 2
|
||||
current_step = 0
|
||||
|
||||
try:
|
||||
# Обработка каждого видео файла
|
||||
for i, data in enumerate(video_data):
|
||||
video_path = data['path']
|
||||
time_ranges = data['time_ranges']
|
||||
|
||||
self.logger.log("INFO", f"Обработка файла: {os.path.basename(video_path)}")
|
||||
|
||||
with VideoFileClip(video_path) as video:
|
||||
# Вырезаем указанные диапазоны
|
||||
for start, end in time_ranges:
|
||||
if progress_callback:
|
||||
progress = current_step / total_steps
|
||||
progress_callback(progress,
|
||||
f"Вырезание фрагмента {i + 1}/{len(video_data)}")
|
||||
|
||||
# Обрезаем видео по таймкодам
|
||||
clip = video.subclip(start, end)
|
||||
clips.append(clip)
|
||||
current_step += 1
|
||||
|
||||
self.logger.log("INFO",
|
||||
f"Вырезан фрагмент: {self.format_time(start)} - {self.format_time(end)}")
|
||||
|
||||
if not clips:
|
||||
raise ValueError("Нет видео фрагментов для объединения")
|
||||
|
||||
# Объединение клипов
|
||||
if progress_callback:
|
||||
progress_callback(current_step / total_steps, "Объединение видео фрагментов")
|
||||
|
||||
self.logger.log("INFO", f"Объединение {len(clips)} фрагментов")
|
||||
final_clip = concatenate_videoclips(clips)
|
||||
|
||||
# Настройка качества
|
||||
bitrate = self.get_bitrate(quality)
|
||||
|
||||
# Генерация имени выходного файла
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
output_filename = f"edited_video_{timestamp}.{output_format}"
|
||||
output_path = os.path.join(output_dir, output_filename)
|
||||
|
||||
# Сохранение результата
|
||||
if progress_callback:
|
||||
progress_callback((total_steps - 1) / total_steps, "Сохранение итогового файла")
|
||||
|
||||
self.logger.log("INFO", f"Сохранение файла: {output_path}")
|
||||
final_clip.write_videofile(
|
||||
output_path,
|
||||
codec='libx264',
|
||||
bitrate=bitrate,
|
||||
audio_codec='aac',
|
||||
verbose=False,
|
||||
logger=None
|
||||
)
|
||||
|
||||
# Закрытие клипов
|
||||
final_clip.close()
|
||||
for clip in clips:
|
||||
clip.close()
|
||||
|
||||
self.logger.log("SUCCESS", f"Обработка завершена успешно: {output_path}")
|
||||
return output_path
|
||||
|
||||
except Exception as e:
|
||||
self.logger.log("ERROR", f"Ошибка обработки: {str(e)}")
|
||||
# Закрытие клипов в случае ошибки
|
||||
for clip in clips:
|
||||
try:
|
||||
clip.close()
|
||||
except:
|
||||
pass
|
||||
raise
|
||||
|
||||
def get_bitrate(self, quality):
|
||||
"""Определение битрейта в зависимости от качества"""
|
||||
quality_settings = {
|
||||
'low': '1000k',
|
||||
'medium': '3000k',
|
||||
'high': '8000k'
|
||||
}
|
||||
return quality_settings.get(quality, '3000k')
|
||||
|
||||
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}"
|
||||
Reference in New Issue
Block a user