mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-02 01:05:20 +03:00
frigate config
This commit is contained in:
parent
dd2c1cdcf7
commit
93edf4eee3
@ -363,8 +363,16 @@ class FfmpegConfig(FrigateBaseModel):
|
|||||||
|
|
||||||
|
|
||||||
class GstreamerConfig(FrigateBaseModel):
|
class GstreamerConfig(FrigateBaseModel):
|
||||||
pipeline: List[str] = Field(
|
manual_pipeline: List[str] = Field(
|
||||||
default=[], title="GStreamer pipeline. Each pipeline will be splited by ! sign")
|
default=[], title="GStreamer manual pipeline. Use `manual_pipeline` to fine tune gstreamer. Each item will be splited by the `!`.")
|
||||||
|
input_pipeline: List[str] = Field(
|
||||||
|
default=[], title="Override the `rtspsrc location={{gstreamer_input.path}} latency=0` default pipeline item.")
|
||||||
|
decoder_pipeline: List[str] = Field(
|
||||||
|
default=[], title="Set the hardware specific decoder. Example: ['rtph265depay', 'h265parse', 'omxh265dec']")
|
||||||
|
source_format_pipeline: List[str] = Field(
|
||||||
|
default=[], title="Set the camera source format. Default is: ['video/x-raw,format=(string)NV12', 'videoconvert', 'videoscale']")
|
||||||
|
destination_format_pipeline: List[str] = Field(
|
||||||
|
default=[], title="Set the Frigate format. Please keep `format=I420` if override. Default is: ['video/x-raw,width=(int){self.detect.width},height=(int){self.detect.height},format=(string)I420', 'videoconvert']")
|
||||||
|
|
||||||
|
|
||||||
class CameraRoleEnum(str, Enum):
|
class CameraRoleEnum(str, Enum):
|
||||||
@ -607,48 +615,63 @@ class CameraConfig(FrigateBaseModel):
|
|||||||
def _get_gstreamer_cmd(self, gstreamer_input: CameraGStreamerInput):
|
def _get_gstreamer_cmd(self, gstreamer_input: CameraGStreamerInput):
|
||||||
assert list(
|
assert list(
|
||||||
["detect"]) == gstreamer_input.roles, "only detect role is supported"
|
["detect"]) == gstreamer_input.roles, "only detect role is supported"
|
||||||
pipeline = [part for part in self.gstreamer.pipeline if part != ""]
|
manual_pipeline = [
|
||||||
|
part for part in self.gstreamer.manual_pipeline if part != ""]
|
||||||
|
input_pipeline = [
|
||||||
|
part for part in self.gstreamer.input_pipeline if part != ""]
|
||||||
|
decoder_pipeline = [
|
||||||
|
part for part in self.gstreamer.decoder_pipeline if part != ""]
|
||||||
|
source_format_pipeline = [
|
||||||
|
part for part in self.gstreamer.source_format_pipeline if part != ""]
|
||||||
|
destination_format_pipeline = [
|
||||||
|
part for part in self.gstreamer.destination_format_pipeline if part != ""]
|
||||||
|
|
||||||
video_format = f"video/x-raw,width=(int){self.detect.width},height=(int){self.detect.height},format=(string)I420"
|
video_format = f"video/x-raw,width=(int){self.detect.width},height=(int){self.detect.height},format=(string)I420"
|
||||||
if len(pipeline) == 0:
|
if not manual_pipeline and not input_pipeline and not decoder_pipeline and not source_format_pipeline and not destination_format_pipeline:
|
||||||
|
logger.warn(
|
||||||
|
"gsreamer pipeline not configured. Using videotestsrc pattern=0")
|
||||||
pipeline = [
|
pipeline = [
|
||||||
#"videotestsrc pattern=0",
|
"videotestsrc pattern=0",
|
||||||
"rtspsrc location=\"rtsp://admin:123456@192.168.5.95:554/stream0\"",
|
|
||||||
"rtph265depay", "h265parse","omxh265dec",
|
|
||||||
"video/x-raw,format=(string)NV12",
|
|
||||||
"videoconvert","videoscale",
|
|
||||||
video_format,
|
video_format,
|
||||||
"videoconvert"
|
]
|
||||||
# "videoscale",
|
elif len(manual_pipeline) > 0:
|
||||||
# video_format,
|
logger.warn(
|
||||||
# "videoconvert"
|
"gsreamer manual pipeline is set. Please make sure your detect width and height does math the gstreamer parameters")
|
||||||
|
pipeline = manual_pipeline
|
||||||
|
else:
|
||||||
|
input_pipeline = input_pipeline if input_pipeline else [
|
||||||
|
f"rtspsrc location=\"{gstreamer_input.path}\" latency=0"
|
||||||
]
|
]
|
||||||
|
|
||||||
# pipeline = [
|
decoder_pipeline = decoder_pipeline if decoder_pipeline else [
|
||||||
# #"videotestsrc pattern=0",
|
"rtph265depay", "h265parse", "omxh265dec"
|
||||||
# "rtspsrc location=\"rtsp://admin:123456@192.168.5.180:554/cam/realmonitor?channel=0&subtype=0\"",
|
]
|
||||||
# "rtph264depay",
|
source_format_pipeline = source_format_pipeline if source_format_pipeline else [
|
||||||
# "h264parse",
|
'video/x-raw,format=(string)NV12', 'videoconvert', 'videoscale'
|
||||||
# "omxh264dec",
|
]
|
||||||
# "video/x-raw,format=(string)NV12",
|
destination_format_pipeline = destination_format_pipeline if destination_format_pipeline else [
|
||||||
# "videoconvert",
|
video_format, "videoconvert"
|
||||||
# "videoscale",
|
]
|
||||||
# video_format,
|
pipeline = [
|
||||||
# "videoconvert"
|
*input_pipeline,
|
||||||
# # "videoscale",
|
*decoder_pipeline,
|
||||||
# # video_format,
|
*source_format_pipeline,
|
||||||
# # "videoconvert"
|
*destination_format_pipeline
|
||||||
# ]
|
]
|
||||||
pipeline_args = (
|
pipeline_args = (
|
||||||
[f"{item} !".split(" ") for item in pipeline]
|
[f"{item} !".split(" ") for item in pipeline]
|
||||||
)
|
)
|
||||||
pipeline_args = [item for sublist in pipeline_args for item in sublist]
|
pipeline_args = [item for sublist in pipeline_args for item in sublist]
|
||||||
return [
|
pipeline_args = [
|
||||||
"gst-launch-1.0",
|
"gst-launch-1.0",
|
||||||
"-q",
|
"-q",
|
||||||
*pipeline_args,
|
*pipeline_args,
|
||||||
"fdsink"
|
"fdsink"
|
||||||
]
|
]
|
||||||
|
logger.debug(
|
||||||
|
f"using gstreamer pipeline: {' '.join(pipeline_args)}")
|
||||||
|
|
||||||
|
return pipeline_args
|
||||||
|
|
||||||
def _get_ffmpeg_cmd(self, ffmpeg_input: CameraFFmpegInput):
|
def _get_ffmpeg_cmd(self, ffmpeg_input: CameraFFmpegInput):
|
||||||
ffmpeg_output_args = []
|
ffmpeg_output_args = []
|
||||||
|
|||||||
@ -39,9 +39,8 @@ class FFMpegConverter:
|
|||||||
# )
|
# )
|
||||||
|
|
||||||
|
|
||||||
logger.error(f" ffmpeg_cmd >>>> {ffmpeg_cmd}")
|
|
||||||
self.logpipe = LogPipe(
|
self.logpipe = LogPipe(
|
||||||
"ffmpeg.output", logging.ERROR)
|
"ffmpeg.converter", logging.ERROR)
|
||||||
self.process = sp.Popen(
|
self.process = sp.Popen(
|
||||||
ffmpeg_cmd,
|
ffmpeg_cmd,
|
||||||
stdout=sp.PIPE,
|
stdout=sp.PIPE,
|
||||||
@ -54,6 +53,7 @@ class FFMpegConverter:
|
|||||||
try:
|
try:
|
||||||
self.process.stdin.write(b)
|
self.process.stdin.write(b)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
logger.error("Failure while writing to the stream:")
|
||||||
self.logpipe.dump()
|
self.logpipe.dump()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -61,6 +61,7 @@ class FFMpegConverter:
|
|||||||
try:
|
try:
|
||||||
return self.process.stdout.read1(length)
|
return self.process.stdout.read1(length)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
logger.error("Failure while readig from the stream:")
|
||||||
self.logpipe.dump()
|
self.logpipe.dump()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -427,6 +428,8 @@ def output_frames(config: FrigateConfig, video_output_queue):
|
|||||||
# write to the converter for the camera if clients are listening to the specific camera
|
# write to the converter for the camera if clients are listening to the specific camera
|
||||||
converters[camera].write(frame.tobytes())
|
converters[camera].write(frame.tobytes())
|
||||||
except Exception:
|
except Exception:
|
||||||
|
# in case of videoconverter failure continure processing video_output_queue
|
||||||
|
# FFMpegConverter should dump an error response
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# update birdseye if websockets are connected
|
# update birdseye if websockets are connected
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user