Write preview frames as webp instead of jpg and ensure webp are cached in nginx

This commit is contained in:
Nicolas Mowen 2024-03-11 10:44:07 -06:00
parent fa22f01f39
commit 98686af504
5 changed files with 18 additions and 17 deletions

View File

@ -210,7 +210,7 @@ http {
include proxy.conf; include proxy.conf;
} }
location ~* /api/.*\.(jpg|jpeg|png)$ { location ~* /api/.*\.(jpg|jpeg|png|webp)$ {
rewrite ^/api/(.*)$ $1 break; rewrite ^/api/(.*)$ $1 break;
proxy_pass http://frigate_api; proxy_pass http://frigate_api;
include proxy.conf; include proxy.conf;

View File

@ -30,6 +30,7 @@ from frigate.const import (
CLIPS_DIR, CLIPS_DIR,
EXPORT_DIR, EXPORT_DIR,
MAX_SEGMENT_DURATION, MAX_SEGMENT_DURATION,
PREVIEW_FRAME_TYPE,
RECORD_DIR, RECORD_DIR,
) )
from frigate.models import Event, Previews, Recordings, Regions, ReviewSegment from frigate.models import Event, Previews, Recordings, Regions, ReviewSegment
@ -1173,8 +1174,8 @@ def preview_gif(camera_name: str, start_ts, end_ts, max_cache_age=2592000):
# need to generate from existing images # need to generate from existing images
preview_dir = os.path.join(CACHE_DIR, "preview_frames") preview_dir = os.path.join(CACHE_DIR, "preview_frames")
file_start = f"preview_{camera_name}" file_start = f"preview_{camera_name}"
start_file = f"{file_start}-{start_ts}.jpg" start_file = f"{file_start}-{start_ts}.{PREVIEW_FRAME_TYPE}"
end_file = f"{file_start}-{end_ts}.jpg" end_file = f"{file_start}-{end_ts}.{PREVIEW_FRAME_TYPE}"
selected_previews = [] selected_previews = []
for file in sorted(os.listdir(preview_dir)): for file in sorted(os.listdir(preview_dir)):
@ -1258,8 +1259,9 @@ def review_preview(id: str):
@MediaBp.route("/preview/<file_name>/thumbnail.jpg") @MediaBp.route("/preview/<file_name>/thumbnail.jpg")
@MediaBp.route("/preview/<file_name>/thumbnail.webp")
def preview_thumbnail(file_name: str): def preview_thumbnail(file_name: str):
"""Get a thumbnail from the cached preview jpgs.""" """Get a thumbnail from the cached preview frames."""
safe_file_name_current = secure_filename(file_name) safe_file_name_current = secure_filename(file_name)
preview_dir = os.path.join(CACHE_DIR, "preview_frames") preview_dir = os.path.join(CACHE_DIR, "preview_frames")

View File

@ -11,7 +11,7 @@ from flask import (
make_response, make_response,
) )
from frigate.const import CACHE_DIR from frigate.const import CACHE_DIR, PREVIEW_FRAME_TYPE
from frigate.models import Previews from frigate.models import Previews
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -97,8 +97,8 @@ def get_preview_frames_from_cache(camera_name: str, start_ts, end_ts):
"""Get list of cached preview frames""" """Get list of cached preview frames"""
preview_dir = os.path.join(CACHE_DIR, "preview_frames") preview_dir = os.path.join(CACHE_DIR, "preview_frames")
file_start = f"preview_{camera_name}" file_start = f"preview_{camera_name}"
start_file = f"{file_start}-{start_ts}.jpg" start_file = f"{file_start}-{start_ts}.{PREVIEW_FRAME_TYPE}"
end_file = f"{file_start}-{end_ts}.jpg" end_file = f"{file_start}-{end_ts}.{PREVIEW_FRAME_TYPE}"
selected_previews = [] selected_previews = []
for file in sorted(os.listdir(preview_dir)): for file in sorted(os.listdir(preview_dir)):

View File

@ -57,6 +57,10 @@ DRIVER_AMD = "radeonsi"
DRIVER_INTEL_i965 = "i965" DRIVER_INTEL_i965 = "i965"
DRIVER_INTEL_iHD = "iHD" DRIVER_INTEL_iHD = "iHD"
# Preview Values
PREVIEW_FRAME_TYPE = "webp"
# Record Values # Record Values
CACHE_SEGMENT_FORMAT = "%Y%m%d%H%M%S%z" CACHE_SEGMENT_FORMAT = "%Y%m%d%H%M%S%z"

View File

@ -12,7 +12,7 @@ import numpy as np
from frigate.comms.inter_process import InterProcessRequestor from frigate.comms.inter_process import InterProcessRequestor
from frigate.config import CameraConfig, RecordQualityEnum from frigate.config import CameraConfig, RecordQualityEnum
from frigate.const import CACHE_DIR, CLIPS_DIR, INSERT_PREVIEW from frigate.const import CACHE_DIR, CLIPS_DIR, INSERT_PREVIEW, PREVIEW_FRAME_TYPE
from frigate.ffmpeg_presets import ( from frigate.ffmpeg_presets import (
FPS_VFR_PARAM, FPS_VFR_PARAM,
EncodeTypeEnum, EncodeTypeEnum,
@ -42,12 +42,12 @@ def get_cache_image_name(camera: str, frame_time: float) -> str:
"""Get the image name in cache.""" """Get the image name in cache."""
return os.path.join( return os.path.join(
CACHE_DIR, CACHE_DIR,
f"{FOLDER_PREVIEW_FRAMES}/preview_{camera}-{frame_time}.jpg", f"{FOLDER_PREVIEW_FRAMES}/preview_{camera}-{frame_time}.{PREVIEW_FRAME_TYPE}",
) )
class FFMpegConverter(threading.Thread): class FFMpegConverter(threading.Thread):
"""Convert a list of jpg frames into a vfr mp4.""" """Convert a list of still frames into a vfr mp4."""
def __init__( def __init__(
self, self,
@ -176,7 +176,7 @@ class PreviewRecorder:
) )
file_start = f"preview_{config.name}" file_start = f"preview_{config.name}"
start_file = f"{file_start}-{start_ts}.jpg" start_file = f"{file_start}-{start_ts}.webp"
for file in sorted(os.listdir(os.path.join(CACHE_DIR, FOLDER_PREVIEW_FRAMES))): for file in sorted(os.listdir(os.path.join(CACHE_DIR, FOLDER_PREVIEW_FRAMES))):
if not file.startswith(file_start): if not file.startswith(file_start):
@ -242,12 +242,7 @@ class PreviewRecorder:
small_frame, small_frame,
cv2.COLOR_YUV2BGR_I420, cv2.COLOR_YUV2BGR_I420,
) )
_, jpg = cv2.imencode(".jpg", small_frame) cv2.imwrite(get_cache_image_name(self.config.name, frame_time), small_frame, [int(cv2.IMWRITE_WEBP_QUALITY), 80])
with open(
get_cache_image_name(self.config.name, frame_time),
"wb",
) as j:
j.write(jpg.tobytes())
def write_data( def write_data(
self, self,