import tkinter as tk
from tkinter import filedialog, colorchooser
import matplotlib.pyplot as plt
import numpy as np
import librosa
import moviepy.editor as mp
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import threading
import os
from pydub import AudioSegment
from pydub.playback import play

class AudioVisualizerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Audio Visualizer")
        self.audio_file = None
        self.is_playing = False
        self.fig, self.ax = plt.subplots()
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.root)
        self.canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
        self.setup_gui()

    def setup_gui(self):
        self.file_button = tk.Button(self.root, text="Select Audio File", command=self.load_file)
        self.file_button.pack(pady=10)

        self.start_pause_button = tk.Button(self.root, text="Start", command=self.toggle_playback)
        self.start_pause_button.pack(pady=10)

        self.render_button = tk.Button(self.root, text="Render Video", command=self.render_video)
        self.render_button.pack(pady=10)

        self.bar_count_label = tk.Label(self.root, text="Number of Bars:")
        self.bar_count_label.pack(pady=5)
        self.bar_count = tk.Entry(self.root)
        self.bar_count.pack(pady=5)
        self.bar_count.insert(0, "50")

        self.bar_space_label = tk.Label(self.root, text="Space Between Bars:")
        self.bar_space_label.pack(pady=5)
        self.bar_space = tk.Entry(self.root)
        self.bar_space.pack(pady=5)
        self.bar_space.insert(0, "2")

        self.bar_color_label = tk.Label(self.root, text="Bar Color:")
        self.bar_color_label.pack(pady=5)
        self.bar_color_button = tk.Button(self.root, text="Choose Color", command=self.choose_color)
        self.bar_color_button.pack(pady=5)
        self.bar_color = "#FFFFFF"

        self.fig.patch.set_facecolor('green')
        self.ax.set_facecolor('green')
        self.ax.set_xticks([])
        self.ax.set_yticks([])
        self.ax.set_xlim(0, 1)
        self.ax.set_ylim(0, 1)
        self.bars = self.ax.bar(np.arange(50), np.zeros(50), color=self.bar_color)
        self.canvas.draw()

    def load_file(self):
        self.audio_file = filedialog.askopenfilename(filetypes=[("Audio Files", "*.wav;*.mp3")])
        if self.audio_file:
            self.audio_data, self.sample_rate = librosa.load(self.audio_file, sr=None)
            self.is_playing = False

    def toggle_playback(self):
        if self.audio_file:
            if self.is_playing:
                self.is_playing = False
                self.start_pause_button.config(text="Start")
            else:
                self.is_playing = True
                self.start_pause_button.config(text="Pause")
                if not hasattr(self, 'play_thread') or not self.play_thread.is_alive():
                    self.play_thread = threading.Thread(target=self.start_playback)
                    self.play_thread.start()

    def start_playback(self):
        # Load audio with pydub for playback
        audio = AudioSegment.from_file(self.audio_file)
        playback_thread = threading.Thread(target=self.play_audio, args=(audio,))
        playback_thread.start()
        self.update_visualization()

    def play_audio(self, audio):
        play(audio)

    def update_visualization(self):
        hop_length = 512
        while self.is_playing:
            try:
                # Visualization logic
                S, phase = librosa.magphase(librosa.stft(self.audio_data, hop_length=hop_length))
                self.ax.clear()
                self.ax.set_facecolor('green')
                self.ax.set_xticks([])
                self.ax.set_yticks([])
                num_bars = int(self.bar_count.get())
                space_between_bars = float(self.bar_space.get())
                color = self.bar_color
                bars = self.ax.bar(np.arange(num_bars) * space_between_bars, np.mean(S, axis=1)[:num_bars], color=color)
                self.canvas.draw()
                plt.pause(0.1)
            except Exception as e:
                print(f"Error in visualization: {e}")
                self.is_playing = False
                self.start_pause_button.config(text="Start")
                break
        plt.close()

    def choose_color(self):
        color = colorchooser.askcolor()[1]
        if color:
            self.bar_color = color

    def render_video(self):
        if self.audio_file:
            try:
                duration = librosa.get_duration(filename=self.audio_file)
                fps = 30
                num_frames = int(duration * fps)
                frames = []

                for i in range(num_frames):
                    frame = np.zeros((1080, 1920, 3), dtype=np.uint8)
                    frame[:, :] = [0, 255, 0]  # Green background
                    self.ax.clear()
                    self.ax.set_facecolor('green')
                    self.ax.set_xticks([])
                    self.ax.set_yticks([])
                    num_bars = int(self.bar_count.get())
                    space_between_bars = float(self.bar_space.get())
                    color = self.bar_color
                    bars = self.ax.bar(np.arange(num_bars) * space_between_bars, np.random.rand(num_bars), color=color)
                    self.canvas.draw()
                    plt.savefig('frame.png', dpi=200)
                    frame = plt.imread('frame.png')
                    frames.append(frame)

                video_clip = mp.ImageSequenceClip(frames, fps=fps)
                video_clip.write_videofile('visualization.mp4', codec='libx264', fps=fps)
                os.remove('frame.png')
            except Exception as e:
                print(f"Error in video rendering: {e}")

if __name__ == "__main__":
    root = tk.Tk()
    app = AudioVisualizerApp(root)
    root.mainloop()

lets update this version because its stable
regenerate this cause fixing the issue that when i click start the audio play for 1 second then stop
i dont want this to happen i want to see all the uploded audio file played with his visiolosation in real time be a good boy and fix the code so kids dont die under a track