AICoverGen / src /modules /utils.py
R-Kentaren's picture
Upload src/modules/utils.py with huggingface_hub
f774f66 verified
Raw
History Blame Contribute Delete
1.95 kB
"""
Utility helpers for the improved AICoverGen.
"""
import os
import re
from typing import Any, Dict
def format_time(seconds: float) -> str:
"""Format seconds as M:SS or H:MM:SS."""
if seconds is None or seconds < 0:
return "0:00"
seconds = int(seconds)
hours = seconds // 3600
minutes = (seconds % 3600) // 60
secs = seconds % 60
if hours > 0:
return f"{hours}:{minutes:02d}:{secs:02d}"
return f"{minutes}:{secs:02d}"
def get_audio_info(path: str) -> Dict[str, Any]:
"""Return basic info about an audio file (duration, sample rate, channels)."""
info: Dict[str, Any] = {
"path": path,
"exists": False,
"duration": 0.0,
"sample_rate": 0,
"channels": 0,
"size_bytes": 0,
}
if not path or not os.path.exists(path):
return info
info["exists"] = True
info["size_bytes"] = os.path.getsize(path)
try:
import soundfile as sf
with sf.SoundFile(path) as f:
info["duration"] = len(f) / f.samplerate
info["sample_rate"] = f.samplerate
info["channels"] = f.channels
except Exception:
try:
import librosa
y, sr = librosa.load(path, sr=None, mono=False)
info["sample_rate"] = sr
if y.ndim > 1:
info["channels"] = y.shape[0]
info["duration"] = y.shape[1] / sr
else:
info["channels"] = 1
info["duration"] = y.shape[0] / sr
except Exception:
pass
return info
def human_size(num_bytes: int) -> str:
"""Convert bytes to human-readable string."""
if num_bytes is None or num_bytes < 0:
return "0 B"
units = ["B", "KB", "MB", "GB", "TB"]
size = float(num_bytes)
idx = 0
while size >= 1024 and idx < len(units) - 1:
size /= 1024
idx += 1
return f"{size:.1f} {units[idx]}"