recording for GStreamer

This commit is contained in:
YS 2022-01-07 12:23:08 +03:00
parent d5dd82fa47
commit 1aa6ccaa6d
4 changed files with 31 additions and 11 deletions

View File

@ -12,7 +12,7 @@ import yaml
from pydantic import BaseModel, Extra, Field, validator, root_validator
from pydantic.fields import PrivateAttr
from frigate.const import BASE_DIR, CACHE_DIR, YAML_EXT
from frigate.const import BASE_DIR, CACHE_DIR, YAML_EXT, RECORD_SEGMENT_TIME_SECONDS
from frigate.util import (
create_mask,
deep_merge,
@ -315,7 +315,7 @@ RECORD_FFMPEG_OUTPUT_ARGS_DEFAULT = [
"-f",
"segment",
"-segment_time",
"10",
str(RECORD_SEGMENT_TIME_SECONDS),
"-segment_format",
"mp4",
"-reset_timestamps",
@ -616,7 +616,7 @@ class CameraConfig(FrigateBaseModel):
)
builder = GstreamerBuilder(
gstreamer_input.path, self.detect.width, self.detect.height
gstreamer_input.path, self.detect.width, self.detect.height, self.name
)
if caps is None or len(caps) == 0:
logger.warn("gsreamer was not able to detect the input stream format")

View File

@ -3,3 +3,5 @@ CLIPS_DIR = f"{BASE_DIR}/clips"
RECORD_DIR = f"{BASE_DIR}/recordings"
CACHE_DIR = "/tmp/cache"
YAML_EXT = (".yaml", ".yml")
RECORD_SEGMENT_TIME_SECONDS = 10
GSTREAMER_RECORD_SUFFIX = "-gstsplitmuxchunk"

View File

@ -3,7 +3,11 @@ import logging
import traceback
import subprocess as sp
from typing import Dict, List, Optional
from frigate.const import CACHE_DIR
from frigate.const import (
CACHE_DIR,
GSTREAMER_RECORD_SUFFIX,
RECORD_SEGMENT_TIME_SECONDS,
)
logger = logging.getLogger(__name__)
@ -62,6 +66,7 @@ def gst_inspect_find_codec(codec: str) -> List[str]:
)
return None
def autodetect_decoder_pipeline(
codec: Optional[str],
) -> List[str]:
@ -118,10 +123,11 @@ CODECS = {
class GstreamerBuilder:
def __init__(self, uri, width, height, format="I420"):
def __init__(self, uri, width, height, name, format="I420"):
self.uri = uri
self.width = width
self.height = height
self.name = name
self.video_format = f"video/x-raw,width=(int){width},height=(int){height},format=(string){format}"
self.input_pipeline = [f'rtspsrc location="{uri}" latency=0']
self.destination_format_pipeline = [self.video_format, "videoconvert"]
@ -176,7 +182,7 @@ class GstreamerBuilder:
"queue2",
"x264enc key-int-max=10",
"h264parse",
f"splitmuxsink async-handling=true location={os.path.join(CACHE_DIR, self.name)}-gst-%05d.mp4 max-size-time=10000000000",
f"splitmuxsink async-handling=true location={os.path.join(CACHE_DIR, self.name)}{GSTREAMER_RECORD_SUFFIX}-%05d.mp4 max-size-time={RECORD_SEGMENT_TIME_SECONDS*1000000000}",
]
if use_record
else []
@ -188,4 +194,3 @@ class GstreamerBuilder:
]
pipeline_args = [item for sublist in pipeline_args for item in sublist]
return ["gst-launch-1.0", "-q", *pipeline_args][:-1]

View File

@ -1,4 +1,5 @@
import datetime
from dateutil import tz
import itertools
import logging
import multiprocessing as mp
@ -17,7 +18,12 @@ import psutil
from peewee import JOIN, DoesNotExist
from frigate.config import RetainModeEnum, FrigateConfig
from frigate.const import CACHE_DIR, RECORD_DIR
from frigate.const import (
CACHE_DIR,
RECORD_DIR,
GSTREAMER_RECORD_SUFFIX,
RECORD_SEGMENT_TIME_SECONDS,
)
from frigate.models import Event, Recordings
from frigate.util import area
@ -69,7 +75,7 @@ class RecordingMaintainer(threading.Thread):
files_in_use = []
for process in psutil.process_iter():
try:
if process.name() != "ffmpeg":
if process.name() not in ["ffmpeg", "gst-launch-1.0"]:
continue
flist = process.open_files()
if flist:
@ -89,7 +95,14 @@ class RecordingMaintainer(threading.Thread):
cache_path = os.path.join(CACHE_DIR, f)
basename = os.path.splitext(f)[0]
camera, date = basename.rsplit("-", maxsplit=1)
start_time = datetime.datetime.strptime(date, "%Y%m%d%H%M%S")
if camera.endswith(GSTREAMER_RECORD_SUFFIX):
camera = camera.split(GSTREAMER_RECORD_SUFFIX)[0]
creation_time = (
os.path.getmtime(cache_path) - RECORD_SEGMENT_TIME_SECONDS
)
start_time = datetime.datetime.utcfromtimestamp(creation_time)
else:
start_time = datetime.datetime.strptime(date, "%Y%m%d%H%M%S")
grouped_recordings[camera].append(
{