Optimize nginx & recordings (#4688)

* Add segment duration metadata

* Use faststart only for kept segments

* Add more options for performance

* Build nginx locally

* Build nginx in dockerfile and enable threaded vod handling

* Use DASH instead of hls

* Allow player to continue on error

* Undo DASH change

* Fix typo

* Correct log

* Fix bad comments

* Fix indentation

* Preload stream

* remove unused

* Fix spacing

* Fix tabs / sspaces

* Retab

* More cleanup
This commit is contained in:
Nicolas Mowen
2022-12-17 16:53:34 -07:00
committed by GitHub
parent 9b99ba81e5
commit 369299315f
8 changed files with 129 additions and 41 deletions

View File

@@ -5,6 +5,7 @@ CACHE_DIR = "/tmp/cache"
YAML_EXT = (".yaml", ".yml")
PLUS_ENV_VAR = "PLUS_API_KEY"
PLUS_API_HOST = "https://api.frigate.video"
MAX_SEGMENT_DURATION = 600
# Regex Consts

View File

@@ -32,7 +32,7 @@ from peewee import SqliteDatabase, operator, fn, DoesNotExist
from playhouse.shortcuts import model_to_dict
from frigate.config import FrigateConfig
from frigate.const import CLIPS_DIR, RECORD_DIR
from frigate.const import CLIPS_DIR, MAX_SEGMENT_DURATION, RECORD_DIR
from frigate.models import Event, Recordings
from frigate.object_processing import TrackedObject
from frigate.stats import stats_snapshot
@@ -1050,6 +1050,7 @@ def vod_ts(camera_name, start_ts, end_ts):
clips = []
durations = []
max_duration_ms = MAX_SEGMENT_DURATION * 1000
recording: Recordings
for recording in recordings:
@@ -1060,7 +1061,7 @@ def vod_ts(camera_name, start_ts, end_ts):
if recording.end_time > end_ts:
duration -= int((recording.end_time - end_ts) * 1000)
if duration > 0:
if 0 < duration < max_duration_ms:
clip["keyFrameDurations"] = [duration]
clips.append(clip)
durations.append(duration)
@@ -1076,7 +1077,9 @@ def vod_ts(camera_name, start_ts, end_ts):
{
"cache": hour_ago.timestamp() > start_ts,
"discontinuity": False,
"consistentSequenceMediaInfo": True,
"durations": durations,
"segment_duration": max(durations),
"sequences": [{"clips": clips}],
}
)

View File

@@ -5,7 +5,6 @@ import multiprocessing as mp
import os
import queue
import random
import shutil
import string
import subprocess as sp
import threading
@@ -16,7 +15,7 @@ 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, MAX_SEGMENT_DURATION, RECORD_DIR
from frigate.models import Event, Recordings
from frigate.util import area
@@ -173,7 +172,7 @@ class RecordingMaintainer(threading.Thread):
duration = -1
# ensure duration is within expected length
if 0 < duration < 600:
if 0 < duration < MAX_SEGMENT_DURATION:
end_time = start_time + datetime.timedelta(seconds=duration)
self.end_time_cache[cache_path] = (end_time, duration)
else:
@@ -296,13 +295,38 @@ class RecordingMaintainer(threading.Thread):
try:
if not os.path.exists(file_path):
start_frame = datetime.datetime.now().timestamp()
# copy then delete is required when recordings are stored on some network drives
shutil.copyfile(cache_path, file_path)
logger.debug(
f"Copied {file_path} in {datetime.datetime.now().timestamp()-start_frame} seconds."
# add faststart to kept segments to improve metadata reading
ffmpeg_cmd = [
"ffmpeg",
"-y",
"-i",
cache_path,
"-c",
"copy",
"-movflags",
"+faststart",
file_path,
]
p = sp.run(
ffmpeg_cmd,
encoding="ascii",
capture_output=True,
)
if p.returncode != 0:
logger.error(f"Unable to convert {cache_path} to {file_path}")
logger.error(p.stderr)
return
else:
logger.debug(
f"Copied {file_path} in {datetime.datetime.now().timestamp()-start_frame} seconds."
)
try:
# get the segment size of the cache file
# file without faststart is same size
segment_size = round(
float(os.path.getsize(cache_path)) / 1000000, 1
)