import os import time import tempfile import streamlit as st from config import PYGAME_AVAILABLE, MOVIEPY_AVAILABLE if PYGAME_AVAILABLE: import pygame if MOVIEPY_AVAILABLE: from moviepy import VideoFileClip class AudioPlayer: """A class to handle audio extraction and playback for the video.""" def __init__(self): self.is_playing = False self.audio_file = None self.start_time = None self.pygame_initialized = False if PYGAME_AVAILABLE: try: # Initialize pygame mixer with a specific frequency to avoid common issues pygame.mixer.pre_init(frequency=44100, size=-16, channels=2, buffer=512) pygame.mixer.init() self.pygame_initialized = True except Exception as e: st.warning(f"Audio mixer initialization failed: {e}") def extract_audio_from_video(self, video_path): """Extracts audio from a video file using MoviePy.""" if not MOVIEPY_AVAILABLE or not self.pygame_initialized: return None try: temp_audio = tempfile.mktemp(suffix='.wav') video_clip = VideoFileClip(video_path) if video_clip.audio is not None: video_clip.audio.write_audiofile(temp_audio, logger=None) video_clip.close() return temp_audio else: video_clip.close() return None except Exception as e: st.warning(f"Could not extract audio: {e}") return None def load_audio(self, video_path): """Loads an audio file for playback.""" if not self.pygame_initialized: return False try: audio_file = self.extract_audio_from_video(video_path) if audio_file and os.path.exists(audio_file): self.audio_file = audio_file return True return False except Exception as e: st.error(f"Failed to load audio: {e}") return False def play(self): """Plays the loaded audio file.""" if not self.pygame_initialized or not self.audio_file or self.is_playing: return False try: pygame.mixer.music.load(self.audio_file) pygame.mixer.music.play() self.is_playing = True self.start_time = time.time() return True except Exception as e: st.warning(f"Audio playback failed: {e}") return False def stop(self): """Stops the audio playback.""" if self.pygame_initialized and self.is_playing: try: pygame.mixer.music.stop() self.is_playing = False return True except Exception as e: return False return False def restart(self): """Restarts the audio from the beginning.""" if self.pygame_initialized and self.audio_file: self.stop() # Small delay to ensure proper stopping time.sleep(0.1) return self.play() return False def cleanup(self): """Cleans up audio resources.""" self.stop() if self.audio_file and os.path.exists(self.audio_file): try: os.unlink(self.audio_file) self.audio_file = None except Exception: pass