feat: Add support for Frigate reviews / detections [initial PR] (#2315)

- Add support for Frigate reviews / detections.
 - Add support for GenAI metadata.
- Significant internal refactor to more flexible "UnifiedQuery" to allow
mixing cameras with simple metadata and review metadata (e.g. a timeline
view of a Frigate camera with reviews, and a Reolink camera with simple
metadata).
 - Add support for folder media as camera media.

There are a few more PRs to commit prior to this going live, but
commiting this for now due to the scale of the change.

BREAKING CHANGE: `media_type` and `events_type` are retired under
`live`, `viewer` and `timeline` configuration sections, instead media
type is associated (once) with the camera under `media`.
This commit is contained in:
Dermot Duffy
2026-01-19 13:32:50 -08:00
committed by GitHub
parent 6eb0a87ca8
commit fc32727860
215 changed files with 14491 additions and 6160 deletions
+9 -13
View File
@@ -109,6 +109,15 @@
}
},
"common": {
"media_types": {
"events": "Esdeveniments",
"recordings": "Enregistraments"
},
"events_media_types": {
"all": "Tots els tipus de mitjans",
"clips": "Clips",
"snapshots": "Imatges instantànies"
},
"controls": {
"builtin": "Controls de vídeo integrats",
"filter": {
@@ -134,15 +143,7 @@
"thumbnails": {
"editor_label": "Miniatures",
"events_media_type": "Si voleu mostrar miniatures d'esdeveniments de clips o instantànies",
"events_media_types": {
"clips": "Miniatures de clips",
"snapshots": "Miniatures d'instantànies"
},
"media_type": "Si voleu mostrar miniatures d'esdeveniments o enregistraments",
"media_types": {
"events": "Esdeveniments",
"recordings": "Enregistraments"
},
"mode": "Mode de miniatures",
"modes": {
"above": "Miniatures a dalt",
@@ -203,11 +204,6 @@
"timeline": {
"clustering_threshold": "El recompte d'esdeveniments en què s'agrupen (0=sense agrupació)",
"events_media_type": "Els esdeveniments multimèdia que mostra la línia de temps",
"events_media_types": {
"all": "Tots els tipus de mitjans",
"clips": "Clips",
"snapshots": "Imatges instantànies"
},
"show_recordings": "Mostra les gravacions",
"style": "Estil de cronologia",
"styles": {
+5 -5
View File
@@ -116,14 +116,14 @@
}
},
"common": {
"media_types": {
"events": "Ereignisse",
"recordings": "Aufzeichnungen"
},
"controls": {
"builtin": "Eingebettete Video Bedienelemente",
"thumbnails": {
"media_type": "Ob Vorschau von Ereignissen oder Aufzeichnungen angezeigt werden",
"media_types": {
"events": "Ereignisse",
"recordings": "Aufzeichnungen"
}
"media_type": "Ob Vorschau von Ereignissen oder Aufzeichnungen angezeigt werden"
},
"timeline": {
"format": {
+49 -17
View File
@@ -6,11 +6,22 @@
"common": {
"advanced_camera_card": "Advanced Camera Card",
"advanced_camera_card_description": "An Advanced Camera Card",
"up": "Up",
"folder": "Folder",
"live": "Live",
"no_folder": "No folder to display",
"no_media": "No media to display",
"recordings": "Recordings",
"set_reviews": {
"reviewed": "Mark as reviewed",
"unreviewed": "Mark as unreviewed"
},
"severities": {
"high": "High",
"low": "Low",
"medium": "Medium"
},
"severity": "Severity",
"version": "Version"
},
"config": {
@@ -83,9 +94,9 @@
"rotation": "Rotation",
"rotations": {
"0": "No rotation",
"90": "90 degrees clockwise",
"180": "180 degrees clockwise",
"270": "270 degrees clockwise"
"270": "270 degrees clockwise",
"90": "90 degrees clockwise"
}
},
"engines": {
@@ -130,6 +141,12 @@
"jsmpeg": "JSMpeg",
"webrtc-card": "WebRTC Card (i.e. AlexxIT's WebRTC Card)"
},
"media": {
"editor_label": "Default Media",
"events_type": "Events media subtype",
"folders": "Folder IDs",
"type": "Default media type"
},
"motioneye": {
"editor_label": "MotionEye options",
"images": {
@@ -187,7 +204,11 @@
"snapshots": "Events with new snapshots"
},
"motion": "Trigger by auto-detecting the motion sensor",
"occupancy": "Trigger by auto-detecting the occupancy sensor"
"occupancy": "Trigger by auto-detecting the occupancy sensor",
"reviews": {
"description": "Trigger on description updates",
"editor_label": "Review Triggers"
}
},
"webrtc_card": {
"editor_label": "WebRTC Card Options",
@@ -221,15 +242,7 @@
"thumbnails": {
"editor_label": "Thumbnails",
"events_media_type": "Whether to show event thumbnails of clips or snapshots",
"events_media_types": {
"clips": "Clip thumbnails",
"snapshots": "Snapshot thumbnails"
},
"media_type": "Whether to show thumnails of events or recordings",
"media_types": {
"events": "Events",
"recordings": "Recordings"
},
"media_type": "What to show thumbnails of",
"mode": "Thumbnails mode",
"modes": {
"above": "Thumbnails above",
@@ -241,6 +254,8 @@
"show_details": "Show details with thumbnails",
"show_download_control": "Show download control on thumbnails",
"show_favorite_control": "Show favorite control on thumbnails",
"show_info_control": "Show info control on thumbnails",
"show_review_control": "Show review control on thumbnails",
"show_timeline_control": "Show timeline control on thumbnails",
"size": "Thumbnails size in pixels"
},
@@ -279,6 +294,11 @@
"grid_selected_width_factor": "Increase selected media width by this factor",
"mode": "Mode"
},
"events_media_types": {
"all": "All",
"clips": "Clips",
"snapshots": "Snapshots"
},
"image": {
"entity": "Entity for use with entity mode",
"entity_parameters": "Query parameters added to the entity-based picture URLs (e.g. width=1920&height=1080)",
@@ -302,14 +322,16 @@
"unselected": "On unselection",
"visible": "On browser/tab visibility"
},
"media_types": {
"auto": "Automatic",
"events": "Events",
"folder": "Folder",
"recordings": "Recordings",
"reviews": "Reviews"
},
"timeline": {
"clustering_threshold": "The count of events at which they are clustered (0=no clustering)",
"events_media_type": "The events media the timeline displays",
"events_media_types": {
"all": "All event media types",
"clips": "Clips",
"snapshots": "Snapshots"
},
"show_recordings": "Show recordings",
"style": "Timeline style",
"styles": {
@@ -433,6 +455,7 @@
"fullscreen": "Fullscreen",
"icon": "Icon",
"image": "Image",
"info": "Info",
"iris": "Iris / Default View / Unhide menu",
"live": "Live",
"media_player": "Send to media player",
@@ -444,7 +467,9 @@
"ptz_controls": "Show PTZ controls",
"ptz_home": "PTZ Home",
"recordings": "Recordings",
"reviews": "Reviews",
"screenshot": "Screenshot",
"set_review": "Set review status",
"snapshots": "Snapshots",
"substreams": "Substream(s)",
"timeline": "Timeline",
@@ -604,6 +629,8 @@
"live": "Live view",
"recording": "Most recent recording",
"recordings": "Recordings gallery",
"review": "Most recent media to review",
"reviews": "Reviews gallery",
"snapshot": "Most recent snapshot",
"snapshots": "Snapshots gallery",
"timeline": "Timeline view"
@@ -734,12 +761,16 @@
"media_types": {
"clips": "Clips",
"recordings": "Recordings",
"reviews": "Reviews",
"snapshots": "Snapshots"
},
"not_favorite": "Not Favorite",
"not_reviewed": "Not Reviewed",
"reviewed": "Reviewed",
"select_camera": "Select camera...",
"select_favorite": "Select favorite...",
"select_media_type": "Select media type...",
"select_reviewed": "Select reviewed...",
"select_tag": "Select tag...",
"select_what": "Select what...",
"select_when": "Select when...",
@@ -765,6 +796,7 @@
"duration": "Duration",
"events": "Events",
"in_progress": "In Progress",
"info": "Info",
"no_thumbnail": "No thumbnail available",
"retain_indefinitely": "Media will be indefinitely retained",
"score": "Score",
+9 -13
View File
@@ -178,6 +178,15 @@
}
},
"common": {
"media_types": {
"events": "Événements",
"recordings": "Enregistrements"
},
"events_media_types": {
"all": "Tous types de médias",
"clips": "Extraits",
"snapshots": "Instantanés"
},
"controls": {
"builtin": "Commandes vidéo intégrées",
"filter": {
@@ -203,15 +212,7 @@
"thumbnails": {
"editor_label": "Vignettes",
"events_media_type": "S'il faut afficher des vignettes de clips ou des instantanés",
"events_media_types": {
"clips": "Vignettes de clips",
"snapshots": "Vignettes d'instantanés"
},
"media_type": "Afficher ou non les vignettes des événements ou des enregistrements",
"media_types": {
"events": "Événements",
"recordings": "Enregistrements"
},
"mode": "Mode vignettes",
"modes": {
"above": "Vignettes en haut",
@@ -281,11 +282,6 @@
"timeline": {
"clustering_threshold": "Nombre d'événements pour lesquels ils sont regroupés (0 = pas de clustering)",
"events_media_type": "Médias affichés par la chronologie",
"events_media_types": {
"all": "Tous types de médias",
"clips": "Extraits",
"snapshots": "Instantanés"
},
"show_recordings": "Afficher les enregistrements",
"style": "Style de chronologie",
"styles": {
+5 -9
View File
@@ -94,6 +94,11 @@
}
},
"common": {
"events_media_types": {
"all": "Tutti i tipi di media",
"clips": "Clip",
"snapshots": "Istantanee"
},
"controls": {
"filter": {
"editor_label": "Filtro multimediale",
@@ -118,10 +123,6 @@
"thumbnails": {
"editor_label": "Miniature",
"events_media_type": "Se mostrare miniature di clip o istantanee",
"events_media_types": {
"clips": "Miniature di clip",
"snapshots": "Miniature istantanee"
},
"mode": "Modalità miniatura",
"modes": {
"above": "Miniature sopra",
@@ -166,11 +167,6 @@
"timeline": {
"clustering_threshold": "Il conteggio degli eventi in cui sono raggruppati (0 = nessun clustering)",
"events_media_type": "I media vengono visualizzati la sequenza temporale",
"events_media_types": {
"all": "Tutti i tipi di media",
"clips": "Clip",
"snapshots": "Istantanee"
},
"show_recordings": "Mostra registrazioni",
"window_seconds": "La lunghezza predefinita della vista della sequenza temporale in secondi"
}
+5 -9
View File
@@ -94,6 +94,11 @@
}
},
"common": {
"events_media_types": {
"all": "Todos os tipos de mídia",
"clips": "Clipes",
"snapshots": "Instantâneos"
},
"controls": {
"filter": {
"editor_label": "Filtro de Mídia",
@@ -118,10 +123,6 @@
"thumbnails": {
"editor_label": "Miniaturas",
"events_media_type": "Se deve mostrar miniaturas de clipes ou snapshots",
"events_media_types": {
"clips": "Miniaturas de clipes",
"snapshots": "Miniaturas de Snapshots"
},
"mode": "Modo de miniaturas",
"modes": {
"above": "Miniaturas acima da mídia",
@@ -166,11 +167,6 @@
"timeline": {
"clustering_threshold": "A contagem de eventos nos quais eles são agrupados (0 = sem agrupamento)",
"events_media_type": "A mídia que a linha do tempo exibe",
"events_media_types": {
"all": "Todos os tipos de mídia",
"clips": "Clipes",
"snapshots": "Instantâneos"
},
"show_recordings": "Mostrar gravações",
"window_seconds": "A duração padrão da visualização da linha do tempo em segundos"
}
+5 -9
View File
@@ -94,6 +94,11 @@
}
},
"common": {
"events_media_types": {
"all": "Todos os tipos de mídia",
"clips": "Clipes",
"snapshots": "Instantâneos"
},
"controls": {
"filter": {
"editor_label": "Editor de titulos",
@@ -118,10 +123,6 @@
"thumbnails": {
"editor_label": "Editor de titulos",
"events_media_type": "Mostrar miniaturas de clipes ou snapshots",
"events_media_types": {
"clips": "Miniaturas de clipes",
"snapshots": "Miniaturas de Snapshots"
},
"mode": "Modos",
"modes": {
"above": "Miniaturas acima da mídia",
@@ -166,11 +167,6 @@
"timeline": {
"clustering_threshold": "A contagem de eventos nos quais eles são agrupados (0 = sem agrupamento)",
"events_media_type": "A mídia que a linha do tempo exibe",
"events_media_types": {
"all": "Todos os tipos de mídia",
"clips": "Clipes",
"snapshots": "Instantâneos"
},
"show_recordings": "Mostrar gravações",
"window_seconds": "A duração padrão da visualização da linha do tempo em segundos"
}