|
|
|
|
@ -50,18 +50,28 @@ def validate_media_path(path: Path) -> Path:
|
|
|
|
|
|
|
|
|
|
def parse_probe_output(path: Path, size_bytes: int, payload: str) -> MediaInfo: |
|
|
|
|
try: |
|
|
|
|
data: dict[str, Any] = json.loads(payload) |
|
|
|
|
data: Any = json.loads(payload) |
|
|
|
|
except (json.JSONDecodeError, TypeError) as exc: |
|
|
|
|
raise ProbeOutputError("FFprobe returned invalid data.") from exc |
|
|
|
|
if not isinstance(data, dict): |
|
|
|
|
raise ProbeOutputError("FFprobe returned invalid data.") |
|
|
|
|
format_data = data.get("format", {}) |
|
|
|
|
streams = data.get("streams", []) |
|
|
|
|
if ( |
|
|
|
|
not isinstance(format_data, dict) |
|
|
|
|
or not isinstance(streams, list) |
|
|
|
|
or not all(isinstance(stream, dict) for stream in streams) |
|
|
|
|
): |
|
|
|
|
raise ProbeOutputError("FFprobe returned invalid data.") |
|
|
|
|
duration: float | None = None |
|
|
|
|
raw_duration = data.get("format", {}).get("duration") |
|
|
|
|
raw_duration = format_data.get("duration") |
|
|
|
|
try: |
|
|
|
|
if raw_duration is not None: |
|
|
|
|
duration = float(raw_duration) |
|
|
|
|
except (TypeError, ValueError): |
|
|
|
|
duration = None |
|
|
|
|
codec = next( |
|
|
|
|
(stream.get("codec_name") for stream in data.get("streams", []) if stream.get("codec_type") == "audio"), |
|
|
|
|
(stream.get("codec_name") for stream in streams if stream.get("codec_type") == "audio"), |
|
|
|
|
None, |
|
|
|
|
) |
|
|
|
|
return MediaInfo(path=path, size_bytes=size_bytes, duration_seconds=duration, audio_codec=codec) |
|
|
|
|
|