""" FFmpeg probe module - Extract metadata from media files using ffprobe. """ from dataclasses import dataclass from typing import Any, Dict, Optional import ffmpeg @dataclass class ProbeResult: """Structured ffprobe result.""" duration: Optional[float] file_size: int # Video video_codec: Optional[str] width: Optional[int] height: Optional[int] framerate: Optional[float] video_bitrate: Optional[int] # Audio audio_codec: Optional[str] audio_channels: Optional[int] audio_samplerate: Optional[int] audio_bitrate: Optional[int] # Raw data raw: Dict[str, Any] def probe_file(file_path: str) -> ProbeResult: """ Run ffprobe and return structured result. Args: file_path: Path to the media file Returns: ProbeResult with extracted metadata Raises: ffmpeg.Error: If ffprobe fails """ data = ffmpeg.probe(file_path) # Extract video stream info video_stream = next( (s for s in data.get("streams", []) if s.get("codec_type") == "video"), {} ) # Extract audio stream info audio_stream = next( (s for s in data.get("streams", []) if s.get("codec_type") == "audio"), {} ) format_info = data.get("format", {}) # Parse framerate (e.g., "30000/1001" -> 29.97) framerate = None if "r_frame_rate" in video_stream: try: num, den = video_stream["r_frame_rate"].split("/") framerate = float(num) / float(den) except (ValueError, ZeroDivisionError): pass # Parse duration duration = None if "duration" in format_info: try: duration = float(format_info["duration"]) except ValueError: pass return ProbeResult( duration=duration, file_size=int(format_info.get("size", 0)), video_codec=video_stream.get("codec_name"), width=video_stream.get("width"), height=video_stream.get("height"), framerate=framerate, video_bitrate=int(video_stream.get("bit_rate", 0)) or None, audio_codec=audio_stream.get("codec_name"), audio_channels=audio_stream.get("channels"), audio_samplerate=int(audio_stream.get("sample_rate", 0)) or None, audio_bitrate=int(audio_stream.get("bit_rate", 0)) or None, raw=data, )