Currently translated at 89.9% (695 of 773 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.4% (472 of 522 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (141 of 141 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.2% (1260 of 1396 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (74 of 74 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 89.1% (107 of 120 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (50 of 50 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.5% (240 of 265 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 89.9% (695 of 773 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 64.4% (181 of 281 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.2% (1260 of 1396 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.2% (1260 of 1396 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 89.9% (695 of 773 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.4% (472 of 522 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 64.4% (181 of 281 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.2% (1260 of 1396 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (50 of 50 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.5% (240 of 265 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (129 of 129 strings)
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 89.9% (695 of 773 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.2% (1265 of 1401 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (129 of 129 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (500 of 500 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 96.8% (62 of 64 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.2% (1265 of 1401 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (129 of 129 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 90.5% (240 of 265 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (500 of 500 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 98.5% (67 of 68 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (500 of 500 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (500 of 500 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (129 of 129 strings)
Translated using Weblate (Chinese (Traditional Han script))
Currently translated at 100.0% (500 of 500 strings)
Update translation files
Updated by "Cleanup translation files" add-on in Weblate.
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: 蘭蘭露 <flandretw@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/audio/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/common/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-camera/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-dialog/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/components-filter/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/config-cameras/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/config-global/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/objects/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-classificationmodel/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-events/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-motionsearch/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-settings/zh_Hant/
Translate-URL: https://hosted.weblate.org/projects/frigate-nvr/views-system/zh_Hant/
Translation: Frigate NVR/Config - Cameras
Translation: Frigate NVR/Config - Global
Translation: Frigate NVR/audio
Translation: Frigate NVR/common
Translation: Frigate NVR/components-camera
Translation: Frigate NVR/components-dialog
Translation: Frigate NVR/components-filter
Translation: Frigate NVR/objects
Translation: Frigate NVR/views-classificationmodel
Translation: Frigate NVR/views-events
Translation: Frigate NVR/views-motionSearch
Translation: Frigate NVR/views-settings
Translation: Frigate NVR/views-system
* Add analytics opt-in setting, prompt notice kind, and notice watermarks
* Add the analytics report schema
* Add the analytics state file
* Add the install and hardware analytics collectors
* Add the detection analytics collector
* Add the cameras analytics collector
* Add the features analytics collector
* Add the health analytics collector
* Build analytics reports from the section collectors
* Add the analytics report transport
* Send the daily analytics report from the main process
* Add the analytics preview API
* Generate the analytics schema and check it in CI
* Record the image variant in each Dockerfile
* Show the analytics preview in telemetry settings
* Document anonymous analytics
* change wording
* fixes
* update network requirements docs
* adapt analytics to free-form model scenes, split notice counts, and peewee 4
* fixes
* change log levels
* docstrings
* docstrings
* honor file-only analytics opt-outs and skip pre-consent notices
An opt-out saved through the YAML editor's "Save only" or a hand edit never reached the live config, so reports kept going out under the old install ID until a restart. The reporter now reads telemetry.analytics from the config file when a report is due, validated with TelemetryConfig so yes, on, and 1 still count as consent, and an opt-out there deletes the state file and skips the send. The first report under a new install ID also carried every notice since the counters started, including ones from before the opt-in, so a fresh state file now resets the notice watermarks before the report's snapshot.
* take the notice baseline at opt-in instead of the first send
The watermark reset ran at the first send attempt, so notices raised between the opt-in and that send, up to 45 minutes after a startup, were absorbed into the reset and never reported. The reporter now writes the new install ID and resets the watermarks as soon as it sees consent without a state file.
* report notice counts cumulatively from a database baseline
Moving watermarks after each accepted send kept the install ID and the notice baseline out of step: pre-consent notices went out, notices raised before the first send were dropped, and a send that finished after an off/on toggle overwrote the new identity's baseline. health.notices now carries cumulative counts since the install ID was created. Creating an ID copies the lifetime counts into the existing reported_* columns before the state file names it, and nothing is written after a send, so the backend diffs consecutive reports per install ID.
* write held notice repeats before the analytics baseline reset
Repeats of batched kinds like failed_login wait in memory until the stats emitter flushes them, so a baseline reset taken while some were held left them out, and the next flush counted those pre-opt-in repeats as post-consent. The reset now writes held repeats to the notice history under the same lock before copying the counts.
* seed detector inference speed from the first inference
The average started at 0 so idle detectors read 0, but that made every detector's speed climb from 0 for its first couple dozen inferences after a start. Detectors now use the same InferenceSpeed helper as enrichments, so the first inference seeds the average and idle detectors still read 0.
* miscellaneous fixes
- keep base path in recording share links
- reject non-positive scale on recordings/unavailable, which looped forever on the event loop
- reject negative vod event padding, which cleared has_clip
- clamp negative preview gif/mp4 offsets
- don't delete exports that are still in progress
- hash on unknown login usernames so timing doesn't reveal valid users
- include the first minute of the events time-of-day filter
- show an error when the push subscription is refused
- don't wipe an unnamed known plates entry when Add is pressed again
- use elapsed hours for export last N hours so DST doesn't shift the range
* fix live audio settings and trigger highlights
- start each camera group's audio from that group's saved settings instead of merging every group
- don't clear the previous trigger's highlight timeout when another trigger fires
* address review feedback
- Discard the export row when an export fails before or during ffmpeg, so it doesn't stay in progress until a restart
- Skip the empty thumbnail path when discarding a failed export
- Measure preview clip duration from the clamped start
- Default live player volume to 1 when the group has no saved setting
- Clear the unsaved registration message when notification registration fails
- Keep a highlight timer per trigger
- Remove the severity order_by in /review, which the start_time order_by replaced
* Hold pandas 3.1 until numpy 2
* fix two-way talk shortcut and detail stream active item after camera switch
* show already running message when a media sync is in progress
* pick the earliest overlapping preview for preview gif and mp4
* unmute camera audio when starting two-way talk from the shortcut
* remove password strength meter and fix confirm password feedback
The strength meter still scored against the old 8 character and character class rules, so any password with a digit, like test1234, showed a full green "Very Strong" bar next to the failing 12 character requirement. The meter is gone and the length checklist is the only feedback. The password field's form message duplicated the checklist, and editing the password never revalidated the confirm field, so a fixed mismatch kept showing "Passwords do not match". Editing the password now revalidates the confirm field once it has a value, and both dialogs show a live match/mismatch indicator in place of the confirm form message.
* add configurable ttl for active alert notifications
Notifications sent while an alert was active always used a TTL of 0, so the push service dropped them if the device wasn't reachable at that moment and users only received the notification sent when the alert ended. A new `ttl` notifications option, settable globally or per camera, lets the push service retry these notifications for that many seconds. It defaults to 0, and the settings UI warns that a non-zero value can deliver stale notifications.
* make notification ttl a global advanced setting
- Read `ttl` from the global notifications config and hide it on the camera form
- Show it under Advanced Settings on the Notifications page
- Remove extra padding that misaligned the Notifications cards with the rest of the form
- Shorten the ttl warning
* tweaks
* use enum instead of raw seconds value
* show validation errors in multi-camera export
Clearing part of a time field in the export time picker set the range to NaN, while the picker kept showing a valid fallback time. The multi-camera Export button then stayed disabled with no explanation, and non-admins could never start an export because a case name was required even though they can't see the case field. The picker now ignores incomplete time values. The multi-camera tab shows inline errors for an invalid range, no selected cameras, and a blank case name, only requires a case name from admins, and prefills a default case name.
* add viewer export test and remove stale non-admin case text
* fix test
* fix races in ui settings import e2e tests
confirmImport clicked any button named "Import", so when the file parse was slow it hit the Import Settings button before the dialog opened and the page never reloaded. The click is now scoped to the dialog. The legacy layouts test also wrote naturalAspectLayout after the view had already read it, so it reloads the view after the write.
* update zod to 4.6.7
zod 4 types the input of z.coerce.number() as unknown, so the zone, camera wizard, and classification edit forms pass number to keep their field types. The ONVIF port error showed zod's built-in English text, which zod 4 rewords, so it now uses a translated message. New e2e tests cover zone inertia validation and camera wizard step 1 validation.
* limit concurrent motion search jobs and search range
Any viewer could start unlimited motion search jobs over an unbounded time range, and finished jobs were never dropped from memory. Each user now gets one active job (409), at most 3 run at once (429), the range is capped at 48 hours, and finished jobs are evicted 10 minutes after they end. Jobs are no longer filed in the shared job manager, which kept every finished job forever.
* show translated errors for motion search limits
* release the motion search slot if the runner fails to start
* keep wedged or shared-identity motion searches from locking out users
A stalled VOD read blocked the runner forever, so a wedged job held its user and global slot until restart, and on installs without per-user identity (internal port, or auth disabled without a proxy user header) everyone shared one per-user slot. VOD ffmpeg and ffprobe inputs now use a 30 s rw_timeout, a cancel also drops queued parallel runs, a cancelled job stops counting after 60 s, and the per-user limit only applies when the request carries a real username. A failed runner start also stops its requestor.
* treat timed-out VOD segments as motion search errors
With rw_timeout, the HLS demuxer skipped a timed-out segment and exited cleanly, so a run reported success with a hole in it, and when the keyframe probe and the decode lost different segments the equal frame counts paired frames with the wrong timestamps. The keyframe path now requires the probe to cover the whole run without a gap over 5 s, a decode whose stderr shows a skipped segment fails the run, and a cadence decode more than 5 s short of the run's duration fails it too, so these runs land in segments_with_errors. The keyframe probe polls should_stop and is killed on cancel, probe_video_dimensions gets the read timeout, and a user's own cancelled job no longer blocks their next search while it still counts toward the global cap.
* drop motion search stall detection and range cap
* remove motion search range check from the UI