Fix ffprobe handling for WebM and format families
This commit is contained in:
parent
0504013c5a
commit
05ac6ce20d
4 changed files with 500 additions and 169 deletions
|
|
@ -77,7 +77,7 @@ def probe_media(file_path) -> Dict[str, Any]:
|
|||
def bitrate(info) -> float:
|
||||
try:
|
||||
return int(info["format"]["bit_rate"])
|
||||
except KeyError | ValueError:
|
||||
except (KeyError, ValueError):
|
||||
logger.error("extracting bitrate from ffprobe failed")
|
||||
return math.inf
|
||||
|
||||
|
|
@ -85,16 +85,34 @@ def bitrate(info) -> float:
|
|||
def format_name(info) -> Optional[str]:
|
||||
try:
|
||||
return info["format"]["format_name"]
|
||||
except KeyError | ValueError:
|
||||
except (KeyError, ValueError):
|
||||
logger.error("extracting format from ffprobe failed")
|
||||
return None
|
||||
|
||||
|
||||
def _stream_duration_sort_key(stream: Dict[str, Any]) -> tuple[int, float]:
|
||||
duration_ts = _int_value(stream.get("duration_ts"))
|
||||
if duration_ts is not None:
|
||||
return 1, float(duration_ts)
|
||||
try:
|
||||
duration = float(str(stream.get("duration", "")))
|
||||
except (TypeError, ValueError):
|
||||
duration = 0.0
|
||||
return 0, duration
|
||||
|
||||
|
||||
def _matches_format(probe: Dict[str, Any], expected: str) -> bool:
|
||||
current = format_name(probe)
|
||||
if current is None:
|
||||
return False
|
||||
return expected in current.split(",")
|
||||
|
||||
|
||||
def primary_video_stream(probe):
|
||||
video_streams = [
|
||||
stream for stream in probe["streams"] if stream["codec_type"] == "video"
|
||||
]
|
||||
video_streams = sorted(video_streams, key=lambda x: x["duration_ts"], reverse=True)
|
||||
video_streams = sorted(video_streams, key=_stream_duration_sort_key, reverse=True)
|
||||
if not video_streams:
|
||||
return None
|
||||
if len(video_streams) > 1:
|
||||
|
|
@ -108,7 +126,7 @@ def primary_audio_stream(probe):
|
|||
audio_streams = [
|
||||
stream for stream in probe["streams"] if stream["codec_type"] == "audio"
|
||||
]
|
||||
audio_streams = sorted(audio_streams, key=lambda x: x["duration_ts"], reverse=True)
|
||||
audio_streams = sorted(audio_streams, key=_stream_duration_sort_key, reverse=True)
|
||||
if not audio_streams:
|
||||
return None
|
||||
if len(audio_streams) > 1:
|
||||
|
|
@ -126,7 +144,7 @@ def get_resolution(probe) -> Tuple[Optional[float], Optional[float]]:
|
|||
width = int(video_stream["width"])
|
||||
height = int(video_stream["height"])
|
||||
return width, height
|
||||
except KeyError | ValueError:
|
||||
except (KeyError, ValueError):
|
||||
logger.error("extracting resolution from ffprobe failed")
|
||||
return None, None
|
||||
|
||||
|
|
@ -137,7 +155,7 @@ def get_vcodec_name(probe) -> Optional[str]:
|
|||
if not video_stream:
|
||||
return None
|
||||
return video_stream["codec_name"]
|
||||
except KeyError | ValueError:
|
||||
except (KeyError, ValueError):
|
||||
logger.error("extracting video codec_name from ffprobe failed")
|
||||
return None
|
||||
|
||||
|
|
@ -147,8 +165,11 @@ def get_acodec_info(probe) -> Tuple[Optional[str], Optional[int]]:
|
|||
audio_stream = primary_audio_stream(probe)
|
||||
if not audio_stream:
|
||||
return None, None
|
||||
return audio_stream["codec_name"], int(audio_stream["bit_rate"])
|
||||
except KeyError | ValueError:
|
||||
audio_bitrate = _int_value(
|
||||
audio_stream.get("bit_rate") or probe["format"].get("bit_rate")
|
||||
)
|
||||
return audio_stream["codec_name"], audio_bitrate
|
||||
except (KeyError, ValueError):
|
||||
logger.error("extracting audio codec_name from ffprobe failed")
|
||||
return None, None
|
||||
|
||||
|
|
@ -218,7 +239,7 @@ def audio_transcode_params(
|
|||
is_br = True
|
||||
else:
|
||||
is_br = False
|
||||
if format_name(probe_result) == fmt:
|
||||
if _matches_format(probe_result, fmt):
|
||||
is_fmt = True
|
||||
else:
|
||||
is_fmt = False
|
||||
|
|
@ -289,11 +310,7 @@ def video_transcode_params(
|
|||
# TODO: turn this into an exception and catch it for reporting
|
||||
return None
|
||||
|
||||
current_container_many = format_name(probe_result)
|
||||
is_container = False
|
||||
if current_container_many is not None:
|
||||
if target_container in current_container_many.split(","):
|
||||
is_container = True
|
||||
is_container = _matches_format(probe_result, target_container)
|
||||
|
||||
is_vcodec = vcodec == target_vcodec
|
||||
is_acodec = acodec == target_acodec
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue