Offload preview encoding and Plus upload off the API event loop (#23552)

* offload preview ffmpeg encoding to a thread to avoid blocking the api event loop

* offload Frigate+ recording snapshot upload to a thread to avoid blocking the api event loop
This commit is contained in:
Josh Hawkins 2026-06-24 07:17:23 -05:00 committed by GitHub
parent b3ce4486b9
commit 4e5e8e3c59
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -380,7 +380,9 @@ async def submit_recording_snapshot_to_plus(
)
nd = cv2.imdecode(np.frombuffer(image_data, dtype=np.int8), cv2.IMREAD_COLOR)
request.app.frigate_config.plus_api.upload_image(nd, camera_name)
await asyncio.to_thread(
request.app.frigate_config.plus_api.upload_image, nd, camera_name
)
return JSONResponse(
content={
@ -1517,14 +1519,14 @@ async def event_preview(request: Request, event_id: str):
end_ts = start_ts + (
min(event.end_time - event.start_time, 20) if event.end_time else 20
)
return preview_gif(request, event.camera, start_ts, end_ts)
return await preview_gif(request, event.camera, start_ts, end_ts)
@router.get(
"/{camera_name}/start/{start_ts}/end/{end_ts}/preview.gif",
dependencies=[Depends(require_camera_access)],
)
def preview_gif(
async def preview_gif(
request: Request,
camera_name: str,
start_ts: float,
@ -1587,7 +1589,8 @@ def preview_gif(
"-",
]
process = sp.run(
process = await asyncio.to_thread(
sp.run,
ffmpeg_cmd,
capture_output=True,
)
@ -1654,7 +1657,8 @@ def preview_gif(
"-",
]
process = sp.run(
process = await asyncio.to_thread(
sp.run,
ffmpeg_cmd,
input=str.encode("\n".join(selected_previews)),
capture_output=True,
@ -1683,7 +1687,7 @@ def preview_gif(
"/{camera_name}/start/{start_ts}/end/{end_ts}/preview.mp4",
dependencies=[Depends(require_camera_access)],
)
def preview_mp4(
async def preview_mp4(
request: Request,
camera_name: str,
start_ts: float,
@ -1763,7 +1767,8 @@ def preview_mp4(
path,
]
process = sp.run(
process = await asyncio.to_thread(
sp.run,
ffmpeg_cmd,
capture_output=True,
)
@ -1827,7 +1832,8 @@ def preview_mp4(
path,
]
process = sp.run(
process = await asyncio.to_thread(
sp.run,
ffmpeg_cmd,
input=str.encode("\n".join(selected_previews)),
capture_output=True,
@ -1880,9 +1886,9 @@ async def review_preview(
)
if format == "gif":
return preview_gif(request, review.camera, start_ts, end_ts)
return await preview_gif(request, review.camera, start_ts, end_ts)
else:
return preview_mp4(request, review.camera, start_ts, end_ts)
return await preview_mp4(request, review.camera, start_ts, end_ts)
@router.get(