use a nginx internal redirect

This commit is contained in:
Blake Blackshear 2021-08-10 08:27:31 -05:00
parent 1823bd0305
commit 189b9c6648
3 changed files with 32 additions and 25 deletions

View File

@ -125,6 +125,11 @@ http {
root /media/frigate; root /media/frigate;
} }
location /cache/ {
internal; # This tells nginx it's not accessible from the outside
alias /tmp/cache/;
}
location /recordings/ { location /recordings/ {
add_header 'Access-Control-Allow-Origin' "$http_origin" always; add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Credentials' 'true';

View File

@ -245,17 +245,24 @@ def event_clip(id):
event_config = current_app.frigate_config.cameras[event.camera].record.events event_config = current_app.frigate_config.cameras[event.camera].record.events
start_ts = event.start_time - event_config.pre_capture start_ts = event.start_time - event_config.pre_capture
end_ts = event.end_time + event_config.post_capture end_ts = event.end_time + event_config.post_capture
clip_path = os.path.join(CLIPS_DIR, f"{event.camera}-{id}.mp4") file_name = f"{event.camera}-{id}.mp4"
clip_path = os.path.join(CLIPS_DIR, file_name)
if not os.path.isfile(clip_path): if not os.path.isfile(clip_path):
return recording_clip(event.camera, start_ts, end_ts) return recording_clip(event.camera, start_ts, end_ts)
return send_file( response = make_response()
clip_path, response.headers["Content-Description"] = "File Transfer"
mimetype="video/mp4", response.headers["Cache-Control"] = "no-cache"
as_attachment=download, response.headers["Content-Type"] = "video/mp4"
attachment_filename=f"{event.camera}_{start_ts}-{end_ts}.mp4", if download:
) response.headers["Content-Disposition"] = "attachment; filename=%s" % file_name
response.headers["Content-Length"] = os.path.getsize(clip_path)
response.headers[
"X-Accel-Redirect"
] = f"/clips/{file_name}" # nginx: http://wiki.nginx.org/NginxXSendfile
return response
@bp.route("/events") @bp.route("/events")
@ -579,7 +586,8 @@ def recording_clip(camera, start_ts, end_ts):
if clip.end_time > end_ts: if clip.end_time > end_ts:
playlist_lines.append(f"outpoint {int(end_ts - clip.start_time)}") playlist_lines.append(f"outpoint {int(end_ts - clip.start_time)}")
path = f"/tmp/cache/tmp_clip_{camera}_{start_ts}-{end_ts}.mp4" file_name = f"clip_{camera}_{start_ts}-{end_ts}.mp4"
path = f"/tmp/cache/{file_name}"
ffmpeg_cmd = [ ffmpeg_cmd = [
"ffmpeg", "ffmpeg",
@ -609,23 +617,17 @@ def recording_clip(camera, start_ts, end_ts):
logger.error(p.stderr) logger.error(p.stderr)
return f"Could not create clip from recordings for {camera}.", 500 return f"Could not create clip from recordings for {camera}.", 500
mp4_bytes = None response = make_response()
try: response.headers["Content-Description"] = "File Transfer"
# read clip from disk response.headers["Cache-Control"] = "no-cache"
with open(path, "rb") as mp4_file: response.headers["Content-Type"] = "video/mp4"
mp4_bytes = mp4_file.read()
# delete after we have the bytes
os.remove(path)
except DoesNotExist:
return f"Could not create clip from recordings for {camera}.", 500
response = make_response(mp4_bytes)
response.mimetype = "video/mp4"
if download: if download:
response.headers[ response.headers["Content-Disposition"] = "attachment; filename=%s" % file_name
"Content-Disposition" response.headers["Content-Length"] = os.path.getsize(path)
] = f"attachment; filename={camera}_{start_ts}-{end_ts}.mp4" response.headers[
"X-Accel-Redirect"
] = f"/cache/{file_name}" # nginx: http://wiki.nginx.org/NginxXSendfile
return response return response

View File

@ -51,7 +51,7 @@ class RecordingMaintainer(threading.Thread):
for d in os.listdir(CACHE_DIR) for d in os.listdir(CACHE_DIR)
if os.path.isfile(os.path.join(CACHE_DIR, d)) if os.path.isfile(os.path.join(CACHE_DIR, d))
and d.endswith(".mp4") and d.endswith(".mp4")
and not d.startswith("tmp_clip") and not d.startswith("clip_")
] ]
files_in_use = [] files_in_use = []