Compare commits

..
210 Commits
Author SHA1 Message Date
Paul ArmstrongandBlake Blackshear 0232a9f94a fix(web): ensure all links on events page include pathname 2021-01-25 21:15:25 -06:00
Blake Blackshear e8586d6459 updating for docusaurus2 docs 2021-01-25 21:13:33 -06:00
Paul ArmstrongandBlake Blackshear 9cf49b5bc4 fix(web): make camera latest.jpg responsive 2021-01-25 21:03:46 -06:00
Blake Blackshear 4a18fc58de add search to docs 2021-01-25 21:01:43 -06:00
Blake Blackshear 5ddfde2e72 tweaking the docs 2021-01-24 08:27:43 -06:00
Blake Blackshear 714d76887d use sqlitequeuedb 2021-01-24 06:53:37 -06:00
James CarlosandBlake Blackshear 0c0e1416ff Update documentation link in sidebar to new docs 2021-01-23 07:00:51 -06:00
Blake Blackshear c6044ba9a1 add debug log when cache is cleaned up 2021-01-22 17:54:30 -06:00
Blake Blackshear a7739a0a62 if detection stopped, assume the container needs a restart 2021-01-22 16:58:14 -06:00
Blake Blackshear 84ed126db6 fix table in docs 2021-01-22 08:02:09 -06:00
Blake Blackshear a76f54c326 readme update 2021-01-22 07:48:40 -06:00
Paul ArmstrongandBlake Blackshear b93d354c60 docs: move docs to docusaurus 2021-01-22 07:33:27 -06:00
Blake Blackshear 14d218af46 rate limit tracked object updates to every 5 seconds 2021-01-22 06:40:01 -06:00
Blake Blackshear bd4973e3f7 add snapshot endpoint that works during the event fixes #575 2021-01-21 18:49:20 -06:00
Blake Blackshear d94f81969b get the thumbnail instead of the full frame 2021-01-21 17:28:49 -06:00
Blake Blackshear d32fed2c01 dont wait forever for the cache 2021-01-21 17:26:53 -06:00
Blake Blackshear 7b4e510b95 fix initial switch state 2021-01-20 21:56:43 -06:00
Blake Blackshear bb4f79cdfe handle exception when frame isnt in cache 2021-01-20 21:56:43 -06:00
Paul ArmstrongandBlake Blackshear e32e69c2d0 feat(web): AutoUpdatingCameraImage to replace MJPEG feed 2021-01-20 21:15:25 -06:00
Paul ArmstrongandBlake Blackshear a71ae053e4 fix(web): set default path to cameras view 2021-01-20 06:46:25 -06:00
Blake Blackshear fcc9cd56cc update index.js to use baseUrl 2021-01-19 21:31:17 -06:00
Blake Blackshear b981a3110b first pass at subfilter for ingress support 2021-01-19 19:58:42 -06:00
Paul ArmstrongandBlake Blackshear 2da50cc538 fix(web): dark mode text color fixes
fixes #544
2021-01-19 18:02:08 -06:00
Blake Blackshear cb4a0aa594 ensure error message with missing config is printed 2021-01-19 18:00:26 -06:00
Blake Blackshear 52da1fddc7 update notification example 2021-01-19 07:41:45 -06:00
Blake Blackshear 14645ce4f8 fix mqtt switch handling 2021-01-19 07:41:17 -06:00
Blake Blackshear 97ce7f3028 initialize detection correctly from config 2021-01-19 07:40:51 -06:00
Blake Blackshear 3b5302f6ea update wheels version 2021-01-19 06:19:28 -06:00
Blake Blackshear 74eb16f213 pin numpy 2021-01-19 06:16:44 -06:00
Paul ArmstrongandBlake Blackshear a3d6bf214c feat(web): layout & auto-update debug page 2021-01-18 12:57:09 -06:00
Paul ArmstrongandBlake Blackshear 16121ffd00 fix(web): ensure button bg colors show in prod builds 2021-01-18 11:39:42 -06:00
Blake Blackshear 91628bd5d8 fix zone config 2021-01-18 06:38:26 -06:00
Blake Blackshear b10b64bf57 no longer need special aarch64 wheels build 2021-01-17 08:18:54 -06:00
Blake Blackshear 749c34be9f versioning wheels image 2021-01-16 20:03:42 -06:00
Blake Blackshear 8cfdfab985 move wheels to build container 2021-01-16 19:56:21 -06:00
Paul ArmstrongandBlake Blackshear ef25f8a31e fix(web): mask zone editor to handle object filter masks
Includes additional handlers for adding/removing masks, as well as click to copy configs

