# app.py import gradio as gr # --- "Ленивое" хранилище для наших тяжелых объектов --- class AppState: audio_analyzer = None asset_generator = None APP_STATE = AppState() # --- Главная функция-оркестратор --- def generate_visualization( audio_file, user_prompt, style, enable_particles, enable_spectrum, enable_camera, duration, progress=gr.Progress(track_tqdm=True) ): # --- Все импорты и инициализация происходят здесь --- from audio_analyzer import AudioAnalyzer from asset_generator import AssetGenerator from renderer import VideoRenderer # Ленивая инициализация: создаем объекты только если их еще нет if APP_STATE.audio_analyzer is None: progress(0, desc="Первый запуск: инициализация анализатора...") APP_STATE.audio_analyzer = AudioAnalyzer() if APP_STATE.asset_generator is None: progress(0, desc="Первый запуск: инициализация AI-художника...") APP_STATE.asset_generator = AssetGenerator() # --- Дальнейшая логика --- if not audio_file: raise gr.Error("Пожалуйста, загрузите аудиофайл.") if not user_prompt: raise gr.Error("Пожалуйста, опишите вашу идею в поле для промпта.") progress(0.1, desc="Шаг 1/3: Анализ ритма и энергии...") audio_features = APP_STATE.audio_analyzer.analyze(audio_file) progress(0.3, desc="Шаг 2/3: Подготовка AI-художника...") # --- ИСПРАВЛЕНИЕ --- # Вызываем загрузку модели здесь, ПЕРЕД ее использованием. # Метод сам проверит, загружена ли модель, и не будет делать лишней работы. # Это гарантирует, что self.pipe не будет None. APP_STATE.asset_generator.load_model() progress(0.5, desc="Шаг 2/3: ИИ-художник рисует вашу идею...") base_texture = APP_STATE.asset_generator.create_background_texture(style, user_prompt) progress(0.7, desc="Шаг 3/3: Анимация и синхронизация с музыкой...") user_settings = { 'artist': '', 'title': '', 'enable_particles': enable_particles, 'enable_spectrum': enable_spectrum, 'enable_camera_effect': enable_camera, 'duration': duration } renderer = VideoRenderer(1920, 1080, 30, base_texture, audio_features, user_settings) final_video_path = renderer.render(audio_file) progress(1.0, desc="Готово!") return final_video_path, base_texture # --- Интерфейс Gradio (без изменений) --- with gr.Blocks(theme=gr.themes.Soft(), title="Creative AI Music Visualizer") as demo: gr.Markdown("# 🎨 Creative AI Music Visualizer v5.4 (Logic Fix)") gr.Markdown("**Вы — режиссёр. ИИ — ваш инструмент.**") with gr.Row(): with gr.Column(scale=1): gr.Markdown("### 1. Загрузите трек") audio_input = gr.Audio(label="Аудиофайл (для анализа ритма и синхронизации)", type="filepath") gr.Markdown("### 2. Опишите вашу идею") style_input = gr.Dropdown( label="Общий стиль", choices=["Cinematic 8K Wallpaper", "Dark Fantasy Art", "Surrealism", "Symbolic Masterpiece", "Abstract Painting"], value="Cinematic 8K Wallpaper" ) prompt_input = gr.Textbox( label="Ваш творческий промпт", lines=5, placeholder="Опишите здесь вашу метафору, например: 'потресканные песочные часы с черным песком внутри, на черном фоне с тяжелыми цепями, которые медленно качаются'..." ) gr.Markdown("### 3. Настройки анимации") with gr.Accordion("Включить/выключить эффекты", open=True): particles_toggle = gr.Checkbox(label="Эффект частиц", value=True) spectrum_toggle = gr.Checkbox(label="Эквалайзер", value=False) camera_toggle = gr.Checkbox(label="Эффект камеры (зум на битах)", value=True) duration_slider = gr.Slider(label="Длительность видео (сек)", minimum=10, maximum=60, value=20, step=1) generate_btn = gr.Button("✨ Воплотить идею!", variant="primary") with gr.Column(scale=2): output_video = gr.Video(label="Ваше видео") output_image = gr.Image(label="Концепт-арт, созданный по вашему промпту") generate_btn.click( fn=generate_visualization, inputs=[ audio_input, prompt_input, style_input, particles_toggle, spectrum_toggle, camera_toggle, duration_slider ], outputs=[output_video, output_image] ) # --- Запуск приложения (без изменений) --- if __name__ == "__main__": demo.launch()