mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-03 12:07:40 +03:00
Add camera wizard improvements (#22963)
* warn in camera wizard when detect stream resolution cannot be determined * add timeout and tcp fallback for rtsp urls only
This commit is contained in:
parent
2dcaeb6809
commit
f4ac063b37
@ -807,10 +807,15 @@ async def get_video_properties(
|
|||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
async def probe_with_ffprobe(
|
async def probe_with_ffprobe(
|
||||||
url: str,
|
url: str,
|
||||||
|
rtsp_transport: Optional[str] = None,
|
||||||
) -> tuple[bool, int, int, Optional[str], float]:
|
) -> tuple[bool, int, int, Optional[str], float]:
|
||||||
"""Fallback using ffprobe: returns (valid, width, height, codec, duration)."""
|
"""Fallback using ffprobe: returns (valid, width, height, codec, duration)."""
|
||||||
cmd = [
|
cmd = [ffmpeg.ffprobe_path]
|
||||||
ffmpeg.ffprobe_path,
|
if rtsp_transport:
|
||||||
|
cmd += ["-rtsp_transport", rtsp_transport]
|
||||||
|
cmd += [
|
||||||
|
"-rw_timeout",
|
||||||
|
"5000000",
|
||||||
"-v",
|
"-v",
|
||||||
"quiet",
|
"quiet",
|
||||||
"-print_format",
|
"-print_format",
|
||||||
@ -879,6 +884,12 @@ async def get_video_properties(
|
|||||||
if not has_video or (get_duration and duration < 0):
|
if not has_video or (get_duration and duration < 0):
|
||||||
has_video, width, height, fourcc, duration = await probe_with_ffprobe(url)
|
has_video, width, height, fourcc, duration = await probe_with_ffprobe(url)
|
||||||
|
|
||||||
|
# last resort for RTSP: try TCP transport, since default UDP may be blocked
|
||||||
|
if (not has_video or (get_duration and duration < 0)) and url.startswith("rtsp://"):
|
||||||
|
has_video, width, height, fourcc, duration = await probe_with_ffprobe(
|
||||||
|
url, rtsp_transport="tcp"
|
||||||
|
)
|
||||||
|
|
||||||
result: dict[str, Any] = {"has_valid_video": has_video}
|
result: dict[str, Any] = {"has_valid_video": has_video}
|
||||||
if has_video:
|
if has_video:
|
||||||
result.update({"width": width, "height": height})
|
result.update({"width": width, "height": height})
|
||||||
|
|||||||
@ -415,6 +415,7 @@
|
|||||||
"audioCodecGood": "Audio codec is {{codec}}.",
|
"audioCodecGood": "Audio codec is {{codec}}.",
|
||||||
"resolutionHigh": "A resolution of {{resolution}} may cause increased resource usage.",
|
"resolutionHigh": "A resolution of {{resolution}} may cause increased resource usage.",
|
||||||
"resolutionLow": "A resolution of {{resolution}} may be too low for reliable detection of small objects.",
|
"resolutionLow": "A resolution of {{resolution}} may be too low for reliable detection of small objects.",
|
||||||
|
"resolutionUnknown": "The resolution of this stream could not be probed. This will cause issues on startup. You should manually set the detect resolution in Settings or your config.",
|
||||||
"noAudioWarning": "No audio detected for this stream, recordings will not have audio.",
|
"noAudioWarning": "No audio detected for this stream, recordings will not have audio.",
|
||||||
"audioCodecRecordError": "The AAC audio codec is required to support audio in recordings.",
|
"audioCodecRecordError": "The AAC audio codec is required to support audio in recordings.",
|
||||||
"audioCodecRequired": "An audio stream is required to support audio detection.",
|
"audioCodecRequired": "An audio stream is required to support audio detection.",
|
||||||
|
|||||||
@ -607,23 +607,38 @@ function StreamIssues({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream.roles.includes("detect") && stream.resolution) {
|
if (stream.roles.includes("detect") && stream.testResult) {
|
||||||
const [width, height] = stream.resolution.split("x").map(Number);
|
const probedResolution = stream.testResult.resolution;
|
||||||
if (!isNaN(width) && !isNaN(height) && width > 0 && height > 0) {
|
let probedWidth = 0;
|
||||||
const minDimension = Math.min(width, height);
|
let probedHeight = 0;
|
||||||
const maxDimension = Math.max(width, height);
|
if (probedResolution) {
|
||||||
|
const [w, h] = probedResolution.split("x").map(Number);
|
||||||
|
if (!isNaN(w) && !isNaN(h)) {
|
||||||
|
probedWidth = w;
|
||||||
|
probedHeight = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (probedWidth <= 0 || probedHeight <= 0) {
|
||||||
|
result.push({
|
||||||
|
type: "error",
|
||||||
|
message: t("cameraWizard.step4.issues.resolutionUnknown"),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const minDimension = Math.min(probedWidth, probedHeight);
|
||||||
|
const maxDimension = Math.max(probedWidth, probedHeight);
|
||||||
if (minDimension > 1080) {
|
if (minDimension > 1080) {
|
||||||
result.push({
|
result.push({
|
||||||
type: "warning",
|
type: "warning",
|
||||||
message: t("cameraWizard.step4.issues.resolutionHigh", {
|
message: t("cameraWizard.step4.issues.resolutionHigh", {
|
||||||
resolution: stream.resolution,
|
resolution: probedResolution,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
} else if (maxDimension < 640) {
|
} else if (maxDimension < 640) {
|
||||||
result.push({
|
result.push({
|
||||||
type: "error",
|
type: "error",
|
||||||
message: t("cameraWizard.step4.issues.resolutionLow", {
|
message: t("cameraWizard.step4.issues.resolutionLow", {
|
||||||
resolution: stream.resolution,
|
resolution: probedResolution,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user