fixes #523
2021-01-16 19:09:18 -06:00
Paul ArmstrongandBlake Blackshear 2a0551a08a feat(web): hash build files to avoid cache issues 2021-01-16 19:09:18 -06:00
Paul ArmstrongandBlake Blackshear 0b80419f15 fix(web): ensure mask editing works in firefox 2021-01-16 19:09:18 -06:00
Blake Blackshear 0dc81117aa docs updates for notification changes 2021-01-16 19:09:18 -06:00
Blake Blackshear 49b29d72a7 rename snapshot endpoint to thumbnail 2021-01-16 19:09:18 -06:00
Blake Blackshear 21ece238ff mqtt tweaks for switches 2021-01-16 19:09:18 -06:00
Blake Blackshear f6ba3f2daa allow summary data to be filtered 2021-01-16 19:09:18 -06:00
Blake Blackshear bb0d3cb59a update readme 2021-01-16 19:09:18 -06:00
Blake Blackshear ca9b6d6c5c snapshots config typo 2021-01-16 19:09:18 -06:00
Blake Blackshear 3103ad2bfe update object filters to inherit like motion settings 2021-01-16 19:09:18 -06:00
Blake Blackshear eab3998ad0 remove support for image masks 2021-01-16 19:09:18 -06:00
Blake Blackshear a3dfd3a8e0 don't fallback to the CPU
fixes #381
2021-01-16 19:09:18 -06:00
Blake Blackshear f1c3087775 add change type to events topic
#476
2021-01-16 19:09:18 -06:00
Blake Blackshear 1be91ed3f2 ensure each camera has a detect role set 2021-01-16 19:09:18 -06:00
Blake Blackshear fd83c4f229 add detection enable to config
fixes #482
2021-01-16 19:09:18 -06:00
Blake Blackshear de99221ad5 add env vars to config
fixes #509
2021-01-16 19:09:18 -06:00
Blake Blackshear 6892ce56ac enable and disable detection via mqtt 2021-01-16 19:09:18 -06:00
Blake Blackshear 41cea6f62e move setproctitle to prebuilt wheel location 2021-01-16 19:09:18 -06:00
Blake Blackshear 4bbffa97df switch to docker based web builds 2021-01-16 19:09:18 -06:00
Blake Blackshear 614f8abfef handle null thumbnail data 2021-01-16 19:09:18 -06:00
Blake Blackshear 14289b5fd1 add mask as object filter 2021-01-16 19:09:18 -06:00
Blake Blackshear 4164beff1c add object masks and move moton mask 2021-01-16 19:09:18 -06:00
Blake Blackshear 9b3ab486de add missing global shapshots config 2021-01-16 19:09:18 -06:00
Patrick DecatandBlake Blackshear 232a49814a Add missing migrations in docker images 2021-01-16 19:09:18 -06:00
Paul ArmstrongandBlake Blackshear 6c61f0b135 fix(web): ensure postcss and postcss-cli are marked as deps 2021-01-16 19:09:18 -06:00
Patrick DecatandBlake Blackshear c572cec253 Fix Makefile to ignore gpg signatures in commits 2021-01-16 19:09:18 -06:00
Paul ArmstrongandBlake Blackshear d4941f2a5f feat!: web user interface 2021-01-16 19:09:18 -06:00
Blake Blackshear bf5ec2f65f try to cleanup some migration logging 2021-01-16 19:09:18 -06:00
Blake Blackshear f8e21584b6 add retention settings for snapshots 2021-01-16 19:09:18 -06:00
Blake Blackshear 3cba83f84b init variables on camera state 2021-01-16 19:09:18 -06:00
Blake Blackshear dcb4255d7e handle process exit exceptions 2021-01-16 19:09:18 -06:00
Blake Blackshear 9fc3c0dc2f store has_clip and has_snapshot on events 2021-01-16 19:09:18 -06:00
Blake Blackshear a78830b48e add database migrations 2021-01-16 19:09:18 -06:00
Nat MorrisandBlake Blackshear 949fbadcdc Set titles for forked processes 2021-01-16 19:09:18 -06:00
Nat MorrisandBlake Blackshear 12c9e63b13 New stats module, refactor stats generation out of http module.
StatsEmitter thread to send stats to MQTT every 60 seconds by default, optional stats_interval config value.

