Spaces:
Build error
Build error
Download renderer.py from Zeroistheoneq/Music_visualization: direct link, hf CLI and curl.
- Browser
- Download file 2.97 kB
-
https://huggingface.co/spaces/Zeroistheoneq/Music_visualization/resolve/main/renderer.py
- Command line
-
hf download hf://spaces/Zeroistheoneq/Music_visualization/renderer.py
-
curl -L -o renderer.py https://huggingface.co/spaces/Zeroistheoneq/Music_visualization/resolve/main/renderer.py
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 |