mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-12-06 13:34:13 +03:00
Revert "only use ffprobe for duration to avoid blocking"
This reverts commit 8b15078005.
This commit is contained in:
parent
8b15078005
commit
4109bc4f4d
@ -652,36 +652,53 @@ def auto_detect_hwaccel() -> str:
|
||||
async def get_video_properties(
|
||||
ffmpeg, url: str, get_duration: bool = False
|
||||
) -> dict[str, Any]:
|
||||
async def probe_duration_with_ffprobe(url: str) -> float:
|
||||
"""Only extract duration from ffprobe if cv2 fails"""
|
||||
async def probe_with_ffprobe(
|
||||
url: str,
|
||||
) -> tuple[bool, int, int, Optional[str], float]:
|
||||
"""Fallback using ffprobe: returns (valid, width, height, codec, duration)."""
|
||||
cmd = [
|
||||
ffmpeg.ffprobe_path,
|
||||
"-v",
|
||||
"quiet",
|
||||
"-print_format",
|
||||
"json",
|
||||
"-show_format",
|
||||
"-show_streams",
|
||||
url,
|
||||
]
|
||||
try:
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
ffmpeg.ffprobe_path,
|
||||
"-v",
|
||||
"error",
|
||||
"-show_entries",
|
||||
"format=duration",
|
||||
"-of",
|
||||
"default=noprint_wrappers=1:nokey=1",
|
||||
url,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
out, _ = await proc.communicate()
|
||||
stdout, _ = await proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
return -1.0
|
||||
return False, 0, 0, None, -1
|
||||
|
||||
result = out.decode().strip()
|
||||
return float(result) if result else -1.0
|
||||
except Exception:
|
||||
return -1.0
|
||||
data = json.loads(stdout.decode())
|
||||
video_streams = [
|
||||
s for s in data.get("streams", []) if s.get("codec_type") == "video"
|
||||
]
|
||||
if not video_streams:
|
||||
return False, 0, 0, None, -1
|
||||
|
||||
v = video_streams[0]
|
||||
width = int(v.get("width", 0))
|
||||
height = int(v.get("height", 0))
|
||||
codec = v.get("codec_name")
|
||||
|
||||
duration_str = data.get("format", {}).get("duration")
|
||||
duration = float(duration_str) if duration_str else -1.0
|
||||
|
||||
return True, width, height, codec, duration
|
||||
except (json.JSONDecodeError, ValueError, KeyError, asyncio.SubprocessError):
|
||||
return False, 0, 0, None, -1
|
||||
|
||||
def probe_with_cv2(url: str) -> tuple[bool, int, int, Optional[str], float]:
|
||||
"""Get width, height, codec, and optionally duration via frames/FPS."""
|
||||
"""Primary attempt using cv2: returns (valid, width, height, fourcc, duration)."""
|
||||
cap = cv2.VideoCapture(url)
|
||||
if not cap.isOpened():
|
||||
cap.release()
|
||||
return False, 0, 0, None, -1.0
|
||||
return False, 0, 0, None, -1
|
||||
|
||||
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
||||
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
||||
@ -705,14 +722,13 @@ async def get_video_properties(
|
||||
# try cv2 first
|
||||
has_video, width, height, fourcc, duration = probe_with_cv2(url)
|
||||
|
||||
# If we still need duration, use ffprobe
|
||||
if get_duration and duration < 0:
|
||||
duration = await probe_duration_with_ffprobe(url)
|
||||
# fallback to ffprobe if needed
|
||||
if not has_video or (get_duration and duration < 0):
|
||||
has_video, width, height, fourcc, duration = await probe_with_ffprobe(url)
|
||||
|
||||
result: dict[str, Any] = {"has_valid_video": has_video}
|
||||
if has_video:
|
||||
result["width"] = width
|
||||
result["height"] = height
|
||||
result.update({"width": width, "height": height})
|
||||
if fourcc:
|
||||
result["fourcc"] = fourcc
|
||||
if get_duration:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user