New service stats attribute, containing uptime in seconds and version.
2021-01-16 19:09:18 -06:00
Blake Blackshear 157b230702 turn off snapshots via mqtt 2021-01-16 19:09:18 -06:00
Blake Blackshear c69299d659 enable turning clips on and off via mqtt 2021-01-16 19:09:18 -06:00
Blake Blackshear 285d630770 cleanup save_Clips/clips inconsistency 2021-01-16 19:09:18 -06:00
Blake Blackshear b9318092f4 add jpg snapshots to disk and clean up config 2021-01-16 19:09:18 -06:00
Paul ArmstrongandBlake Blackshear 905c361d52 fix: ensure timestamp is drawn above mask 2021-01-13 06:55:10 -06:00
Leonardo MerzaandBlake Blackshear 4443abbc49 add notes for Blue Iris RTSP support 2020-12-31 08:36:03 -06:00
yllarandBlake Blackshear dabb36ad93 Update README.md
change tmpfs size from 100MB to 1GB
2020-12-31 08:33:31 -06:00
kluszczynandBlake Blackshear 2bc8736fd9 Recordings - fix expire_file 2020-12-22 09:58:26 -05:00
Blake Blackshear e9b3b09cc2 add clips endpoint to readme 2020-12-22 09:58:26 -05:00
Blake Blackshear ca337c32b4 better mask error handling 2020-12-22 09:58:26 -05:00
Blake Blackshear 24b8bd7c85 fix tmpfs 2020-12-22 09:58:26 -05:00
Blake Blackshear 3ad75a441d remove redundant error output 2020-12-20 08:04:54 -06:00
Blake Blackshear f006e9be8d use CACHE_DIR constant 2020-12-20 08:04:54 -06:00
Blake Blackshear 03f3ba8008 enable mounting tmpfs volume on start 2020-12-20 08:04:54 -06:00
Blake Blackshear 96a44eb7bf docs and issue template 2020-12-20 07:37:44 -06:00
Blake Blackshear 006782fe3d update process clip for latest changes 2020-12-20 07:37:44 -06:00
Blake Blackshear ff3e95bbf7 publish event updates on zone change 2020-12-20 07:37:44 -06:00
Blake Blackshear 4b95a37e65 readme updates 2020-12-20 07:37:44 -06:00
Blake Blackshear 38c661b3a8 handle scenario with empty cache 2020-12-20 07:37:44 -06:00
Blake Blackshear 0d6e4f6a66 add qsv support to amd64 image 2020-12-20 07:37:44 -06:00
Blake Blackshear 1ad2219f1c add num_threads fixes #322 2020-12-20 07:37:44 -06:00
Blake Blackshear dfcdd289c3 optimize clips fixes #299 2020-12-20 07:37:44 -06:00
Blake Blackshear 32f5f2cca9 add post_capture option 2020-12-20 07:37:44 -06:00
Blake Blackshear 24bfe9f3e8 re-crop to the object rather than the region 2020-12-20 07:37:44 -06:00
Blake Blackshear 004667dc99 allow runtime drawing settings for mjpeg and latest 2020-12-20 07:37:44 -06:00
Blake Blackshear 9d785dc781 allow the mask to be a list of masks 2020-12-20 07:37:44 -06:00
Blake Blackshear cbba5a7af0 adding version endpoint 2020-12-20 07:37:44 -06:00
Blake Blackshear 29b29ee349 configurable motion and detect settings 2020-12-20 07:37:44 -06:00
Blake Blackshear 9ad53e09af update gitignore 2020-12-20 07:37:44 -06:00
Blake Blackshear c9278991c9 fix test 2020-12-20 07:37:44 -06:00
Blake Blackshear 729de48934 switch default threshold to .7 2020-12-20 07:37:44 -06:00
Blake Blackshear 7476bff5fb allow process clips to output a csv of scores 2020-12-20 07:37:44 -06:00
Blake Blackshear 1e9eae8d9a allow db path to be customized 2020-12-20 07:37:44 -06:00
Blake Blackshear 8113a53381 add telegram example 2020-12-20 07:37:44 -06:00
Blake Blackshear 72833686f1 fix process clip 2020-12-20 07:37:44 -06:00
Blake Blackshear 096c21f105 handle empty string args 2020-12-20 07:37:44 -06:00
Blake Blackshear 181f66357b allow region to extend beyond the frame 2020-12-20 07:37:44 -06:00
tubalainenandBlake Blackshear a54fbc483c Updated file
ref: https://github.com/blakeblackshear/frigate/issues/373
2020-12-12 10:38:02 -06:00
Blake Blackshear 92d5a002d3 swap width and height to reduce confusion 2020-12-10 19:22:03 -06:00
Blake Blackshear f9184903d7 updating compose example to reduce confusion 2020-12-10 19:02:08 -06:00
Blake Blackshear 91cde6ce7b allow defining model shape and switch to mobiledet as default model 2020-12-09 07:22:26 -06:00
Blake Blackshear 186a4587c7 add model dimensions to config 2020-12-09 07:22:26 -06:00
Patrick DecatandBlake Blackshear 6049acb1f3 Document beta addon host 2020-12-08 07:25:13 -06:00
Blake Blackshear 2d2ebf313c make shm consistent with compose 2020-12-08 07:24:37 -06:00
tubalainenandBlake Blackshear 3d329dcb52 Updated docker command line...
...to correspond with 0.8.0 feature set.
2020-12-08 07:24:37 -06:00
Blake Blackshear 06854fc34f readme cleanup fixes #332 2020-12-07 18:00:12 -06:00
Blake Blackshear e01e14d866 handle and warn if roles dont match enabled features 2020-12-07 08:07:35 -06:00
Blake Blackshear 3dfd251ebb camera recommendations 2020-12-07 07:36:29 -06:00
Blake Blackshear dcea807f77 catch all psutil errors 2020-12-07 07:16:48 -06:00
Blake Blackshear 87d83ff33a clarify height width and fps 2020-12-07 07:16:28 -06:00
Blake Blackshear 1d31cbdf0d readme updates 2020-12-06 14:25:28 -06:00
Blake Blackshear e05b27b8dc tweak screenshots 2020-12-06 08:27:03 -06:00
Blake Blackshear 7111bd208e readme updates 2020-12-06 08:25:25 -06:00
Blake Blackshear 04a80280da set ffmpeg image versions 2020-12-06 07:09:14 -06:00
Blake Blackshear 3bda092140 comment you zeroconf 2020-12-06 07:05:45 -06:00
Blake Blackshear 9086820479 fix flask logger config 2020-12-05 19:05:03 -06:00
Blake Blackshear d1da57aedc fix graceful exits 2020-12-05 12:06:07 -06:00
Blake Blackshear 6ded12c566 better exception handling 2020-12-05 12:06:07 -06:00
Blake Blackshear 70352566a7 fix default args 2020-12-05 12:06:07 -06:00
Blake Blackshear cf5cc86588 fix fontconfig issue 2020-12-05 08:48:46 -06:00
Blake Blackshear e41db49ab8 doc updates 2020-12-05 08:48:46 -06:00
Blake Blackshear 1b7effafee update some default config values 2020-12-05 08:48:46 -06:00
Blake Blackshear 69e9e0b0bf log level configuration 2020-12-05 08:48:46 -06:00
Blake Blackshear 89624df411 no need to write jpg disk 2020-12-05 08:48:46 -06:00
Blake Blackshear d1a7405211 dont delete the recordings directory 2020-12-05 08:48:46 -06:00
Blake Blackshear 040f8c7c20 default save_clips objects 2020-12-05 08:48:46 -06:00
Blake Blackshear 6d7acabf4c add logging for directory creation 2020-12-05 08:48:46 -06:00
Blake Blackshear 45a8b42157 exit on config errors 2020-12-05 08:48:46 -06:00
Blake Blackshear 8785be24b7 add zeroconf discovery 2020-12-05 08:48:46 -06:00
Blake Blackshear cc0812540c optional android notification aspect ratio 2020-12-05 08:48:46 -06:00
Blake Blackshear 5cf38ca4f7 reduce min timestamp size 2020-12-05 08:48:46 -06:00
Blake Blackshear 7e4395c30e publish object counts rather than on/off 2020-12-05 08:48:46 -06:00
Blake Blackshear 598d3aeda2 make directories constants 2020-12-05 08:48:46 -06:00
Blake Blackshear 012dbf81f7 cleanup empty directories 2020-12-05 08:48:46 -06:00
Blake Blackshear f869def12e serve up recordings with nginx 2020-12-05 08:48:46 -06:00
Blake Blackshear 31f7666337 add recording maintenance 2020-12-05 08:48:46 -06:00
Blake Blackshear 9e339acbca add record settings to config 2020-12-05 08:48:46 -06:00
Blake Blackshear 8f8054a299 fix log timeout 2020-12-05 08:48:46 -06:00
Blake Blackshear f7021eec4c ensure zones dont have the same name as a camera 2020-12-05 08:48:46 -06:00
Blake Blackshear c124153da4 graceful exit of subprocesses 2020-12-05 08:48:46 -06:00
Blake Blackshear 706c2f921e add multiple streams per camera 2020-12-05 08:48:46 -06:00
Blake Blackshear de1d66bcb9 fix fontconfig error 2020-12-05 08:48:46 -06:00
Blake Blackshear 4502ca8e80 add support for rebroadcasting as rtmp 2020-12-05 08:48:46 -06:00
Blake Blackshear 32a66fe5e8 avoid null error 2020-12-05 08:48:46 -06:00
Blake Blackshear e1251aafdb minimize logging 2020-12-05 08:48:46 -06:00
Blake Blackshear 587494068c oops 2020-12-05 08:48:46 -06:00
Blake Blackshear 7a4d90a47a only publish end events for true positives 2020-12-05 08:48:46 -06:00
Blake Blackshear d06b587d33 ensure all events are cleaned up 2020-12-05 08:48:46 -06:00
Blake Blackshear eef70e434b publish events like a change feed 2020-12-05 08:48:46 -06:00
Blake Blackshear b39da3ee01 pull from memory if event in progress 2020-12-05 08:48:46 -06:00
Blake Blackshear e07c4e0d8c add endpoint for event thumbnail 2020-12-05 08:48:46 -06:00
Blake Blackshear 2f41ba6f77 add service to get by id 2020-12-05 08:48:46 -06:00
Blake Blackshear bf95af0f22 add zones to summary data 2020-12-05 08:48:46 -06:00
Blake Blackshear 2e15847f86 sleep in the right place 2020-12-05 08:48:46 -06:00
Blake Blackshear 5992e85dc8 manage events for unlisted cameras 2020-12-05 08:48:46 -06:00
Blake Blackshear 24d416b869 add event cleanup thread 2020-12-05 08:48:46 -06:00
Blake Blackshear 5dbf368c4b add clip retention to config 2020-12-05 08:48:46 -06:00
Blake Blackshear 7d56fe105f use localtime in group by 2020-12-05 08:48:46 -06:00
Blake Blackshear e9327aa18c new http endpoints 2020-12-05 08:48:46 -06:00
Blake Blackshear df56e079de add parameters to event query 2020-12-05 08:48:46 -06:00
Blake Blackshear 8c5bfbd187 only save events when a clip is created 2020-12-05 08:48:46 -06:00
Blake Blackshear 2613e74f97 add bas64 encoded thumbnail to the database 2020-12-05 08:48:46 -06:00
Blake Blackshear 9a7fb96357 check for None value thumbnail_data 2020-12-05 08:48:46 -06:00
Blake Blackshear 37f9dfed92 only set thumbnail data if object is a true positive 2020-12-05 08:48:46 -06:00
Blake Blackshear 68c1544808 add some debug logging to frame cache 2020-12-05 08:48:46 -06:00
Blake Blackshear 2b3d3c5824 dont use a property 2020-12-05 08:48:46 -06:00
Blake Blackshear efea87a3ea attempt to fix missing thumbs 2020-12-05 08:48:46 -06:00
Blake Blackshear 977785fb10 better frame handling for best images 2020-12-05 08:48:46 -06:00
Blake Blackshear 4e113e62c0 cleanup false_positive attribute 2020-12-05 08:48:46 -06:00
Blake Blackshear 5080b2d781 ensure some valid thumbnail is available 2020-12-05 08:48:46 -06:00
Blake Blackshear 5cfd6d1edb don't save thumbnails for false positives 2020-12-05 08:48:46 -06:00
Blake Blackshear 27ae4d8ab0 cleanup 2020-12-05 08:48:46 -06:00
Blake Blackshear 3db33302ec reduce logging 2020-12-05 08:48:46 -06:00
Blake Blackshear f2910d48e0 fixes 2020-12-05 08:48:46 -06:00
Blake Blackshear cf0f8892e2 update nginx config 2020-12-05 08:48:46 -06:00
Blake Blackshear 4d22e172ff stop writing json file to disk 2020-12-05 08:48:46 -06:00
Blake Blackshear 8874a55b0f create tracked object class and save thumbnails 2020-12-05 08:48:46 -06:00
Blake Blackshear 24b703a875 maintain thumbnail frames for tracked objects 2020-12-05 08:48:46 -06:00
Blake Blackshear 8b8f5b5c40 sort imports 2020-12-05 08:48:46 -06:00
Blake Blackshear eac81136d2 naming threads and processes for logs 2020-12-05 08:48:46 -06:00
Blake Blackshear d1e27b43ea use a queue for logging 2020-12-05 08:48:46 -06:00
Blake Blackshear 105dcb7094 create typed config classes 2020-12-05 08:48:46 -06:00
Blake Blackshear c0a16efdc1 add nginx and change default file locations 2020-12-05 08:48:46 -06:00
Blake Blackshear 2800c54743 config setup 2020-12-05 08:48:46 -06:00
Blake Blackshear 2a24e8abcb add watchdog 2020-12-05 08:48:46 -06:00
Blake Blackshear 37ee746ebb add back all endpoints 2020-12-05 08:48:46 -06:00
Blake Blackshear 7ee6bfe855 add event processor 2020-12-05 08:48:46 -06:00
Blake Blackshear 40f57a8754 add capture processes 2020-12-05 08:48:46 -06:00
Blake Blackshear e0da462223 add camera processors 2020-12-05 08:48:46 -06:00
Blake Blackshear 47a9fc4292 add detected_frames_processor 2020-12-05 08:48:46 -06:00
Blake Blackshear 03fe5158db add detector processes 2020-12-05 08:48:46 -06:00
Blake Blackshear 72be6b480d init db/http/mqtt 2020-12-05 08:48:46 -06:00
Blake Blackshear a8964dcc1f app container and config schema 2020-12-05 08:48:46 -06:00
Blake Blackshear 732e91ee42 move primary script into the module 2020-12-05 08:48:46 -06:00
Blake Blackshear 27da080ce6 saving events and simple endpoint 2020-12-05 08:48:46 -06:00
Blake Blackshear 075d06b108 basic database model and api endpoint 2020-12-05 08:48:46 -06:00
Blake Blackshear 95dc17ffcd store events in tinydb 2020-12-05 08:48:46 -06:00
Blake Blackshear 408b53f8b4 update events model 2020-12-05 08:48:46 -06:00
Marc SeegerandBlake Blackshear 3ef68a297a Add support for AMD Ryzen iGPU (fixes #311)
This package will add support for the iGPU of AMD Ryzen and presumably a few more AMD cards.
See details of the package here: https://packages.ubuntu.com/focal/mesa-va-drivers
It also adds support for the open source Nvidia Nouveau driver according to https://wiki.debian.org/HardwareVideoAcceleration
2020-12-05 07:00:07 -06:00
Michael WeiandBlake Blackshear 3e9b3711dc Use cv2.bitwise_and instead of numpy.where 2020-12-05 06:59:28 -06:00
6 changed files with 88 additions and 163 deletions
+2 -1
View File
@@ -26,7 +26,7 @@ export default function App() {
<Config.Provider value={config}>
<div className="md:flex flex-col md:flex-row md:min-h-screen w-full bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white">
<Sidebar />
<div className="flex-auto p-4 lg:pl-8 lg:pr-8 min-w-0">
<div className="p-4 min-w-0">
<Router>
<CameraMap path="/cameras/:camera/editor" />
<Camera path="/cameras/:camera" />
@@ -39,4 +39,5 @@ export default function App() {
</div>
</Config.Provider>
);
return;
}
+8 -37
View File
@@ -1,6 +1,7 @@
import { h } from 'preact';
import Box from './components/Box';
import Button from './components/Button';
import CameraImage from './components/CameraImage';
import Heading from './components/Heading';
import Switch from './components/Switch';
import { route } from 'preact-router';
@@ -189,7 +190,7 @@ ${Object.keys(zonePoints)
const handleAddObjectMask = useCallback(() => {
const n = Object.keys(objectMaskPoints).filter((name) => name.startsWith('object_')).length;
const newObjectName = `object_${n}`;
const newObjectMaskPoints = { ...objectMaskPoints, [newObjectName]: [[]] };
const newObjectMaskPoints = { ...objectMaskPoints, [newObjectName]: [] };
setObjectMaskPoints(newObjectMaskPoints);
setEditing({ set: newObjectMaskPoints, key: newObjectName, subkey: 0, fn: setObjectMaskPoints });
}, [objectMaskPoints, setObjectMaskPoints, setEditing]);
@@ -197,7 +198,7 @@ ${Object.keys(zonePoints)
const handleRemoveObjectMask = useCallback(
(key, subkey) => {
const newObjectMaskPoints = { ...objectMaskPoints };
delete newObjectMaskPoints[key][subkey];
delete newObjectMaskPoints[key];
setObjectMaskPoints(newObjectMaskPoints);
},
[objectMaskPoints, setObjectMaskPoints]
@@ -217,20 +218,6 @@ ${Object.keys(objectMaskPoints)
.join('\n')}`);
}, [objectMaskPoints]);
const handleAddToObjectMask = useCallback(
(key) => {
const newObjectMaskPoints = { ...objectMaskPoints, [key]: [...objectMaskPoints[key], []] };
setObjectMaskPoints(newObjectMaskPoints);
setEditing({
set: newObjectMaskPoints,
key,
subkey: newObjectMaskPoints[key].length - 1,
fn: setObjectMaskPoints,
});
},
[objectMaskPoints, setObjectMaskPoints, setEditing]
);
const handleChangeSnap = useCallback(
(id, value) => {
setSnap(value);
@@ -252,10 +239,10 @@ ${Object.keys(objectMaskPoints)
<Box className="space-y-4">
<div className="relative">
<img ref={imageRef} src={`${apiHost}/api/${camera}/latest.jpg`} />
<CameraImage imageRef={imageRef} camera={camera} />
<EditableMask
onChange={handleUpdateEditable}
points={'subkey' in editing ? editing.set[editing.key][editing.subkey] : editing.set[editing.key]}
points={editing.subkey ? editing.set[editing.key][editing.subkey] : editing.set[editing.key]}
scale={imageScale}
snap={snap}
width={width}
@@ -294,7 +281,6 @@ ${Object.keys(objectMaskPoints)
isMulti
editing={editing}
title="Object masks"
onAdd={handleAddToObjectMask}
onCopy={handleCopyObjectMasks}
onCreate={handleAddObjectMask}
onEdit={handleEditObjectMask}
@@ -424,7 +410,6 @@ function MaskValues({
isMulti = false,
editing,
title,
onAdd,
onCopy,
onCreate,
onEdit,
@@ -466,14 +451,6 @@ function MaskValues({
[onRemove]
);
const handleAdd = useCallback(
(event) => {
const { key } = event.target.dataset;
onAdd(key);
},
[onAdd]
);
return (
<Box className="overflow-hidden" onmouseover={handleMousein} onmouseout={handleMouseout}>
<div class="flex space-x-4">
@@ -490,20 +467,15 @@ function MaskValues({
return (
<div>
{` ${mainkey}:\n mask:\n`}
{onAdd && showButtons ? (
<Button className="absolute -mt-12 right-0 font-sans" data-key={mainkey} onClick={handleAdd}>
{`Add to ${mainkey}`}
</Button>
) : null}
{points[mainkey].map((item, subkey) => (
<Item
mainkey={mainkey}
subkey={subkey}
editing={editing}
handleEdit={handleEdit}
handleRemove={handleRemove}
points={item}
showButtons={showButtons}
handleRemove={handleRemove}
yamlKeyPrefix={yamlKeyPrefix}
/>
))}
@@ -514,11 +486,10 @@ function MaskValues({
<Item
mainkey={mainkey}
editing={editing}
handleAdd={onAdd ? handleAdd : undefined}
handleEdit={handleEdit}
handleRemove={handleRemove}
points={points[mainkey]}
showButtons={showButtons}
handleRemove={handleRemove}
yamlKeyPrefix={yamlKeyPrefix}
/>
);
@@ -529,7 +500,7 @@ function MaskValues({
);
}
function Item({ mainkey, subkey, editing, handleEdit, points, showButtons, handleAdd, handleRemove, yamlKeyPrefix }) {
function Item({ mainkey, subkey, editing, handleEdit, points, showButtons, handleRemove, yamlKeyPrefix }) {
return (
<span
data-key={mainkey}
+41 -57
View File
@@ -1,6 +1,4 @@
import { h } from 'preact';
import Box from './components/Box';
import Button from './components/Button';
import Heading from './components/Heading';
import Link from './components/Link';
import { ApiHost, Config } from './context';
@@ -41,73 +39,59 @@ export default function Debug() {
const cameraNames = Object.keys(cameras);
const cameraDataKeys = Object.keys(cameras[cameraNames[0]]);
const handleCopyConfig = useCallback(async () => {
await window.navigator.clipboard.writeText(JSON.stringify(config, null, 2));
}, [config]);
return (
<div class="space-y-4">
<div>
<Heading>
Debug <span className="text-sm">{service.version}</span>
</Heading>
<Box>
<Table className="w-full">
<Thead>
<Tr>
<Th>detector</Th>
<Table className="w-full">
<Thead>
<Tr>
<Th>detector</Th>
{detectorDataKeys.map((name) => (
<Th>{name.replace('_', ' ')}</Th>
))}
</Tr>
</Thead>
<Tbody>
{detectorNames.map((detector, i) => (
<Tr index={i}>
<Td>{detector}</Td>
{detectorDataKeys.map((name) => (
<Th>{name.replace('_', ' ')}</Th>
<Td key={`${name}-${detector}`}>{detectors[detector][name]}</Td>
))}
</Tr>
</Thead>
<Tbody>
{detectorNames.map((detector, i) => (
<Tr index={i}>
<Td>{detector}</Td>
{detectorDataKeys.map((name) => (
<Td key={`${name}-${detector}`}>{detectors[detector][name]}</Td>
))}
</Tr>
))}
</Tbody>
</Table>
</Box>
))}
</Tbody>
</Table>
<Box>
<Table className="w-full">
<Thead>
<Tr>
<Th>camera</Th>
<Table className="w-full">
<Thead>
<Tr>
<Th>camera</Th>
{cameraDataKeys.map((name) => (
<Th>{name.replace('_', ' ')}</Th>
))}
</Tr>
</Thead>
<Tbody>
{cameraNames.map((camera, i) => (
<Tr index={i}>
<Td>
<Link href={`/cameras/${camera}`}>{camera}</Link>
</Td>
{cameraDataKeys.map((name) => (
<Th>{name.replace('_', ' ')}</Th>
<Td key={`${name}-${camera}`}>{cameras[camera][name]}</Td>
))}
</Tr>
</Thead>
<Tbody>
{cameraNames.map((camera, i) => (
<Tr index={i}>
<Td>
<Link href={`/cameras/${camera}`}>{camera}</Link>
</Td>
{cameraDataKeys.map((name) => (
<Td key={`${name}-${camera}`}>{cameras[camera][name]}</Td>
))}
</Tr>
))}
</Tbody>
</Table>
</Box>
))}
</Tbody>
</Table>
<Box className="relative">
<Heading size="sm">Config</Heading>
<Button className="absolute top-4 right-8" onClick={handleCopyConfig}>
Copy to Clipboard
</Button>
<pre className="overflow-auto font-mono text-gray-900 dark:text-gray-100 rounded bg-gray-100 dark:bg-gray-800 p-2 max-h-96">
{JSON.stringify(config, null, 2)}
</pre>
</Box>
<Heading size="sm">Config</Heading>
<pre className="font-mono overflow-y-scroll overflow-x-scroll max-h-96 rounded bg-white dark:bg-gray-900">
{JSON.stringify(config, null, 2)}
</pre>
</div>
);
}
+2 -2
View File
@@ -23,7 +23,7 @@ export default function Events({ url } = {}) {
const searchKeys = Array.from(searchParams.keys());
return (
<div className="space-y-4 w-full">
<div className="space-y-4">
<Heading>Events</Heading>
{searchKeys.length ? (
@@ -43,7 +43,7 @@ export default function Events({ url } = {}) {
) : null}
<Box className="min-w-0 overflow-auto">
<Table className="w-full">
<Table>
<Thead>
<Tr>
<Th></Th>
+12 -21
View File
@@ -1,29 +1,20 @@
import { h } from 'preact';
import CameraImage from './CameraImage';
import { ApiHost, Config } from '../context';
import { useCallback, useState } from 'preact/hooks';
import { useCallback, useEffect, useContext, useState } from 'preact/hooks';
const MIN_LOAD_TIMEOUT_MS = 200;
export default function AutoUpdatingCameraImage({ camera, searchParams }) {
const apiHost = useContext(ApiHost);
export default function AutoUpdatingCameraImage({ camera, searchParams, showFps = true }) {
const [key, setKey] = useState(Date.now());
const [fps, setFps] = useState(0);
useEffect(() => {
const timeoutId = setTimeout(() => {
setKey(Date.now());
}, 500);
return () => {
clearTimeout(timeoutId);
};
}, [key, searchParams]);
const handleLoad = useCallback(() => {
const loadTime = Date.now() - key;
setFps((1000 / Math.max(loadTime, MIN_LOAD_TIMEOUT_MS)).toFixed(1));
setTimeout(
() => {
setKey(Date.now());
},
loadTime > MIN_LOAD_TIMEOUT_MS ? 1 : MIN_LOAD_TIMEOUT_MS
);
}, [key, searchParams, setFps]);
return (
<div>
<CameraImage camera={camera} onload={handleLoad} searchParams={`cache=${key}&${searchParams}`} />
{showFps ? <span className="text-xs">Displaying at {fps}fps</span> : null}
</div>
);
return <CameraImage camera={camera} searchParams={`cache=${key}&${searchParams}`} />;
}
+23 -45
View File
@@ -1,60 +1,38 @@
import { h } from 'preact';
import { ApiHost, Config } from '../context';
import { useCallback, useEffect, useContext, useMemo, useRef, useState } from 'preact/hooks';
import { useCallback, useEffect, useContext, useState } from 'preact/hooks';
export default function CameraImage({ camera, onload, searchParams = '' }) {
export default function CameraImage({ camera, searchParams = '', imageRef }) {
const config = useContext(Config);
const apiHost = useContext(ApiHost);
const [availableWidth, setAvailableWidth] = useState(0);
const [loadedSrc, setLoadedSrc] = useState(null);
const containerRef = useRef(null);
const { name, width, height } = config.cameras[camera];
const aspectRatio = width / height;
const innerWidth = parseInt(window.innerWidth, 10);
const resizeObserver = useMemo(() => {
return new ResizeObserver((entries) => {
window.requestAnimationFrame(() => {
if (Array.isArray(entries) && entries.length) {
setAvailableWidth(entries[0].contentRect.width);
}
});
});
}, [setAvailableWidth, width]);
const responsiveWidths = [640, 768, 1024, 1280];
if (innerWidth > responsiveWidths[responsiveWidths.length - 1]) {
responsiveWidths.push(innerWidth);
}
useEffect(() => {
if (!containerRef.current) {
return;
}
resizeObserver.observe(containerRef.current);
}, [resizeObserver, containerRef.current]);
const scaledHeight = useMemo(() => Math.min(Math.ceil(availableWidth / aspectRatio), height), [
availableWidth,
aspectRatio,
height,
]);
const img = useMemo(() => new Image(), [camera]);
img.onload = useCallback(
(event) => {
const src = event.path[0].currentSrc;
setLoadedSrc(src);
onload && onload(event);
const src = `${apiHost}/api/${camera}/latest.jpg`;
const { srcset, sizes } = responsiveWidths.reduce(
(memo, w, i) => {
memo.srcset.push(`${src}?h=${Math.ceil(w / aspectRatio)}&${searchParams} ${w}w`);
memo.sizes.push(`(max-width: ${w}) ${Math.ceil((w / innerWidth) * 100)}vw`);
return memo;
},
[searchParams, onload]
{ srcset: [], sizes: [] }
);
useEffect(() => {
if (!scaledHeight) {
return;
}
img.src = `${apiHost}/api/${name}/latest.jpg?h=${scaledHeight}${searchParams ? `&${searchParams}` : ''}`;
}, [apiHost, name, img, searchParams, scaledHeight]);
return (
<div ref={containerRef}>
{loadedSrc ? <img width={scaledHeight * aspectRatio} height={scaledHeight} src={loadedSrc} alt={name} /> : null}
</div>
<img
className="w-full"
srcset={srcset.join(', ')}
sizes={sizes.join(', ')}
src={`${srcset[srcset.length - 1]}`}
alt={name}
ref={imageRef}
/>
);
}