Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 4,511 Bytes
bf67612 14e5437 bf67612 14e5437 bf67612 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
import os
from typing import Dict, Any
import librosa
def validate_audio_path(audio_path: str) -> str:
"""
Validate and return absolute path for audio file.
Args:
audio_path: Path to audio file or URL (can be relative or absolute)
Returns:
Absolute path to audio file
Raises:
FileNotFoundError: If file doesn't exist
ValueError: If path is invalid
"""
if not audio_path:
raise ValueError("Audio path cannot be empty")
# Convert to absolute path
abs_path = os.path.abspath(audio_path)
# Check if file exists
if not os.path.exists(abs_path):
raise FileNotFoundError(f"Audio file not found: {abs_path}")
# Check if it's a file (not directory)
if not os.path.isfile(abs_path):
raise ValueError(f"Path is not a file: {abs_path}")
return abs_path
def get_audio_info(audio_path: str) -> Dict[str, Any]:
"""
Get detailed information about an audio file.
This function analyzes an audio file and returns comprehensive metadata
including duration, sample rate, channels, and format information.
Args:
audio_path: Path to the input audio file or URL (supports common formats: WAV, MP3, FLAC, M4A)
Returns:
Dictionary with audio information:
{
"duration": duration_in_seconds,
"sample_rate": sample_rate,
"channels": number_of_channels,
"format": "stereo" or "mono",
"filename": original_filename,
"file_size": file_size_bytes,
"bit_depth": bit_depth_if_available
}
Example:
info = get_audio_info("song.mp3")
print(f"Duration: {info['duration']} seconds")
print(f"Sample rate: {info['sample_rate']} Hz")
print(f"Channels: {info['channels']} ({info['format']})")
Note:
Uses librosa for audio analysis which supports most common audio formats
File size is included for reference
Bit depth is available for uncompressed formats like WAV
"""
try:
# Validate audio path
validated_path = validate_audio_path(audio_path)
# Load audio with librosa
y, sr = librosa.load(validated_path, sr=None, mono=False)
# Get basic audio info
duration = len(y) / sr if y.ndim == 1 else len(y[0]) / sr
channels = 1 if y.ndim == 1 else y.shape[0]
audio_format = "mono" if channels == 1 else "stereo"
# Get file info
filename = os.path.basename(validated_path)
file_size = os.path.getsize(validated_path)
# Try to get bit depth for WAV files
bit_depth = None
try:
import soundfile as sf
with sf.SoundFile(validated_path) as f:
if hasattr(f, "subtype"):
bit_depth = f.subtype
except Exception:
pass # Bit depth not available or error occurred
return {
"duration": round(duration, 2),
"sample_rate": sr,
"channels": channels,
"format": audio_format,
"filename": filename,
"file_size": file_size,
"file_size_mb": round(file_size / (1024 * 1024), 2),
"bit_depth": bit_depth,
"status": "success",
}
except Exception as e:
return {"status": "error", "message": f"Error analyzing audio: {str(e)}"}
if __name__ == "__main__":
import argparse
import json
parser = argparse.ArgumentParser(
description="Get detailed information about audio files"
)
parser.add_argument("audio_path", help="Path to audio file")
parser.add_argument("--json", action="store_true", help="Output as JSON")
args = parser.parse_args()
try:
info = get_audio_info(args.audio_path)
if args.json:
print(json.dumps(info, indent=2))
else:
print(f"Audio Information for: {info.get('filename', args.audio_path)}")
print(f"Duration: {info.get('duration', 'N/A')} seconds")
print(f"Sample Rate: {info.get('sample_rate', 'N/A')} Hz")
print(
f"Channels: {info.get('channels', 'N/A')} ({info.get('format', 'N/A')})"
)
print(f"File Size: {info.get('file_size_mb', 'N/A')} MB")
if info.get("bit_depth"):
print(f"Bit Depth: {info.get('bit_depth')}")
except Exception as e:
print(f"Error: {e}")
exit(1)
|