| import librosa | |
| import numpy as np | |
| class BeatTracker: | |
| def __init__(self): | |
| pass | |
| def track(self, audio_path: str): | |
| """ | |
| Track beats and tempo from audio file. | |
| Returns: { | |
| "bpm": float, | |
| "beats": list[float] # timestamps | |
| } | |
| """ | |
| try: | |
| print(f"Tracking beats for {audio_path}...") | |
| y, sr = librosa.load(audio_path) | |
| # Estimate tempo and beats | |
| tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr) | |
| # Log output to be sure | |
| # tempo is usually a scalar, but sometimes an array in older versions | |
| if isinstance(tempo, np.ndarray): | |
| tempo = tempo[0] | |
| beat_times = librosa.frames_to_time(beat_frames, sr=sr) | |
| return { | |
| "bpm": round(float(tempo), 2), | |
| "beats": [round(float(t), 2) for t in beat_times] | |
| } | |
| except Exception as e: | |
| print(f"Error tracking beats: {e}") | |
| return {"bpm": 0, "beats": []} | |