Music_visualization / renderer.py
Zeroistheoneq's picture
Update renderer.py
fc15bf4 verified
Raw History Blame Contribute Delete
2.97 kB
# renderer.py
import cv2
import tempfile
import subprocess
import numpy as np
from PIL import Image, ImageDraw
# ИСПРАВЛЕНО: Заменены слэши на точки и убрана папка visualizer
from effects.particles import ParticleEffect
from effects.text import ScrollingTextEffect
from effects.spectrum import SpectrumEffect
from effects.camera import AICameraEffect
class VideoRenderer:
def __init__(self, width, height, fps, base_texture, audio_features, user_settings):
self.width = width
self.height = height
self.fps = fps
self.base_texture = base_texture.resize((width, height), Image.LANCZOS)
self.audio_features = audio_features
self.settings = user_settings
self.effects = []
if self.settings['enable_particles']: self.effects.append(ParticleEffect(width, height))
if self.settings['enable_spectrum']: self.effects.append(SpectrumEffect(width, height))
text = f"{self.settings.get('artist', '')} - {self.settings.get('title', '')}".strip(" -")
if text: self.effects.append(ScrollingTextEffect(text, width, height))
self.camera_effect = AICameraEffect(width, height) if self.settings['enable_camera_effect'] else None
def render(self, audio_path):
duration = min(self.settings['duration'], self.audio_features['duration'])
total_frames = int(duration * self.fps)
video_path = tempfile.mktemp(suffix=".mp4")
out = cv2.VideoWriter(video_path, cv2.VideoWriter_fourcc(*'mp4v'), self.fps, (self.width, self.height))
for i in range(total_frames):
current_time = i / self.fps
frame = self.base_texture.copy().convert("RGBA")
if self.camera_effect:
frame = self.camera_effect.draw(frame, current_time, self.audio_features)
draw = ImageDraw.Draw(frame, 'RGBA')
for effect in self.effects:
effect.draw(draw, current_time, self.audio_features)
cv_frame = cv2.cvtColor(np.array(frame), cv2.COLOR_RGBA2BGR)
out.write(cv_frame)
out.release()
print("Рендеринг видео завершен. Добавление аудио...")
final_video_path = self.mux_audio_video(video_path, audio_path, duration)
return final_video_path
def mux_audio_video(self, video_path, audio_path, duration):
final_path = tempfile.mktemp(suffix="_final.mp4")
cmd = ['ffmpeg', '-y', '-i', video_path, '-i', audio_path, '-c:v', 'copy', '-c:a', 'aac', '-map', '0:v:0', '-map', '1:a:0', '-t', str(duration), final_path]
try:
subprocess.run(cmd, check=True, capture_output=True, text=True)
print("Аудио успешно добавлено.")
return final_path
except subprocess.CalledProcessError as e:
print(f"FFMPEG Ошибка: {e.stderr}")
return video_path