from .base_effect import BaseEffect from PIL import Image class AICameraEffect(BaseEffect): def __init__(self, width, height): self.width = width self.height = height self.zoom = 1.0 def draw(self, frame_image, current_time, audio_features): # Этот эффект не рисует на холсте, а модифицирует его, поэтому он вызывается отдельно beat_times = audio_features['beat_times'] time_since_beat = min([abs(current_time - bt) for bt in beat_times] or [1]) if time_since_beat < 0.05: self.zoom = 1.05 # Резкое приближение на бите else: self.zoom = max(1.0, self.zoom * 0.99) # Плавное возвращение if self.zoom > 1.001: w, h = frame_image.size zoom_w, zoom_h = int(w / self.zoom), int(h / self.zoom) x1, y1 = (w - zoom_w) // 2, (h - zoom_h) // 2 cropped = frame_image.crop((x1, y1, x1 + zoom_w, y1 + zoom_h)) return cropped.resize((w, h), Image.LANCZOS) return frame_image