mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-10 05:05:26 +03:00
Write preview frames as webp instead of jpg and ensure webp are cached in nginx
This commit is contained in:
parent
fa22f01f39
commit
98686af504
@ -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;
|
||||||
|
|||||||
@ -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")
|
||||||
|
|
||||||
|
|||||||
@ -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)):
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user