Replace green screen with error message and force camera_fps to 0 (#4544)

* Move to images specific folder

* Send error image when camera stream is not available

* Immediately set camera_fps to 0 if camera crashes

* Cache error image so it is not read from file system on each run

* Move camera fps set
This commit is contained in:
Nicolas Mowen 2022-11-28 20:47:20 -07:00 committed by GitHub
parent aaedd24f37
commit 69560c8bde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 4 deletions

View File

@ -1,6 +1,7 @@
import base64 import base64
from datetime import datetime, timedelta from datetime import datetime, timedelta
import copy import copy
import glob
import logging import logging
import json import json
import os import os
@ -62,6 +63,7 @@ def create_app(
app.stats_tracking = stats_tracking app.stats_tracking = stats_tracking
app.detected_frames_processor = detected_frames_processor app.detected_frames_processor = detected_frames_processor
app.plus_api = plus_api app.plus_api = plus_api
app.camera_error_image = None
app.register_blueprint(bp) app.register_blueprint(bp)
@ -657,8 +659,20 @@ def latest_frame(camera_name):
frame = current_app.detected_frames_processor.get_current_frame( frame = current_app.detected_frames_processor.get_current_frame(
camera_name, draw_options camera_name, draw_options
) )
if frame is None:
frame = np.zeros((720, 1280, 3), np.uint8) if frame is None or datetime.now().timestamp() > (
current_app.detected_frames_processor.get_current_frame_time(camera_name)
+ 10
):
if current_app.camera_error_image is None:
error_image = glob.glob("/opt/frigate/frigate/images/camera-error.jpg")
if len(error_image) > 0:
current_app.camera_error_image = cv2.imread(
error_image[0], cv2.IMREAD_UNCHANGED
)
frame = current_app.camera_error_image
height = int(request.args.get("h", str(frame.shape[0]))) height = int(request.args.get("h", str(frame.shape[0])))
width = int(height * frame.shape[1] / frame.shape[0]) width = int(height * frame.shape[1] / frame.shape[0])

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

View File

@ -882,6 +882,10 @@ class TrackedObjectProcessor(threading.Thread):
def get_current_frame(self, camera, draw_options={}): def get_current_frame(self, camera, draw_options={}):
return self.camera_states[camera].get_current_frame(draw_options) return self.camera_states[camera].get_current_frame(draw_options)
def get_current_frame_time(self, camera) -> int:
"""Returns the latest frame time for a given camera."""
return self.camera_states[camera].current_frame_time
def run(self): def run(self):
while not self.stop_event.is_set(): while not self.stop_event.is_set():
try: try:

View File

@ -7,7 +7,6 @@ import queue
import signal import signal
import subprocess as sp import subprocess as sp
import threading import threading
from multiprocessing import shared_memory
from wsgiref.simple_server import make_server from wsgiref.simple_server import make_server
import cv2 import cv2
@ -113,7 +112,7 @@ class BirdsEyeFrameManager:
birdseye_logo = cv2.imread(custom_logo_files[0], cv2.IMREAD_UNCHANGED) birdseye_logo = cv2.imread(custom_logo_files[0], cv2.IMREAD_UNCHANGED)
if birdseye_logo is None: if birdseye_logo is None:
logo_files = glob.glob("/opt/frigate/frigate/birdseye.png") logo_files = glob.glob("/opt/frigate/frigate/images/birdseye.png")
if len(logo_files) > 0: if len(logo_files) > 0:
birdseye_logo = cv2.imread(logo_files[0], cv2.IMREAD_UNCHANGED) birdseye_logo = cv2.imread(logo_files[0], cv2.IMREAD_UNCHANGED)

View File

@ -242,6 +242,7 @@ class CameraWatchdog(threading.Thread):
now = datetime.datetime.now().timestamp() now = datetime.datetime.now().timestamp()
if not self.capture_thread.is_alive(): if not self.capture_thread.is_alive():
self.camera_fps.value = 0
self.logger.error( self.logger.error(
f"Ffmpeg process crashed unexpectedly for {self.camera_name}." f"Ffmpeg process crashed unexpectedly for {self.camera_name}."
) )
@ -251,6 +252,7 @@ class CameraWatchdog(threading.Thread):
self.logpipe.dump() self.logpipe.dump()
self.start_ffmpeg_detect() self.start_ffmpeg_detect()
elif now - self.capture_thread.current_frame.value > 20: elif now - self.capture_thread.current_frame.value > 20:
self.camera_fps.value = 0
self.logger.info( self.logger.info(
f"No frames received from {self.camera_name} in 20 seconds. Exiting ffmpeg..." f"No frames received from {self.camera_name} in 20 seconds. Exiting ffmpeg..."
) )