diff --git a/frigate/api/app.py b/frigate/api/app.py index 46a2b9c13..b1b3b8449 100644 --- a/frigate/api/app.py +++ b/frigate/api/app.py @@ -414,7 +414,7 @@ def ffprobe(): output = [] for path in paths: - ffprobe = ffprobe_stream(path.strip()) + ffprobe = ffprobe_stream(current_app.frigate_config.ffmpeg, path.strip()) output.append( { "return_code": ffprobe.returncode, diff --git a/frigate/config.py b/frigate/config.py index 3963d06d3..7d3633617 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -899,6 +899,20 @@ class FfmpegConfig(FrigateBaseModel): else: return f"{self.path}/bin/ffmpeg" + @property + def ffprobe_path(self) -> str: + if self.path == "default": + if int(os.getenv("LIBAVFORMAT_VERSION_MAJOR", "59")) >= 59: + return "/usr/lib/ffmpeg/7.0/bin/ffprobe" + else: + return "ffprobe" + elif self.path == "7.0": + return "/usr/lib/ffmpeg/7.0/bin/ffprobe" + elif self.path == "5.0": + return "/usr/lib/ffmpeg/5.0/bin/ffprobe" + else: + return f"{self.path}/bin/ffprobe" + class CameraRoleEnum(str, Enum): audio = "audio" @@ -1535,7 +1549,7 @@ class FrigateConfig(FrigateBaseModel): if need_detect_dimensions or need_record_fourcc: stream_info = {"width": 0, "height": 0, "fourcc": None} try: - stream_info = stream_info_retriever.get_stream_info(input.path) + stream_info = stream_info_retriever.get_stream_info(config.ffmpeg, input.path) except Exception: logger.warn( f"Error detecting stream parameters automatically for {input.path} Applying default values." diff --git a/frigate/util/config.py b/frigate/util/config.py index a40efeafd..729215e9e 100644 --- a/frigate/util/config.py +++ b/frigate/util/config.py @@ -314,10 +314,10 @@ class StreamInfoRetriever: def __init__(self) -> None: self.stream_cache: dict[str, tuple[int, int]] = {} - def get_stream_info(self, path: str) -> str: + def get_stream_info(self, ffmpeg, path: str) -> str: if path in self.stream_cache: return self.stream_cache[path] - info = asyncio.run(get_video_properties(path)) + info = asyncio.run(get_video_properties(ffmpeg, path)) self.stream_cache[path] = info return info diff --git a/frigate/util/services.py b/frigate/util/services.py index 16f46e114..c7b2b7eaa 100644 --- a/frigate/util/services.py +++ b/frigate/util/services.py @@ -15,6 +15,7 @@ import psutil import py3nvml.py3nvml as nvml import requests +from frigate.config import FfmpegConfig from frigate.const import ( DRIVER_AMD, DRIVER_ENV_VAR, @@ -378,11 +379,11 @@ def get_jetson_stats() -> dict[int, dict]: return results -def ffprobe_stream(path: str) -> sp.CompletedProcess: +def ffprobe_stream(ffmpeg: FfmpegConfig, path: str) -> sp.CompletedProcess: """Run ffprobe on stream.""" clean_path = escape_special_characters(path) ffprobe_cmd = [ - "ffprobe", + ffmpeg.ffprobe_path, "-timeout", "1000000", "-print_format", @@ -438,7 +439,7 @@ def auto_detect_hwaccel() -> str: return "" -async def get_video_properties(url, get_duration=False) -> dict[str, any]: +async def get_video_properties(ffmpeg: FfmpegConfig, url: str, get_duration: bool = False) -> dict[str, any]: async def calculate_duration(video: Optional[any]) -> float: duration = None @@ -453,7 +454,7 @@ async def get_video_properties(url, get_duration=False) -> dict[str, any]: # if cv2 failed need to use ffprobe if duration is None: p = await asyncio.create_subprocess_exec( - "ffprobe", + ffmpeg.ffprobe_path, "-v", "error", "-show_entries",