Compare commits
992 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3846a13805 | ||
|
|
7c60753ab0 | ||
|
|
df40b96b44 | ||
|
|
faf583451f | ||
|
|
be7b858cbd | ||
|
|
a6a0e4d1de | ||
|
|
14faf0b2f6 | ||
|
|
bdfe4a961a | ||
|
|
1bc8d94312 | ||
|
|
7e9f913ff6 | ||
|
|
0882e4a454 | ||
|
|
699bd3748a | ||
|
|
2ca59f0abe | ||
|
|
64b1b8e15c | ||
|
|
b6f799e641 | ||
|
|
c461c9e700 | ||
|
|
9df415b3f2 | ||
|
|
f7c5e02a35 | ||
|
|
656e6a2a89 | ||
|
|
afefa3ec02 | ||
|
|
8c45dab9b8 | ||
|
|
0d6dd1ed0f | ||
|
|
911d6fdfa7 | ||
|
|
0cf759acad | ||
|
|
7c57c8c2da | ||
|
|
89c04acdff | ||
|
|
05d5f13f0e | ||
|
|
4682af81fb | ||
|
|
e649a1eb98 | ||
|
|
01482d791b | ||
|
|
6e2e297aeb | ||
|
|
5577ef081f | ||
|
|
2d5d3bdaf4 | ||
|
|
3376e85be6 | ||
|
|
7a1215d581 | ||
|
|
a94297ac93 | ||
|
|
37325c70ba | ||
|
|
3c46a33992 | ||
|
|
ed1897db71 | ||
|
|
dfbebb63ff | ||
|
|
e68f80b44a | ||
|
|
a67a768e89 | ||
|
|
43f05c18d6 | ||
|
|
3b076c28c2 | ||
|
|
cbf12e3f90 | ||
|
|
17b745434c | ||
|
|
37011c2fda | ||
|
|
fa95a041dd | ||
|
|
0879d7a2d1 | ||
|
|
653c2274e1 | ||
|
|
061fb15a80 | ||
|
|
3246fcce22 | ||
|
|
f2a3797b46 | ||
|
|
b80080ac52 | ||
|
|
b36b63599b | ||
|
|
5d8c0e43c2 | ||
|
|
7845995dfd | ||
|
|
afe88d6e3a | ||
|
|
560ee0104d | ||
|
|
dc8b625d55 | ||
|
|
162c0147d2 | ||
|
|
ef54cd6fb3 | ||
|
|
c2465a46a8 | ||
|
|
24d3a9cdd5 | ||
|
|
5e82eaed88 | ||
|
|
1d45b0b351 | ||
|
|
ba119e4f96 | ||
|
|
75c2feb387 | ||
|
|
da637d3c8f | ||
|
|
bc078fcc88 | ||
|
|
93cd973e59 | ||
|
|
5f9d477863 | ||
|
|
ca693240b1 | ||
|
|
468febc434 | ||
|
|
4b81c88794 | ||
|
|
2ac28b93f3 | ||
|
|
3e7ed982d4 | ||
|
|
d8d410802f | ||
|
|
ca7bad8909 | ||
|
|
7b2b5bfa71 | ||
|
|
d2c3cdcf04 | ||
|
|
7c8142174e | ||
|
|
efe3f96223 | ||
|
|
de244d6873 | ||
|
|
53bf3cd2e6 | ||
|
|
f59871a189 | ||
|
|
2dda7608bb | ||
|
|
10db9faff9 | ||
|
|
90bff605fa | ||
|
|
f512df44c1 | ||
|
|
4e8ce28948 | ||
|
|
16057cdef7 | ||
|
|
da36f25fd0 | ||
|
|
0e9c8a4ddd | ||
|
|
ccc9b90625 | ||
|
|
d992a959f2 | ||
|
|
358d0521a1 | ||
|
|
691ed6a4c7 | ||
|
|
78e1782084 | ||
|
|
0d5ae9a399 | ||
|
|
d343a658ec | ||
|
|
0bd3cff13b | ||
|
|
5b71271b3c | ||
|
|
0a4d658c7f | ||
|
|
b75929a846 | ||
|
|
e33cd442cd | ||
|
|
91539de3ff | ||
|
|
bc0206de9d | ||
|
|
f536494a38 | ||
|
|
f2030d301f | ||
|
|
d890217447 | ||
|
|
cafe0917c7 | ||
|
|
ebf4e43ced | ||
|
|
a1afade9ba | ||
|
|
b86b2d6602 | ||
|
|
12abbc59d6 | ||
|
|
ec91466fe4 | ||
|
|
0044f73d7a | ||
|
|
65e0ec7826 | ||
|
|
a5016afdd4 | ||
|
|
6808ba1b3b | ||
|
|
41f58c7692 | ||
|
|
c6234bf548 | ||
|
|
d995761419 | ||
|
|
d749cf2e6b | ||
|
|
164e9b7eb8 | ||
|
|
d43f9189a6 | ||
|
|
a292f272e9 | ||
|
|
58c32857d3 | ||
|
|
35bd1de5ba | ||
|
|
51fd18f56d | ||
|
|
162e275ef3 | ||
|
|
44a2b54773 | ||
|
|
d17828931b | ||
|
|
cef77fba01 | ||
|
|
e724fe3da6 | ||
|
|
045aac8933 | ||
|
|
2e5d082ef3 | ||
|
|
923d07b1a4 | ||
|
|
c424c4b7ef | ||
|
|
b1cc64d4fa | ||
|
|
0abd0627df | ||
|
|
dccfc3b84f | ||
|
|
deb3536cb2 | ||
|
|
1d8f1b24a9 | ||
|
|
7cabf8e5f5 | ||
|
|
ffee9c8065 | ||
|
|
00112eb7bc | ||
|
|
9bbe75d64e | ||
|
|
95fe62e141 | ||
|
|
1c9ba11e07 | ||
|
|
4bae3993da | ||
|
|
d03865d1a5 | ||
|
|
83481afee1 | ||
|
|
b1a2b0cda2 | ||
|
|
0dfba6e8d9 | ||
|
|
e4afe50509 | ||
|
|
006569391f | ||
|
|
f4c3bb0617 | ||
|
|
3e07d4eddb | ||
|
|
4004048add | ||
|
|
cbf26e09a4 | ||
|
|
20b4b503f0 | ||
|
|
08f573aaa5 | ||
|
|
3dd3786055 | ||
|
|
bfecee9650 | ||
|
|
395c16300d | ||
|
|
ff19cdb773 | ||
|
|
5627b66a6e | ||
|
|
ebdfbfe96c | ||
|
|
1a009c7fd1 | ||
|
|
c14f986fae | ||
|
|
ee5b9986ad | ||
|
|
190f217b13 | ||
|
|
e78662b924 | ||
|
|
5a2e395352 | ||
|
|
8de15af7b4 | ||
|
|
21178613de | ||
|
|
340be7f86d | ||
|
|
0ff4acd59c | ||
|
|
28dd43f8ae | ||
|
|
56d24cbf6d | ||
|
|
e433bec17f | ||
|
|
3189467a36 | ||
|
|
63536d249f | ||
|
|
3e90f3032c | ||
|
|
5cff849e59 | ||
|
|
06cc7527a9 | ||
|
|
d78dc2388c | ||
|
|
583912db9c | ||
|
|
5792cf042e | ||
|
|
4524dca3ed | ||
|
|
304a569c7e | ||
|
|
10c200dc24 | ||
|
|
0b8617d09f | ||
|
|
e7026dfd6e | ||
|
|
b82d75b79e | ||
|
|
ac30091258 | ||
|
|
de58bdcc9f | ||
|
|
329e5f8f91 | ||
|
|
4a16171f96 | ||
|
|
f0212c2aa4 | ||
|
|
7401cf2399 | ||
|
|
493d16519a | ||
|
|
a87675d3cc | ||
|
|
0bef16bb17 | ||
|
|
e0078f388e | ||
|
|
cf6e66c453 | ||
|
|
34fa53afcc | ||
|
|
663bf05fd7 | ||
|
|
f512af2563 | ||
|
|
7e7d70aa5b | ||
|
|
dd1cf4d2ce | ||
|
|
e627f4e935 | ||
|
|
c6445898ce | ||
|
|
f1ddd0e6f7 | ||
|
|
db369a5b7f | ||
|
|
87cd618998 | ||
|
|
338e4004d4 | ||
|
|
675f21e23a | ||
|
|
4d2d11193f | ||
|
|
69aaf1f8e6 | ||
|
|
a10970d7c9 | ||
|
|
6eecb6780e | ||
|
|
80627e4989 | ||
|
|
9e987fdebc | ||
|
|
e6292c719d | ||
|
|
7c74bf2566 | ||
|
|
2c91e7853c | ||
|
|
1e7f196e5c | ||
|
|
f91f4f0053 | ||
|
|
8b2622a234 | ||
|
|
a2ddb12eb3 | ||
|
|
985bd6d9bd | ||
|
|
ec3c15e4a7 | ||
|
|
188b202836 | ||
|
|
01e607a14e | ||
|
|
5b164b72dc | ||
|
|
dcf65febba | ||
|
|
56a2d4e64d | ||
|
|
ef214fb80a | ||
|
|
93f418ac0b | ||
|
|
689af4ff87 | ||
|
|
4ab0927de8 | ||
|
|
014e6fc909 | ||
|
|
6832575643 | ||
|
|
07ad2d97b1 | ||
|
|
039f1a522e | ||
|
|
24e2f84231 | ||
|
|
e0c0033852 | ||
|
|
c50e9d48bf | ||
|
|
173eaabddf | ||
|
|
a748b70da1 | ||
|
|
8eabe5dd41 | ||
|
|
114415b5e1 | ||
|
|
ba55b5a6db | ||
|
|
7533f2a8ab | ||
|
|
543a8a1712 | ||
|
|
9b23ff597c | ||
|
|
b2ce1edd5a | ||
|
|
a0235b7da4 | ||
|
|
87e2300855 | ||
|
|
34bc6a6457 | ||
|
|
273076e7f4 | ||
|
|
b29b311e92 | ||
|
|
5a9e82c4b0 | ||
|
|
6218791708 | ||
|
|
0e43f452d2 | ||
|
|
0695bb097d | ||
|
|
294c79a271 | ||
|
|
e351e132f5 | ||
|
|
258215a3ae | ||
|
|
08ddfc100f | ||
|
|
8ab6cba521 | ||
|
|
eb16de7395 | ||
|
|
dde0498ed3 | ||
|
|
75c8570913 | ||
|
|
e36099a342 | ||
|
|
2f2329ba44 | ||
|
|
6c8b184d2c | ||
|
|
32878bd016 | ||
|
|
12d13988c4 | ||
|
|
9e4d921488 | ||
|
|
edc1884c4e | ||
|
|
a2d1bd2c67 | ||
|
|
bb68a2405b | ||
|
|
42ac4172ff | ||
|
|
998921ae63 | ||
|
|
26ae6084ea | ||
|
|
76142e9699 | ||
|
|
5e692acfbb | ||
|
|
a67b8ab84d | ||
|
|
4cf55ad8e2 | ||
|
|
c1132e6897 | ||
|
|
d6104f2eb2 | ||
|
|
b0e0abe385 | ||
|
|
4916e1cd1d | ||
|
|
cd87f3e6f4 | ||
|
|
18f4ab2644 | ||
|
|
0bd3be94ec | ||
|
|
25bb515afc | ||
|
|
7ab6961ee1 | ||
|
|
ae24cf3bb2 | ||
|
|
2e494477a6 | ||
|
|
80b72c75d9 | ||
|
|
9494bb7f5f | ||
|
|
86a741b6e6 | ||
|
|
f738275d21 | ||
|
|
e297e02800 | ||
|
|
b2e05afff2 | ||
|
|
05fc35fc3d | ||
|
|
c809494c98 | ||
|
|
ef82c5c691 | ||
|
|
c0e2a75715 | ||
|
|
01ddd00bc5 | ||
|
|
d150f01a2c | ||
|
|
f9e159deaf | ||
|
|
381b00157e | ||
|
|
800f33e7be | ||
|
|
b8218876be | ||
|
|
5669f4c161 | ||
|
|
c492b30adb | ||
|
|
eb48722126 | ||
|
|
8e881b60f0 | ||
|
|
0260d824a6 | ||
|
|
0877a7dec7 | ||
|
|
4c7919ad69 | ||
|
|
4e997124b3 | ||
|
|
8b040f5c95 | ||
|
|
96156805ed | ||
|
|
b8d48d7e62 | ||
|
|
8ca12806ca | ||
|
|
de811b7018 | ||
|
|
7bf7365f6c | ||
|
|
1daffd92fd | ||
|
|
74986982a0 | ||
|
|
aa807d25ed | ||
|
|
cd28869649 | ||
|
|
ae97692883 | ||
|
|
e8e778c6d4 | ||
|
|
5c552a0d71 | ||
|
|
0f5dfea9de | ||
|
|
e6cdb6a7a2 | ||
|
|
1d25936f31 | ||
|
|
1049673413 | ||
|
|
c3109f808c | ||
|
|
a943ac1308 | ||
|
|
96319e795c | ||
|
|
5a8016de87 | ||
|
|
bc350644bd | ||
|
|
c793500ad2 | ||
|
|
1b2134c49e | ||
|
|
86a5b46c68 | ||
|
|
f83d4a58dd | ||
|
|
a5f241d5bd | ||
|
|
661f7baa21 | ||
|
|
7b063a19dc | ||
|
|
0320d94ea6 | ||
|
|
a7b7a45b23 | ||
|
|
89e317a6bb | ||
|
|
5a209caed3 | ||
|
|
288b1a0562 | ||
|
|
d35b09b18f | ||
|
|
e8eb3125a5 | ||
|
|
8109445fdd | ||
|
|
f63a7cb6c0 | ||
|
|
7fc5297f60 | ||
|
|
00ff76a0b9 | ||
|
|
b8df419bad | ||
|
|
faf103152a | ||
|
|
65855e23d9 | ||
|
|
6c28613def | ||
|
|
56480dc1ef | ||
|
|
8e1c15291d | ||
|
|
a1e52c51b1 | ||
|
|
8cc834633e | ||
|
|
7d65c05994 | ||
|
|
d74021af47 | ||
|
|
46fe06e779 | ||
|
|
fbea51372f | ||
|
|
fa5ec8d019 | ||
|
|
11c425a7eb | ||
|
|
0d352f3d8a | ||
|
|
6ccff71408 | ||
|
|
41fea2a531 | ||
|
|
3d6dad7e7e | ||
|
|
4efc584816 | ||
|
|
10ab70080a | ||
|
|
bddde74c06 | ||
|
|
29de723267 | ||
|
|
354a9240f0 | ||
|
|
5ae4f47e96 | ||
|
|
26424488a5 | ||
|
|
334095252c | ||
|
|
1c85f774eb | ||
|
|
bbf0fc8324 | ||
|
|
b143e11e0e | ||
|
|
927f56ab9f | ||
|
|
2181379475 | ||
|
|
45798d6d14 | ||
|
|
f6d5e96dbf | ||
|
|
e18aa56427 | ||
|
|
f3a1c1de0a | ||
|
|
0ccf543ec1 | ||
|
|
1f1a708388 | ||
|
|
58c0d97b5f | ||
|
|
abef002af8 | ||
|
|
adf2bc078c | ||
|
|
b33f4e2dc6 | ||
|
|
9cab5da74c | ||
|
|
189b9c6648 | ||
|
|
1823bd0305 | ||
|
|
8fd12f001b | ||
|
|
fc40567794 | ||
|
|
de121008c1 | ||
|
|
2fbfbf614b | ||
|
|
1181620f33 | ||
|
|
c527b1ca5d | ||
|
|
181a504a14 | ||
|
|
5d940bcb86 | ||
|
|
dcfe26c9c0 | ||
|
|
5d94c68d66 | ||
|
|
a476bc9885 | ||
|
|
dc759a3e56 | ||
|
|
4818c08fe2 | ||
|
|
3bc75ae931 | ||
|
|
a94b61ef91 | ||
|
|
e51021c573 | ||
|
|
19115fb828 | ||
|
|
16ef432228 | ||
|
|
4449bc5292 | ||
|
|
50f0c05e69 | ||
|
|
6b26fc753e | ||
|
|
ebee204ca0 | ||
|
|
1a3567c5d0 | ||
|
|
4fa6fa2001 | ||
|
|
92aa16c556 | ||
|
|
a3853af47a | ||
|
|
f26f7b8d3f | ||
|
|
f4aa02cc19 | ||
|
|
da2492413f | ||
|
|
3876b00088 | ||
|
|
b1dfee2cf5 | ||
|
|
13c2c582ad | ||
|
|
f892a821f5 | ||
|
|
bb3ba2d572 | ||
|
|
9ee2e776fa | ||
|
|
fd61ca20b0 | ||
|
|
f9add57ed4 | ||
|
|
e1b341788d | ||
|
|
04c8b089a5 | ||
|
|
9971482506 | ||
|
|
955d9e6ec2 | ||
|
|
fe2e32c84f | ||
|
|
c6e53d0ea8 | ||
|
|
436b10a87b | ||
|
|
a2d5754e4b | ||
|
|
3d28d8cee2 | ||
|
|
11d8095cdd | ||
|
|
a4052a9fe5 | ||
|
|
6e6ee93282 | ||
|
|
85de881181 | ||
|
|
3712a8ab80 | ||
|
|
4ee7240ef3 | ||
|
|
df8126de73 | ||
|
|
2eddbe3d03 | ||
|
|
46dad7b58d | ||
|
|
eb5e6d19fa | ||
|
|
5afeb6e081 | ||
|
|
17944882f4 | ||
|
|
b24bb3eb18 | ||
|
|
98d8118fb2 | ||
|
|
3e1b680e4c | ||
|
|
b4e7e51e63 | ||
|
|
2a41a9d3ff | ||
|
|
09b0068d16 | ||
|
|
f9457be109 | ||
|
|
e9291fe9d1 | ||
|
|
20912c12e7 | ||
|
|
7ddba4fc59 | ||
|
|
7ad8b8298d | ||
|
|
3fb24b4bf5 | ||
|
|
ab93cae4c0 | ||
|
|
8d01cc4807 | ||
|
|
1e21a62851 | ||
|
|
c664bd63f6 | ||
|
|
dada764d2c | ||
|
|
762afb8f43 | ||
|
|
f009897eca | ||
|
|
fa61e9da29 | ||
|
|
0ff037997f | ||
|
|
e8c2cfa5b5 | ||
|
|
fb214b64ca | ||
|
|
222dc2f7c9 | ||
|
|
f94a946418 | ||
|
|
b3ee2de079 | ||
|
|
515d8c04ad | ||
|
|
49c65cf9c6 | ||
|
|
211fcd64c7 | ||
|
|
5075e4eee1 | ||
|
|
7bfe8e4f5b | ||
|
|
8e0c2b256e | ||
|
|
d66f5f6bad | ||
|
|
fd9c8c1f0d | ||
|
|
3a3b788c65 | ||
|
|
b134db48b3 | ||
|
|
f110a261b9 | ||
|
|
b72b66781a | ||
|
|
9b3a649f17 | ||
|
|
d83ffd8984 | ||
|
|
175c85d69a | ||
|
|
3aa7f753b3 | ||
|
|
861ee0485d | ||
|
|
03e756dd27 | ||
|
|
5d0984998d | ||
|
|
3b695040d1 | ||
|
|
40bf7a0f41 | ||
|
|
cbdf2c2c71 | ||
|
|
bbe3f07ec6 | ||
|
|
35281c037c | ||
|
|
e0eb247028 | ||
|
|
a7ecc2af4b | ||
|
|
f2d1f7b00f | ||
|
|
89c2ae2208 | ||
|
|
0df35379ef | ||
|
|
138fa45820 | ||
|
|
58cfb8bba4 | ||
|
|
ed761d1767 | ||
|
|
babe1dd1eb | ||
|
|
cbd418b8de | ||
|
|
9c5b0d4138 | ||
|
|
94c21a6363 | ||
|
|
d1a5e2e8e0 | ||
|
|
17179abf5a | ||
|
|
61f717daa3 | ||
|
|
c70419bd0b | ||
|
|
4eed27e178 | ||
|
|
8e2ba4a8ea | ||
|
|
700f25abc3 | ||
|
|
4596ada801 | ||
|
|
a8df97dc1a | ||
|
|
4e0203ca68 | ||
|
|
8413e10091 | ||
|
|
7aaf5bd29f | ||
|
|
5afda72b84 | ||
|
|
7a6ffb1032 | ||
|
|
fd51c7a955 | ||
|
|
b91b0d39dd | ||
|
|
7fc9026ca6 | ||
|
|
f4a0ec43a6 | ||
|
|
46e5a042ae | ||
|
|
7309c06be8 | ||
|
|
c71b717a54 | ||
|
|
da8e54ed51 | ||
|
|
b70c11e7a7 | ||
|
|
e8c342e162 | ||
|
|
f7975cbbc4 | ||
|
|
098e293c82 | ||
|
|
eb3f50c9f0 | ||
|
|
78a0b5e6c9 | ||
|
|
055bd22138 | ||
|
|
8dfff83447 | ||
|
|
de3a19c4f0 | ||
|
|
2a33c05378 | ||
|
|
bbb4d10718 | ||
|
|
68dfaaf767 | ||
|
|
0bb998c465 | ||
|
|
ec9b525a3c | ||
|
|
88ed7501a7 | ||
|
|
c73aebadcb | ||
|
|
40c4ca305e | ||
|
|
7b3abe330e | ||
|
|
0d96c3529d | ||
|
|
62452b1d21 | ||
|
|
c5f005afef | ||
|
|
4a45b6e76d | ||
|
|
a3cfbb6722 | ||
|
|
dc8ba5239d | ||
|
|
b53a50cd54 | ||
|
|
9822d614e2 | ||
|
|
ca20c735f7 | ||
|
|
d3dc018260 | ||
|
|
28a2a3816a | ||
|
|
5461308d30 | ||
|
|
b2f469ad76 | ||
|
|
8ea75e6748 | ||
|
|
09a4d6d030 | ||
|
|
abbc608ee4 | ||
|
|
9634ec8e31 | ||
|
|
84a0827aee | ||
|
|
1fbcf4d9b9 | ||
|
|
80f8256422 | ||
|
|
57864f2be6 | ||
|
|
f4bc68d396 | ||
|
|
926eec3c65 | ||
|
|
abc6bbe7e0 | ||
|
|
acdfd1ccc4 | ||
|
|
315a13e1ce | ||
|
|
aab6a00e4c | ||
|
|
a4e6d9ed9a | ||
|
|
e16dbcb671 | ||
|
|
e89697fab0 | ||
|
|
c52782aa3f | ||
|
|
7060f22024 | ||
|
|
d1931f249c | ||
|
|
bf1a542afb | ||
|
|
ebb6d348a3 | ||
|
|
f667bd9066 | ||
|
|
ff2eba5b9f | ||
|
|
3eb0021207 | ||
|
|
6379f5cd5e | ||
|
|
e3a8448a23 | ||
|
|
00d6036788 | ||
|
|
53bb69621c | ||
|
|
ad85beea91 | ||
|
|
d7a237677a | ||
|
|
16effa3938 | ||
|
|
33a04c425b | ||
|
|
20a52bc4e6 | ||
|
|
482399d82f | ||
|
|
3a171d19e3 | ||
|
|
480970c799 | ||
|
|
ceb3329f9e | ||
|
|
1c0162c181 | ||
|
|
cf62dccef7 | ||
|
|
42410a260c | ||
|
|
00c6a8f577 | ||
|
|
9d2469549f | ||
|
|
d2bc2c20c1 | ||
|
|
10c37a3036 | ||
|
|
00d14fa49f | ||
|
|
0f1bc40f00 | ||
|
|
4252857e19 | ||
|
|
6d12a34c40 | ||
|
|
9e126a4b91 | ||
|
|
040ffda687 | ||
|
|
39ff49e054 | ||
|
|
b8f72a5bcb | ||
|
|
43db704b74 | ||
|
|
5043040530 | ||
|
|
3c60aeeef9 | ||
|
|
0344d61b26 | ||
|
|
0e8467782b | ||
|
|
423ea26266 | ||
|
|
2f3339ba85 | ||
|
|
9433b50785 | ||
|
|
1e7b53dc0e | ||
|
|
bc94748f2a | ||
|
|
2395f93ed1 | ||
|
|
d771726c2a | ||
|
|
b2a2fe898c | ||
|
|
31d408a746 | ||
|
|
4a74f295e7 | ||
|
|
b6ba6459fb | ||
|
|
e399790442 | ||
|
|
20c65b9a31 | ||
|
|
1a7853a47e | ||
|
|
683c3a4c90 | ||
|
|
4a8d998afe | ||
|
|
fe59d90c51 | ||
|
|
f87813805a | ||
|
|
a7e5b9978f | ||
|
|
0a3959af86 | ||
|
|
9ba6054140 | ||
|
|
3348f04889 | ||
|
|
c12aec7c8f | ||
|
|
05f66b8f24 | ||
|
|
d8b80f0fe9 | ||
|
|
7314572d97 | ||
|
|
52a29ed00a | ||
|
|
5eaf8a5448 | ||
|
|
f70fb12c3d | ||
|
|
ece6c1203c | ||
|
|
9c7e3177a2 | ||
|
|
058c0affaf | ||
|
|
5ee7146884 | ||
|
|
1aa9a7a093 | ||
|
|
a202c44a0f | ||
|
|
85776cc7d0 | ||
|
|
6d133ef724 | ||
|
|
53288d361c | ||
|
|
e729bd52aa | ||
|
|
ddb6127519 | ||
|
|
50b42eb6fe | ||
|
|
b6572b7272 | ||
|
|
57ced2c284 | ||
|
|
26a3491466 | ||
|
|
eed8463832 | ||
|
|
718b4f3fd7 | ||
|
|
22461d1728 | ||
|
|
69cab1e6bb | ||
|
|
a661fddaf3 | ||
|
|
1b85e561b9 | ||
|
|
a803ab8577 | ||
|
|
daa759cc55 | ||
|
|
513a099c24 | ||
|
|
e299e73a68 | ||
|
|
9550ac7422 | ||
|
|
07bd376649 | ||
|
|
ec6a1ed9d1 | ||
|
|
7aee28d080 | ||
|
|
24ec13e36d | ||
|
|
d2e7c360b9 | ||
|
|
f00628f4e5 | ||
|
|
19bd5ace7d | ||
|
|
3e2506136c | ||
|
|
4e03acc944 | ||
|
|
188eb6b9ea | ||
|
|
c89e1a5735 | ||
|
|
e50cc59f0d | ||
|
|
96f87caff0 | ||
|
|
b422a83b57 | ||
|
|
15ae3bee55 | ||
|
|
0cac2fec2a | ||
|
|
5965da88c3 | ||
|
|
ba0338e9d5 | ||
|
|
ff62338359 | ||
|
|
9867f4eeee | ||
|
|
ba278dfc3d | ||
|
|
063030bcf3 | ||
|
|
276ce8710c | ||
|
|
5ed7a17f46 | ||
|
|
01c3b4fa6e | ||
|
|
165ca8fbc7 | ||
|
|
ce90ae343c | ||
|
|
a99f360a64 | ||
|
|
d51e9446ff | ||
|
|
d3524ee46f | ||
|
|
121ea37825 | ||
|
|
9592d95599 | ||
|
|
d6faa18adb | ||
|
|
1cbe6f77ee | ||
|
|
4f5d4e36b7 | ||
|
|
163025c1f2 | ||
|
|
880178d62e | ||
|
|
d285ff7e54 | ||
|
|
54671fc522 | ||
|
|
53e3e6545d | ||
|
|
91cb49c4a3 | ||
|
|
c065cb48f2 | ||
|
|
d376f6b1d2 | ||
|
|
45526a7652 | ||
|
|
cc7929932b | ||
|
|
e6516235fa | ||
|
|
40d5a9f890 | ||
|
|
ee3e744cc6 | ||
|
|
b55bd1e027 | ||
|
|
9a96df0319 | ||
|
|
e9b1618364 | ||
|
|
6dc6ed1e94 | ||
|
|
1943a49274 | ||
|
|
a8c00edc94 | ||
|
|
faa8abb2b9 | ||
|
|
f6cd2fc68e | ||
|
|
6482000d6b | ||
|
|
dcf7209706 | ||
|
|
2ec921593e | ||
|
|
75a01f657e | ||
|
|
d4e512c1fc | ||
|
|
26e7d34f18 | ||
|
|
15b5ffddd4 | ||
|
|
f0f3764992 | ||
|
|
2beb44b591 | ||
|
|
27b659dde1 | ||
|
|
630c2ee6f6 | ||
|
|
600477c487 | ||
|
|
d31c295598 | ||
|
|
a7bb0931c4 | ||
|
|
ff99a01423 | ||
|
|
ea6e311318 | ||
|
|
6790467bbc | ||
|
|
d315dbea22 | ||
|
|
8db7ab6724 | ||
|
|
9a2c034ae8 | ||
|
|
2885b80a13 | ||
|
|
4a85156e87 | ||
|
|
1785c69e1b | ||
|
|
a862ba8348 | ||
|
|
633d45d02f | ||
|
|
7f4e042dfa | ||
|
|
507ec13848 | ||
|
|
2132352639 | ||
|
|
11016b8486 | ||
|
|
8615f14407 | ||
|
|
1e84f08018 | ||
|
|
7f663328dc | ||
|
|
ea53068432 | ||
|
|
144aff9b4e | ||
|
|
18db6daf0a | ||
|
|
26ba29b538 | ||
|
|
70167a34b6 | ||
|
|
ccb668a1b6 | ||
|
|
0989c64eab | ||
|
|
c082fc5cb2 | ||
|
|
d39111a294 | ||
|
|
3c072f94b0 | ||
|
|
7f8ae2ce5c | ||
|
|
d84b75168c | ||
|
|
eb0a5e1c55 | ||
|
|
47ac77dbb0 | ||
|
|
ec84847be7 | ||
|
|
e7839bfd40 | ||
|
|
8762da627b | ||
|
|
3fab321045 | ||
|
|
9451048574 | ||
|
|
46c002038b | ||
|
|
d1d833ea9a | ||
|
|
c1f0750526 | ||
|
|
89e02b6956 | ||
|
|
97e8258288 | ||
|
|
39040c1874 | ||
|
|
c709851888 | ||
|
|
b022bec1fa | ||
|
|
bca0531963 | ||
|
|
b2c7fc8f5b | ||
|
|
96ac2c29d6 | ||
|
|
14a5118b4d | ||
|
|
232fa1ffe8 | ||
|
|
d2e91754e9 | ||
|
|
4d9066a58d | ||
|
|
c618867941 | ||
|
|
5ad4017510 | ||
|
|
63e14a98f9 | ||
|
|
25e3fe8eab | ||
|
|
840f046572 | ||
|
|
89e3c2e4b1 | ||
|
|
c770470b58 | ||
|
|
4619836122 | ||
|
|
76403bba8e | ||
|
|
a9afa303a2 | ||
|
|
e5399ae07a | ||
|
|
80a5a7b129 | ||
|
|
9dc97d4b6b | ||
|
|
d8c9169af2 | ||
|
|
ec256f7130 | ||
|
|
19bbfce4ed | ||
|
|
b0b2d9d972 | ||
|
|
6f5f5c9461 | ||
|
|
fc04bc6046 | ||
|
|
9f504253fb | ||
|
|
961997e078 | ||
|
|
363594a9a2 | ||
|
|
247e2677f3 | ||
|
|
5b5159f4dd | ||
|
|
bc8b85860c | ||
|
|
44d45c5880 | ||
|
|
a6d8e4fc3f | ||
|
|
2cc9a15f6a | ||
|
|
151f9fb2ee | ||
|
|
32fb76b3d1 | ||
|
|
8d52e2635a | ||
|
|
f20e1f20a6 | ||
|
|
af8594c5c6 | ||
|
|
899d41f361 | ||
|
|
7dc6382c90 | ||
|
|
e8009c2d26 | ||
|
|
3bc7cdaab6 | ||
|
|
724d8187c6 | ||
|
|
8f68df60c7 | ||
|
|
6af3cb6134 | ||
|
|
2ff0c3907f | ||
|
|
dd102ff01d | ||
|
|
f20b1d75e6 | ||
|
|
a4b88ac4a7 | ||
|
|
93b9d586d2 | ||
|
|
41dd4447cc | ||
|
|
8b9c8a2e80 | ||
|
|
a63ff1bb99 | ||
|
|
d5e3b59245 | ||
|
|
d0470fffcc | ||
|
|
5053305e17 | ||
|
|
9c79392060 | ||
|
|
708c3278bf | ||
|
|
c0249f6e59 | ||
|
|
afd8aefac2 | ||
|
|
3c07767138 | ||
|
|
953c442f13 | ||
|
|
e147852878 | ||
|
|
db7ee6cfb3 | ||
|
|
3b41b6cc33 | ||
|
|
5e79888370 | ||
|
|
a6aa9bdd59 | ||
|
|
d78b7cc110 | ||
|
|
e7cdace0ab | ||
|
|
f60eb4e977 | ||
|
|
7aecf6c6de | ||
|
|
75d62096a6 | ||
|
|
7c44994070 | ||
|
|
f49f3fd9c3 | ||
|
|
5ea86d636c | ||
|
|
4c6e90717a | ||
|
|
d60ca9d783 | ||
|
|
d304718ea0 | ||
|
|
c787c8948e | ||
|
|
62728ef7fb | ||
|
|
47e256f03d | ||
|
|
527db52d5e | ||
|
|
f78b2c48a7 | ||
|
|
90c965a32a | ||
|
|
d4afcde6c9 | ||
|
|
257de89ce4 | ||
|
|
735cc3962b | ||
|
|
feb42181de | ||
|
|
f5c4bfa7b4 | ||
|
|
65ddd91855 | ||
|
|
6d7d838613 | ||
|
|
5edf7b7f00 | ||
|
|
117569830d | ||
|
|
d62aec7287 | ||
|
|
4e0cf3681e | ||
|
|
d98751102a | ||
|
|
1acbeb813e | ||
|
|
b87ec752cf | ||
|
|
753df31fa6 | ||
|
|
bd77b74689 | ||
|
|
810c23d8ee | ||
|
|
34d9b2983e | ||
|
|
63c5c8412a | ||
|
|
60207723d1 | ||
|
|
f4117ad096 | ||
|
|
8bed4e9970 | ||
|
|
f72eaf781c | ||
|
|
e9ecc20a36 | ||
|
|
addfa2a32d | ||
|
|
0dad9bc393 | ||
|
|
5155875a72 | ||
|
|
4ed1217366 | ||
|
|
50e898a684 | ||
|
|
251c7fa982 | ||
|
|
00c75e9f98 | ||
|
|
1b5b02d286 | ||
|
|
946d655cee | ||
|
|
d56710b0b5 | ||
|
|
0cf78277b5 | ||
|
|
ce2a583ff9 | ||
|
|
84bddad30e | ||
|
|
0ff682504a | ||
|
|
5d5984166f | ||
|
|
b825eb44fe | ||
|
|
7015eb66f2 | ||
|
|
494eeb16a5 | ||
|
|
692fdc8d5d | ||
|
|
ec1a8ebd4a | ||
|
|
59daa6597b | ||
|
|
3941ce4ad1 | ||
|
|
aff87d4372 | ||
|
|
373ca87887 | ||
|
|
03c855ecbe | ||
|
|
3a3cb24631 | ||
|
|
4c3fea25a5 | ||
|
|
af303cbf2a | ||
|
|
b7c09a9b38 | ||
|
|
eced06eea8 | ||
|
|
15d989255c | ||
|
|
095566b9c2 | ||
|
|
b77a65d446 | ||
|
|
9778a748fc | ||
|
|
a89dddcafa | ||
|
|
75973fd4c0 | ||
|
|
514036f9d1 | ||
|
|
36fbedab20 | ||
|
|
180baeba50 | ||
|
|
cce82fe2a5 | ||
|
|
5512bb2e06 | ||
|
|
be1fcbbdf8 | ||
|
|
422cd52049 | ||
|
|
d67a56d37e | ||
|
|
070c9721b6 | ||
|
|
0219834dd1 | ||
|
|
a1cc9ad1f0 | ||
|
|
29e8aa4020 | ||
|
|
777aff403f | ||
|
|
4b3b702459 | ||
|
|
893e6b40a7 | ||
|
|
a85d780020 | ||
|
|
34439699ae | ||
|
|
64b63142b1 | ||
|
|
cee1ab000b | ||
|
|
3ff98770c1 | ||
|
|
244203463d | ||
|
|
b6f7940b10 | ||
|
|
75312602aa | ||
|
|
75977128f0 | ||
|
|
eafde6c677 | ||
|
|
da0598baef | ||
|
|
35ba5e2f7c | ||
|
|
49258d6dbe | ||
|
|
5a081e4f00 | ||
|
|
4feae472e9 | ||
|
|
4e83239258 | ||
|
|
c4cccf44a5 | ||
|
|
64e7cbcc62 |
40
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "Frigate Dev",
|
||||
"dockerComposeFile": "../docker-compose.yml",
|
||||
"service": "dev",
|
||||
"workspaceFolder": "/lab/frigate",
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"visualstudioexptteam.vscodeintellicode",
|
||||
"mhutchie.git-graph",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"esbenp.prettier-vscode",
|
||||
"ms-python.vscode-pylance",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"mikestead.dotenv",
|
||||
"csstools.postcss",
|
||||
"blanu.vscode-styled-jsx",
|
||||
"bradlc.vscode-tailwindcss"
|
||||
],
|
||||
"settings": {
|
||||
"python.linting.pylintEnabled": true,
|
||||
"python.linting.enabled": true,
|
||||
"python.formatting.provider": "black",
|
||||
"python.languageServer": "Pylance",
|
||||
"editor.formatOnPaste": false,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnType": true,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"eslint.workingDirectories": ["./web"],
|
||||
"[json][jsonc]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[jsx][js][tsx][ts]": {
|
||||
"editor.codeActionsOnSave": ["source.addMissingImports", "source.fixAll"],
|
||||
"editor.tabSize": 2
|
||||
},
|
||||
"cSpell.ignoreWords": ["rtmp"],
|
||||
"cSpell.words": ["preact"]
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
README.md
|
||||
diagram.png
|
||||
docs/
|
||||
.gitignore
|
||||
debug
|
||||
config/
|
||||
*.pyc
|
||||
.git
|
||||
core
|
||||
*.mp4
|
||||
*.jpg
|
||||
*.db
|
||||
*.ts
|
||||
4
.github/FUNDING.yml
vendored
@@ -1 +1,3 @@
|
||||
github: blakeblackshear
|
||||
github:
|
||||
- blakeblackshear
|
||||
- paularmstrong
|
||||
|
||||
55
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,55 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Version of frigate**
|
||||
What version are you using?
|
||||
|
||||
**Config file**
|
||||
Include your full config file wrapped in back ticks.
|
||||
```
|
||||
config here
|
||||
```
|
||||
|
||||
**Logs**
|
||||
```
|
||||
Include relevant log output here
|
||||
```
|
||||
|
||||
**Frigate debug stats**
|
||||
```
|
||||
Output from frigate's /debug/stats endpoint
|
||||
```
|
||||
|
||||
**FFprobe from your camera**
|
||||
|
||||
Run the following command and paste output below
|
||||
```
|
||||
ffprobe <stream_url>
|
||||
```
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Computer Hardware**
|
||||
- OS: [e.g. Ubuntu, Windows]
|
||||
- Virtualization: [e.g. Proxmox, Virtualbox]
|
||||
- Coral Version: [e.g. USB, PCIe, None]
|
||||
- Network Setup: [e.g. Wired, WiFi]
|
||||
|
||||
**Camera Info:**
|
||||
- Manufacturer: [e.g. Dahua]
|
||||
- Model: [e.g. IPC-HDW5231R-ZE]
|
||||
- Resolution: [e.g. 720p]
|
||||
- FPS: [e.g. 5]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
107
.github/ISSUE_TEMPLATE/camera_support_request.yml
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
name: Camera Support Request
|
||||
description: Support for setting up cameras in Frigate
|
||||
title: "[Camera Support]: "
|
||||
labels: ["support", "triage"]
|
||||
assignees: []
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the problem you are having
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the Debug page in the Web UI
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Frigate config file
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: ffprobe
|
||||
attributes:
|
||||
label: FFprobe output from your camera
|
||||
description: Run `ffprobe <camera_url>` and provide output below
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: stats
|
||||
attributes:
|
||||
label: Frigate stats
|
||||
description: Output from frigate's /api/stats endpoint
|
||||
render: json
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: coral
|
||||
attributes:
|
||||
label: Coral version
|
||||
options:
|
||||
- USB
|
||||
- PCIe
|
||||
- M.2
|
||||
- Dev Board
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: network
|
||||
attributes:
|
||||
label: Network connection
|
||||
options:
|
||||
- Wired
|
||||
- Wireless
|
||||
- Mixed
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: camera
|
||||
attributes:
|
||||
label: Camera make and model
|
||||
description: Dahua, hikvision, amcrest, reolink, etc and model number
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
label: Any other information that may be helpful
|
||||
1
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
82
.github/ISSUE_TEMPLATE/config_support_request.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: Config Support Request
|
||||
description: Support for Frigate configuration
|
||||
title: "[Config Support]: "
|
||||
labels: ["support", "triage"]
|
||||
assignees: []
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the problem you are having
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the Debug page in the Web UI
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Frigate config file
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: stats
|
||||
attributes:
|
||||
label: Frigate stats
|
||||
description: Output from frigate's /api/stats endpoint
|
||||
render: json
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: coral
|
||||
attributes:
|
||||
label: Coral version
|
||||
options:
|
||||
- USB
|
||||
- PCIe
|
||||
- M.2
|
||||
- Dev Board
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
label: Any other information that may be helpful
|
||||
84
.github/ISSUE_TEMPLATE/edgetpu_support_request.yml
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
name: EdgeTpu Support Request
|
||||
description: Support for setting up EdgeTPU in Frigate
|
||||
title: "[EdgeTPU Support]: "
|
||||
labels: ["support", "triage"]
|
||||
assignees: []
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the problem you are having
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the Debug page in the Web UI
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Frigate config file
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: docker
|
||||
attributes:
|
||||
label: docker-compose file or Docker CLI command
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: coral
|
||||
attributes:
|
||||
label: Coral version
|
||||
options:
|
||||
- USB
|
||||
- PCIe
|
||||
- M.2
|
||||
- Dev Board
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
label: Any other information that may be helpful
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe what you are trying to accomplish and why in non technical terms**
|
||||
I want to be able to ... so that I can ...
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
107
.github/ISSUE_TEMPLATE/general_support_request.yml
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
name: General Support Request
|
||||
description: General support request for Frigate
|
||||
title: "[Support]: "
|
||||
labels: ["support", "triage"]
|
||||
assignees: []
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the problem you are having
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the Debug page in the Web UI
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Frigate config file
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: ffprobe
|
||||
attributes:
|
||||
label: FFprobe output from your camera
|
||||
description: Run `ffprobe <camera_url>` and provide output below
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: stats
|
||||
attributes:
|
||||
label: Frigate stats
|
||||
description: Output from frigate's /api/stats endpoint
|
||||
render: json
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: coral
|
||||
attributes:
|
||||
label: Coral version
|
||||
options:
|
||||
- USB
|
||||
- PCIe
|
||||
- M.2
|
||||
- Dev Board
|
||||
- Other
|
||||
- CPU (no coral)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: network
|
||||
attributes:
|
||||
label: Network connection
|
||||
options:
|
||||
- Wired
|
||||
- Wireless
|
||||
- Mixed
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: camera
|
||||
attributes:
|
||||
label: Camera make and model
|
||||
description: Dahua, hikvision, amcrest, reolink, etc and model number
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
label: Any other information that may be helpful
|
||||
96
.github/ISSUE_TEMPLATE/hwaccel_support_request.yml
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
name: Hardware Acceleration Support Request
|
||||
description: Support for setting up GPU hardware acceleration in Frigate
|
||||
title: "[HW Accel Support]: "
|
||||
labels: ["support", "triage"]
|
||||
assignees: []
|
||||
body:
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the problem you are having
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Version
|
||||
description: Visible on the Debug page in the Web UI
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: config
|
||||
attributes:
|
||||
label: Frigate config file
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: docker
|
||||
attributes:
|
||||
label: docker-compose file or Docker CLI command
|
||||
description: This will be automatically formatted into code, so no need for backticks.
|
||||
render: yaml
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks.
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: ffprobe
|
||||
attributes:
|
||||
label: FFprobe output from your camera
|
||||
description: Run `ffprobe <camera_url>` and provide output below
|
||||
render: shell
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system
|
||||
options:
|
||||
- HassOS
|
||||
- Debian
|
||||
- Other Linux
|
||||
- Proxmox
|
||||
- UNRAID
|
||||
- Windows
|
||||
- Other
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: install-method
|
||||
attributes:
|
||||
label: Install method
|
||||
options:
|
||||
- HassOS Addon
|
||||
- Docker Compose
|
||||
- Docker CLI
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: network
|
||||
attributes:
|
||||
label: Network connection
|
||||
options:
|
||||
- Wired
|
||||
- Wireless
|
||||
- Mixed
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: camera
|
||||
attributes:
|
||||
label: Camera make and model
|
||||
description: Dahua, hikvision, amcrest, reolink, etc and model number
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other
|
||||
attributes:
|
||||
label: Any other information that may be helpful
|
||||
80
.github/workflows/pull_request.yml
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
name: On pull request
|
||||
|
||||
on: pull_request
|
||||
|
||||
env:
|
||||
DEFAULT_PYTHON: 3.9
|
||||
|
||||
jobs:
|
||||
web_lint:
|
||||
name: Web - Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 16.x
|
||||
- run: npm install
|
||||
working-directory: ./web
|
||||
- name: Lint
|
||||
run: npm run lint
|
||||
working-directory: ./web
|
||||
|
||||
web_test:
|
||||
name: Web - Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 16.x
|
||||
- run: npm install
|
||||
working-directory: ./web
|
||||
- name: Test
|
||||
run: npm run test
|
||||
working-directory: ./web
|
||||
|
||||
python_checks:
|
||||
runs-on: ubuntu-latest
|
||||
name: Python checks
|
||||
steps:
|
||||
- name: Check out the repository
|
||||
uses: actions/checkout@v2.3.4
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.2.2
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
- name: Install requirements
|
||||
run: |
|
||||
pip install pip
|
||||
pip install -r requirements-dev.txt
|
||||
- name: Lint
|
||||
run: |
|
||||
python3 -m black frigate --check
|
||||
|
||||
python_tests:
|
||||
runs-on: ubuntu-latest
|
||||
name: Python Tests
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@master
|
||||
with:
|
||||
node-version: 16.x
|
||||
- run: npm install
|
||||
working-directory: ./web
|
||||
- name: Build web
|
||||
run: npm run build
|
||||
working-directory: ./web
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Create Version Module
|
||||
run: make version
|
||||
- name: Build
|
||||
run: make
|
||||
- name: Run mypy
|
||||
run: docker run --rm --entrypoint=python3 frigate:latest -u -m mypy --config-file frigate/mypy.ini frigate
|
||||
- name: Run tests
|
||||
run: docker run --rm --entrypoint=python3 frigate:latest -u -m unittest
|
||||
25
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Close Stale Issues
|
||||
# Warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||
# https://github.com/actions/stale
|
||||
|
||||
name: "Stalebot"
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # run stalebot once a day
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@main
|
||||
id: stale
|
||||
with:
|
||||
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
|
||||
close-issue-message: ''
|
||||
days-before-stale: 30
|
||||
days-before-close: 3
|
||||
exempt-draft-pr: true
|
||||
exempt-issue-labels: 'pinned,security'
|
||||
exempt-pr-labels: 'pinned,security'
|
||||
- name: Print outputs
|
||||
run: echo ${{ join(steps.stale.outputs.*, ',') }}
|
||||
13
.gitignore
vendored
@@ -1,4 +1,17 @@
|
||||
.DS_Store
|
||||
*.pyc
|
||||
*.swp
|
||||
debug
|
||||
.vscode
|
||||
config/config.yml
|
||||
models
|
||||
*.mp4
|
||||
*.ts
|
||||
*.db
|
||||
*.csv
|
||||
frigate/version.py
|
||||
web/build
|
||||
web/node_modules
|
||||
web/coverage
|
||||
core
|
||||
!/web/**/*.ts
|
||||
|
||||
588
.pylintrc
Normal file
@@ -0,0 +1,588 @@
|
||||
[MASTER]
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code.
|
||||
extension-pkg-whitelist=
|
||||
|
||||
# Specify a score threshold to be exceeded before program exits with error.
|
||||
fail-under=10.0
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS
|
||||
|
||||
# Add files or directories matching the regex patterns to the blacklist. The
|
||||
# regex matches against base names, not paths.
|
||||
ignore-patterns=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
#init-hook=
|
||||
|
||||
# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the
|
||||
# number of processors available to use.
|
||||
jobs=1
|
||||
|
||||
# Control the amount of potential inferred values when inferring a single
|
||||
# object. This can help the performance when dealing with large functions or
|
||||
# complex, nested conditions.
|
||||
limit-inference-results=100
|
||||
|
||||
# List of plugins (as comma separated values of python module names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# When enabled, pylint would attempt to guess common misconfiguration and emit
|
||||
# user-friendly hints instead of false-positive error messages.
|
||||
suggestion-mode=yes
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.
|
||||
confidence=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once). You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use "--disable=all --enable=classes
|
||||
# --disable=W".
|
||||
disable=print-statement,
|
||||
parameter-unpacking,
|
||||
unpacking-in-except,
|
||||
old-raise-syntax,
|
||||
backtick,
|
||||
long-suffix,
|
||||
old-ne-operator,
|
||||
old-octal-literal,
|
||||
import-star-module-level,
|
||||
non-ascii-bytes-literal,
|
||||
raw-checker-failed,
|
||||
bad-inline-option,
|
||||
locally-disabled,
|
||||
file-ignored,
|
||||
suppressed-message,
|
||||
useless-suppression,
|
||||
deprecated-pragma,
|
||||
use-symbolic-message-instead,
|
||||
apply-builtin,
|
||||
basestring-builtin,
|
||||
buffer-builtin,
|
||||
cmp-builtin,
|
||||
coerce-builtin,
|
||||
execfile-builtin,
|
||||
file-builtin,
|
||||
long-builtin,
|
||||
raw_input-builtin,
|
||||
reduce-builtin,
|
||||
standarderror-builtin,
|
||||
unicode-builtin,
|
||||
xrange-builtin,
|
||||
coerce-method,
|
||||
delslice-method,
|
||||
getslice-method,
|
||||
setslice-method,
|
||||
no-absolute-import,
|
||||
old-division,
|
||||
dict-iter-method,
|
||||
dict-view-method,
|
||||
next-method-called,
|
||||
metaclass-assignment,
|
||||
indexing-exception,
|
||||
raising-string,
|
||||
reload-builtin,
|
||||
oct-method,
|
||||
hex-method,
|
||||
nonzero-method,
|
||||
cmp-method,
|
||||
input-builtin,
|
||||
round-builtin,
|
||||
intern-builtin,
|
||||
unichr-builtin,
|
||||
map-builtin-not-iterating,
|
||||
zip-builtin-not-iterating,
|
||||
range-builtin-not-iterating,
|
||||
filter-builtin-not-iterating,
|
||||
using-cmp-argument,
|
||||
eq-without-hash,
|
||||
div-method,
|
||||
idiv-method,
|
||||
rdiv-method,
|
||||
exception-message-attribute,
|
||||
invalid-str-codec,
|
||||
sys-max-int,
|
||||
bad-python3-import,
|
||||
deprecated-string-function,
|
||||
deprecated-str-translate-call,
|
||||
deprecated-itertools-function,
|
||||
deprecated-types-field,
|
||||
next-method-defined,
|
||||
dict-items-not-iterating,
|
||||
dict-keys-not-iterating,
|
||||
dict-values-not-iterating,
|
||||
deprecated-operator-function,
|
||||
deprecated-urllib-function,
|
||||
xreadlines-attribute,
|
||||
deprecated-sys-function,
|
||||
exception-escape,
|
||||
comprehension-escape
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time (only on the command line, not in the configuration file where
|
||||
# it should appear only once). See also the "--disable" option for examples.
|
||||
enable=c-extension-no-member
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Python expression which should return a score less than or equal to 10. You
|
||||
# have access to the variables 'error', 'warning', 'refactor', and 'convention'
|
||||
# which contain the number of messages in each category, as well as 'statement'
|
||||
# which is the total number of statements analyzed. This score is used by the
|
||||
# global evaluation report (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details.
|
||||
#msg-template=
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, json
|
||||
# and msvs (visual studio). You can also give a reporter class, e.g.
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Tells whether to display a full report or only the messages.
|
||||
reports=no
|
||||
|
||||
# Activate the evaluation score.
|
||||
score=yes
|
||||
|
||||
|
||||
[REFACTORING]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=5
|
||||
|
||||
# Complete name of functions that never returns. When checking for
|
||||
# inconsistent-return-statements if a never returning function is called then
|
||||
# it will be considered as an explicit return statement and no message will be
|
||||
# printed.
|
||||
never-returning-functions=sys.exit
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Limits count of emitted suggestions for spelling mistakes.
|
||||
max-spelling-suggestions=4
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it work,
|
||||
# install the python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains the private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to the private dictionary (see the
|
||||
# --spelling-private-dict-file option) instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# List of decorators that produce context managers, such as
|
||||
# contextlib.contextmanager. Add to this list to register other decorators that
|
||||
# produce valid context managers.
|
||||
contextmanager-decorators=contextlib.contextmanager
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# Tells whether to warn about missing members when the owner of the attribute
|
||||
# is inferred to be None.
|
||||
ignore-none=yes
|
||||
|
||||
# This flag controls whether pylint should warn about no-member and similar
|
||||
# checks whenever an opaque object is returned when inferring. The inference
|
||||
# can return multiple potential results while evaluating a Python object, but
|
||||
# some branches might not be evaluated, which results in partial inference. In
|
||||
# that case, it might be useful to still emit no-member and other checks for
|
||||
# the rest of the inferred objects.
|
||||
ignore-on-opaque-inference=yes
|
||||
|
||||
# List of class names for which member attributes should not be checked (useful
|
||||
# for classes with dynamically set attributes). This supports the use of
|
||||
# qualified names.
|
||||
ignored-classes=optparse.Values,thread._local,_thread._local
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis). It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=
|
||||
|
||||
# Show a hint with possible names when a member name was not found. The aspect
|
||||
# of finding the hint is based on edit distance.
|
||||
missing-member-hint=yes
|
||||
|
||||
# The minimum edit distance a name should have in order to be considered a
|
||||
# similar match for a missing member name.
|
||||
missing-member-hint-distance=1
|
||||
|
||||
# The total number of similar names that should be taken in consideration when
|
||||
# showing a hint for a missing member.
|
||||
missing-member-max-choices=1
|
||||
|
||||
# List of decorators that change the signature of a decorated function.
|
||||
signature-mutators=
|
||||
|
||||
|
||||
[STRING]
|
||||
|
||||
# This flag controls whether inconsistent-quotes generates a warning when the
|
||||
# character used as a quote delimiter is used inconsistently within a module.
|
||||
check-quote-consistency=no
|
||||
|
||||
# This flag controls whether the implicit-str-concat should generate a warning
|
||||
# on implicit string concatenation in sequences defined over several lines.
|
||||
check-str-concat-over-line-jumps=no
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=100
|
||||
|
||||
# Maximum number of lines in a module.
|
||||
max-module-lines=1000
|
||||
|
||||
# Allow the body of a class to be on the same line as the declaration if body
|
||||
# contains single statement.
|
||||
single-line-class-stmt=no
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=4
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=FIXME,
|
||||
XXX,
|
||||
TODO
|
||||
|
||||
# Regular expression of note tags to take in consideration.
|
||||
#notes-rgx=
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# Naming style matching correct argument names.
|
||||
argument-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct argument names. Overrides argument-
|
||||
# naming-style.
|
||||
#argument-rgx=
|
||||
|
||||
# Naming style matching correct attribute names.
|
||||
attr-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct attribute names. Overrides attr-naming-
|
||||
# style.
|
||||
#attr-rgx=
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma.
|
||||
bad-names=foo,
|
||||
bar,
|
||||
baz,
|
||||
toto,
|
||||
tutu,
|
||||
tata
|
||||
|
||||
# Bad variable names regexes, separated by a comma. If names match any regex,
|
||||
# they will always be refused
|
||||
bad-names-rgxs=
|
||||
|
||||
# Naming style matching correct class attribute names.
|
||||
class-attribute-naming-style=any
|
||||
|
||||
# Regular expression matching correct class attribute names. Overrides class-
|
||||
# attribute-naming-style.
|
||||
#class-attribute-rgx=
|
||||
|
||||
# Naming style matching correct class names.
|
||||
class-naming-style=PascalCase
|
||||
|
||||
# Regular expression matching correct class names. Overrides class-naming-
|
||||
# style.
|
||||
#class-rgx=
|
||||
|
||||
# Naming style matching correct constant names.
|
||||
const-naming-style=UPPER_CASE
|
||||
|
||||
# Regular expression matching correct constant names. Overrides const-naming-
|
||||
# style.
|
||||
#const-rgx=
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
# Naming style matching correct function names.
|
||||
function-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct function names. Overrides function-
|
||||
# naming-style.
|
||||
#function-rgx=
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma.
|
||||
good-names=i,
|
||||
j,
|
||||
k,
|
||||
ex,
|
||||
Run,
|
||||
_
|
||||
|
||||
# Good variable names regexes, separated by a comma. If names match any regex,
|
||||
# they will always be accepted
|
||||
good-names-rgxs=
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name.
|
||||
include-naming-hint=no
|
||||
|
||||
# Naming style matching correct inline iteration names.
|
||||
inlinevar-naming-style=any
|
||||
|
||||
# Regular expression matching correct inline iteration names. Overrides
|
||||
# inlinevar-naming-style.
|
||||
#inlinevar-rgx=
|
||||
|
||||
# Naming style matching correct method names.
|
||||
method-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct method names. Overrides method-naming-
|
||||
# style.
|
||||
#method-rgx=
|
||||
|
||||
# Naming style matching correct module names.
|
||||
module-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct module names. Overrides module-naming-
|
||||
# style.
|
||||
#module-rgx=
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# List of decorators that produce properties, such as abc.abstractproperty. Add
|
||||
# to this list to register other decorators that produce valid properties.
|
||||
# These decorators are taken in consideration only for invalid-name.
|
||||
property-classes=abc.abstractproperty
|
||||
|
||||
# Naming style matching correct variable names.
|
||||
variable-naming-style=snake_case
|
||||
|
||||
# Regular expression matching correct variable names. Overrides variable-
|
||||
# naming-style.
|
||||
#variable-rgx=
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid defining new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# Tells whether unused global variables should be treated as a violation.
|
||||
allow-global-unused-variables=yes
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,
|
||||
_cb
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expected to
|
||||
# not be used).
|
||||
dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore.
|
||||
ignored-argument-names=_.*|^ignored_|^unused_
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# List of qualified module names which can have objects that can redefine
|
||||
# builtins.
|
||||
redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# The type of string formatting that logging methods do. `old` means using %
|
||||
# formatting, `new` is for `{}` formatting.
|
||||
logging-format-style=fstr
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format.
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method.
|
||||
max-args=5
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=7
|
||||
|
||||
# Maximum number of boolean expressions in an if statement (see R0916).
|
||||
max-bool-expr=5
|
||||
|
||||
# Maximum number of branch for function / method body.
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of locals for function / method body.
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of return / yield for function / method body.
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of statements in function / method body.
|
||||
max-statements=50
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,
|
||||
__new__,
|
||||
setUp,
|
||||
__post_init__
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,
|
||||
_fields,
|
||||
_replace,
|
||||
_source,
|
||||
_make
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=cls
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# List of modules that can be imported at any level, not just the top level
|
||||
# one.
|
||||
allow-any-import-level=
|
||||
|
||||
# Allow wildcard imports from modules that define __all__.
|
||||
allow-wildcard-with-all=no
|
||||
|
||||
# Analyse import fallback blocks. This can be used to support both Python 2 and
|
||||
# 3 compatible code, which means that the block might have code that exists
|
||||
# only in one or another interpreter, leading to false positives when analysed.
|
||||
analyse-fallback-blocks=no
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma.
|
||||
deprecated-modules=optparse,tkinter.tix
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled).
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled).
|
||||
import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled).
|
||||
int-import-graph=
|
||||
|
||||
# Force import order to recognize a module as part of the standard
|
||||
# compatibility libraries.
|
||||
known-standard-library=
|
||||
|
||||
# Force import order to recognize a module as part of a third party library.
|
||||
known-third-party=enchant
|
||||
|
||||
# Couples of modules and preferred modules, separated by a comma.
|
||||
preferred-modules=
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "BaseException, Exception".
|
||||
overgeneral-exceptions=BaseException,
|
||||
Exception
|
||||
52
Makefile
@@ -1,37 +1,39 @@
|
||||
default_target: amd64_frigate
|
||||
default_target: local
|
||||
|
||||
amd64_wheels:
|
||||
docker build --tag blakeblackshear/frigate-wheels:amd64 --file docker/Dockerfile.wheels .
|
||||
COMMIT_HASH := $(shell git log -1 --pretty=format:"%h"|tail -1)
|
||||
VERSION = 0.11.0
|
||||
CURRENT_UID := $(shell id -u)
|
||||
CURRENT_GID := $(shell id -g)
|
||||
|
||||
amd64_ffmpeg:
|
||||
docker build --tag blakeblackshear/frigate-ffmpeg:amd64 --file docker/Dockerfile.ffmpeg.amd64 .
|
||||
version:
|
||||
echo "VERSION=\"$(VERSION)-$(COMMIT_HASH)\"" > frigate/version.py
|
||||
|
||||
amd64_frigate:
|
||||
docker build --tag frigate-base --build-arg ARCH=amd64 --file docker/Dockerfile.base .
|
||||
docker build --tag frigate --file docker/Dockerfile.amd64 .
|
||||
build_web:
|
||||
docker run --volume ${PWD}/web:/web -w /web --volume /etc/passwd:/etc/passwd:ro --volume /etc/group:/etc/group:ro -u $(CURRENT_UID):$(CURRENT_GID) node:16 /bin/bash -c "npm install && npm run build"
|
||||
|
||||
amd64_all: amd64_wheels amd64_ffmpeg amd64_frigate
|
||||
nginx_frigate:
|
||||
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag blakeblackshear/frigate-nginx:1.0.2 --file docker/Dockerfile.nginx .
|
||||
|
||||
aarch64_wheels:
|
||||
docker build --tag blakeblackshear/frigate-wheels:aarch64 --file docker/Dockerfile.wheels.aarch64 .
|
||||
local:
|
||||
DOCKER_BUILDKIT=1 docker build -t frigate -f docker/Dockerfile .
|
||||
|
||||
aarch64_ffmpeg:
|
||||
docker build --tag blakeblackshear/frigate-ffmpeg:aarch64 --file docker/Dockerfile.ffmpeg.aarch64 .
|
||||
amd64:
|
||||
docker buildx build --platform linux/amd64 --tag blakeblackshear/frigate:$(VERSION)-$(COMMIT_HASH) --file docker/Dockerfile .
|
||||
|
||||
aarch64_frigate:
|
||||
docker build --tag frigate-base --build-arg ARCH=aarch64 --file docker/Dockerfile.base .
|
||||
docker build --tag frigate --file docker/Dockerfile.aarch64 .
|
||||
arm64:
|
||||
docker buildx build --platform linux/arm64 --tag blakeblackshear/frigate:$(VERSION)-$(COMMIT_HASH) --file docker/Dockerfile .
|
||||
|
||||
armv7_all: armv7_wheels armv7_ffmpeg armv7_frigate
|
||||
armv7:
|
||||
docker buildx build --platform linux/arm/v7 --tag blakeblackshear/frigate:$(VERSION)-$(COMMIT_HASH) --file docker/Dockerfile .
|
||||
|
||||
armv7_wheels:
|
||||
docker build --tag blakeblackshear/frigate-wheels:armv7 --file docker/Dockerfile.wheels .
|
||||
build: version amd64 arm64 armv7
|
||||
docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag blakeblackshear/frigate:$(VERSION)-$(COMMIT_HASH) --file docker/Dockerfile .
|
||||
|
||||
armv7_ffmpeg:
|
||||
docker build --tag blakeblackshear/frigate-ffmpeg:armv7 --file docker/Dockerfile.ffmpeg.armv7 .
|
||||
push: build
|
||||
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 --tag blakeblackshear/frigate:$(VERSION)-$(COMMIT_HASH) --file docker/Dockerfile .
|
||||
|
||||
armv7_frigate:
|
||||
docker build --tag frigate-base --build-arg ARCH=armv7 --file docker/Dockerfile.base .
|
||||
docker build --tag frigate --file docker/Dockerfile.armv7 .
|
||||
run_tests: frigate
|
||||
docker run --rm --entrypoint=python3 frigate:latest -u -m unittest
|
||||
docker run --rm --entrypoint=python3 frigate:latest -u -m mypy --config-file frigate/mypy.ini frigate
|
||||
|
||||
armv7_all: armv7_wheels armv7_ffmpeg armv7_frigate
|
||||
.PHONY: run_tests
|
||||
|
||||
423
README.md
@@ -1,410 +1,45 @@
|
||||
<p align="center">
|
||||
<img align="center" alt="logo" src="docs/static/img/frigate.png">
|
||||
</p>
|
||||
|
||||
# Frigate - NVR With Realtime Object Detection for IP Cameras
|
||||
Uses OpenCV and Tensorflow to perform realtime object detection locally for IP cameras. Designed for integration with HomeAssistant or others via MQTT.
|
||||
|
||||
Use of a [Google Coral Accelerator](https://coral.ai/products/) is optional, but highly recommended. On my Intel i7 processor, I can process 2-3 FPS with the CPU. The Coral can process 100+ FPS with very low CPU load.
|
||||
A complete and local NVR designed for [Home Assistant](https://www.home-assistant.io) with AI object detection. Uses OpenCV and Tensorflow to perform realtime object detection locally for IP cameras.
|
||||
|
||||
Use of a [Google Coral Accelerator](https://coral.ai/products/) is optional, but highly recommended. The Coral will outperform even the best CPUs and can process 100+ FPS with very little overhead.
|
||||
|
||||
- Tight integration with Home Assistant via a [custom component](https://github.com/blakeblackshear/frigate-hass-integration)
|
||||
- Designed to minimize resource use and maximize performance by only looking for objects when and where it is necessary
|
||||
- Leverages multiprocessing heavily with an emphasis on realtime over processing every frame
|
||||
- Uses a very low overhead motion detection to determine where to run object detection
|
||||
- Object detection with Tensorflow runs in a separate process
|
||||
- Object info is published over MQTT for integration into HomeAssistant as a binary sensor
|
||||
- An endpoint is available to view an MJPEG stream for debugging, but should not be used continuously
|
||||
|
||||

|
||||
|
||||
## Example video (from older version)
|
||||
You see multiple bounding boxes because it draws bounding boxes from all frames in the past 1 second where a person was detected. Not all of the bounding boxes were from the current frame.
|
||||
[](http://www.youtube.com/watch?v=nqHbCtyo4dY "Frigate")
|
||||
- Object detection with TensorFlow runs in separate processes for maximum FPS
|
||||
- Communicates over MQTT for easy integration into other systems
|
||||
- Records video with retention settings based on detected objects
|
||||
- 24/7 recording
|
||||
- Re-streaming via RTMP to reduce the number of connections to your camera
|
||||
|
||||
## Documentation
|
||||
- [Camera Specific Docs](docs/CAMERAS.md)
|
||||
- [Hardware Acceleration](docs/HWACCEL.md)
|
||||
|
||||
## Getting Started
|
||||
Run the container with
|
||||
```bash
|
||||
docker run --rm \
|
||||
--name frigate \
|
||||
--privileged \
|
||||
--shm-size=100m \ # only needed with large numbers of high res cameras
|
||||
-v /dev/bus/usb:/dev/bus/usb \
|
||||
-v <path_to_config_dir>:/config:ro \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
-p 5000:5000 \
|
||||
-e FRIGATE_RTSP_PASSWORD='password' \
|
||||
blakeblackshear/frigate:0.7.0-amd64
|
||||
```
|
||||
View the documentation at https://docs.frigate.video
|
||||
|
||||
Example docker-compose:
|
||||
```yaml
|
||||
frigate:
|
||||
container_name: frigate
|
||||
restart: unless-stopped
|
||||
privileged: true
|
||||
shm_size: '100m' # only needed with large numbers of high res cameras
|
||||
image: blakeblackshear/frigate:0.7.0-amd64
|
||||
volumes:
|
||||
- /dev/bus/usb:/dev/bus/usb
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- <path_to_config>:/config
|
||||
- <path_to_directory_for_clips>:/clips
|
||||
ports:
|
||||
- "5000:5000"
|
||||
environment:
|
||||
FRIGATE_RTSP_PASSWORD: "password"
|
||||
healthcheck:
|
||||
test: ["CMD", "wget" , "-q", "-O-", "http://localhost:5000"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 3m
|
||||
```
|
||||
## Donations
|
||||
|
||||
A `config.yml` file must exist in the `config` directory. See example [here](config/config.example.yml) and camera specific info can be found [here](docs/CAMERAS.md).
|
||||
If you would like to make a donation to support development, please use [Github Sponsors](https://github.com/sponsors/blakeblackshear).
|
||||
|
||||
### Calculating shm-size
|
||||
The default shm-size of 64m should be fine for most setups. If you start seeing segfault errors, it could be because you have too many high resolution cameras and you need to specify a higher shm size.
|
||||
## Screenshots
|
||||
|
||||
You can calculate the necessary shm-size for each camera with the following formula:
|
||||
```
|
||||
(width * height * 3 + 270480)/1048576 = <shm size in mb>
|
||||
```
|
||||
Integration into Home Assistant
|
||||
|
||||
## Recommended Hardware
|
||||
|Name|Inference Speed|Notes|
|
||||
|----|---------------|-----|
|
||||
|Atomic Pi|16ms|Best option for a dedicated low power board with a small number of cameras.|
|
||||
|Intel NUC NUC7i3BNK|8-10ms|Best possible performance. Can handle 7+ cameras at 5fps depending on typical amounts of motion.|
|
||||
|BMAX B2 Plus|10-12ms|Good balance of performance and cost. Also capable of running many other services at the same time as frigate.|
|
||||
|Minisforum GK41|9-10ms|Great alternative to a NUC. Easily handiles 4 1080p cameras.|
|
||||
|Raspberry Pi 3B (32bit)|60ms|Can handle a small number of cameras, but the detection speeds are slow|
|
||||
|Raspberry Pi 4 (32bit)|15-20ms|Can handle a small number of cameras. The 2GB version runs fine.|
|
||||
|Raspberry Pi 4 (64bit)|10-15ms|Can handle a small number of cameras. The 2GB version runs fine.|
|
||||
<div>
|
||||
<a href="docs/static/img/media_browser.png"><img src="docs/static/img/media_browser.png" height=400></a>
|
||||
<a href="docs/static/img/notification.png"><img src="docs/static/img/notification.png" height=400></a>
|
||||
</div>
|
||||
|
||||
Users have reported varying success in getting frigate to run in a VM. In some cases, the virtualization layer introduces a significant delay in communication with the Coral. If running virtualized in Proxmox, pass the USB card/interface to the virtual machine not the USB ID for faster inference speed.
|
||||
Also comes with a builtin UI:
|
||||
|
||||
## Integration with HomeAssistant
|
||||
|
||||
Setup a camera, binary_sensor, sensor and optionally automation as shown for each camera you define in frigate. Replace <camera_name> with the camera name as defined in the frigate `config.yml` (The `frigate_coral_fps` and `frigate_coral_inference` sensors only need to be defined once)
|
||||
|
||||
```
|
||||
camera:
|
||||
- name: <camera_name> Last Person
|
||||
platform: mqtt
|
||||
topic: frigate/<camera_name>/person/snapshot
|
||||
- name: <camera_name> Last Car
|
||||
platform: mqtt
|
||||
topic: frigate/<camera_name>/car/snapshot
|
||||
|
||||
binary_sensor:
|
||||
- name: <camera_name> Person
|
||||
platform: mqtt
|
||||
state_topic: "frigate/<camera_name>/person"
|
||||
device_class: motion
|
||||
availability_topic: "frigate/available"
|
||||
|
||||
sensor:
|
||||
- platform: rest
|
||||
name: Frigate Debug
|
||||
resource: http://localhost:5000/debug/stats
|
||||
scan_interval: 5
|
||||
json_attributes:
|
||||
- <camera_name>
|
||||
- detection_fps
|
||||
- detectors
|
||||
value_template: 'OK'
|
||||
- platform: template
|
||||
sensors:
|
||||
<camera_name>_fps:
|
||||
value_template: '{{ states.sensor.frigate_debug.attributes["<camera_name>"]["fps"] }}'
|
||||
unit_of_measurement: 'FPS'
|
||||
<camera_name>_skipped_fps:
|
||||
value_template: '{{ states.sensor.frigate_debug.attributes["<camera_name>"]["skipped_fps"] }}'
|
||||
unit_of_measurement: 'FPS'
|
||||
<camera_name>_detection_fps:
|
||||
value_template: '{{ states.sensor.frigate_debug.attributes["<camera_name>"]["detection_fps"] }}'
|
||||
unit_of_measurement: 'FPS'
|
||||
frigate_detection_fps:
|
||||
value_template: '{{ states.sensor.frigate_debug.attributes["detection_fps"] }}'
|
||||
unit_of_measurement: 'FPS'
|
||||
frigate_coral_inference:
|
||||
value_template: '{{ states.sensor.frigate_debug.attributes["detectors"]["coral"]["inference_speed"] }}'
|
||||
unit_of_measurement: 'ms'
|
||||
|
||||
automation:
|
||||
- alias: Alert me if a person is detected while armed away
|
||||
trigger:
|
||||
platform: state
|
||||
entity_id: binary_sensor.camera_person
|
||||
from: 'off'
|
||||
to: 'on'
|
||||
condition:
|
||||
- condition: state
|
||||
entity_id: alarm_control_panel.home_alarm
|
||||
state: armed_away
|
||||
action:
|
||||
- service: notify.user_telegram
|
||||
data:
|
||||
message: "A person was detected."
|
||||
data:
|
||||
photo:
|
||||
- url: http://<ip>:5000/<camera_name>/person/best.jpg
|
||||
caption: A person was detected.
|
||||
```
|
||||
## HTTP Endpoints
|
||||
A web server is available on port 5000 with the following endpoints.
|
||||
|
||||
### `/<camera_name>`
|
||||
An mjpeg stream for debugging. Keep in mind the mjpeg endpoint is for debugging only and will put additional load on the system when in use.
|
||||
|
||||
You can access a higher resolution mjpeg stream by appending `h=height-in-pixels` to the endpoint. For example `http://localhost:5000/back?h=1080`. You can also increase the FPS by appending `fps=frame-rate` to the URL such as `http://localhost:5000/back?fps=10` or both with `?fps=10&h=1000`
|
||||
|
||||
### `/<camera_name>/<object_name>/best.jpg[?h=300&crop=1]`
|
||||
The best snapshot for any object type. It is a full resolution image by default.
|
||||
|
||||
Example parameters:
|
||||
- `h=300`: resizes the image to 300 pixes tall
|
||||
- `crop=1`: crops the image to the region of the detection rather than returning the entire image
|
||||
|
||||
### `/<camera_name>/latest.jpg[?h=300]`
|
||||
The most recent frame that frigate has finished processing. It is a full resolution image by default.
|
||||
|
||||
Example parameters:
|
||||
- `h=300`: resizes the image to 300 pixes tall
|
||||
|
||||
### `/debug/stats`
|
||||
Contains some granular debug info that can be used for sensors in HomeAssistant. See details below.
|
||||
|
||||
## MQTT Messages
|
||||
These are the MQTT messages generated by Frigate. The default topic_prefix is `frigate`, but can be changed in the config file.
|
||||
|
||||
### frigate/available
|
||||
Designed to be used as an availability topic with HomeAssistant. Possible message are:
|
||||
"online": published when frigate is running (on startup)
|
||||
"offline": published right before frigate stops
|
||||
|
||||
### frigate/<camera_name>/<object_name>
|
||||
Publishes `ON` or `OFF` and is designed to be used a as a binary sensor in HomeAssistant for whether or not that object type is detected.
|
||||
|
||||
### frigate/<camera_name>/<object_name>/snapshot
|
||||
Publishes a jpeg encoded frame of the detected object type. When the object is no longer detected, the highest confidence image is published or the original image
|
||||
is published again.
|
||||
|
||||
The height and crop of snapshots can be configured as shown in the example config.
|
||||
|
||||
### frigate/<camera_name>/events/start
|
||||
Message published at the start of any tracked object. JSON looks as follows:
|
||||
```json
|
||||
{
|
||||
"label": "person",
|
||||
"score": 0.87890625,
|
||||
"box": [
|
||||
95,
|
||||
155,
|
||||
581,
|
||||
1182
|
||||
],
|
||||
"area": 499122,
|
||||
"region": [
|
||||
0,
|
||||
132,
|
||||
1080,
|
||||
1212
|
||||
],
|
||||
"frame_time": 1600208805.60284,
|
||||
"centroid": [
|
||||
338,
|
||||
668
|
||||
],
|
||||
"id": "1600208805.60284-k1l43p",
|
||||
"start_time": 1600208805.60284,
|
||||
"top_score": 0.87890625,
|
||||
"zones": [],
|
||||
"score_history": [
|
||||
0.87890625
|
||||
],
|
||||
"computed_score": 0.0,
|
||||
"false_positive": true
|
||||
}
|
||||
```
|
||||
|
||||
### frigate/<camera_name>/events/end
|
||||
Same as `frigate/<camera_name>/events/start`, but with an `end_time` property as well.
|
||||
|
||||
### frigate/<zone_name>/<object_name>
|
||||
Publishes `ON` or `OFF` and is designed to be used a as a binary sensor in HomeAssistant for whether or not that object type is detected in the zone.
|
||||
|
||||
## Understanding min_score and threshold filters
|
||||
`min_score` defines the minimum score for Frigate to begin tracking a detected object. Any single detection below `min_score` will be ignored as a false positive. `threshold` is based on the median of the history of scores for a tracked object. Consider the following frames when `min_score` is set to 0.6 and threshold is set to 0.85:
|
||||
|
||||
| Frame | Current Score | Score History | Computed Score | Detected Object |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 1 | 0.7 | 0.0, 0, 0.7 | 0.0 | No
|
||||
| 2 | 0.55 | 0.0, 0.7, 0.0 | 0.0 | No
|
||||
| 3 | 0.85 | 0.7, 0.0, 0.85 | 0.7 | No
|
||||
| 4 | 0.90 | 0.7, 0.85, 0.95, 0.90 | 0.875 | Yes
|
||||
| 5 | 0.88 | 0.7, 0.85, 0.95, 0.90, 0.88 | 0.88 | Yes
|
||||
| 6 | 0.95 | 0.7, 0.85, 0.95, 0.90, 0.88, 0.95 | 0.89 | Yes
|
||||
|
||||
In frame 2, the score is below the `min_score` value, so frigate ignores it and it becomes a 0.0. The computed score is the median of the score history (padding to at least 3 values), and only when that computed score crosses the `threshold` is the object marked as a true positive. That happens in frame 4 in the example.
|
||||
|
||||
## Using a custom model or labels
|
||||
Models for both CPU and EdgeTPU (Coral) are bundled in the image. You can use your own models with volume mounts:
|
||||
- CPU Model: `/cpu_model.tflite`
|
||||
- EdgeTPU Model: `/edgetpu_model.tflite`
|
||||
- Labels: `/labelmap.txt`
|
||||
|
||||
### Customizing the Labelmap
|
||||
The labelmap can be customized to your needs. A common reason to do this is to combine multiple object types that are easily confused when you don't need to be as granular such as car/truck. You must retain the same number of labels, but you can change the names. To change:
|
||||
|
||||
- Download the [COCO labelmap](https://dl.google.com/coral/canned_models/coco_labels.txt)
|
||||
- Modify the label names as desired. For example, change `7 truck` to `7 car`
|
||||
- Mount the new file at `/labelmap.txt` in the container with an additional volume
|
||||
```
|
||||
-v ./config/labelmap.txt:/labelmap.txt
|
||||
```
|
||||
|
||||
## Recording Clips
|
||||
**Note**: Previous versions of frigate included `-vsync drop` in input parameters. This is not compatible with FFmpeg's segment feature and must be removed from your input parameters if you have overrides set.
|
||||
|
||||
Frigate can save video clips without any CPU overhead for encoding by simply copying the stream directly with FFmpeg. It leverages FFmpeg's segment functionality to maintain a cache of 90 seconds of video for each camera. The cache files are written to disk at /cache and do not introduce memory overhead. When an object is being tracked, it will extend the cache to ensure it can assemble a clip when the event ends. Once the event ends, it again uses FFmpeg to assemble a clip by combining the video clips without any encoding by the CPU. Assembled clips are are saved to the /clips directory along with a json file containing the current information about the tracked object.
|
||||
|
||||
### Global Configuration Options
|
||||
- `max_seconds`: This limits the size of the cache when an object is being tracked. If an object is stationary and being tracked for a long time, the cache files will expire and this value will be the maximum clip length for the *end* of the event. For example, if this is set to 300 seconds and an object is being tracked for 600 seconds, the clip will end up being the last 300 seconds. Defaults to 300 seconds.
|
||||
|
||||
### Per-camera Configuration Options
|
||||
- `pre_capture`: Defines how much time should be included in the clip prior to the beginning of the event. Defaults to 30 seconds.
|
||||
- `objects`: List of object types to save clips for. Object types here must be listed for tracking at the camera or global configuration. Defaults to all tracked objects.
|
||||
|
||||
## Detectors Configuration
|
||||
Frigate attempts to detect your Coral device automatically. If you have multiple Coral devices or a version that is not detected automatically, you can specify using the `detectors` config option as shown in the example config.
|
||||
|
||||
## Masks and limiting detection to a certain area
|
||||
The mask works by looking at the bottom center of any bounding box (first image, red dot below) and comparing that to your mask. If that red dot falls on an area of your mask that is black, the detection (and motion) will be ignored. The mask in the second image would limit detection on this camera to only objects that are in the front yard and not the street.
|
||||
|
||||
<a href="docs/example-mask-check-point.png"><img src="docs/example-mask-check-point.png" height="300"></a>
|
||||
<a href="docs/example-mask.bmp"><img src="docs/example-mask.bmp" height="300"></a>
|
||||
<a href="docs/example-mask-overlay.png"><img src="docs/example-mask-overlay.png" height="300"></a>
|
||||
|
||||
The following types of masks are supported:
|
||||
- `base64`: Base64 encoded image file
|
||||
- `poly`: List of x,y points like zone configuration
|
||||
- `image`: Path to an image file in the config directory
|
||||
|
||||
`base64` and `image` masks must be the same aspect ratio as your camera.
|
||||
|
||||
## Zones
|
||||
Zones allow you to define a specific area of the frame and apply additional filters for object types so you can determine whether or not an object is within a particular area. Zones cannot have the same name as a camera. If desired, a single zone can include multiple cameras if you have multiple cameras covering the same area. See the sample config for details on how to configure.
|
||||
|
||||
During testing, `draw_zones` can be set in the config to tell frigate to draw the zone on the frames so you can adjust as needed. The zone line will increase in thickness when any object enters the zone.
|
||||
|
||||

|
||||
|
||||
## Debug Info
|
||||
```jsonc
|
||||
{
|
||||
/* Per Camera Stats */
|
||||
"back": {
|
||||
/***************
|
||||
* Frames per second being consumed from your camera. If this is higher
|
||||
* than it is supposed to be, you should set -r FPS in your input_args.
|
||||
* camera_fps = process_fps + skipped_fps
|
||||
***************/
|
||||
"camera_fps": 5.0,
|
||||
/***************
|
||||
* Number of times detection is run per second. This can be higher than
|
||||
* your camera FPS because frigate often looks at the same frame multiple times
|
||||
* or in multiple locations
|
||||
***************/
|
||||
"detection_fps": 1.5,
|
||||
/***************
|
||||
* PID for the ffmpeg process that consumes this camera
|
||||
***************/
|
||||
"ffmpeg_pid": 27,
|
||||
/***************
|
||||
* Timestamps of frames in various parts of processing
|
||||
***************/
|
||||
"frame_info": {
|
||||
/***************
|
||||
* Timestamp of the frame frigate is running object detection on.
|
||||
***************/
|
||||
"detect": 1596994991.91426,
|
||||
/***************
|
||||
* Timestamp of the frame frigate is processing detected objects on.
|
||||
* This is where MQTT messages are sent, zones are checked, etc.
|
||||
***************/
|
||||
"process": 1596994991.91426,
|
||||
/***************
|
||||
* Timestamp of the frame frigate last read from ffmpeg.
|
||||
***************/
|
||||
"read": 1596994991.91426
|
||||
},
|
||||
/***************
|
||||
* PID for the process that runs detection for this camera
|
||||
***************/
|
||||
"pid": 34,
|
||||
/***************
|
||||
* Frames per second being processed by frigate.
|
||||
***************/
|
||||
"process_fps": 5.1,
|
||||
/***************
|
||||
* Timestamp when the detection process started looking for a frame. If this value stays constant
|
||||
* for a long time, that means there aren't any frames in the frame queue.
|
||||
***************/
|
||||
"read_start": 1596994991.943814,
|
||||
/***************
|
||||
* Frames per second skip for processing by frigate.
|
||||
***************/
|
||||
"skipped_fps": 0.0
|
||||
},
|
||||
/***************
|
||||
* Sum of detection_fps across all cameras and detectors.
|
||||
* This should be the sum of all detection_fps values from cameras.
|
||||
***************/
|
||||
"detection_fps": 5.0,
|
||||
/* Detectors Stats */
|
||||
"detectors": {
|
||||
"coral": {
|
||||
/***************
|
||||
* Timestamp when object detection started. If this value stays non-zero and constant
|
||||
* for a long time, that means the detection process is stuck.
|
||||
***************/
|
||||
"detection_start": 0.0,
|
||||
/***************
|
||||
* Time spent running object detection in milliseconds.
|
||||
***************/
|
||||
"inference_speed": 10.48,
|
||||
/***************
|
||||
* PID for the shared process that runs object detection on the Coral.
|
||||
***************/
|
||||
"pid": 25321
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tips
|
||||
- Lower the framerate of the video feed on the camera to reduce the CPU usage for capturing the feed. Not as effective, but you can also modify the `take_frame` [configuration](config/config.example.yml) for each camera to only analyze every other frame, or every third frame, etc.
|
||||
- Hard code the resolution of each camera in your config if you are having difficulty starting frigate or if the initial ffprobe for camerea resolution fails or returns incorrect info. Example:
|
||||
```
|
||||
cameras:
|
||||
back:
|
||||
ffmpeg:
|
||||
input: rtsp://<camera>
|
||||
height: 1080
|
||||
width: 1920
|
||||
```
|
||||
- Additional logging is available in the docker container - You can view the logs by running `docker logs -t frigate`
|
||||
- Object configuration - Tracked objects types, sizes and thresholds can be defined globally and/or on a per camera basis. The global and camera object configuration is *merged*. For example, if you defined tracking person, car, and truck globally but modified your backyard camera to only track person, the global config would merge making the effective list for the backyard camera still contain person, car and truck. If you want precise object tracking per camera, best practice to put a minimal list of objects at the global level and expand objects on a per camera basis. Object threshold and area configuration will be used first from the camera object config (if defined) and then from the global config. See the [example config](config/config.example.yml) for more information.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "ffmpeg didnt return a frame. something is wrong"
|
||||
Turn on logging for the camera by overriding the global_args and setting the log level to `info`:
|
||||
```yaml
|
||||
ffmpeg:
|
||||
global_args:
|
||||
- -hide_banner
|
||||
- -loglevel
|
||||
- info
|
||||
```
|
||||
<div>
|
||||
<a href="docs/static/img/home-ui.png"><img src="docs/static/img/home-ui.png" height=400></a>
|
||||
<a href="docs/static/img/camera-ui.png"><img src="docs/static/img/camera-ui.png" height=400></a>
|
||||
</div>
|
||||
|
||||

|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 MiB |
@@ -1,234 +0,0 @@
|
||||
web_port: 5000
|
||||
|
||||
################
|
||||
## List of detectors.
|
||||
## Currently supported types: cpu, edgetpu
|
||||
## EdgeTPU requires device as defined here: https://coral.ai/docs/edgetpu/multiple-edgetpu/#using-the-tensorflow-lite-python-api
|
||||
################
|
||||
detectors:
|
||||
coral:
|
||||
type: edgetpu
|
||||
device: usb
|
||||
|
||||
mqtt:
|
||||
host: mqtt.server.com
|
||||
topic_prefix: frigate
|
||||
# client_id: frigate # Optional -- set to override default client id of 'frigate' if running multiple instances
|
||||
# user: username # Optional
|
||||
#################
|
||||
## Environment variables that begin with 'FRIGATE_' may be referenced in {}.
|
||||
## password: '{FRIGATE_MQTT_PASSWORD}'
|
||||
#################
|
||||
# password: password # Optional
|
||||
|
||||
################
|
||||
# Global configuration for saving clips
|
||||
################
|
||||
save_clips:
|
||||
###########
|
||||
# Maximum length of time to retain video during long events.
|
||||
# If an object is being tracked for longer than this amount of time, the cache
|
||||
# will begin to expire and the resulting clip will be the last x seconds of the event.
|
||||
###########
|
||||
max_seconds: 300
|
||||
clips_dir: /clips
|
||||
cache_dir: /cache
|
||||
|
||||
#################
|
||||
# Default ffmpeg args. Optional and can be overwritten per camera.
|
||||
# Should work with most RTSP cameras that send h264 video
|
||||
# Built from the properties below with:
|
||||
# "ffmpeg" + global_args + input_args + "-i" + input + output_args
|
||||
#################
|
||||
# ffmpeg:
|
||||
# global_args:
|
||||
# - -hide_banner
|
||||
# - -loglevel
|
||||
# - panic
|
||||
# hwaccel_args: []
|
||||
# input_args:
|
||||
# - -avoid_negative_ts
|
||||
# - make_zero
|
||||
# - -fflags
|
||||
# - nobuffer
|
||||
# - -flags
|
||||
# - low_delay
|
||||
# - -strict
|
||||
# - experimental
|
||||
# - -fflags
|
||||
# - +genpts+discardcorrupt
|
||||
# - -vsync
|
||||
# - drop
|
||||
# - -rtsp_transport
|
||||
# - tcp
|
||||
# - -stimeout
|
||||
# - '5000000'
|
||||
# - -use_wallclock_as_timestamps
|
||||
# - '1'
|
||||
# output_args:
|
||||
# - -f
|
||||
# - rawvideo
|
||||
# - -pix_fmt
|
||||
# - yuv420p
|
||||
|
||||
####################
|
||||
# Global object configuration. Applies to all cameras
|
||||
# unless overridden at the camera levels.
|
||||
# Keys must be valid labels. By default, the model uses coco (https://dl.google.com/coral/canned_models/coco_labels.txt).
|
||||
# All labels from the model are reported over MQTT. These values are used to filter out false positives.
|
||||
# min_area (optional): minimum width*height of the bounding box for the detected object
|
||||
# max_area (optional): maximum width*height of the bounding box for the detected object
|
||||
# min_score (optional): minimum score for the object to initiate tracking
|
||||
# threshold (optional): The minimum decimal percentage for tracked object's computed score to considered a true positive
|
||||
####################
|
||||
objects:
|
||||
track:
|
||||
- person
|
||||
filters:
|
||||
person:
|
||||
min_area: 5000
|
||||
max_area: 100000
|
||||
min_score: 0.5
|
||||
threshold: 0.85
|
||||
|
||||
cameras:
|
||||
back:
|
||||
ffmpeg:
|
||||
################
|
||||
# Source passed to ffmpeg after the -i parameter. Supports anything compatible with OpenCV and FFmpeg.
|
||||
# Environment variables that begin with 'FRIGATE_' may be referenced in {}
|
||||
################
|
||||
input: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2
|
||||
#################
|
||||
# These values will override default values for just this camera
|
||||
#################
|
||||
# global_args: []
|
||||
# hwaccel_args: []
|
||||
# input_args: []
|
||||
# output_args: []
|
||||
|
||||
################
|
||||
## Optionally specify the resolution of the video feed. Frigate will try to auto detect if not specified
|
||||
################
|
||||
# height: 1280
|
||||
# width: 720
|
||||
|
||||
################
|
||||
## Specify the framerate of your camera
|
||||
##
|
||||
## NOTE: This should only be set in the event ffmpeg is unable to determine your camera's framerate
|
||||
## on its own and the reported framerate for your camera in frigate is well over what is expected.
|
||||
################
|
||||
# fps: 5
|
||||
|
||||
################
|
||||
## Optional mask. Must be the same aspect ratio as your video feed. Value is any of the following:
|
||||
## - name of a file in the config directory
|
||||
## - base64 encoded image prefixed with 'base64,' eg. 'base64,asfasdfasdf....'
|
||||
## - polygon of x,y coordinates prefixed with 'poly,' eg. 'poly,0,900,1080,900,1080,1920,0,1920'
|
||||
##
|
||||
## The mask works by looking at the bottom center of the bounding box for the detected
|
||||
## person in the image. If that pixel in the mask is a black pixel, it ignores it as a
|
||||
## false positive. In my mask, the grass and driveway visible from my backdoor camera
|
||||
## are white. The garage doors, sky, and trees (anywhere it would be impossible for a
|
||||
## person to stand) are black.
|
||||
##
|
||||
## Masked areas are also ignored for motion detection.
|
||||
################
|
||||
# mask: back-mask.bmp
|
||||
|
||||
################
|
||||
# Allows you to limit the framerate within frigate for cameras that do not support
|
||||
# custom framerates. A value of 1 tells frigate to look at every frame, 2 every 2nd frame,
|
||||
# 3 every 3rd frame, etc.
|
||||
################
|
||||
take_frame: 1
|
||||
|
||||
################
|
||||
# The number of seconds to retain the highest scoring image for the best.jpg endpoint before allowing it
|
||||
# to be replaced by a newer image. Defaults to 60 seconds.
|
||||
################
|
||||
best_image_timeout: 60
|
||||
|
||||
################
|
||||
# MQTT settings
|
||||
################
|
||||
# mqtt:
|
||||
# crop_to_region: True
|
||||
# snapshot_height: 300
|
||||
|
||||
################
|
||||
# Zones
|
||||
################
|
||||
zones:
|
||||
#################
|
||||
# Name of the zone
|
||||
################
|
||||
front_steps:
|
||||
####################
|
||||
# A list of x,y coordinates to define the polygon of the zone. The top
|
||||
# left corner is 0,0. Can also be a comma separated string of all x,y coordinates combined.
|
||||
# The same zone name can exist across multiple cameras if they have overlapping FOVs.
|
||||
# An object is determined to be in the zone based on whether or not the bottom center
|
||||
# of it's bounding box is within the polygon. The polygon must have at least 3 points.
|
||||
# Coordinates can be generated at https://www.image-map.net/
|
||||
####################
|
||||
coordinates:
|
||||
- 545,1077
|
||||
- 747,939
|
||||
- 788,805
|
||||
################
|
||||
# Zone level object filters. These are applied in addition to the global and camera filters
|
||||
# and should be more restrictive than the global and camera filters. The global and camera
|
||||
# filters are applied upstream.
|
||||
################
|
||||
filters:
|
||||
person:
|
||||
min_area: 5000
|
||||
max_area: 100000
|
||||
threshold: 0.8
|
||||
|
||||
################
|
||||
# This will save a clip for each tracked object by frigate along with a json file that contains
|
||||
# data related to the tracked object. This works by telling ffmpeg to write video segments to /cache
|
||||
# from the video stream without re-encoding. Clips are then created by using ffmpeg to merge segments
|
||||
# without re-encoding. The segments saved are unaltered from what frigate receives to avoid re-encoding.
|
||||
# They do not contain bounding boxes. These are optimized to capture "false_positive" examples for improving frigate.
|
||||
#
|
||||
# NOTE: This feature does not work if you have "-vsync drop" configured in your input params.
|
||||
# This will only work for camera feeds that can be copied into the mp4 container format without
|
||||
# encoding such as h264. It may not work for some types of streams.
|
||||
################
|
||||
save_clips:
|
||||
enabled: False
|
||||
#########
|
||||
# Number of seconds before the event to include in the clips
|
||||
#########
|
||||
pre_capture: 30
|
||||
#########
|
||||
# Objects to save clips for. Defaults to all tracked object types.
|
||||
#########
|
||||
# objects:
|
||||
# - person
|
||||
|
||||
################
|
||||
# Configuration for the snapshots in the debug view and mqtt
|
||||
################
|
||||
snapshots:
|
||||
show_timestamp: True
|
||||
draw_zones: False
|
||||
draw_bounding_boxes: True
|
||||
|
||||
################
|
||||
# Camera level object config. If defined, this is used instead of the global config.
|
||||
################
|
||||
objects:
|
||||
track:
|
||||
- person
|
||||
- car
|
||||
filters:
|
||||
person:
|
||||
min_area: 5000
|
||||
max_area: 100000
|
||||
min_score: 0.5
|
||||
threshold: 0.85
|
||||
@@ -1,480 +0,0 @@
|
||||
import faulthandler; faulthandler.enable()
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
import traceback
|
||||
import signal
|
||||
import cv2
|
||||
import time
|
||||
import datetime
|
||||
import queue
|
||||
import yaml
|
||||
import json
|
||||
import threading
|
||||
import multiprocessing as mp
|
||||
import subprocess as sp
|
||||
import numpy as np
|
||||
import logging
|
||||
from flask import Flask, Response, make_response, jsonify, request
|
||||
import paho.mqtt.client as mqtt
|
||||
|
||||
from frigate.video import track_camera, get_ffmpeg_input, get_frame_shape, CameraCapture, start_or_restart_ffmpeg
|
||||
from frigate.object_processing import TrackedObjectProcessor
|
||||
from frigate.events import EventProcessor
|
||||
from frigate.util import EventsPerSecond
|
||||
from frigate.edgetpu import EdgeTPUProcess
|
||||
|
||||
FRIGATE_VARS = {k: v for k, v in os.environ.items() if k.startswith('FRIGATE_')}
|
||||
|
||||
CONFIG_FILE = os.environ.get('CONFIG_FILE', '/config/config.yml')
|
||||
|
||||
if CONFIG_FILE.endswith(".yml"):
|
||||
with open(CONFIG_FILE) as f:
|
||||
CONFIG = yaml.safe_load(f)
|
||||
elif CONFIG_FILE.endswith(".json"):
|
||||
with open(CONFIG_FILE) as f:
|
||||
CONFIG = json.load(f)
|
||||
|
||||
CACHE_DIR = CONFIG.get('save_clips', {}).get('cache_dir', '/cache')
|
||||
CLIPS_DIR = CONFIG.get('save_clips', {}).get('clips_dir', '/clips')
|
||||
|
||||
if not os.path.exists(CACHE_DIR) and not os.path.islink(CACHE_DIR):
|
||||
os.makedirs(CACHE_DIR)
|
||||
if not os.path.exists(CLIPS_DIR) and not os.path.islink(CLIPS_DIR):
|
||||
os.makedirs(CLIPS_DIR)
|
||||
|
||||
MQTT_HOST = CONFIG['mqtt']['host']
|
||||
MQTT_PORT = CONFIG.get('mqtt', {}).get('port', 1883)
|
||||
MQTT_TOPIC_PREFIX = CONFIG.get('mqtt', {}).get('topic_prefix', 'frigate')
|
||||
MQTT_USER = CONFIG.get('mqtt', {}).get('user')
|
||||
MQTT_PASS = CONFIG.get('mqtt', {}).get('password')
|
||||
if not MQTT_PASS is None:
|
||||
MQTT_PASS = MQTT_PASS.format(**FRIGATE_VARS)
|
||||
MQTT_CLIENT_ID = CONFIG.get('mqtt', {}).get('client_id', 'frigate')
|
||||
|
||||
# Set the default FFmpeg config
|
||||
FFMPEG_CONFIG = CONFIG.get('ffmpeg', {})
|
||||
FFMPEG_DEFAULT_CONFIG = {
|
||||
'global_args': FFMPEG_CONFIG.get('global_args',
|
||||
['-hide_banner','-loglevel','panic']),
|
||||
'hwaccel_args': FFMPEG_CONFIG.get('hwaccel_args',
|
||||
[]),
|
||||
'input_args': FFMPEG_CONFIG.get('input_args',
|
||||
['-avoid_negative_ts', 'make_zero',
|
||||
'-fflags', 'nobuffer',
|
||||
'-flags', 'low_delay',
|
||||
'-strict', 'experimental',
|
||||
'-fflags', '+genpts+discardcorrupt',
|
||||
'-rtsp_transport', 'tcp',
|
||||
'-stimeout', '5000000',
|
||||
'-use_wallclock_as_timestamps', '1']),
|
||||
'output_args': FFMPEG_CONFIG.get('output_args',
|
||||
['-f', 'rawvideo',
|
||||
'-pix_fmt', 'yuv420p'])
|
||||
}
|
||||
|
||||
GLOBAL_OBJECT_CONFIG = CONFIG.get('objects', {})
|
||||
|
||||
WEB_PORT = CONFIG.get('web_port', 5000)
|
||||
DETECTORS = CONFIG.get('detectors', {'coral': {'type': 'edgetpu', 'device': 'usb'}})
|
||||
|
||||
class CameraWatchdog(threading.Thread):
|
||||
def __init__(self, camera_processes, config, detectors, detection_queue, tracked_objects_queue, stop_event):
|
||||
threading.Thread.__init__(self)
|
||||
self.camera_processes = camera_processes
|
||||
self.config = config
|
||||
self.detectors = detectors
|
||||
self.detection_queue = detection_queue
|
||||
self.tracked_objects_queue = tracked_objects_queue
|
||||
self.stop_event = stop_event
|
||||
|
||||
def run(self):
|
||||
time.sleep(10)
|
||||
while True:
|
||||
# wait a bit before checking
|
||||
time.sleep(10)
|
||||
|
||||
if self.stop_event.is_set():
|
||||
print(f"Exiting watchdog...")
|
||||
break
|
||||
|
||||
now = datetime.datetime.now().timestamp()
|
||||
|
||||
# check the detection processes
|
||||
for detector in self.detectors.values():
|
||||
detection_start = detector.detection_start.value
|
||||
if (detection_start > 0.0 and
|
||||
now - detection_start > 10):
|
||||
print("Detection appears to be stuck. Restarting detection process")
|
||||
detector.start_or_restart()
|
||||
elif not detector.detect_process.is_alive():
|
||||
print("Detection appears to have stopped. Restarting detection process")
|
||||
detector.start_or_restart()
|
||||
|
||||
# check the camera processes
|
||||
for name, camera_process in self.camera_processes.items():
|
||||
process = camera_process['process']
|
||||
if not process.is_alive():
|
||||
print(f"Track process for {name} is not alive. Starting again...")
|
||||
camera_process['process_fps'].value = 0.0
|
||||
camera_process['detection_fps'].value = 0.0
|
||||
camera_process['read_start'].value = 0.0
|
||||
process = mp.Process(target=track_camera, args=(name, self.config[name], camera_process['frame_queue'],
|
||||
camera_process['frame_shape'], self.detection_queue, self.tracked_objects_queue,
|
||||
camera_process['process_fps'], camera_process['detection_fps'],
|
||||
camera_process['read_start'], self.stop_event))
|
||||
process.daemon = True
|
||||
camera_process['process'] = process
|
||||
process.start()
|
||||
print(f"Track process started for {name}: {process.pid}")
|
||||
|
||||
if not camera_process['capture_thread'].is_alive():
|
||||
frame_shape = camera_process['frame_shape']
|
||||
frame_size = frame_shape[0] * frame_shape[1] * frame_shape[2]
|
||||
ffmpeg_process = start_or_restart_ffmpeg(camera_process['ffmpeg_cmd'], frame_size)
|
||||
camera_capture = CameraCapture(name, ffmpeg_process, frame_shape, camera_process['frame_queue'],
|
||||
camera_process['take_frame'], camera_process['camera_fps'], self.stop_event)
|
||||
camera_capture.start()
|
||||
camera_process['ffmpeg_process'] = ffmpeg_process
|
||||
camera_process['capture_thread'] = camera_capture
|
||||
elif now - camera_process['capture_thread'].current_frame.value > 5:
|
||||
print(f"No frames received from {name} in 5 seconds. Exiting ffmpeg...")
|
||||
ffmpeg_process = camera_process['ffmpeg_process']
|
||||
ffmpeg_process.terminate()
|
||||
try:
|
||||
print("Waiting for ffmpeg to exit gracefully...")
|
||||
ffmpeg_process.communicate(timeout=30)
|
||||
except sp.TimeoutExpired:
|
||||
print("FFmpeg didnt exit. Force killing...")
|
||||
ffmpeg_process.kill()
|
||||
ffmpeg_process.communicate()
|
||||
|
||||
def main():
|
||||
stop_event = threading.Event()
|
||||
# connect to mqtt and setup last will
|
||||
def on_connect(client, userdata, flags, rc):
|
||||
print("On connect called")
|
||||
if rc != 0:
|
||||
if rc == 3:
|
||||
print ("MQTT Server unavailable")
|
||||
elif rc == 4:
|
||||
print ("MQTT Bad username or password")
|
||||
elif rc == 5:
|
||||
print ("MQTT Not authorized")
|
||||
else:
|
||||
print ("Unable to connect to MQTT: Connection refused. Error code: " + str(rc))
|
||||
# publish a message to signal that the service is running
|
||||
client.publish(MQTT_TOPIC_PREFIX+'/available', 'online', retain=True)
|
||||
client = mqtt.Client(client_id=MQTT_CLIENT_ID)
|
||||
client.on_connect = on_connect
|
||||
client.will_set(MQTT_TOPIC_PREFIX+'/available', payload='offline', qos=1, retain=True)
|
||||
if not MQTT_USER is None:
|
||||
client.username_pw_set(MQTT_USER, password=MQTT_PASS)
|
||||
client.connect(MQTT_HOST, MQTT_PORT, 60)
|
||||
client.loop_start()
|
||||
|
||||
##
|
||||
# Setup config defaults for cameras
|
||||
##
|
||||
for name, config in CONFIG['cameras'].items():
|
||||
config['snapshots'] = {
|
||||
'show_timestamp': config.get('snapshots', {}).get('show_timestamp', True),
|
||||
'draw_zones': config.get('snapshots', {}).get('draw_zones', False),
|
||||
'draw_bounding_boxes': config.get('snapshots', {}).get('draw_bounding_boxes', True)
|
||||
}
|
||||
config['zones'] = config.get('zones', {})
|
||||
|
||||
# Queue for cameras to push tracked objects to
|
||||
tracked_objects_queue = mp.Queue()
|
||||
|
||||
# Queue for clip processing
|
||||
event_queue = mp.Queue()
|
||||
|
||||
# create the detection pipes and shms
|
||||
out_events = {}
|
||||
camera_shms = []
|
||||
for name in CONFIG['cameras'].keys():
|
||||
out_events[name] = mp.Event()
|
||||
shm_in = mp.shared_memory.SharedMemory(name=name, create=True, size=300*300*3)
|
||||
shm_out = mp.shared_memory.SharedMemory(name=f"out-{name}", create=True, size=20*6*4)
|
||||
camera_shms.append(shm_in)
|
||||
camera_shms.append(shm_out)
|
||||
|
||||
detection_queue = mp.Queue()
|
||||
|
||||
detectors = {}
|
||||
for name, detector in DETECTORS.items():
|
||||
if detector['type'] == 'cpu':
|
||||
detectors[name] = EdgeTPUProcess(detection_queue, out_events=out_events, tf_device='cpu')
|
||||
if detector['type'] == 'edgetpu':
|
||||
detectors[name] = EdgeTPUProcess(detection_queue, out_events=out_events, tf_device=detector['device'])
|
||||
|
||||
# create the camera processes
|
||||
camera_processes = {}
|
||||
for name, config in CONFIG['cameras'].items():
|
||||
# Merge the ffmpeg config with the global config
|
||||
ffmpeg = config.get('ffmpeg', {})
|
||||
ffmpeg_input = get_ffmpeg_input(ffmpeg['input'])
|
||||
ffmpeg_global_args = ffmpeg.get('global_args', FFMPEG_DEFAULT_CONFIG['global_args'])
|
||||
ffmpeg_hwaccel_args = ffmpeg.get('hwaccel_args', FFMPEG_DEFAULT_CONFIG['hwaccel_args'])
|
||||
ffmpeg_input_args = ffmpeg.get('input_args', FFMPEG_DEFAULT_CONFIG['input_args'])
|
||||
ffmpeg_output_args = ffmpeg.get('output_args', FFMPEG_DEFAULT_CONFIG['output_args'])
|
||||
if not config.get('fps') is None:
|
||||
ffmpeg_output_args = ["-r", str(config.get('fps'))] + ffmpeg_output_args
|
||||
if config.get('save_clips', {}).get('enabled', False):
|
||||
ffmpeg_output_args = [
|
||||
"-f",
|
||||
"segment",
|
||||
"-segment_time",
|
||||
"10",
|
||||
"-segment_format",
|
||||
"mp4",
|
||||
"-reset_timestamps",
|
||||
"1",
|
||||
"-strftime",
|
||||
"1",
|
||||
"-c",
|
||||
"copy",
|
||||
"-an",
|
||||
"-map",
|
||||
"0",
|
||||
f"{os.path.join(CACHE_DIR, name)}-%Y%m%d%H%M%S.mp4"
|
||||
] + ffmpeg_output_args
|
||||
ffmpeg_cmd = (['ffmpeg'] +
|
||||
ffmpeg_global_args +
|
||||
ffmpeg_hwaccel_args +
|
||||
ffmpeg_input_args +
|
||||
['-i', ffmpeg_input] +
|
||||
ffmpeg_output_args +
|
||||
['pipe:'])
|
||||
|
||||
if 'width' in config and 'height' in config:
|
||||
frame_shape = (config['height'], config['width'], 3)
|
||||
else:
|
||||
frame_shape = get_frame_shape(ffmpeg_input)
|
||||
|
||||
config['frame_shape'] = frame_shape
|
||||
|
||||
frame_size = frame_shape[0] * frame_shape[1] * frame_shape[2]
|
||||
take_frame = config.get('take_frame', 1)
|
||||
|
||||
detection_frame = mp.Value('d', 0.0)
|
||||
|
||||
ffmpeg_process = start_or_restart_ffmpeg(ffmpeg_cmd, frame_size)
|
||||
frame_queue = mp.Queue(maxsize=2)
|
||||
camera_fps = EventsPerSecond()
|
||||
camera_fps.start()
|
||||
camera_capture = CameraCapture(name, ffmpeg_process, frame_shape, frame_queue, take_frame, camera_fps, stop_event)
|
||||
camera_capture.start()
|
||||
|
||||
camera_processes[name] = {
|
||||
'camera_fps': camera_fps,
|
||||
'take_frame': take_frame,
|
||||
'process_fps': mp.Value('d', 0.0),
|
||||
'detection_fps': mp.Value('d', 0.0),
|
||||
'detection_frame': detection_frame,
|
||||
'read_start': mp.Value('d', 0.0),
|
||||
'ffmpeg_process': ffmpeg_process,
|
||||
'ffmpeg_cmd': ffmpeg_cmd,
|
||||
'frame_queue': frame_queue,
|
||||
'frame_shape': frame_shape,
|
||||
'capture_thread': camera_capture
|
||||
}
|
||||
|
||||
# merge global object config into camera object config
|
||||
camera_objects_config = config.get('objects', {})
|
||||
# get objects to track for camera
|
||||
objects_to_track = camera_objects_config.get('track', GLOBAL_OBJECT_CONFIG.get('track', ['person']))
|
||||
# get object filters
|
||||
object_filters = camera_objects_config.get('filters', GLOBAL_OBJECT_CONFIG.get('filters', {}))
|
||||
config['objects'] = {
|
||||
'track': objects_to_track,
|
||||
'filters': object_filters
|
||||
}
|
||||
|
||||
camera_process = mp.Process(target=track_camera, args=(name, config, frame_queue, frame_shape,
|
||||
detection_queue, out_events[name], tracked_objects_queue, camera_processes[name]['process_fps'],
|
||||
camera_processes[name]['detection_fps'],
|
||||
camera_processes[name]['read_start'], camera_processes[name]['detection_frame'], stop_event))
|
||||
camera_process.daemon = True
|
||||
camera_processes[name]['process'] = camera_process
|
||||
|
||||
# start the camera_processes
|
||||
for name, camera_process in camera_processes.items():
|
||||
camera_process['process'].start()
|
||||
print(f"Camera_process started for {name}: {camera_process['process'].pid}")
|
||||
|
||||
event_processor = EventProcessor(CONFIG, camera_processes, CACHE_DIR, CLIPS_DIR, event_queue, stop_event)
|
||||
event_processor.start()
|
||||
|
||||
object_processor = TrackedObjectProcessor(CONFIG['cameras'], client, MQTT_TOPIC_PREFIX, tracked_objects_queue, event_queue, stop_event)
|
||||
object_processor.start()
|
||||
|
||||
camera_watchdog = CameraWatchdog(camera_processes, CONFIG['cameras'], detectors, detection_queue, tracked_objects_queue, stop_event)
|
||||
camera_watchdog.start()
|
||||
|
||||
def receiveSignal(signalNumber, frame):
|
||||
print('Received:', signalNumber)
|
||||
stop_event.set()
|
||||
event_processor.join()
|
||||
object_processor.join()
|
||||
camera_watchdog.join()
|
||||
for camera_name, camera_process in camera_processes.items():
|
||||
camera_process['capture_thread'].join()
|
||||
# cleanup the frame queue
|
||||
while not camera_process['frame_queue'].empty():
|
||||
frame_time = camera_process['frame_queue'].get()
|
||||
shm = mp.shared_memory.SharedMemory(name=f"{camera_name}{frame_time}")
|
||||
shm.close()
|
||||
shm.unlink()
|
||||
|
||||
for detector in detectors.values():
|
||||
detector.stop()
|
||||
for shm in camera_shms:
|
||||
shm.close()
|
||||
shm.unlink()
|
||||
sys.exit()
|
||||
|
||||
signal.signal(signal.SIGTERM, receiveSignal)
|
||||
signal.signal(signal.SIGINT, receiveSignal)
|
||||
|
||||
# create a flask app that encodes frames a mjpeg on demand
|
||||
app = Flask(__name__)
|
||||
log = logging.getLogger('werkzeug')
|
||||
log.setLevel(logging.ERROR)
|
||||
|
||||
@app.route('/')
|
||||
def ishealthy():
|
||||
# return a healh
|
||||
return "Frigate is running. Alive and healthy!"
|
||||
|
||||
@app.route('/debug/stack')
|
||||
def processor_stack():
|
||||
frame = sys._current_frames().get(object_processor.ident, None)
|
||||
if frame:
|
||||
return "<br>".join(traceback.format_stack(frame)), 200
|
||||
else:
|
||||
return "no frame found", 200
|
||||
|
||||
@app.route('/debug/print_stack')
|
||||
def print_stack():
|
||||
pid = int(request.args.get('pid', 0))
|
||||
if pid == 0:
|
||||
return "missing pid", 200
|
||||
else:
|
||||
os.kill(pid, signal.SIGUSR1)
|
||||
return "check logs", 200
|
||||
|
||||
@app.route('/debug/stats')
|
||||
def stats():
|
||||
stats = {}
|
||||
|
||||
total_detection_fps = 0
|
||||
|
||||
for name, camera_stats in camera_processes.items():
|
||||
total_detection_fps += camera_stats['detection_fps'].value
|
||||
capture_thread = camera_stats['capture_thread']
|
||||
stats[name] = {
|
||||
'camera_fps': round(capture_thread.fps.eps(), 2),
|
||||
'process_fps': round(camera_stats['process_fps'].value, 2),
|
||||
'skipped_fps': round(capture_thread.skipped_fps.eps(), 2),
|
||||
'detection_fps': round(camera_stats['detection_fps'].value, 2),
|
||||
'read_start': camera_stats['read_start'].value,
|
||||
'pid': camera_stats['process'].pid,
|
||||
'ffmpeg_pid': camera_stats['ffmpeg_process'].pid,
|
||||
'frame_info': {
|
||||
'read': capture_thread.current_frame.value,
|
||||
'detect': camera_stats['detection_frame'].value,
|
||||
'process': object_processor.camera_data[name]['current_frame_time']
|
||||
}
|
||||
}
|
||||
|
||||
stats['detectors'] = {}
|
||||
for name, detector in detectors.items():
|
||||
stats['detectors'][name] = {
|
||||
'inference_speed': round(detector.avg_inference_speed.value*1000, 2),
|
||||
'detection_start': detector.detection_start.value,
|
||||
'pid': detector.detect_process.pid
|
||||
}
|
||||
stats['detection_fps'] = round(total_detection_fps, 2)
|
||||
|
||||
return jsonify(stats)
|
||||
|
||||
@app.route('/<camera_name>/<label>/best.jpg')
|
||||
def best(camera_name, label):
|
||||
if camera_name in CONFIG['cameras']:
|
||||
best_object = object_processor.get_best(camera_name, label)
|
||||
best_frame = best_object.get('frame')
|
||||
if best_frame is None:
|
||||
best_frame = np.zeros((720,1280,3), np.uint8)
|
||||
else:
|
||||
best_frame = cv2.cvtColor(best_frame, cv2.COLOR_YUV2BGR_I420)
|
||||
|
||||
crop = bool(request.args.get('crop', 0, type=int))
|
||||
if crop:
|
||||
region = best_object.get('region', [0,0,300,300])
|
||||
best_frame = best_frame[region[1]:region[3], region[0]:region[2]]
|
||||
|
||||
height = int(request.args.get('h', str(best_frame.shape[0])))
|
||||
width = int(height*best_frame.shape[1]/best_frame.shape[0])
|
||||
|
||||
best_frame = cv2.resize(best_frame, dsize=(width, height), interpolation=cv2.INTER_AREA)
|
||||
ret, jpg = cv2.imencode('.jpg', best_frame)
|
||||
response = make_response(jpg.tobytes())
|
||||
response.headers['Content-Type'] = 'image/jpg'
|
||||
return response
|
||||
else:
|
||||
return "Camera named {} not found".format(camera_name), 404
|
||||
|
||||
@app.route('/<camera_name>')
|
||||
def mjpeg_feed(camera_name):
|
||||
fps = int(request.args.get('fps', '3'))
|
||||
height = int(request.args.get('h', '360'))
|
||||
if camera_name in CONFIG['cameras']:
|
||||
# return a multipart response
|
||||
return Response(imagestream(camera_name, fps, height),
|
||||
mimetype='multipart/x-mixed-replace; boundary=frame')
|
||||
else:
|
||||
return "Camera named {} not found".format(camera_name), 404
|
||||
|
||||
@app.route('/<camera_name>/latest.jpg')
|
||||
def latest_frame(camera_name):
|
||||
if camera_name in CONFIG['cameras']:
|
||||
# max out at specified FPS
|
||||
frame = object_processor.get_current_frame(camera_name)
|
||||
if frame is None:
|
||||
frame = np.zeros((720,1280,3), np.uint8)
|
||||
|
||||
height = int(request.args.get('h', str(frame.shape[0])))
|
||||
width = int(height*frame.shape[1]/frame.shape[0])
|
||||
|
||||
frame = cv2.resize(frame, dsize=(width, height), interpolation=cv2.INTER_AREA)
|
||||
|
||||
ret, jpg = cv2.imencode('.jpg', frame)
|
||||
response = make_response(jpg.tobytes())
|
||||
response.headers['Content-Type'] = 'image/jpg'
|
||||
return response
|
||||
else:
|
||||
return "Camera named {} not found".format(camera_name), 404
|
||||
|
||||
def imagestream(camera_name, fps, height):
|
||||
while True:
|
||||
# max out at specified FPS
|
||||
time.sleep(1/fps)
|
||||
frame = object_processor.get_current_frame(camera_name, draw=True)
|
||||
if frame is None:
|
||||
frame = np.zeros((height,int(height*16/9),3), np.uint8)
|
||||
|
||||
width = int(height*frame.shape[1]/frame.shape[0])
|
||||
frame = cv2.resize(frame, dsize=(width, height), interpolation=cv2.INTER_LINEAR)
|
||||
|
||||
ret, jpg = cv2.imencode('.jpg', frame)
|
||||
yield (b'--frame\r\n'
|
||||
b'Content-Type: image/jpeg\r\n\r\n' + jpg.tobytes() + b'\r\n\r\n')
|
||||
|
||||
app.run(host='0.0.0.0', port=WEB_PORT, debug=False)
|
||||
|
||||
object_processor.join()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
37
docker-compose.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
version: "3"
|
||||
services:
|
||||
dev:
|
||||
container_name: frigate-dev
|
||||
user: vscode
|
||||
# add groups from host for render, plugdev, video
|
||||
group_add:
|
||||
- "109" # render
|
||||
- "110" # render
|
||||
- "44" # video
|
||||
- "46" # plugdev
|
||||
shm_size: "256mb"
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile.dev
|
||||
devices:
|
||||
- /dev/bus/usb:/dev/bus/usb
|
||||
- /dev/dri:/dev/dri # for intel hwaccel, needs to be updated for your hardware
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- .:/lab/frigate:cached
|
||||
- ./config/config.yml:/config/config.yml:ro
|
||||
- ./debug:/media/frigate
|
||||
- /dev/bus/usb:/dev/bus/usb
|
||||
ports:
|
||||
- "1935:1935"
|
||||
- "3000:3000"
|
||||
- "5000:5000"
|
||||
- "5001:5001"
|
||||
- "8080:8080"
|
||||
entrypoint: ["sudo", "/init"]
|
||||
command: /bin/sh -c "while sleep 1000; do :; done"
|
||||
mqtt:
|
||||
container_name: mqtt
|
||||
image: eclipse-mosquitto:1.6
|
||||
ports:
|
||||
- "1883:1883"
|
||||
148
docker/Dockerfile
Normal file
@@ -0,0 +1,148 @@
|
||||
FROM blakeblackshear/frigate-nginx:1.0.2 as nginx
|
||||
|
||||
FROM debian:11 as wheels
|
||||
ARG TARGETARCH
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Use a separate container to build wheels to prevent build dependencies in final image
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install -y \
|
||||
apt-transport-https \
|
||||
gnupg \
|
||||
wget \
|
||||
&& apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E \
|
||||
&& echo "deb http://raspbian.raspberrypi.org/raspbian/ bullseye main contrib non-free rpi" | tee /etc/apt/sources.list.d/raspi.list \
|
||||
&& apt-get -qq update \
|
||||
&& apt-get -qq install -y \
|
||||
python3 \
|
||||
python3-dev \
|
||||
wget \
|
||||
# opencv dependencies
|
||||
build-essential cmake git pkg-config libgtk-3-dev \
|
||||
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
|
||||
libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
|
||||
gfortran openexr libatlas-base-dev libssl-dev\
|
||||
libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev \
|
||||
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
|
||||
# scipy dependencies
|
||||
gcc gfortran libopenblas-dev liblapack-dev
|
||||
|
||||
RUN wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \
|
||||
&& python3 get-pip.py "pip"
|
||||
|
||||
RUN if [ "${TARGETARCH}" = "arm" ]; \
|
||||
then echo "[global]" > /etc/pip.conf \
|
||||
&& echo "extra-index-url=https://www.piwheels.org/simple" >> /etc/pip.conf; \
|
||||
fi
|
||||
|
||||
COPY requirements.txt /requirements.txt
|
||||
RUN pip3 install -r requirements.txt
|
||||
|
||||
COPY requirements-wheels.txt /requirements-wheels.txt
|
||||
RUN pip3 wheel --wheel-dir=/wheels -r requirements-wheels.txt
|
||||
|
||||
# Frigate Container
|
||||
FROM debian:11-slim
|
||||
ARG TARGETARCH
|
||||
|
||||
# https://askubuntu.com/questions/972516/debian-frontend-environment-variable
|
||||
ARG DEBIAN_FRONTEND="noninteractive"
|
||||
# http://stackoverflow.com/questions/48162574/ddg#49462622
|
||||
ARG APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn
|
||||
# https://github.com/NVIDIA/nvidia-docker/wiki/Installation-(Native-GPU-Support)
|
||||
ENV NVIDIA_DRIVER_CAPABILITIES="compute,video,utility"
|
||||
|
||||
ENV FLASK_ENV=development
|
||||
|
||||
COPY --from=wheels /wheels /wheels
|
||||
|
||||
# Install ffmpeg
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install --no-install-recommends -y \
|
||||
apt-transport-https \
|
||||
gnupg \
|
||||
wget \
|
||||
unzip tzdata libxml2 xz-utils \
|
||||
python3-pip \
|
||||
# add raspberry pi repo
|
||||
&& apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9165938D90FDDD2E \
|
||||
&& echo "deb http://raspbian.raspberrypi.org/raspbian/ bullseye main contrib non-free rpi" | tee /etc/apt/sources.list.d/raspi.list \
|
||||
# add coral repo
|
||||
&& apt-key adv --fetch-keys https://packages.cloud.google.com/apt/doc/apt-key.gpg \
|
||||
&& echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list \
|
||||
&& echo "libedgetpu1-max libedgetpu/accepted-eula select true" | debconf-set-selections \
|
||||
# enable non-free repo
|
||||
&& sed -i -e's/ main/ main contrib non-free/g' /etc/apt/sources.list \
|
||||
&& apt-get -qq update \
|
||||
&& apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
# coral drivers
|
||||
libedgetpu1-max python3-tflite-runtime python3-pycoral \
|
||||
&& pip3 install -U /wheels/*.whl \
|
||||
# btbn-ffmpeg -> amd64 / arm64
|
||||
&& if [ "${TARGETARCH}" = "amd64" ] || [ "${TARGETARCH}" = "arm64" ]; then \
|
||||
mkdir -p /usr/lib/btbn-ffmpeg \
|
||||
&& wget -O btbn-ffmpeg.tar.xz "https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2022-07-31-12-37/ffmpeg-n5.1-2-g915ef932a3-linux$( [ "$TARGETARCH" = "amd64" ] && echo "64" || echo "arm64" )-gpl-5.1.tar.xz" \
|
||||
&& tar -xf btbn-ffmpeg.tar.xz -C /usr/lib/btbn-ffmpeg --strip-components 1 \
|
||||
&& rm btbn-ffmpeg.tar.xz; \
|
||||
fi \
|
||||
# ffmpeg -> arm32
|
||||
&& if [ "${TARGETARCH}" = "arm" ]; then \
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y ffmpeg; \
|
||||
fi \
|
||||
# arch specific packages
|
||||
&& if [ "${TARGETARCH}" = "amd64" ]; then \
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
mesa-va-drivers libva-drm2 intel-media-va-driver-non-free i965-va-driver libmfx1; \
|
||||
fi \
|
||||
&& if [ "${TARGETARCH}" = "arm64" ]; then \
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
libva-drm2 mesa-va-drivers; \
|
||||
fi \
|
||||
# not sure why 32bit arm requires all these
|
||||
&& if [ "${TARGETARCH}" = "arm" ]; then \
|
||||
apt-get -qq install --no-install-recommends --no-install-suggests -y \
|
||||
libgtk-3-dev \
|
||||
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
|
||||
libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
|
||||
gfortran openexr libatlas-base-dev libssl-dev\
|
||||
libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev \
|
||||
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev; \
|
||||
fi \
|
||||
&& rm -rf /wheels \
|
||||
&& apt-get remove gnupg apt-transport-https -y \
|
||||
&& apt-get clean autoclean -y \
|
||||
&& apt-get autoremove -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PATH=$PATH:/usr/lib/btbn-ffmpeg/bin
|
||||
|
||||
COPY --from=nginx /usr/local/nginx/ /usr/local/nginx/
|
||||
|
||||
# get model and labels
|
||||
COPY labelmap.txt /labelmap.txt
|
||||
RUN wget -q https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite -O /edgetpu_model.tflite
|
||||
RUN wget -q https://github.com/google-coral/test_data/raw/release-frogfish/ssdlite_mobiledet_coco_qat_postprocess.tflite -O /cpu_model.tflite
|
||||
|
||||
WORKDIR /opt/frigate/
|
||||
ADD frigate frigate/
|
||||
ADD migrations migrations/
|
||||
|
||||
COPY web/dist web/
|
||||
|
||||
COPY docker/rootfs/ /
|
||||
|
||||
# s6-overlay
|
||||
RUN S6_ARCH="${TARGETARCH}" \
|
||||
&& if [ "${TARGETARCH}" = "amd64" ]; then S6_ARCH="amd64"; fi \
|
||||
&& if [ "${TARGETARCH}" = "arm" ]; then S6_ARCH="armhf"; fi \
|
||||
&& if [ "${TARGETARCH}" = "arm64" ]; then S6_ARCH="aarch64"; fi \
|
||||
&& wget -O /tmp/s6-overlay-installer "https://github.com/just-containers/s6-overlay/releases/download/v2.2.0.3/s6-overlay-${S6_ARCH}-installer" \
|
||||
&& chmod +x /tmp/s6-overlay-installer && /tmp/s6-overlay-installer /
|
||||
|
||||
EXPOSE 5000
|
||||
EXPOSE 1935
|
||||
|
||||
ENTRYPOINT ["/init"]
|
||||
|
||||
CMD ["python3", "-u", "-m", "frigate"]
|
||||
@@ -1,22 +0,0 @@
|
||||
FROM frigate-base
|
||||
LABEL maintainer "blakeb@blakeshome.com"
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
# Install packages for apt repo
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install --no-install-recommends -y \
|
||||
# ffmpeg runtime dependencies
|
||||
libgomp1 \
|
||||
# runtime dependencies
|
||||
libopenexr24 \
|
||||
libgstreamer1.0-0 \
|
||||
libgstreamer-plugins-base1.0-0 \
|
||||
libopenblas-base \
|
||||
libjpeg-turbo8 \
|
||||
libpng16-16 \
|
||||
libtiff5 \
|
||||
libdc1394-22 \
|
||||
## Tensorflow lite
|
||||
&& pip3 install https://dl.google.com/coral/python/tflite_runtime-2.1.0.post1-cp38-cp38-linux_aarch64.whl \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& (apt-get autoremove -y; apt-get autoclean -y)
|
||||
@@ -1,16 +0,0 @@
|
||||
FROM frigate-base
|
||||
LABEL maintainer "blakeb@blakeshome.com"
|
||||
|
||||
# Install packages for apt repo
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install --no-install-recommends -y \
|
||||
# ffmpeg dependencies
|
||||
libgomp1 \
|
||||
# VAAPI drivers for Intel hardware accel
|
||||
libva-drm2 libva2 i965-va-driver vainfo \
|
||||
## Tensorflow lite
|
||||
&& wget -q https://dl.google.com/coral/python/tflite_runtime-2.1.0.post1-cp38-cp38-linux_x86_64.whl \
|
||||
&& python3.8 -m pip install tflite_runtime-2.1.0.post1-cp38-cp38-linux_x86_64.whl \
|
||||
&& rm tflite_runtime-2.1.0.post1-cp38-cp38-linux_x86_64.whl \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& (apt-get autoremove -y; apt-get autoclean -y)
|
||||
@@ -1,24 +0,0 @@
|
||||
FROM frigate-base
|
||||
LABEL maintainer "blakeb@blakeshome.com"
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
# Install packages for apt repo
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install --no-install-recommends -y \
|
||||
# ffmpeg runtime dependencies
|
||||
libgomp1 \
|
||||
# runtime dependencies
|
||||
libopenexr24 \
|
||||
libgstreamer1.0-0 \
|
||||
libgstreamer-plugins-base1.0-0 \
|
||||
libopenblas-base \
|
||||
libjpeg-turbo8 \
|
||||
libpng16-16 \
|
||||
libtiff5 \
|
||||
libdc1394-22 \
|
||||
libaom0 \
|
||||
libx265-179 \
|
||||
## Tensorflow lite
|
||||
&& pip3 install https://dl.google.com/coral/python/tflite_runtime-2.1.0.post1-cp38-cp38-linux_armv7l.whl \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& (apt-get autoremove -y; apt-get autoclean -y)
|
||||
@@ -1,41 +0,0 @@
|
||||
ARG ARCH=amd64
|
||||
FROM blakeblackshear/frigate-wheels:${ARCH} as wheels
|
||||
FROM blakeblackshear/frigate-ffmpeg:${ARCH} as ffmpeg
|
||||
|
||||
FROM ubuntu:20.04
|
||||
LABEL maintainer "blakeb@blakeshome.com"
|
||||
|
||||
COPY --from=ffmpeg /usr/local /usr/local/
|
||||
|
||||
COPY --from=wheels /wheels/. /wheels/
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
# Install packages for apt repo
|
||||
RUN apt-get -qq update && apt-get -qq install --no-install-recommends -y \
|
||||
gnupg wget unzip tzdata \
|
||||
&& apt-get -qq install --no-install-recommends -y \
|
||||
python3-pip \
|
||||
&& pip3 install -U /wheels/*.whl \
|
||||
&& APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=DontWarn apt-key adv --fetch-keys https://packages.cloud.google.com/apt/doc/apt-key.gpg \
|
||||
&& echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" > /etc/apt/sources.list.d/coral-edgetpu.list \
|
||||
&& echo "libedgetpu1-max libedgetpu/accepted-eula select true" | debconf-set-selections \
|
||||
&& apt-get -qq update && apt-get -qq install --no-install-recommends -y \
|
||||
libedgetpu1-max \
|
||||
&& rm -rf /var/lib/apt/lists/* /wheels \
|
||||
&& (apt-get autoremove -y; apt-get autoclean -y)
|
||||
|
||||
# get model and labels
|
||||
ARG MODEL_REFS=7064b94dd5b996189242320359dbab8b52c94a84
|
||||
COPY labelmap.txt /labelmap.txt
|
||||
RUN wget -q https://github.com/google-coral/edgetpu/raw/$MODEL_REFS/test_data/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite -O /edgetpu_model.tflite
|
||||
RUN wget -q https://github.com/google-coral/edgetpu/raw/$MODEL_REFS/test_data/ssd_mobilenet_v2_coco_quant_postprocess.tflite -O /cpu_model.tflite
|
||||
|
||||
RUN mkdir /cache /clips
|
||||
|
||||
WORKDIR /opt/frigate/
|
||||
ADD frigate frigate/
|
||||
COPY detect_objects.py .
|
||||
COPY benchmark.py .
|
||||
COPY process_clip.py .
|
||||
|
||||
CMD ["python3", "-u", "detect_objects.py"]
|
||||
27
docker/Dockerfile.dev
Normal file
@@ -0,0 +1,27 @@
|
||||
FROM frigate:latest
|
||||
|
||||
ARG USERNAME=vscode
|
||||
ARG USER_UID=1000
|
||||
ARG USER_GID=$USER_UID
|
||||
|
||||
# Create the user
|
||||
RUN groupadd --gid $USER_GID $USERNAME \
|
||||
&& useradd --uid $USER_UID --gid $USER_GID -m $USERNAME -s /bin/bash \
|
||||
#
|
||||
# [Optional] Add sudo support. Omit if you don't need to install software after connecting.
|
||||
&& apt-get update \
|
||||
&& apt-get install -y sudo \
|
||||
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
|
||||
&& chmod 0440 /etc/sudoers.d/$USERNAME
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y git curl vim htop
|
||||
|
||||
COPY requirements-dev.txt /opt/frigate/requirements-dev.txt
|
||||
RUN pip3 install -r requirements-dev.txt
|
||||
|
||||
# Install Node 16
|
||||
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - \
|
||||
&& apt-get install -y nodejs
|
||||
|
||||
RUN npm install -g npm@latest
|
||||
@@ -1,533 +0,0 @@
|
||||
# inspired by:
|
||||
# https://github.com/collelog/ffmpeg/blob/master/4.3.1-alpine-rpi4-arm64v8.Dockerfile
|
||||
# https://github.com/mmastrac/ffmpeg-omx-rpi-docker/blob/master/Dockerfile
|
||||
# https://github.com/jrottenberg/ffmpeg/pull/158/files
|
||||
# https://github.com/jrottenberg/ffmpeg/pull/239
|
||||
FROM ubuntu:20.04 AS base
|
||||
|
||||
WORKDIR /tmp/workdir
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get -yqq update && \
|
||||
apt-get install -yq --no-install-recommends ca-certificates expat libgomp1 && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get clean -y
|
||||
|
||||
FROM base as build
|
||||
|
||||
ENV FFMPEG_VERSION=4.3.1 \
|
||||
AOM_VERSION=v1.0.0 \
|
||||
FDKAAC_VERSION=0.1.5 \
|
||||
FONTCONFIG_VERSION=2.12.4 \
|
||||
FREETYPE_VERSION=2.5.5 \
|
||||
FRIBIDI_VERSION=0.19.7 \
|
||||
KVAZAAR_VERSION=1.2.0 \
|
||||
LAME_VERSION=3.100 \
|
||||
LIBASS_VERSION=0.13.7 \
|
||||
LIBPTHREAD_STUBS_VERSION=0.4 \
|
||||
LIBVIDSTAB_VERSION=1.1.0 \
|
||||
LIBXCB_VERSION=1.13.1 \
|
||||
XCBPROTO_VERSION=1.13 \
|
||||
OGG_VERSION=1.3.2 \
|
||||
OPENCOREAMR_VERSION=0.1.5 \
|
||||
OPUS_VERSION=1.2 \
|
||||
OPENJPEG_VERSION=2.1.2 \
|
||||
THEORA_VERSION=1.1.1 \
|
||||
VORBIS_VERSION=1.3.5 \
|
||||
VPX_VERSION=1.8.0 \
|
||||
WEBP_VERSION=1.0.2 \
|
||||
X264_VERSION=20170226-2245-stable \
|
||||
X265_VERSION=3.1.1 \
|
||||
XAU_VERSION=1.0.9 \
|
||||
XORG_MACROS_VERSION=1.19.2 \
|
||||
XPROTO_VERSION=7.0.31 \
|
||||
XVID_VERSION=1.3.4 \
|
||||
LIBXML2_VERSION=2.9.10 \
|
||||
LIBBLURAY_VERSION=1.1.2 \
|
||||
LIBZMQ_VERSION=4.3.2 \
|
||||
SRC=/usr/local
|
||||
|
||||
ARG FREETYPE_SHA256SUM="5d03dd76c2171a7601e9ce10551d52d4471cf92cd205948e60289251daddffa8 freetype-2.5.5.tar.gz"
|
||||
ARG FRIBIDI_SHA256SUM="3fc96fa9473bd31dcb5500bdf1aa78b337ba13eb8c301e7c28923fea982453a8 0.19.7.tar.gz"
|
||||
ARG LIBASS_SHA256SUM="8fadf294bf701300d4605e6f1d92929304187fca4b8d8a47889315526adbafd7 0.13.7.tar.gz"
|
||||
ARG LIBVIDSTAB_SHA256SUM="14d2a053e56edad4f397be0cb3ef8eb1ec3150404ce99a426c4eb641861dc0bb v1.1.0.tar.gz"
|
||||
ARG OGG_SHA256SUM="e19ee34711d7af328cb26287f4137e70630e7261b17cbe3cd41011d73a654692 libogg-1.3.2.tar.gz"
|
||||
ARG OPUS_SHA256SUM="77db45a87b51578fbc49555ef1b10926179861d854eb2613207dc79d9ec0a9a9 opus-1.2.tar.gz"
|
||||
ARG THEORA_SHA256SUM="40952956c47811928d1e7922cda3bc1f427eb75680c3c37249c91e949054916b libtheora-1.1.1.tar.gz"
|
||||
ARG VORBIS_SHA256SUM="6efbcecdd3e5dfbf090341b485da9d176eb250d893e3eb378c428a2db38301ce libvorbis-1.3.5.tar.gz"
|
||||
ARG XVID_SHA256SUM="4e9fd62728885855bc5007fe1be58df42e5e274497591fec37249e1052ae316f xvidcore-1.3.4.tar.gz"
|
||||
ARG LIBXML2_SHA256SUM="f07dab13bf42d2b8db80620cce7419b3b87827cc937c8bb20fe13b8571ee9501 libxml2-v2.9.10.tar.gz"
|
||||
ARG LIBBLURAY_SHA256SUM="a3dd452239b100dc9da0d01b30e1692693e2a332a7d29917bf84bb10ea7c0b42 libbluray-1.1.2.tar.bz2"
|
||||
ARG LIBZMQ_SHA256SUM="02ecc88466ae38cf2c8d79f09cfd2675ba299a439680b64ade733e26a349edeb v4.3.2.tar.gz"
|
||||
|
||||
|
||||
ARG LD_LIBRARY_PATH=/opt/ffmpeg/lib
|
||||
ARG MAKEFLAGS="-j2"
|
||||
ARG PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig"
|
||||
ARG PREFIX=/opt/ffmpeg
|
||||
ARG LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/usr/lib64:/usr/lib:/lib64:/lib"
|
||||
|
||||
|
||||
RUN buildDeps="autoconf \
|
||||
automake \
|
||||
cmake \
|
||||
curl \
|
||||
bzip2 \
|
||||
libexpat1-dev \
|
||||
g++ \
|
||||
gcc \
|
||||
git \
|
||||
gperf \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
perl \
|
||||
pkg-config \
|
||||
python \
|
||||
libssl-dev \
|
||||
yasm \
|
||||
linux-headers-raspi2 \
|
||||
libomxil-bellagio-dev \
|
||||
zlib1g-dev" && \
|
||||
apt-get -yqq update && \
|
||||
apt-get install -yq --no-install-recommends ${buildDeps}
|
||||
## opencore-amr https://sourceforge.net/projects/opencore-amr/
|
||||
RUN \
|
||||
DIR=/tmp/opencore-amr && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://versaweb.dl.sourceforge.net/project/opencore-amr/opencore-amr/opencore-amr-${OPENCOREAMR_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## x264 http://www.videolan.org/developers/x264.html
|
||||
RUN \
|
||||
DIR=/tmp/x264 && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-${X264_VERSION}.tar.bz2 | \
|
||||
tar -jx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared --enable-pic --disable-cli && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### x265 http://x265.org/
|
||||
RUN \
|
||||
DIR=/tmp/x265 && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://download.videolan.org/pub/videolan/x265/x265_${X265_VERSION}.tar.gz | \
|
||||
tar -zx && \
|
||||
cd x265_${X265_VERSION}/build/linux && \
|
||||
sed -i "/-DEXTRA_LIB/ s/$/ -DCMAKE_INSTALL_PREFIX=\${PREFIX}/" multilib.sh && \
|
||||
sed -i "/^cmake/ s/$/ -DENABLE_CLI=OFF/" multilib.sh && \
|
||||
export CXXFLAGS="${CXXFLAGS} -fPIC" && \
|
||||
./multilib.sh && \
|
||||
make -C 8bit install && \
|
||||
rm -rf ${DIR}
|
||||
### libogg https://www.xiph.org/ogg/
|
||||
RUN \
|
||||
DIR=/tmp/ogg && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz && \
|
||||
echo ${OGG_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libogg-${OGG_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libopus https://www.opus-codec.org/
|
||||
RUN \
|
||||
DIR=/tmp/opus && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz && \
|
||||
echo ${OPUS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f opus-${OPUS_VERSION}.tar.gz && \
|
||||
autoreconf -fiv && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libvorbis https://xiph.org/vorbis/
|
||||
RUN \
|
||||
DIR=/tmp/vorbis && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERSION}.tar.gz && \
|
||||
echo ${VORBIS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libvorbis-${VORBIS_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libtheora http://www.theora.org/
|
||||
RUN \
|
||||
DIR=/tmp/theora && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.gz && \
|
||||
echo ${THEORA_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libtheora-${THEORA_VERSION}.tar.gz && \
|
||||
curl -sL 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' -o config.guess && \
|
||||
curl -sL 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' -o config.sub && \
|
||||
./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libvpx https://www.webmproject.org/code/
|
||||
RUN \
|
||||
DIR=/tmp/vpx && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://codeload.github.com/webmproject/libvpx/tar.gz/v${VPX_VERSION} | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-vp8 --enable-vp9 --enable-vp9-highbitdepth --enable-pic --enable-shared \
|
||||
--disable-debug --disable-examples --disable-docs --disable-install-bins && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libwebp https://developers.google.com/speed/webp/
|
||||
RUN \
|
||||
DIR=/tmp/vebp && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libmp3lame http://lame.sourceforge.net/
|
||||
RUN \
|
||||
DIR=/tmp/lame && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://versaweb.dl.sourceforge.net/project/lame/lame/$(echo ${LAME_VERSION} | sed -e 's/[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)/\1.\2/')/lame-${LAME_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin" --enable-shared --enable-nasm --disable-frontend && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### xvid https://www.xvid.com/
|
||||
RUN \
|
||||
DIR=/tmp/xvid && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xvid.org/downloads/xvidcore-${XVID_VERSION}.tar.gz && \
|
||||
echo ${XVID_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx -f xvidcore-${XVID_VERSION}.tar.gz && \
|
||||
cd xvidcore/build/generic && \
|
||||
./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### fdk-aac https://github.com/mstorsjo/fdk-aac
|
||||
RUN \
|
||||
DIR=/tmp/fdk-aac && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://github.com/mstorsjo/fdk-aac/archive/v${FDKAAC_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
autoreconf -fiv && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared --datadir="${DIR}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## openjpeg https://github.com/uclouvain/openjpeg
|
||||
RUN \
|
||||
DIR=/tmp/openjpeg && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
export CFLAGS="${CFLAGS} -DPNG_ARM_NEON_OPT=0" && \
|
||||
cmake -DBUILD_THIRDPARTY:BOOL=ON -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## freetype https://www.freetype.org/
|
||||
RUN \
|
||||
DIR=/tmp/freetype && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://download.savannah.gnu.org/releases/freetype/freetype-${FREETYPE_VERSION}.tar.gz && \
|
||||
echo ${FREETYPE_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f freetype-${FREETYPE_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## libvstab https://github.com/georgmartius/vid.stab
|
||||
RUN \
|
||||
DIR=/tmp/vid.stab && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/georgmartius/vid.stab/archive/v${LIBVIDSTAB_VERSION}.tar.gz && \
|
||||
echo ${LIBVIDSTAB_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f v${LIBVIDSTAB_VERSION}.tar.gz && \
|
||||
cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## fridibi https://www.fribidi.org/
|
||||
RUN \
|
||||
DIR=/tmp/fribidi && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/fribidi/fribidi/archive/${FRIBIDI_VERSION}.tar.gz && \
|
||||
echo ${FRIBIDI_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f ${FRIBIDI_VERSION}.tar.gz && \
|
||||
sed -i 's/^SUBDIRS =.*/SUBDIRS=gen.tab charset lib bin/' Makefile.am && \
|
||||
./bootstrap --no-config --auto && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j1 && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## fontconfig https://www.freedesktop.org/wiki/Software/fontconfig/
|
||||
RUN \
|
||||
DIR=/tmp/fontconfig && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.freedesktop.org/software/fontconfig/release/fontconfig-${FONTCONFIG_VERSION}.tar.bz2 && \
|
||||
tar -jx --strip-components=1 -f fontconfig-${FONTCONFIG_VERSION}.tar.bz2 && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## libass https://github.com/libass/libass
|
||||
RUN \
|
||||
DIR=/tmp/libass && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/libass/libass/archive/${LIBASS_VERSION}.tar.gz && \
|
||||
echo ${LIBASS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f ${LIBASS_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## kvazaar https://github.com/ultravideo/kvazaar
|
||||
RUN \
|
||||
DIR=/tmp/kvazaar && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/ultravideo/kvazaar/archive/v${KVAZAAR_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f v${KVAZAAR_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/aom && \
|
||||
git clone --branch ${AOM_VERSION} --depth 1 https://aomedia.googlesource.com/aom ${DIR} ; \
|
||||
cd ${DIR} ; \
|
||||
rm -rf CMakeCache.txt CMakeFiles ; \
|
||||
mkdir -p ./aom_build ; \
|
||||
cd ./aom_build ; \
|
||||
cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DBUILD_SHARED_LIBS=1 ..; \
|
||||
make ; \
|
||||
make install ; \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libxcb (and supporting libraries) for screen capture https://xcb.freedesktop.org/
|
||||
RUN \
|
||||
DIR=/tmp/xorg-macros && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive//individual/util/util-macros-${XORG_MACROS_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f util-macros-${XORG_MACROS_VERSION}.tar.gz && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/xproto && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive/individual/proto/xproto-${XPROTO_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f xproto-${XPROTO_VERSION}.tar.gz && \
|
||||
curl -sL 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' -o config.guess && \
|
||||
curl -sL 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' -o config.sub && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libXau && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive/individual/lib/libXau-${XAU_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libXau-${XAU_VERSION}.tar.gz && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libpthread-stubs && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/libpthread-stubs-${LIBPTHREAD_STUBS_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libpthread-stubs-${LIBPTHREAD_STUBS_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libxcb-proto && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/xcb-proto-${XCBPROTO_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f xcb-proto-${XCBPROTO_VERSION}.tar.gz && \
|
||||
ACLOCAL_PATH="${PREFIX}/share/aclocal" ./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libxcb && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/libxcb-${LIBXCB_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libxcb-${LIBXCB_VERSION}.tar.gz && \
|
||||
ACLOCAL_PATH="${PREFIX}/share/aclocal" ./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libxml2 - for libbluray
|
||||
RUN \
|
||||
DIR=/tmp/libxml2 && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://gitlab.gnome.org/GNOME/libxml2/-/archive/v${LIBXML2_VERSION}/libxml2-v${LIBXML2_VERSION}.tar.gz && \
|
||||
echo ${LIBXML2_SHA256SUM} | sha256sum --check && \
|
||||
tar -xz --strip-components=1 -f libxml2-v${LIBXML2_VERSION}.tar.gz && \
|
||||
./autogen.sh --prefix="${PREFIX}" --with-ftp=no --with-http=no --with-python=no && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libbluray - Requires libxml, freetype, and fontconfig
|
||||
RUN \
|
||||
DIR=/tmp/libbluray && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://download.videolan.org/pub/videolan/libbluray/${LIBBLURAY_VERSION}/libbluray-${LIBBLURAY_VERSION}.tar.bz2 && \
|
||||
echo ${LIBBLURAY_SHA256SUM} | sha256sum --check && \
|
||||
tar -jx --strip-components=1 -f libbluray-${LIBBLURAY_VERSION}.tar.bz2 && \
|
||||
./configure --prefix="${PREFIX}" --disable-examples --disable-bdjava-jar --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libzmq https://github.com/zeromq/libzmq/
|
||||
RUN \
|
||||
DIR=/tmp/libzmq && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/zeromq/libzmq/archive/v${LIBZMQ_VERSION}.tar.gz && \
|
||||
echo ${LIBZMQ_SHA256SUM} | sha256sum --check && \
|
||||
tar -xz --strip-components=1 -f v${LIBZMQ_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make check && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## ffmpeg https://ffmpeg.org/
|
||||
RUN \
|
||||
DIR=/tmp/ffmpeg && mkdir -p ${DIR} && cd ${DIR} && \
|
||||
curl -sLO https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2 && \
|
||||
tar -jx --strip-components=1 -f ffmpeg-${FFMPEG_VERSION}.tar.bz2
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/ffmpeg && mkdir -p ${DIR} && cd ${DIR} && \
|
||||
./configure \
|
||||
--disable-debug \
|
||||
--disable-doc \
|
||||
--disable-ffplay \
|
||||
--enable-shared \
|
||||
--enable-avresample \
|
||||
--enable-libopencore-amrnb \
|
||||
--enable-libopencore-amrwb \
|
||||
--enable-gpl \
|
||||
--enable-libass \
|
||||
--enable-fontconfig \
|
||||
--enable-libfreetype \
|
||||
--enable-libvidstab \
|
||||
--enable-libmp3lame \
|
||||
--enable-libopus \
|
||||
--enable-libtheora \
|
||||
--enable-libvorbis \
|
||||
--enable-libvpx \
|
||||
--enable-libwebp \
|
||||
--enable-libxcb \
|
||||
--enable-libx265 \
|
||||
--enable-libxvid \
|
||||
--enable-libx264 \
|
||||
--enable-nonfree \
|
||||
--enable-openssl \
|
||||
--enable-libfdk_aac \
|
||||
--enable-postproc \
|
||||
--enable-small \
|
||||
--enable-version3 \
|
||||
--enable-libbluray \
|
||||
--enable-libzmq \
|
||||
--extra-libs=-ldl \
|
||||
--prefix="${PREFIX}" \
|
||||
--enable-libopenjpeg \
|
||||
--enable-libkvazaar \
|
||||
--enable-libaom \
|
||||
--extra-libs=-lpthread \
|
||||
# --enable-omx \
|
||||
# --enable-omx-rpi \
|
||||
# --enable-mmal \
|
||||
--enable-v4l2_m2m \
|
||||
--enable-neon \
|
||||
--extra-cflags="-I${PREFIX}/include" \
|
||||
--extra-ldflags="-L${PREFIX}/lib" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
make tools/zmqsend && cp tools/zmqsend ${PREFIX}/bin/ && \
|
||||
make distclean && \
|
||||
hash -r && \
|
||||
cd tools && \
|
||||
make qt-faststart && cp qt-faststart ${PREFIX}/bin/
|
||||
|
||||
## cleanup
|
||||
RUN \
|
||||
ldd ${PREFIX}/bin/ffmpeg | grep opt/ffmpeg | cut -d ' ' -f 3 | xargs -i cp {} /usr/local/lib/ && \
|
||||
for lib in /usr/local/lib/*.so.*; do ln -s "${lib##*/}" "${lib%%.so.*}".so; done && \
|
||||
cp ${PREFIX}/bin/* /usr/local/bin/ && \
|
||||
cp -r ${PREFIX}/share/ffmpeg /usr/local/share/ && \
|
||||
LD_LIBRARY_PATH=/usr/local/lib ffmpeg -buildconf && \
|
||||
cp -r ${PREFIX}/include/libav* ${PREFIX}/include/libpostproc ${PREFIX}/include/libsw* /usr/local/include && \
|
||||
mkdir -p /usr/local/lib/pkgconfig && \
|
||||
for pc in ${PREFIX}/lib/pkgconfig/libav*.pc ${PREFIX}/lib/pkgconfig/libpostproc.pc ${PREFIX}/lib/pkgconfig/libsw*.pc; do \
|
||||
sed "s:${PREFIX}:/usr/local:g" <"$pc" >/usr/local/lib/pkgconfig/"${pc##*/}"; \
|
||||
done
|
||||
|
||||
FROM base AS release
|
||||
|
||||
ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/usr/lib:/usr/lib64:/lib:/lib64
|
||||
|
||||
CMD ["--help"]
|
||||
ENTRYPOINT ["ffmpeg"]
|
||||
|
||||
COPY --from=build /usr/local /usr/local/
|
||||
|
||||
# Run ffmpeg with -c:v h264_v4l2m2m to enable HW accell for decoding on raspberry pi4 64-bit
|
||||
@@ -1,526 +0,0 @@
|
||||
# inspired by:
|
||||
# https://github.com/collelog/ffmpeg/blob/master/4.3.1-alpine-rpi4-arm64v8.Dockerfile
|
||||
# https://github.com/jrottenberg/ffmpeg/pull/158/files
|
||||
# https://github.com/jrottenberg/ffmpeg/pull/239
|
||||
FROM ubuntu:20.04 AS base
|
||||
|
||||
WORKDIR /tmp/workdir
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get -yqq update && \
|
||||
apt-get install -yq --no-install-recommends ca-certificates expat libgomp1 && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get clean -y
|
||||
|
||||
FROM base as build
|
||||
|
||||
ENV FFMPEG_VERSION=4.3.1 \
|
||||
AOM_VERSION=v1.0.0 \
|
||||
FDKAAC_VERSION=0.1.5 \
|
||||
FONTCONFIG_VERSION=2.12.4 \
|
||||
FREETYPE_VERSION=2.5.5 \
|
||||
FRIBIDI_VERSION=0.19.7 \
|
||||
KVAZAAR_VERSION=1.2.0 \
|
||||
LAME_VERSION=3.100 \
|
||||
LIBASS_VERSION=0.13.7 \
|
||||
LIBPTHREAD_STUBS_VERSION=0.4 \
|
||||
LIBVIDSTAB_VERSION=1.1.0 \
|
||||
LIBXCB_VERSION=1.13.1 \
|
||||
XCBPROTO_VERSION=1.13 \
|
||||
OGG_VERSION=1.3.2 \
|
||||
OPENCOREAMR_VERSION=0.1.5 \
|
||||
OPUS_VERSION=1.2 \
|
||||
OPENJPEG_VERSION=2.1.2 \
|
||||
THEORA_VERSION=1.1.1 \
|
||||
VORBIS_VERSION=1.3.5 \
|
||||
VPX_VERSION=1.8.0 \
|
||||
WEBP_VERSION=1.0.2 \
|
||||
X264_VERSION=20170226-2245-stable \
|
||||
X265_VERSION=3.1.1 \
|
||||
XAU_VERSION=1.0.9 \
|
||||
XORG_MACROS_VERSION=1.19.2 \
|
||||
XPROTO_VERSION=7.0.31 \
|
||||
XVID_VERSION=1.3.4 \
|
||||
LIBXML2_VERSION=2.9.10 \
|
||||
LIBBLURAY_VERSION=1.1.2 \
|
||||
LIBZMQ_VERSION=4.3.2 \
|
||||
SRC=/usr/local
|
||||
|
||||
ARG FREETYPE_SHA256SUM="5d03dd76c2171a7601e9ce10551d52d4471cf92cd205948e60289251daddffa8 freetype-2.5.5.tar.gz"
|
||||
ARG FRIBIDI_SHA256SUM="3fc96fa9473bd31dcb5500bdf1aa78b337ba13eb8c301e7c28923fea982453a8 0.19.7.tar.gz"
|
||||
ARG LIBASS_SHA256SUM="8fadf294bf701300d4605e6f1d92929304187fca4b8d8a47889315526adbafd7 0.13.7.tar.gz"
|
||||
ARG LIBVIDSTAB_SHA256SUM="14d2a053e56edad4f397be0cb3ef8eb1ec3150404ce99a426c4eb641861dc0bb v1.1.0.tar.gz"
|
||||
ARG OGG_SHA256SUM="e19ee34711d7af328cb26287f4137e70630e7261b17cbe3cd41011d73a654692 libogg-1.3.2.tar.gz"
|
||||
ARG OPUS_SHA256SUM="77db45a87b51578fbc49555ef1b10926179861d854eb2613207dc79d9ec0a9a9 opus-1.2.tar.gz"
|
||||
ARG THEORA_SHA256SUM="40952956c47811928d1e7922cda3bc1f427eb75680c3c37249c91e949054916b libtheora-1.1.1.tar.gz"
|
||||
ARG VORBIS_SHA256SUM="6efbcecdd3e5dfbf090341b485da9d176eb250d893e3eb378c428a2db38301ce libvorbis-1.3.5.tar.gz"
|
||||
ARG XVID_SHA256SUM="4e9fd62728885855bc5007fe1be58df42e5e274497591fec37249e1052ae316f xvidcore-1.3.4.tar.gz"
|
||||
ARG LIBXML2_SHA256SUM="f07dab13bf42d2b8db80620cce7419b3b87827cc937c8bb20fe13b8571ee9501 libxml2-v2.9.10.tar.gz"
|
||||
ARG LIBBLURAY_SHA256SUM="a3dd452239b100dc9da0d01b30e1692693e2a332a7d29917bf84bb10ea7c0b42 libbluray-1.1.2.tar.bz2"
|
||||
ARG LIBZMQ_SHA256SUM="02ecc88466ae38cf2c8d79f09cfd2675ba299a439680b64ade733e26a349edeb v4.3.2.tar.gz"
|
||||
|
||||
|
||||
ARG LD_LIBRARY_PATH=/opt/ffmpeg/lib
|
||||
ARG MAKEFLAGS="-j2"
|
||||
ARG PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig"
|
||||
ARG PREFIX=/opt/ffmpeg
|
||||
ARG LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/usr/lib64:/usr/lib:/lib64:/lib"
|
||||
|
||||
|
||||
RUN buildDeps="autoconf \
|
||||
automake \
|
||||
cmake \
|
||||
curl \
|
||||
bzip2 \
|
||||
libexpat1-dev \
|
||||
g++ \
|
||||
gcc \
|
||||
git \
|
||||
gperf \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
perl \
|
||||
pkg-config \
|
||||
python \
|
||||
libssl-dev \
|
||||
yasm \
|
||||
libva-dev \
|
||||
zlib1g-dev" && \
|
||||
apt-get -yqq update && \
|
||||
apt-get install -yq --no-install-recommends ${buildDeps}
|
||||
## opencore-amr https://sourceforge.net/projects/opencore-amr/
|
||||
RUN \
|
||||
DIR=/tmp/opencore-amr && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://versaweb.dl.sourceforge.net/project/opencore-amr/opencore-amr/opencore-amr-${OPENCOREAMR_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
## x264 http://www.videolan.org/developers/x264.html
|
||||
RUN \
|
||||
DIR=/tmp/x264 && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-${X264_VERSION}.tar.bz2 | \
|
||||
tar -jx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared --enable-pic --disable-cli && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### x265 http://x265.org/
|
||||
RUN \
|
||||
DIR=/tmp/x265 && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://download.videolan.org/pub/videolan/x265/x265_${X265_VERSION}.tar.gz | \
|
||||
tar -zx && \
|
||||
cd x265_${X265_VERSION}/build/linux && \
|
||||
sed -i "/-DEXTRA_LIB/ s/$/ -DCMAKE_INSTALL_PREFIX=\${PREFIX}/" multilib.sh && \
|
||||
sed -i "/^cmake/ s/$/ -DENABLE_CLI=OFF/" multilib.sh && \
|
||||
./multilib.sh && \
|
||||
make -C 8bit install && \
|
||||
rm -rf ${DIR}
|
||||
### libogg https://www.xiph.org/ogg/
|
||||
RUN \
|
||||
DIR=/tmp/ogg && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz && \
|
||||
echo ${OGG_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libogg-${OGG_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### libopus https://www.opus-codec.org/
|
||||
RUN \
|
||||
DIR=/tmp/opus && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz && \
|
||||
echo ${OPUS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f opus-${OPUS_VERSION}.tar.gz && \
|
||||
autoreconf -fiv && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### libvorbis https://xiph.org/vorbis/
|
||||
RUN \
|
||||
DIR=/tmp/vorbis && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERSION}.tar.gz && \
|
||||
echo ${VORBIS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libvorbis-${VORBIS_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### libtheora http://www.theora.org/
|
||||
RUN \
|
||||
DIR=/tmp/theora && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.gz && \
|
||||
echo ${THEORA_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libtheora-${THEORA_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### libvpx https://www.webmproject.org/code/
|
||||
RUN \
|
||||
DIR=/tmp/vpx && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://codeload.github.com/webmproject/libvpx/tar.gz/v${VPX_VERSION} | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-vp8 --enable-vp9 --enable-vp9-highbitdepth --enable-pic --enable-shared \
|
||||
--disable-debug --disable-examples --disable-docs --disable-install-bins && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### libwebp https://developers.google.com/speed/webp/
|
||||
RUN \
|
||||
DIR=/tmp/vebp && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### libmp3lame http://lame.sourceforge.net/
|
||||
RUN \
|
||||
DIR=/tmp/lame && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://versaweb.dl.sourceforge.net/project/lame/lame/$(echo ${LAME_VERSION} | sed -e 's/[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)/\1.\2/')/lame-${LAME_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin" --enable-shared --enable-nasm --disable-frontend && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### xvid https://www.xvid.com/
|
||||
RUN \
|
||||
DIR=/tmp/xvid && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xvid.org/downloads/xvidcore-${XVID_VERSION}.tar.gz && \
|
||||
echo ${XVID_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx -f xvidcore-${XVID_VERSION}.tar.gz && \
|
||||
cd xvidcore/build/generic && \
|
||||
./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin" && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
### fdk-aac https://github.com/mstorsjo/fdk-aac
|
||||
RUN \
|
||||
DIR=/tmp/fdk-aac && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://github.com/mstorsjo/fdk-aac/archive/v${FDKAAC_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
autoreconf -fiv && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared --datadir="${DIR}" && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
## openjpeg https://github.com/uclouvain/openjpeg
|
||||
RUN \
|
||||
DIR=/tmp/openjpeg && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
cmake -DBUILD_THIRDPARTY:BOOL=ON -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
## freetype https://www.freetype.org/
|
||||
RUN \
|
||||
DIR=/tmp/freetype && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://download.savannah.gnu.org/releases/freetype/freetype-${FREETYPE_VERSION}.tar.gz && \
|
||||
echo ${FREETYPE_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f freetype-${FREETYPE_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
## libvstab https://github.com/georgmartius/vid.stab
|
||||
RUN \
|
||||
DIR=/tmp/vid.stab && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/georgmartius/vid.stab/archive/v${LIBVIDSTAB_VERSION}.tar.gz && \
|
||||
echo ${LIBVIDSTAB_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f v${LIBVIDSTAB_VERSION}.tar.gz && \
|
||||
cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
## fridibi https://www.fribidi.org/
|
||||
RUN \
|
||||
DIR=/tmp/fribidi && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/fribidi/fribidi/archive/${FRIBIDI_VERSION}.tar.gz && \
|
||||
echo ${FRIBIDI_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f ${FRIBIDI_VERSION}.tar.gz && \
|
||||
sed -i 's/^SUBDIRS =.*/SUBDIRS=gen.tab charset lib bin/' Makefile.am && \
|
||||
./bootstrap --no-config --auto && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j1 && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
## fontconfig https://www.freedesktop.org/wiki/Software/fontconfig/
|
||||
RUN \
|
||||
DIR=/tmp/fontconfig && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.freedesktop.org/software/fontconfig/release/fontconfig-${FONTCONFIG_VERSION}.tar.bz2 && \
|
||||
tar -jx --strip-components=1 -f fontconfig-${FONTCONFIG_VERSION}.tar.bz2 && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
## libass https://github.com/libass/libass
|
||||
RUN \
|
||||
DIR=/tmp/libass && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/libass/libass/archive/${LIBASS_VERSION}.tar.gz && \
|
||||
echo ${LIBASS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f ${LIBASS_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
## kvazaar https://github.com/ultravideo/kvazaar
|
||||
RUN \
|
||||
DIR=/tmp/kvazaar && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/ultravideo/kvazaar/archive/v${KVAZAAR_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f v${KVAZAAR_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/aom && \
|
||||
git clone --branch ${AOM_VERSION} --depth 1 https://aomedia.googlesource.com/aom ${DIR} ; \
|
||||
cd ${DIR} ; \
|
||||
rm -rf CMakeCache.txt CMakeFiles ; \
|
||||
mkdir -p ./aom_build ; \
|
||||
cd ./aom_build ; \
|
||||
cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DBUILD_SHARED_LIBS=1 ..; \
|
||||
make ; \
|
||||
make install ; \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libxcb (and supporting libraries) for screen capture https://xcb.freedesktop.org/
|
||||
RUN \
|
||||
DIR=/tmp/xorg-macros && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive//individual/util/util-macros-${XORG_MACROS_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f util-macros-${XORG_MACROS_VERSION}.tar.gz && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/xproto && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive/individual/proto/xproto-${XPROTO_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f xproto-${XPROTO_VERSION}.tar.gz && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libXau && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive/individual/lib/libXau-${XAU_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libXau-${XAU_VERSION}.tar.gz && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libpthread-stubs && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/libpthread-stubs-${LIBPTHREAD_STUBS_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libpthread-stubs-${LIBPTHREAD_STUBS_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libxcb-proto && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/xcb-proto-${XCBPROTO_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f xcb-proto-${XCBPROTO_VERSION}.tar.gz && \
|
||||
ACLOCAL_PATH="${PREFIX}/share/aclocal" ./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libxcb && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/libxcb-${LIBXCB_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libxcb-${LIBXCB_VERSION}.tar.gz && \
|
||||
ACLOCAL_PATH="${PREFIX}/share/aclocal" ./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libxml2 - for libbluray
|
||||
RUN \
|
||||
DIR=/tmp/libxml2 && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://gitlab.gnome.org/GNOME/libxml2/-/archive/v${LIBXML2_VERSION}/libxml2-v${LIBXML2_VERSION}.tar.gz && \
|
||||
echo ${LIBXML2_SHA256SUM} | sha256sum --check && \
|
||||
tar -xz --strip-components=1 -f libxml2-v${LIBXML2_VERSION}.tar.gz && \
|
||||
./autogen.sh --prefix="${PREFIX}" --with-ftp=no --with-http=no --with-python=no && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libbluray - Requires libxml, freetype, and fontconfig
|
||||
RUN \
|
||||
DIR=/tmp/libbluray && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://download.videolan.org/pub/videolan/libbluray/${LIBBLURAY_VERSION}/libbluray-${LIBBLURAY_VERSION}.tar.bz2 && \
|
||||
echo ${LIBBLURAY_SHA256SUM} | sha256sum --check && \
|
||||
tar -jx --strip-components=1 -f libbluray-${LIBBLURAY_VERSION}.tar.bz2 && \
|
||||
./configure --prefix="${PREFIX}" --disable-examples --disable-bdjava-jar --disable-static --enable-shared && \
|
||||
make && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libzmq https://github.com/zeromq/libzmq/
|
||||
RUN \
|
||||
DIR=/tmp/libzmq && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/zeromq/libzmq/archive/v${LIBZMQ_VERSION}.tar.gz && \
|
||||
echo ${LIBZMQ_SHA256SUM} | sha256sum --check && \
|
||||
tar -xz --strip-components=1 -f v${LIBZMQ_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make && \
|
||||
make check && \
|
||||
make install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## ffmpeg https://ffmpeg.org/
|
||||
RUN \
|
||||
DIR=/tmp/ffmpeg && mkdir -p ${DIR} && cd ${DIR} && \
|
||||
curl -sLO https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2 && \
|
||||
tar -jx --strip-components=1 -f ffmpeg-${FFMPEG_VERSION}.tar.bz2
|
||||
|
||||
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/ffmpeg && mkdir -p ${DIR} && cd ${DIR} && \
|
||||
./configure \
|
||||
--disable-debug \
|
||||
--disable-doc \
|
||||
--disable-ffplay \
|
||||
--enable-shared \
|
||||
--enable-avresample \
|
||||
--enable-libopencore-amrnb \
|
||||
--enable-libopencore-amrwb \
|
||||
--enable-gpl \
|
||||
--enable-libass \
|
||||
--enable-fontconfig \
|
||||
--enable-libfreetype \
|
||||
--enable-libvidstab \
|
||||
--enable-libmp3lame \
|
||||
--enable-libopus \
|
||||
--enable-libtheora \
|
||||
--enable-libvorbis \
|
||||
--enable-libvpx \
|
||||
--enable-libwebp \
|
||||
--enable-libxcb \
|
||||
--enable-libx265 \
|
||||
--enable-libxvid \
|
||||
--enable-libx264 \
|
||||
--enable-nonfree \
|
||||
--enable-openssl \
|
||||
--enable-libfdk_aac \
|
||||
--enable-postproc \
|
||||
--enable-small \
|
||||
--enable-version3 \
|
||||
--enable-libbluray \
|
||||
--enable-libzmq \
|
||||
--extra-libs=-ldl \
|
||||
--prefix="${PREFIX}" \
|
||||
--enable-libopenjpeg \
|
||||
--enable-libkvazaar \
|
||||
--enable-libaom \
|
||||
--extra-libs=-lpthread \
|
||||
--enable-vaapi \
|
||||
--extra-cflags="-I${PREFIX}/include" \
|
||||
--extra-ldflags="-L${PREFIX}/lib" && \
|
||||
make && \
|
||||
make install && \
|
||||
make tools/zmqsend && cp tools/zmqsend ${PREFIX}/bin/ && \
|
||||
make distclean && \
|
||||
hash -r && \
|
||||
cd tools && \
|
||||
make qt-faststart && cp qt-faststart ${PREFIX}/bin/
|
||||
|
||||
## cleanup
|
||||
RUN \
|
||||
ldd ${PREFIX}/bin/ffmpeg | grep opt/ffmpeg | cut -d ' ' -f 3 | xargs -i cp {} /usr/local/lib/ && \
|
||||
for lib in /usr/local/lib/*.so.*; do ln -s "${lib##*/}" "${lib%%.so.*}".so; done && \
|
||||
cp ${PREFIX}/bin/* /usr/local/bin/ && \
|
||||
cp -r ${PREFIX}/share/ffmpeg /usr/local/share/ && \
|
||||
LD_LIBRARY_PATH=/usr/local/lib ffmpeg -buildconf && \
|
||||
cp -r ${PREFIX}/include/libav* ${PREFIX}/include/libpostproc ${PREFIX}/include/libsw* /usr/local/include && \
|
||||
mkdir -p /usr/local/lib/pkgconfig && \
|
||||
for pc in ${PREFIX}/lib/pkgconfig/libav*.pc ${PREFIX}/lib/pkgconfig/libpostproc.pc ${PREFIX}/lib/pkgconfig/libsw*.pc; do \
|
||||
sed "s:${PREFIX}:/usr/local:g" <"$pc" >/usr/local/lib/pkgconfig/"${pc##*/}"; \
|
||||
done
|
||||
|
||||
FROM base AS release
|
||||
|
||||
ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/usr/lib:/usr/lib64:/lib:/lib64
|
||||
|
||||
CMD ["--help"]
|
||||
ENTRYPOINT ["ffmpeg"]
|
||||
|
||||
COPY --from=build /usr/local /usr/local/
|
||||
|
||||
RUN \
|
||||
apt-get update -y && \
|
||||
apt-get install -y --no-install-recommends libva-drm2 libva2 i965-va-driver && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
@@ -1,549 +0,0 @@
|
||||
# inspired by:
|
||||
# https://github.com/collelog/ffmpeg/blob/master/4.3.1-alpine-rpi4-arm64v8.Dockerfile
|
||||
# https://github.com/mmastrac/ffmpeg-omx-rpi-docker/blob/master/Dockerfile
|
||||
# https://github.com/jrottenberg/ffmpeg/pull/158/files
|
||||
# https://github.com/jrottenberg/ffmpeg/pull/239
|
||||
FROM ubuntu:20.04 AS base
|
||||
|
||||
WORKDIR /tmp/workdir
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get -yqq update && \
|
||||
apt-get install -yq --no-install-recommends ca-certificates expat libgomp1 && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get clean -y
|
||||
|
||||
FROM base as build
|
||||
|
||||
ENV FFMPEG_VERSION=4.3.1 \
|
||||
AOM_VERSION=v1.0.0 \
|
||||
FDKAAC_VERSION=0.1.5 \
|
||||
FONTCONFIG_VERSION=2.12.4 \
|
||||
FREETYPE_VERSION=2.5.5 \
|
||||
FRIBIDI_VERSION=0.19.7 \
|
||||
KVAZAAR_VERSION=1.2.0 \
|
||||
LAME_VERSION=3.100 \
|
||||
LIBASS_VERSION=0.13.7 \
|
||||
LIBPTHREAD_STUBS_VERSION=0.4 \
|
||||
LIBVIDSTAB_VERSION=1.1.0 \
|
||||
LIBXCB_VERSION=1.13.1 \
|
||||
XCBPROTO_VERSION=1.13 \
|
||||
OGG_VERSION=1.3.2 \
|
||||
OPENCOREAMR_VERSION=0.1.5 \
|
||||
OPUS_VERSION=1.2 \
|
||||
OPENJPEG_VERSION=2.1.2 \
|
||||
THEORA_VERSION=1.1.1 \
|
||||
VORBIS_VERSION=1.3.5 \
|
||||
VPX_VERSION=1.8.0 \
|
||||
WEBP_VERSION=1.0.2 \
|
||||
X264_VERSION=20170226-2245-stable \
|
||||
X265_VERSION=3.1.1 \
|
||||
XAU_VERSION=1.0.9 \
|
||||
XORG_MACROS_VERSION=1.19.2 \
|
||||
XPROTO_VERSION=7.0.31 \
|
||||
XVID_VERSION=1.3.4 \
|
||||
LIBXML2_VERSION=2.9.10 \
|
||||
LIBBLURAY_VERSION=1.1.2 \
|
||||
LIBZMQ_VERSION=4.3.3 \
|
||||
SRC=/usr/local
|
||||
|
||||
ARG FREETYPE_SHA256SUM="5d03dd76c2171a7601e9ce10551d52d4471cf92cd205948e60289251daddffa8 freetype-2.5.5.tar.gz"
|
||||
ARG FRIBIDI_SHA256SUM="3fc96fa9473bd31dcb5500bdf1aa78b337ba13eb8c301e7c28923fea982453a8 0.19.7.tar.gz"
|
||||
ARG LIBASS_SHA256SUM="8fadf294bf701300d4605e6f1d92929304187fca4b8d8a47889315526adbafd7 0.13.7.tar.gz"
|
||||
ARG LIBVIDSTAB_SHA256SUM="14d2a053e56edad4f397be0cb3ef8eb1ec3150404ce99a426c4eb641861dc0bb v1.1.0.tar.gz"
|
||||
ARG OGG_SHA256SUM="e19ee34711d7af328cb26287f4137e70630e7261b17cbe3cd41011d73a654692 libogg-1.3.2.tar.gz"
|
||||
ARG OPUS_SHA256SUM="77db45a87b51578fbc49555ef1b10926179861d854eb2613207dc79d9ec0a9a9 opus-1.2.tar.gz"
|
||||
ARG THEORA_SHA256SUM="40952956c47811928d1e7922cda3bc1f427eb75680c3c37249c91e949054916b libtheora-1.1.1.tar.gz"
|
||||
ARG VORBIS_SHA256SUM="6efbcecdd3e5dfbf090341b485da9d176eb250d893e3eb378c428a2db38301ce libvorbis-1.3.5.tar.gz"
|
||||
ARG XVID_SHA256SUM="4e9fd62728885855bc5007fe1be58df42e5e274497591fec37249e1052ae316f xvidcore-1.3.4.tar.gz"
|
||||
ARG LIBXML2_SHA256SUM="f07dab13bf42d2b8db80620cce7419b3b87827cc937c8bb20fe13b8571ee9501 libxml2-v2.9.10.tar.gz"
|
||||
ARG LIBBLURAY_SHA256SUM="a3dd452239b100dc9da0d01b30e1692693e2a332a7d29917bf84bb10ea7c0b42 libbluray-1.1.2.tar.bz2"
|
||||
|
||||
|
||||
ARG LD_LIBRARY_PATH=/opt/ffmpeg/lib
|
||||
ARG MAKEFLAGS="-j2"
|
||||
ARG PKG_CONFIG_PATH="/opt/ffmpeg/share/pkgconfig:/opt/ffmpeg/lib/pkgconfig:/opt/ffmpeg/lib64/pkgconfig:/opt/vc/lib/pkgconfig"
|
||||
ARG PREFIX=/opt/ffmpeg
|
||||
ARG LD_LIBRARY_PATH="/opt/ffmpeg/lib:/opt/ffmpeg/lib64:/usr/lib64:/usr/lib:/lib64:/lib:/opt/vc/lib"
|
||||
|
||||
|
||||
RUN buildDeps="autoconf \
|
||||
automake \
|
||||
cmake \
|
||||
curl \
|
||||
bzip2 \
|
||||
libexpat1-dev \
|
||||
g++ \
|
||||
gcc \
|
||||
git \
|
||||
gperf \
|
||||
libtool \
|
||||
make \
|
||||
nasm \
|
||||
perl \
|
||||
pkg-config \
|
||||
python \
|
||||
sudo \
|
||||
libssl-dev \
|
||||
yasm \
|
||||
linux-headers-raspi2 \
|
||||
libomxil-bellagio-dev \
|
||||
libx265-dev \
|
||||
libaom-dev \
|
||||
zlib1g-dev" && \
|
||||
apt-get -yqq update && \
|
||||
apt-get install -yq --no-install-recommends ${buildDeps}
|
||||
## opencore-amr https://sourceforge.net/projects/opencore-amr/
|
||||
RUN \
|
||||
DIR=/tmp/opencore-amr && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://versaweb.dl.sourceforge.net/project/opencore-amr/opencore-amr/opencore-amr-${OPENCOREAMR_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## x264 http://www.videolan.org/developers/x264.html
|
||||
RUN \
|
||||
DIR=/tmp/x264 && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-${X264_VERSION}.tar.bz2 | \
|
||||
tar -jx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared --enable-pic --disable-cli && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
# ### x265 http://x265.org/
|
||||
# RUN \
|
||||
# DIR=/tmp/x265 && \
|
||||
# mkdir -p ${DIR} && \
|
||||
# cd ${DIR} && \
|
||||
# curl -sL https://download.videolan.org/pub/videolan/x265/x265_${X265_VERSION}.tar.gz | \
|
||||
# tar -zx && \
|
||||
# cd x265_${X265_VERSION}/build/linux && \
|
||||
# sed -i "/-DEXTRA_LIB/ s/$/ -DCMAKE_INSTALL_PREFIX=\${PREFIX}/" multilib.sh && \
|
||||
# sed -i "/^cmake/ s/$/ -DENABLE_CLI=OFF/" multilib.sh && \
|
||||
# # export CXXFLAGS="${CXXFLAGS} -fPIC" && \
|
||||
# ./multilib.sh && \
|
||||
# make -C 8bit install && \
|
||||
# rm -rf ${DIR}
|
||||
### libogg https://www.xiph.org/ogg/
|
||||
RUN \
|
||||
DIR=/tmp/ogg && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz && \
|
||||
echo ${OGG_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libogg-${OGG_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libopus https://www.opus-codec.org/
|
||||
RUN \
|
||||
DIR=/tmp/opus && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://archive.mozilla.org/pub/opus/opus-${OPUS_VERSION}.tar.gz && \
|
||||
echo ${OPUS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f opus-${OPUS_VERSION}.tar.gz && \
|
||||
autoreconf -fiv && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libvorbis https://xiph.org/vorbis/
|
||||
RUN \
|
||||
DIR=/tmp/vorbis && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERSION}.tar.gz && \
|
||||
echo ${VORBIS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libvorbis-${VORBIS_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libtheora http://www.theora.org/
|
||||
RUN \
|
||||
DIR=/tmp/theora && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.gz && \
|
||||
echo ${THEORA_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f libtheora-${THEORA_VERSION}.tar.gz && \
|
||||
curl -sL 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' -o config.guess && \
|
||||
curl -sL 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' -o config.sub && \
|
||||
./configure --prefix="${PREFIX}" --with-ogg="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libvpx https://www.webmproject.org/code/
|
||||
RUN \
|
||||
DIR=/tmp/vpx && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://codeload.github.com/webmproject/libvpx/tar.gz/v${VPX_VERSION} | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-vp8 --enable-vp9 --enable-vp9-highbitdepth --enable-pic --enable-shared \
|
||||
--disable-debug --disable-examples --disable-docs --disable-install-bins && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libwebp https://developers.google.com/speed/webp/
|
||||
RUN \
|
||||
DIR=/tmp/vebp && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### libmp3lame http://lame.sourceforge.net/
|
||||
RUN \
|
||||
DIR=/tmp/lame && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://versaweb.dl.sourceforge.net/project/lame/lame/$(echo ${LAME_VERSION} | sed -e 's/[^0-9]*\([0-9]*\)[.]\([0-9]*\)[.]\([0-9]*\)\([0-9A-Za-z-]*\)/\1.\2/')/lame-${LAME_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin" --enable-shared --enable-nasm --disable-frontend && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### xvid https://www.xvid.com/
|
||||
RUN \
|
||||
DIR=/tmp/xvid && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO http://downloads.xvid.org/downloads/xvidcore-${XVID_VERSION}.tar.gz && \
|
||||
echo ${XVID_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx -f xvidcore-${XVID_VERSION}.tar.gz && \
|
||||
cd xvidcore/build/generic && \
|
||||
./configure --prefix="${PREFIX}" --bindir="${PREFIX}/bin" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
### fdk-aac https://github.com/mstorsjo/fdk-aac
|
||||
RUN \
|
||||
DIR=/tmp/fdk-aac && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://github.com/mstorsjo/fdk-aac/archive/v${FDKAAC_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
autoreconf -fiv && \
|
||||
./configure --prefix="${PREFIX}" --enable-shared --datadir="${DIR}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## openjpeg https://github.com/uclouvain/openjpeg
|
||||
RUN \
|
||||
DIR=/tmp/openjpeg && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sL https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz | \
|
||||
tar -zx --strip-components=1 && \
|
||||
export CFLAGS="${CFLAGS} -DPNG_ARM_NEON_OPT=0" && \
|
||||
cmake -DBUILD_THIRDPARTY:BOOL=ON -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## freetype https://www.freetype.org/
|
||||
RUN \
|
||||
DIR=/tmp/freetype && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://download.savannah.gnu.org/releases/freetype/freetype-${FREETYPE_VERSION}.tar.gz && \
|
||||
echo ${FREETYPE_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f freetype-${FREETYPE_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## libvstab https://github.com/georgmartius/vid.stab
|
||||
RUN \
|
||||
DIR=/tmp/vid.stab && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/georgmartius/vid.stab/archive/v${LIBVIDSTAB_VERSION}.tar.gz && \
|
||||
echo ${LIBVIDSTAB_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f v${LIBVIDSTAB_VERSION}.tar.gz && \
|
||||
cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" . && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## fridibi https://www.fribidi.org/
|
||||
RUN \
|
||||
DIR=/tmp/fribidi && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/fribidi/fribidi/archive/${FRIBIDI_VERSION}.tar.gz && \
|
||||
echo ${FRIBIDI_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f ${FRIBIDI_VERSION}.tar.gz && \
|
||||
sed -i 's/^SUBDIRS =.*/SUBDIRS=gen.tab charset lib bin/' Makefile.am && \
|
||||
./bootstrap --no-config --auto && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j1 && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## fontconfig https://www.freedesktop.org/wiki/Software/fontconfig/
|
||||
RUN \
|
||||
DIR=/tmp/fontconfig && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.freedesktop.org/software/fontconfig/release/fontconfig-${FONTCONFIG_VERSION}.tar.bz2 && \
|
||||
tar -jx --strip-components=1 -f fontconfig-${FONTCONFIG_VERSION}.tar.bz2 && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## libass https://github.com/libass/libass
|
||||
RUN \
|
||||
DIR=/tmp/libass && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/libass/libass/archive/${LIBASS_VERSION}.tar.gz && \
|
||||
echo ${LIBASS_SHA256SUM} | sha256sum --check && \
|
||||
tar -zx --strip-components=1 -f ${LIBASS_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
## kvazaar https://github.com/ultravideo/kvazaar
|
||||
RUN \
|
||||
DIR=/tmp/kvazaar && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/ultravideo/kvazaar/archive/v${KVAZAAR_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f v${KVAZAAR_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
# RUN \
|
||||
# DIR=/tmp/aom && \
|
||||
# git clone --branch ${AOM_VERSION} --depth 1 https://aomedia.googlesource.com/aom ${DIR} ; \
|
||||
# cd ${DIR} ; \
|
||||
# rm -rf CMakeCache.txt CMakeFiles ; \
|
||||
# mkdir -p ./aom_build ; \
|
||||
# cd ./aom_build ; \
|
||||
# cmake -DCMAKE_INSTALL_PREFIX="${PREFIX}" -DBUILD_SHARED_LIBS=1 ..; \
|
||||
# make ; \
|
||||
# make install ; \
|
||||
# rm -rf ${DIR}
|
||||
|
||||
## libxcb (and supporting libraries) for screen capture https://xcb.freedesktop.org/
|
||||
RUN \
|
||||
DIR=/tmp/xorg-macros && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive//individual/util/util-macros-${XORG_MACROS_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f util-macros-${XORG_MACROS_VERSION}.tar.gz && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/xproto && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive/individual/proto/xproto-${XPROTO_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f xproto-${XPROTO_VERSION}.tar.gz && \
|
||||
curl -sL 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' -o config.guess && \
|
||||
curl -sL 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' -o config.sub && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libXau && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://www.x.org/archive/individual/lib/libXau-${XAU_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libXau-${XAU_VERSION}.tar.gz && \
|
||||
./configure --srcdir=${DIR} --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libpthread-stubs && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/libpthread-stubs-${LIBPTHREAD_STUBS_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libpthread-stubs-${LIBPTHREAD_STUBS_VERSION}.tar.gz && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libxcb-proto && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/xcb-proto-${XCBPROTO_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f xcb-proto-${XCBPROTO_VERSION}.tar.gz && \
|
||||
ACLOCAL_PATH="${PREFIX}/share/aclocal" ./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/libxcb && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://xcb.freedesktop.org/dist/libxcb-${LIBXCB_VERSION}.tar.gz && \
|
||||
tar -zx --strip-components=1 -f libxcb-${LIBXCB_VERSION}.tar.gz && \
|
||||
ACLOCAL_PATH="${PREFIX}/share/aclocal" ./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libxml2 - for libbluray
|
||||
RUN \
|
||||
DIR=/tmp/libxml2 && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://gitlab.gnome.org/GNOME/libxml2/-/archive/v${LIBXML2_VERSION}/libxml2-v${LIBXML2_VERSION}.tar.gz && \
|
||||
echo ${LIBXML2_SHA256SUM} | sha256sum --check && \
|
||||
tar -xz --strip-components=1 -f libxml2-v${LIBXML2_VERSION}.tar.gz && \
|
||||
./autogen.sh --prefix="${PREFIX}" --with-ftp=no --with-http=no --with-python=no && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libbluray - Requires libxml, freetype, and fontconfig
|
||||
RUN \
|
||||
DIR=/tmp/libbluray && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://download.videolan.org/pub/videolan/libbluray/${LIBBLURAY_VERSION}/libbluray-${LIBBLURAY_VERSION}.tar.bz2 && \
|
||||
echo ${LIBBLURAY_SHA256SUM} | sha256sum --check && \
|
||||
tar -jx --strip-components=1 -f libbluray-${LIBBLURAY_VERSION}.tar.bz2 && \
|
||||
./configure --prefix="${PREFIX}" --disable-examples --disable-bdjava-jar --disable-static --enable-shared && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## libzmq https://github.com/zeromq/libzmq/
|
||||
RUN \
|
||||
DIR=/tmp/libzmq && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
curl -sLO https://github.com/zeromq/libzmq/archive/v${LIBZMQ_VERSION}.tar.gz && \
|
||||
tar -xz --strip-components=1 -f v${LIBZMQ_VERSION}.tar.gz && \
|
||||
./autogen.sh && \
|
||||
./configure --prefix="${PREFIX}" && \
|
||||
make -j $(nproc) && \
|
||||
# make check && \
|
||||
make -j $(nproc) install && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## userland https://github.com/raspberrypi/userland
|
||||
RUN \
|
||||
DIR=/tmp/userland && \
|
||||
mkdir -p ${DIR} && \
|
||||
cd ${DIR} && \
|
||||
git clone --depth 1 https://github.com/raspberrypi/userland.git . && \
|
||||
./buildme && \
|
||||
rm -rf ${DIR}
|
||||
|
||||
## ffmpeg https://ffmpeg.org/
|
||||
RUN \
|
||||
DIR=/tmp/ffmpeg && mkdir -p ${DIR} && cd ${DIR} && \
|
||||
curl -sLO https://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2 && \
|
||||
tar -jx --strip-components=1 -f ffmpeg-${FFMPEG_VERSION}.tar.bz2
|
||||
|
||||
RUN \
|
||||
DIR=/tmp/ffmpeg && mkdir -p ${DIR} && cd ${DIR} && \
|
||||
./configure \
|
||||
--disable-debug \
|
||||
--disable-doc \
|
||||
--disable-ffplay \
|
||||
--enable-shared \
|
||||
--enable-avresample \
|
||||
--enable-libopencore-amrnb \
|
||||
--enable-libopencore-amrwb \
|
||||
--enable-gpl \
|
||||
--enable-libass \
|
||||
--enable-fontconfig \
|
||||
--enable-libfreetype \
|
||||
--enable-libvidstab \
|
||||
--enable-libmp3lame \
|
||||
--enable-libopus \
|
||||
--enable-libtheora \
|
||||
--enable-libvorbis \
|
||||
--enable-libvpx \
|
||||
--enable-libwebp \
|
||||
--enable-libxcb \
|
||||
--enable-libx265 \
|
||||
--enable-libxvid \
|
||||
--enable-libx264 \
|
||||
--enable-nonfree \
|
||||
--enable-openssl \
|
||||
--enable-libfdk_aac \
|
||||
--enable-postproc \
|
||||
--enable-small \
|
||||
--enable-version3 \
|
||||
--enable-libbluray \
|
||||
--enable-libzmq \
|
||||
--extra-libs=-ldl \
|
||||
--prefix="${PREFIX}" \
|
||||
--enable-libopenjpeg \
|
||||
--enable-libkvazaar \
|
||||
--enable-libaom \
|
||||
--extra-libs=-lpthread \
|
||||
--enable-omx \
|
||||
--enable-omx-rpi \
|
||||
--enable-mmal \
|
||||
--enable-v4l2_m2m \
|
||||
--enable-neon \
|
||||
--extra-cflags="-I${PREFIX}/include" \
|
||||
--extra-ldflags="-L${PREFIX}/lib" && \
|
||||
make -j $(nproc) && \
|
||||
make -j $(nproc) install && \
|
||||
make tools/zmqsend && cp tools/zmqsend ${PREFIX}/bin/ && \
|
||||
make distclean && \
|
||||
hash -r && \
|
||||
cd tools && \
|
||||
make qt-faststart && cp qt-faststart ${PREFIX}/bin/
|
||||
|
||||
## cleanup
|
||||
RUN \
|
||||
ldd ${PREFIX}/bin/ffmpeg | grep opt/ffmpeg | cut -d ' ' -f 3 | xargs -i cp {} /usr/local/lib/ && \
|
||||
# copy userland lib too
|
||||
ldd ${PREFIX}/bin/ffmpeg | grep opt/vc | cut -d ' ' -f 3 | xargs -i cp {} /usr/local/lib/ && \
|
||||
for lib in /usr/local/lib/*.so.*; do ln -s "${lib##*/}" "${lib%%.so.*}".so; done && \
|
||||
cp ${PREFIX}/bin/* /usr/local/bin/ && \
|
||||
cp -r ${PREFIX}/share/ffmpeg /usr/local/share/ && \
|
||||
LD_LIBRARY_PATH=/usr/local/lib ffmpeg -buildconf && \
|
||||
cp -r ${PREFIX}/include/libav* ${PREFIX}/include/libpostproc ${PREFIX}/include/libsw* /usr/local/include && \
|
||||
mkdir -p /usr/local/lib/pkgconfig && \
|
||||
for pc in ${PREFIX}/lib/pkgconfig/libav*.pc ${PREFIX}/lib/pkgconfig/libpostproc.pc ${PREFIX}/lib/pkgconfig/libsw*.pc; do \
|
||||
sed "s:${PREFIX}:/usr/local:g" <"$pc" >/usr/local/lib/pkgconfig/"${pc##*/}"; \
|
||||
done
|
||||
|
||||
FROM base AS release
|
||||
|
||||
ENV LD_LIBRARY_PATH=/usr/local/lib:/usr/local/lib64:/usr/lib:/usr/lib64:/lib:/lib64
|
||||
|
||||
RUN \
|
||||
apt-get -yqq update && \
|
||||
apt-get install -yq --no-install-recommends libx265-dev libaom-dev && \
|
||||
apt-get autoremove -y && \
|
||||
apt-get clean -y
|
||||
|
||||
CMD ["--help"]
|
||||
ENTRYPOINT ["ffmpeg"]
|
||||
|
||||
COPY --from=build /usr/local /usr/local/
|
||||
@@ -1,39 +0,0 @@
|
||||
FROM ubuntu:20.04 as build
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install -y \
|
||||
python3 \
|
||||
python3-dev \
|
||||
wget \
|
||||
# opencv dependencies
|
||||
build-essential cmake git pkg-config libgtk-3-dev \
|
||||
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
|
||||
libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
|
||||
gfortran openexr libatlas-base-dev libssl-dev\
|
||||
libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev \
|
||||
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
|
||||
# scipy dependencies
|
||||
gcc gfortran libopenblas-dev liblapack-dev cython
|
||||
|
||||
RUN wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \
|
||||
&& python3 get-pip.py
|
||||
|
||||
RUN pip3 install scikit-build
|
||||
|
||||
RUN pip3 wheel --wheel-dir=/wheels \
|
||||
opencv-python-headless \
|
||||
numpy \
|
||||
imutils \
|
||||
scipy \
|
||||
psutil \
|
||||
Flask \
|
||||
paho-mqtt \
|
||||
PyYAML \
|
||||
matplotlib \
|
||||
click
|
||||
|
||||
FROM scratch
|
||||
|
||||
COPY --from=build /wheels /wheels
|
||||
@@ -1,49 +0,0 @@
|
||||
FROM ubuntu:20.04 as build
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get -qq update \
|
||||
&& apt-get -qq install -y \
|
||||
python3 \
|
||||
python3-dev \
|
||||
wget \
|
||||
# opencv dependencies
|
||||
build-essential cmake git pkg-config libgtk-3-dev \
|
||||
libavcodec-dev libavformat-dev libswscale-dev libv4l-dev \
|
||||
libxvidcore-dev libx264-dev libjpeg-dev libpng-dev libtiff-dev \
|
||||
gfortran openexr libatlas-base-dev libssl-dev\
|
||||
libtbb2 libtbb-dev libdc1394-22-dev libopenexr-dev \
|
||||
libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev \
|
||||
# scipy dependencies
|
||||
gcc gfortran libopenblas-dev liblapack-dev cython
|
||||
|
||||
RUN wget -q https://bootstrap.pypa.io/get-pip.py -O get-pip.py \
|
||||
&& python3 get-pip.py
|
||||
|
||||
# need to build cmake from source because binary distribution is broken for arm64
|
||||
# https://github.com/scikit-build/cmake-python-distributions/issues/115
|
||||
# https://github.com/skvark/opencv-python/issues/366
|
||||
# https://github.com/scikit-build/cmake-python-distributions/issues/96#issuecomment-663062358
|
||||
RUN pip3 install scikit-build
|
||||
|
||||
RUN git clone https://github.com/scikit-build/cmake-python-distributions.git \
|
||||
&& cd cmake-python-distributions/ \
|
||||
&& python3 setup.py bdist_wheel
|
||||
|
||||
RUN pip3 install cmake-python-distributions/dist/*.whl
|
||||
|
||||
RUN pip3 wheel --wheel-dir=/wheels \
|
||||
opencv-python-headless \
|
||||
numpy \
|
||||
imutils \
|
||||
scipy \
|
||||
psutil \
|
||||
Flask \
|
||||
paho-mqtt \
|
||||
PyYAML \
|
||||
matplotlib \
|
||||
click
|
||||
|
||||
FROM scratch
|
||||
|
||||
COPY --from=build /wheels /wheels
|
||||
5
docker/rootfs/etc/services.d/nginx/finish
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/execlineb -S1
|
||||
if { s6-test ${1} -ne 0 }
|
||||
if { s6-test ${1} -ne 256 }
|
||||
|
||||
s6-svscanctl -t /var/run/s6/services
|
||||
2
docker/rootfs/etc/services.d/nginx/run
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/execlineb -P
|
||||
/usr/local/nginx/sbin/nginx
|
||||
239
docker/rootfs/usr/local/nginx/conf/nginx.conf
Normal file
@@ -0,0 +1,239 @@
|
||||
daemon off;
|
||||
user root;
|
||||
worker_processes 1;
|
||||
|
||||
error_log /usr/local/nginx/logs/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /usr/local/nginx/logs/access.log main;
|
||||
|
||||
sendfile on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
gzip on;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/javascript image/svg+xml image/x-icon image/bmp image/png image/gif image/jpeg image/jpg;
|
||||
gzip_proxied no-cache no-store private expired auth;
|
||||
gzip_vary on;
|
||||
|
||||
upstream frigate_api {
|
||||
server 127.0.0.1:5001;
|
||||
keepalive 1024;
|
||||
}
|
||||
|
||||
upstream mqtt_ws {
|
||||
server 127.0.0.1:5002;
|
||||
keepalive 1024;
|
||||
}
|
||||
|
||||
upstream jsmpeg {
|
||||
server 127.0.0.1:8082;
|
||||
keepalive 1024;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 5000;
|
||||
|
||||
# vod settings
|
||||
vod_base_url '';
|
||||
vod_segments_base_url '';
|
||||
vod_mode mapped;
|
||||
vod_max_mapping_response_size 1m;
|
||||
vod_upstream_location /api;
|
||||
vod_align_segments_to_key_frames on;
|
||||
vod_manifest_segment_durations_mode accurate;
|
||||
vod_ignore_edit_list on;
|
||||
|
||||
# vod caches
|
||||
vod_metadata_cache metadata_cache 512m;
|
||||
vod_mapping_cache mapping_cache 5m 10m;
|
||||
|
||||
# gzip manifests
|
||||
gzip on;
|
||||
gzip_types application/vnd.apple.mpegurl;
|
||||
|
||||
# file handle caching / aio
|
||||
open_file_cache max=1000 inactive=5m;
|
||||
open_file_cache_valid 2m;
|
||||
open_file_cache_min_uses 1;
|
||||
open_file_cache_errors on;
|
||||
aio on;
|
||||
|
||||
location /vod/ {
|
||||
vod hls;
|
||||
|
||||
secure_token $args;
|
||||
secure_token_types application/vnd.apple.mpegurl;
|
||||
|
||||
add_header Access-Control-Allow-Headers '*';
|
||||
add_header Access-Control-Expose-Headers 'Server,range,Content-Length,Content-Range';
|
||||
add_header Access-Control-Allow-Methods 'GET, HEAD, OPTIONS';
|
||||
add_header Access-Control-Allow-Origin '*';
|
||||
add_header Cache-Control "no-store";
|
||||
expires off;
|
||||
}
|
||||
|
||||
location /stream/ {
|
||||
add_header Cache-Control "no-store";
|
||||
expires off;
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length';
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
types {
|
||||
application/dash+xml mpd;
|
||||
application/vnd.apple.mpegurl m3u8;
|
||||
video/mp2t ts;
|
||||
image/jpeg jpg;
|
||||
}
|
||||
|
||||
root /tmp;
|
||||
}
|
||||
|
||||
location /clips/ {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length';
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
types {
|
||||
video/mp4 mp4;
|
||||
image/jpeg jpg;
|
||||
}
|
||||
|
||||
autoindex on;
|
||||
root /media/frigate;
|
||||
}
|
||||
|
||||
location /cache/ {
|
||||
internal; # This tells nginx it's not accessible from the outside
|
||||
alias /tmp/cache/;
|
||||
}
|
||||
|
||||
location /recordings/ {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
|
||||
add_header 'Access-Control-Allow-Credentials' 'true';
|
||||
add_header 'Access-Control-Expose-Headers' 'Content-Length';
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' "$http_origin";
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'text/plain charset=UTF-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
|
||||
types {
|
||||
video/mp4 mp4;
|
||||
}
|
||||
|
||||
autoindex on;
|
||||
autoindex_format json;
|
||||
root /media/frigate;
|
||||
}
|
||||
|
||||
location /ws {
|
||||
proxy_pass http://mqtt_ws/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location /live/ {
|
||||
proxy_pass http://jsmpeg/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "Upgrade";
|
||||
proxy_set_header Host $host;
|
||||
}
|
||||
|
||||
location ~* /api/.*\.(jpg|jpeg|png)$ {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
|
||||
rewrite ^/api/(.*)$ $1 break;
|
||||
proxy_pass http://frigate_api;
|
||||
proxy_pass_request_headers on;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location /api/ {
|
||||
add_header Cache-Control "no-store";
|
||||
expires off;
|
||||
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
|
||||
proxy_pass http://frigate_api/;
|
||||
proxy_pass_request_headers on;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location / {
|
||||
add_header Cache-Control "no-store";
|
||||
expires off;
|
||||
|
||||
location /assets/ {
|
||||
access_log off;
|
||||
expires 1y;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
sub_filter 'href="/BASE_PATH/' 'href="$http_x_ingress_path/';
|
||||
sub_filter 'url(/BASE_PATH/' 'url($http_x_ingress_path/';
|
||||
sub_filter '"/BASE_PATH/dist/' '"$http_x_ingress_path/dist/';
|
||||
sub_filter '"/BASE_PATH/js/' '"$http_x_ingress_path/js/';
|
||||
sub_filter '"/BASE_PATH/assets/' '"$http_x_ingress_path/assets/';
|
||||
sub_filter '="/BASE_PATH/"' '=window.baseUrl';
|
||||
sub_filter '<body>' '<body><script>window.baseUrl="$http_x_ingress_path/";</script>';
|
||||
sub_filter_types text/css application/javascript;
|
||||
sub_filter_once off;
|
||||
|
||||
root /opt/frigate/web;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rtmp {
|
||||
server {
|
||||
listen 1935;
|
||||
chunk_size 4096;
|
||||
allow publish 127.0.0.1;
|
||||
deny publish all;
|
||||
allow play all;
|
||||
application live {
|
||||
live on;
|
||||
record off;
|
||||
meta copy;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Dependencies
|
||||
/node_modules
|
||||
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -1,23 +0,0 @@
|
||||
# Camera Specific Configuration
|
||||
Frigate should work with most RTSP cameras and h264 feeds such as Dahua.
|
||||
|
||||
## RTMP Cameras
|
||||
The input parameters need to be adjusted for RTMP cameras
|
||||
```yaml
|
||||
ffmpeg:
|
||||
input_args:
|
||||
- -avoid_negative_ts
|
||||
- make_zero
|
||||
- -fflags
|
||||
- nobuffer
|
||||
- -flags
|
||||
- low_delay
|
||||
- -strict
|
||||
- experimental
|
||||
- -fflags
|
||||
- +genpts+discardcorrupt
|
||||
- -vsync
|
||||
- drop
|
||||
- -use_wallclock_as_timestamps
|
||||
- '1'
|
||||
```
|
||||
@@ -1,32 +0,0 @@
|
||||
# Hardware Acceleration for Decoding Video
|
||||
|
||||
FFmpeg is compiled to support hardware accelerated decoding of video streams.
|
||||
|
||||
## Intel-based CPUs via Quicksync (https://trac.ffmpeg.org/wiki/Hardware/QuickSync)
|
||||
```yaml
|
||||
ffmpeg:
|
||||
hwaccel_args:
|
||||
- -hwaccel
|
||||
- vaapi
|
||||
- -hwaccel_device
|
||||
- /dev/dri/renderD128
|
||||
- -hwaccel_output_format
|
||||
- yuv420p
|
||||
```
|
||||
|
||||
## Raspberry Pi 3b and 4 (32bit OS)
|
||||
Ensure you increase the allocated RAM for your GPU to at least 128 (raspi-config > Advanced Options > Memory Split)
|
||||
```yaml
|
||||
ffmpeg:
|
||||
hwaccel_args:
|
||||
- -c:v
|
||||
- h264_mmal
|
||||
```
|
||||
|
||||
## Raspberry Pi 4 (64bit OS)
|
||||
```yaml
|
||||
ffmpeg:
|
||||
hwaccel_args:
|
||||
- -c:v
|
||||
- h264_v4l2m2m
|
||||
```
|
||||
5
docs/README.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Website
|
||||
|
||||
This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator.
|
||||
|
||||
For installation and contributing instructions, please follow the [Contributing Docs](https://blakeblackshear.github.io/frigate/contributing).
|
||||
3
docs/babel.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
||||
80
docs/docs/configuration/advanced.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: advanced
|
||||
title: Advanced Options
|
||||
sidebar_label: Advanced Options
|
||||
---
|
||||
|
||||
## Advanced configuration
|
||||
|
||||
### `logger`
|
||||
|
||||
Change the default log level for troubleshooting purposes.
|
||||
|
||||
```yaml
|
||||
logger:
|
||||
# Optional: default log level (default: shown below)
|
||||
default: info
|
||||
# Optional: module by module log level configuration
|
||||
logs:
|
||||
frigate.mqtt: error
|
||||
```
|
||||
|
||||
Available log levels are: `debug`, `info`, `warning`, `error`, `critical`
|
||||
|
||||
Examples of available modules are:
|
||||
|
||||
- `frigate.app`
|
||||
- `frigate.mqtt`
|
||||
- `frigate.edgetpu`
|
||||
- `frigate.zeroconf`
|
||||
- `detector.<detector_name>`
|
||||
- `watchdog.<camera_name>`
|
||||
- `ffmpeg.<camera_name>.<sorted_roles>` NOTE: All FFmpeg logs are sent as `error` level.
|
||||
|
||||
### `environment_vars`
|
||||
|
||||
This section can be used to set environment variables for those unable to modify the environment of the container (ie. within HassOS)
|
||||
|
||||
### `database`
|
||||
|
||||
Event and recording information is managed in a sqlite database at `/media/frigate/frigate.db`. If that database is deleted, recordings will be orphaned and will need to be cleaned up manually. They also won't show up in the Media Browser within Home Assistant.
|
||||
|
||||
If you are storing your database on a network share (SMB, NFS, etc), you may get a `database is locked` error message on startup. You can customize the location of the database in the config if necessary.
|
||||
|
||||
This may need to be in a custom location if network storage is used for the media folder.
|
||||
|
||||
```yaml
|
||||
database:
|
||||
path: /path/to/frigate.db
|
||||
```
|
||||
|
||||
### `model`
|
||||
|
||||
If using a custom model, the width and height will need to be specified.
|
||||
|
||||
The labelmap can be customized to your needs. A common reason to do this is to combine multiple object types that are easily confused when you don't need to be as granular such as car/truck. By default, truck is renamed to car because they are often confused. You cannot add new object types, but you can change the names of existing objects in the model.
|
||||
|
||||
```yaml
|
||||
model:
|
||||
labelmap:
|
||||
2: vehicle
|
||||
3: vehicle
|
||||
5: vehicle
|
||||
7: vehicle
|
||||
15: animal
|
||||
16: animal
|
||||
17: animal
|
||||
```
|
||||
|
||||
Note that if you rename objects in the labelmap, you will also need to update your `objects -> track` list as well.
|
||||
|
||||
## Custom ffmpeg build
|
||||
|
||||
Included with Frigate is a build of ffmpeg that works for the vast majority of users. However, there exists some hardware setups which have incompatibilities with the included build. In this case, a docker volume mapping can be used to overwrite the included ffmpeg build with an ffmpeg build that works for your specific hardware setup.
|
||||
|
||||
To do this:
|
||||
1. Download your ffmpeg build and uncompress to a folder on the host (let's use `/home/appdata/frigate/custom-ffmpeg` for this example).
|
||||
2. Update your docker-compose or docker CLI to include `'/home/appdata/frigate/custom-ffmpeg':'/usr/lib/btbn-ffmpeg':'ro'` in the volume mappings.
|
||||
3. Restart frigate and the custom version will be used if the mapping was done correctly.
|
||||
|
||||
NOTE: The folder that is mapped from the host needs to be the folder that contains `/bin`. So if the full structure is `/home/appdata/frigate/custom-ffmpeg/bin/ffmpeg` then `/home/appdata/frigate/custom-ffmpeg` needs to be mapped to `/usr/lib/btbn-ffmpeg`.
|
||||
14
docs/docs/configuration/birdseye.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Birdseye
|
||||
|
||||
Birdseye allows a heads-up view of your cameras to see what is going on around your property / space without having to watch all cameras that may have nothing happening. Birdseye allows specific modes that intelligently show and disappear based on what you care about.
|
||||
|
||||
### Birdseye Modes
|
||||
|
||||
Birdseye offers different modes to customize which cameras show under which circumstances.
|
||||
- **continuous:** All cameras are always included
|
||||
- **motion:** Cameras that have detected motion within the last 30 seconds are included
|
||||
- **objects:** Cameras that have tracked an active object within the last 30 seconds are included
|
||||
|
||||
### Custom Birdseye Icon
|
||||
|
||||
A custom icon can be added to the birdseye background by provided a file `custom.png` inside of the Frigate `media` folder. The file must be a png with the icon as transparent, any non-transparent pixels will be white when displayed in the birdseye view.
|
||||
125
docs/docs/configuration/camera_specific.md
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
id: camera_specific
|
||||
title: Camera Specific Configurations
|
||||
---
|
||||
|
||||
### MJPEG Cameras
|
||||
|
||||
The input and output parameters need to be adjusted for MJPEG cameras
|
||||
|
||||
```yaml
|
||||
input_args: -avoid_negative_ts make_zero -fflags nobuffer -flags low_delay -strict experimental -fflags +genpts+discardcorrupt -use_wallclock_as_timestamps 1
|
||||
```
|
||||
|
||||
Note that mjpeg cameras require encoding the video into h264 for recording, and rtmp roles. This will use significantly more CPU than if the cameras supported h264 feeds directly.
|
||||
|
||||
```yaml
|
||||
output_args:
|
||||
record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v libx264 -an
|
||||
rtmp: -c:v libx264 -an -f flv
|
||||
```
|
||||
|
||||
### JPEG Stream Cameras
|
||||
|
||||
Cameras using a live changing jpeg image will need input parameters as below
|
||||
|
||||
```yaml
|
||||
input_args:
|
||||
- -r
|
||||
- 5 # << enter FPS here
|
||||
- -stream_loop
|
||||
- -1
|
||||
- -f
|
||||
- image2
|
||||
- -avoid_negative_ts
|
||||
- make_zero
|
||||
- -fflags
|
||||
- nobuffer
|
||||
- -flags
|
||||
- low_delay
|
||||
- -strict
|
||||
- experimental
|
||||
- -fflags
|
||||
- +genpts+discardcorrupt
|
||||
- -use_wallclock_as_timestamps
|
||||
- 1
|
||||
```
|
||||
|
||||
Outputting the stream will have the same args and caveats as per [MJPEG Cameras](#mjpeg-cameras)
|
||||
|
||||
### RTMP Cameras
|
||||
|
||||
The input parameters need to be adjusted for RTMP cameras
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
input_args: -avoid_negative_ts make_zero -fflags nobuffer -flags low_delay -strict experimental -fflags +genpts+discardcorrupt -rw_timeout 5000000 -use_wallclock_as_timestamps 1 -f live_flv
|
||||
```
|
||||
|
||||
### Reolink 410/520 (possibly others)
|
||||
|
||||
According to [this discussion](https://github.com/blakeblackshear/frigate/issues/3235#issuecomment-1135876973), the http video streams seem to be the most reliable for Reolink.
|
||||
|
||||
```yaml
|
||||
cameras:
|
||||
reolink:
|
||||
ffmpeg:
|
||||
input_args:
|
||||
- -avoid_negative_ts
|
||||
- make_zero
|
||||
- -fflags
|
||||
- +genpts+discardcorrupt
|
||||
- -flags
|
||||
- low_delay
|
||||
- -strict
|
||||
- experimental
|
||||
- -analyzeduration
|
||||
- 1000M
|
||||
- -probesize
|
||||
- 1000M
|
||||
- -rw_timeout
|
||||
- "5000000"
|
||||
inputs:
|
||||
- path: http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_main.bcs&user=username&password=password
|
||||
roles:
|
||||
- record
|
||||
- rtmp
|
||||
- path: http://reolink_ip/flv?port=1935&app=bcs&stream=channel0_ext.bcs&user=username&password=password
|
||||
roles:
|
||||
- detect
|
||||
detect:
|
||||
width: 896
|
||||
height: 672
|
||||
fps: 7
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Blue Iris RTSP Cameras
|
||||
|
||||
You will need to remove `nobuffer` flag for Blue Iris RTSP cameras
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
input_args: -avoid_negative_ts make_zero -flags low_delay -strict experimental -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 5000000 -use_wallclock_as_timestamps 1
|
||||
```
|
||||
|
||||
### UDP Only Cameras
|
||||
|
||||
If your cameras do not support TCP connections for RTSP, you can use UDP.
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
input_args: -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport udp -timeout 5000000 -use_wallclock_as_timestamps 1
|
||||
```
|
||||
|
||||
### Unifi Protect Cameras
|
||||
|
||||
In the Unifi 2.0 update Unifi Protect Cameras had a change in audio sample rate which causes issues for ffmpeg. The input rate needs to be set for record and rtmp.
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
output_args:
|
||||
record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -ar 44100 -c:a aac
|
||||
rtmp: -c:v copy -f flv -ar 44100 -c:a aac
|
||||
```
|
||||
45
docs/docs/configuration/cameras.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: cameras
|
||||
title: Cameras
|
||||
---
|
||||
|
||||
## Setting Up Camera Inputs
|
||||
|
||||
Several inputs can be configured for each camera and the role of each input can be mixed and matched based on your needs. This allows you to use a lower resolution stream for object detection, but create recordings from a higher resolution stream, or vice versa.
|
||||
|
||||
Each role can only be assigned to one input per camera. The options for roles are as follows:
|
||||
|
||||
| Role | Description |
|
||||
| -------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `detect` | Main feed for object detection |
|
||||
| `record` | Saves segments of the video feed based on configuration settings. [docs](/configuration/record) |
|
||||
| `rtmp` | Broadcast as an RTMP feed for other services to consume. [docs](/configuration/rtmp) |
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
host: mqtt.server.com
|
||||
cameras:
|
||||
back:
|
||||
ffmpeg:
|
||||
inputs:
|
||||
- path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2
|
||||
roles:
|
||||
- detect
|
||||
- rtmp
|
||||
- path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/live
|
||||
roles:
|
||||
- record
|
||||
detect:
|
||||
width: 1280
|
||||
height: 720
|
||||
```
|
||||
|
||||
Additional cameras are simply added to the config under the `cameras` entry.
|
||||
|
||||
```yaml
|
||||
mqtt: ...
|
||||
cameras:
|
||||
back: ...
|
||||
front: ...
|
||||
side: ...
|
||||
```
|
||||
79
docs/docs/configuration/detectors.md
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
id: detectors
|
||||
title: Detectors
|
||||
---
|
||||
|
||||
By default, Frigate will use a single CPU detector. If you have a Coral, you will need to configure your detector devices in the config file. When using multiple detectors, they run in dedicated processes, but pull from a common queue of requested detections across all cameras.
|
||||
|
||||
Frigate supports `edgetpu` and `cpu` as detector types. The device value should be specified according to the [Documentation for the TensorFlow Lite Python API](https://coral.ai/docs/edgetpu/multiple-edgetpu/#using-the-tensorflow-lite-python-api).
|
||||
|
||||
**Note**: There is no support for Nvidia GPUs to perform object detection with tensorflow. It can be used for ffmpeg decoding, but not object detection.
|
||||
|
||||
### Single USB Coral
|
||||
|
||||
```yaml
|
||||
detectors:
|
||||
coral:
|
||||
type: edgetpu
|
||||
device: usb
|
||||
```
|
||||
|
||||
### Multiple USB Corals
|
||||
|
||||
```yaml
|
||||
detectors:
|
||||
coral1:
|
||||
type: edgetpu
|
||||
device: usb:0
|
||||
coral2:
|
||||
type: edgetpu
|
||||
device: usb:1
|
||||
```
|
||||
|
||||
### Native Coral (Dev Board)
|
||||
_warning: may have [compatibility issues](https://github.com/blakeblackshear/frigate/issues/1706) after `v0.9.x`_
|
||||
|
||||
```yaml
|
||||
detectors:
|
||||
coral:
|
||||
type: edgetpu
|
||||
device: ""
|
||||
```
|
||||
|
||||
### Multiple PCIE/M.2 Corals
|
||||
|
||||
```yaml
|
||||
detectors:
|
||||
coral1:
|
||||
type: edgetpu
|
||||
device: pci:0
|
||||
coral2:
|
||||
type: edgetpu
|
||||
device: pci:1
|
||||
```
|
||||
|
||||
### Mixing Corals
|
||||
|
||||
```yaml
|
||||
detectors:
|
||||
coral_usb:
|
||||
type: edgetpu
|
||||
device: usb
|
||||
coral_pci:
|
||||
type: edgetpu
|
||||
device: pci
|
||||
```
|
||||
|
||||
### CPU Detectors (not recommended)
|
||||
|
||||
```yaml
|
||||
detectors:
|
||||
cpu1:
|
||||
type: cpu
|
||||
num_threads: 3
|
||||
cpu2:
|
||||
type: cpu
|
||||
num_threads: 3
|
||||
```
|
||||
|
||||
When using CPU detectors, you can add a CPU detector per camera. Adding more detectors than the number of cameras should not improve performance.
|
||||
118
docs/docs/configuration/hardware_acceleration.md
Normal file
@@ -0,0 +1,118 @@
|
||||
---
|
||||
id: hardware_acceleration
|
||||
title: Hardware Acceleration
|
||||
---
|
||||
|
||||
It is recommended to update your configuration to enable hardware accelerated decoding in ffmpeg. Depending on your system, these parameters may not be compatible. More information on hardware accelerated decoding for ffmpeg can be found here: https://trac.ffmpeg.org/wiki/HWAccelIntro
|
||||
|
||||
### Raspberry Pi 3/4
|
||||
|
||||
Ensure you increase the allocated RAM for your GPU to at least 128 (raspi-config > Performance Options > GPU Memory).
|
||||
**NOTICE**: If you are using the addon, you may need to turn off `Protection mode` for hardware acceleration.
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
hwaccel_args: -c:v h264_v4l2m2m
|
||||
```
|
||||
|
||||
### Intel-based CPUs (<10th Generation) via Quicksync
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
hwaccel_args: -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format yuv420p
|
||||
```
|
||||
**NOTICE**: With some of the processors, like the J4125, the default driver `iHD` doesn't seem to work correctly for hardware acceleration. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file.
|
||||
|
||||
### Intel-based CPUs (>=10th Generation) via Quicksync
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
hwaccel_args: -c:v h264_qsv
|
||||
```
|
||||
|
||||
### AMD/ATI GPUs (Radeon HD 2000 and newer GPUs) via libva-mesa-driver
|
||||
|
||||
**Note:** You also need to set `LIBVA_DRIVER_NAME=radeonsi` as an environment variable on the container.
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
hwaccel_args: -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format yuv420p
|
||||
```
|
||||
|
||||
### NVIDIA GPU
|
||||
|
||||
[Supported Nvidia GPUs for Decoding](https://developer.nvidia.com/video-encode-and-decode-gpu-support-matrix-new)
|
||||
|
||||
These instructions are based on the [jellyfin documentation](https://jellyfin.org/docs/general/administration/hardware-acceleration.html#nvidia-hardware-acceleration-on-docker-linux)
|
||||
|
||||
Add `--gpus all` to your docker run command or update your compose file.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
frigate:
|
||||
...
|
||||
image: blakeblackshear/frigate:stable
|
||||
deploy: # <------------- Add this section
|
||||
resources:
|
||||
reservations:
|
||||
devices:
|
||||
- driver: nvidia
|
||||
count: 1
|
||||
capabilities: [gpu]
|
||||
```
|
||||
|
||||
The decoder you need to pass in the `hwaccel_args` will depend on the input video.
|
||||
|
||||
A list of supported codecs (you can use `ffmpeg -decoders | grep cuvid` in the container to get a list)
|
||||
|
||||
```shell
|
||||
V..... h263_cuvid Nvidia CUVID H263 decoder (codec h263)
|
||||
V..... h264_cuvid Nvidia CUVID H264 decoder (codec h264)
|
||||
V..... hevc_cuvid Nvidia CUVID HEVC decoder (codec hevc)
|
||||
V..... mjpeg_cuvid Nvidia CUVID MJPEG decoder (codec mjpeg)
|
||||
V..... mpeg1_cuvid Nvidia CUVID MPEG1VIDEO decoder (codec mpeg1video)
|
||||
V..... mpeg2_cuvid Nvidia CUVID MPEG2VIDEO decoder (codec mpeg2video)
|
||||
V..... mpeg4_cuvid Nvidia CUVID MPEG4 decoder (codec mpeg4)
|
||||
V..... vc1_cuvid Nvidia CUVID VC1 decoder (codec vc1)
|
||||
V..... vp8_cuvid Nvidia CUVID VP8 decoder (codec vp8)
|
||||
V..... vp9_cuvid Nvidia CUVID VP9 decoder (codec vp9)
|
||||
```
|
||||
|
||||
For example, for H264 video, you'll select `h264_cuvid`.
|
||||
|
||||
```yaml
|
||||
ffmpeg:
|
||||
hwaccel_args: -c:v h264_cuvid
|
||||
```
|
||||
|
||||
If everything is working correctly, you should see a significant improvement in performance.
|
||||
Verify that hardware decoding is working by running `nvidia-smi`, which should show the ffmpeg
|
||||
processes:
|
||||
|
||||
```
|
||||
+-----------------------------------------------------------------------------+
|
||||
| NVIDIA-SMI 455.38 Driver Version: 455.38 CUDA Version: 11.1 |
|
||||
|-------------------------------+----------------------+----------------------+
|
||||
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
|
||||
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|
||||
| | | MIG M. |
|
||||
|===============================+======================+======================|
|
||||
| 0 GeForce GTX 166... Off | 00000000:03:00.0 Off | N/A |
|
||||
| 38% 41C P2 36W / 125W | 2082MiB / 5942MiB | 5% Default |
|
||||
| | | N/A |
|
||||
+-------------------------------+----------------------+----------------------+
|
||||
|
||||
+-----------------------------------------------------------------------------+
|
||||
| Processes: |
|
||||
| GPU GI CI PID Type Process name GPU Memory |
|
||||
| ID ID Usage |
|
||||
|=============================================================================|
|
||||
| 0 N/A N/A 12737 C ffmpeg 249MiB |
|
||||
| 0 N/A N/A 12751 C ffmpeg 249MiB |
|
||||
| 0 N/A N/A 12772 C ffmpeg 249MiB |
|
||||
| 0 N/A N/A 12775 C ffmpeg 249MiB |
|
||||
| 0 N/A N/A 12800 C ffmpeg 249MiB |
|
||||
| 0 N/A N/A 12811 C ffmpeg 417MiB |
|
||||
| 0 N/A N/A 12827 C ffmpeg 417MiB |
|
||||
+-----------------------------------------------------------------------------+
|
||||
```
|
||||
461
docs/docs/configuration/index.md
Normal file
@@ -0,0 +1,461 @@
|
||||
---
|
||||
id: index
|
||||
title: Configuration File
|
||||
---
|
||||
|
||||
For Home Assistant Addon installations, the config file needs to be in the root of your Home Assistant config directory (same location as `configuration.yaml`) and named `frigate.yml`.
|
||||
|
||||
For all other installation types, the config file should be mapped to `/config/config.yml` inside the container.
|
||||
|
||||
It is recommended to start with a minimal configuration and add to it as described in [this guide](/guides/getting_started):
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
host: mqtt.server.com
|
||||
cameras:
|
||||
back:
|
||||
ffmpeg:
|
||||
inputs:
|
||||
- path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2
|
||||
roles:
|
||||
- detect
|
||||
- rtmp
|
||||
detect:
|
||||
width: 1280
|
||||
height: 720
|
||||
```
|
||||
|
||||
### VSCode Configuration Schema
|
||||
|
||||
VSCode (and VSCode addon) supports the JSON schemas which will automatically validate the config. This can be added by adding `# yaml-language-server: $schema=http://frigate_host:5000/api/config/schema` to the top of the config file. `frigate_host` being the IP address of frigate or `ccab4aaf-frigate` if running in the addon.
|
||||
|
||||
### Full configuration reference:
|
||||
|
||||
:::caution
|
||||
|
||||
It is not recommended to copy this full configuration file. Only specify values that are different from the defaults. Configuration options and default values may change in future versions.
|
||||
|
||||
:::
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
# Required: host name
|
||||
host: mqtt.server.com
|
||||
# Optional: port (default: shown below)
|
||||
port: 1883
|
||||
# Optional: topic prefix (default: shown below)
|
||||
# NOTE: must be unique if you are running multiple instances
|
||||
topic_prefix: frigate
|
||||
# Optional: client id (default: shown below)
|
||||
# NOTE: must be unique if you are running multiple instances
|
||||
client_id: frigate
|
||||
# Optional: user
|
||||
user: mqtt_user
|
||||
# Optional: password
|
||||
# NOTE: MQTT password can be specified with an environment variables that must begin with 'FRIGATE_'.
|
||||
# e.g. password: '{FRIGATE_MQTT_PASSWORD}'
|
||||
password: password
|
||||
# Optional: tls_ca_certs for enabling TLS using self-signed certs (default: None)
|
||||
tls_ca_certs: /path/to/ca.crt
|
||||
# Optional: tls_client_cert and tls_client key in order to use self-signed client
|
||||
# certificates (default: None)
|
||||
# NOTE: certificate must not be password-protected
|
||||
# do not set user and password when using a client certificate
|
||||
tls_client_cert: /path/to/client.crt
|
||||
tls_client_key: /path/to/client.key
|
||||
# Optional: tls_insecure (true/false) for enabling TLS verification of
|
||||
# the server hostname in the server certificate (default: None)
|
||||
tls_insecure: false
|
||||
# Optional: interval in seconds for publishing stats (default: shown below)
|
||||
stats_interval: 60
|
||||
|
||||
# Optional: Detectors configuration. Defaults to a single CPU detector
|
||||
detectors:
|
||||
# Required: name of the detector
|
||||
coral:
|
||||
# Required: type of the detector
|
||||
# Valid values are 'edgetpu' (requires device property below) and 'cpu'.
|
||||
type: edgetpu
|
||||
# Optional: device name as defined here: https://coral.ai/docs/edgetpu/multiple-edgetpu/#using-the-tensorflow-lite-python-api
|
||||
device: usb
|
||||
# Optional: num_threads value passed to the tflite.Interpreter (default: shown below)
|
||||
# This value is only used for CPU types
|
||||
num_threads: 3
|
||||
|
||||
# Optional: Database configuration
|
||||
database:
|
||||
# The path to store the SQLite DB (default: shown below)
|
||||
path: /media/frigate/frigate.db
|
||||
|
||||
# Optional: model modifications
|
||||
model:
|
||||
# Optional: path to the model (default: automatic based on detector)
|
||||
path: /edgetpu_model.tflite
|
||||
# Optional: path to the labelmap (default: shown below)
|
||||
labelmap_path: /labelmap.txt
|
||||
# Required: Object detection model input width (default: shown below)
|
||||
width: 320
|
||||
# Required: Object detection model input height (default: shown below)
|
||||
height: 320
|
||||
# Optional: Label name modifications. These are merged into the standard labelmap.
|
||||
labelmap:
|
||||
2: vehicle
|
||||
|
||||
# Optional: logger verbosity settings
|
||||
logger:
|
||||
# Optional: Default log verbosity (default: shown below)
|
||||
default: info
|
||||
# Optional: Component specific logger overrides
|
||||
logs:
|
||||
frigate.event: debug
|
||||
|
||||
# Optional: set environment variables
|
||||
environment_vars:
|
||||
EXAMPLE_VAR: value
|
||||
|
||||
# Optional: birdseye configuration
|
||||
# NOTE: Can (enabled, mode) be overridden at the camera level
|
||||
birdseye:
|
||||
# Optional: Enable birdseye view (default: shown below)
|
||||
enabled: True
|
||||
# Optional: Width of the output resolution (default: shown below)
|
||||
width: 1280
|
||||
# Optional: Height of the output resolution (default: shown below)
|
||||
height: 720
|
||||
# Optional: Encoding quality of the mpeg1 feed (default: shown below)
|
||||
# 1 is the highest quality, and 31 is the lowest. Lower quality feeds utilize less CPU resources.
|
||||
quality: 8
|
||||
# Optional: Mode of the view. Available options are: objects, motion, and continuous
|
||||
# objects - cameras are included if they have had a tracked object within the last 30 seconds
|
||||
# motion - cameras are included if motion was detected in the last 30 seconds
|
||||
# continuous - all cameras are included always
|
||||
mode: objects
|
||||
|
||||
# Optional: ffmpeg configuration
|
||||
ffmpeg:
|
||||
# Optional: global ffmpeg args (default: shown below)
|
||||
global_args: -hide_banner -loglevel warning
|
||||
# Optional: global hwaccel args (default: shown below)
|
||||
# NOTE: See hardware acceleration docs for your specific device
|
||||
hwaccel_args: []
|
||||
# Optional: global input args (default: shown below)
|
||||
input_args: -avoid_negative_ts make_zero -fflags +genpts+discardcorrupt -rtsp_transport tcp -timeout 5000000 -use_wallclock_as_timestamps 1
|
||||
# Optional: global output args
|
||||
output_args:
|
||||
# Optional: output args for detect streams (default: shown below)
|
||||
detect: -f rawvideo -pix_fmt yuv420p
|
||||
# Optional: output args for record streams (default: shown below)
|
||||
record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy -an
|
||||
# Optional: output args for rtmp streams (default: shown below)
|
||||
rtmp: -c copy -f flv
|
||||
|
||||
# Optional: Detect configuration
|
||||
# NOTE: Can be overridden at the camera level
|
||||
detect:
|
||||
# Optional: width of the frame for the input with the detect role (default: shown below)
|
||||
width: 1280
|
||||
# Optional: height of the frame for the input with the detect role (default: shown below)
|
||||
height: 720
|
||||
# Optional: desired fps for your camera for the input with the detect role (default: shown below)
|
||||
# NOTE: Recommended value of 5. Ideally, try and reduce your FPS on the camera.
|
||||
fps: 5
|
||||
# Optional: enables detection for the camera (default: True)
|
||||
# This value can be set via MQTT and will be updated in startup based on retained value
|
||||
enabled: True
|
||||
# Optional: Number of frames without a detection before frigate considers an object to be gone. (default: 5x the frame rate)
|
||||
max_disappeared: 25
|
||||
# Optional: Configuration for stationary object tracking
|
||||
stationary:
|
||||
# Optional: Frequency for confirming stationary objects (default: shown below)
|
||||
# When set to 0, object detection will not confirm stationary objects until movement is detected.
|
||||
# If set to 10, object detection will run to confirm the object still exists on every 10th frame.
|
||||
interval: 0
|
||||
# Optional: Number of frames without a position change for an object to be considered stationary (default: 10x the frame rate or 10s)
|
||||
threshold: 50
|
||||
# Optional: Define a maximum number of frames for tracking a stationary object (default: not set, track forever)
|
||||
# This can help with false positives for objects that should only be stationary for a limited amount of time.
|
||||
# It can also be used to disable stationary object tracking. For example, you may want to set a value for person, but leave
|
||||
# car at the default.
|
||||
# WARNING: Setting these values overrides default behavior and disables stationary object tracking.
|
||||
# There are very few situations where you would want it disabled. It is NOT recommended to
|
||||
# copy these values from the example config into your config unless you know they are needed.
|
||||
max_frames:
|
||||
# Optional: Default for all object types (default: not set, track forever)
|
||||
default: 3000
|
||||
# Optional: Object specific values
|
||||
objects:
|
||||
person: 1000
|
||||
|
||||
# Optional: Object configuration
|
||||
# NOTE: Can be overridden at the camera level
|
||||
objects:
|
||||
# Optional: list of objects to track from labelmap.txt (default: shown below)
|
||||
track:
|
||||
- person
|
||||
# Optional: mask to prevent all object types from being detected in certain areas (default: no mask)
|
||||
# Checks based on the bottom center of the bounding box of the object.
|
||||
# NOTE: This mask is COMBINED with the object type specific mask below
|
||||
mask: 0,0,1000,0,1000,200,0,200
|
||||
# Optional: filters to reduce false positives for specific object types
|
||||
filters:
|
||||
person:
|
||||
# Optional: minimum width*height of the bounding box for the detected object (default: 0)
|
||||
min_area: 5000
|
||||
# Optional: maximum width*height of the bounding box for the detected object (default: 24000000)
|
||||
max_area: 100000
|
||||
# Optional: minimum width/height of the bounding box for the detected object (default: 0)
|
||||
min_ratio: 0.5
|
||||
# Optional: maximum width/height of the bounding box for the detected object (default: 24000000)
|
||||
max_ratio: 2.0
|
||||
# Optional: minimum score for the object to initiate tracking (default: shown below)
|
||||
min_score: 0.5
|
||||
# Optional: minimum decimal percentage for tracked object's computed score to be considered a true positive (default: shown below)
|
||||
threshold: 0.7
|
||||
# Optional: mask to prevent this object type from being detected in certain areas (default: no mask)
|
||||
# Checks based on the bottom center of the bounding box of the object
|
||||
mask: 0,0,1000,0,1000,200,0,200
|
||||
|
||||
# Optional: Motion configuration
|
||||
# NOTE: Can be overridden at the camera level
|
||||
motion:
|
||||
# Optional: The threshold passed to cv2.threshold to determine if a pixel is different enough to be counted as motion. (default: shown below)
|
||||
# Increasing this value will make motion detection less sensitive and decreasing it will make motion detection more sensitive.
|
||||
# The value should be between 1 and 255.
|
||||
threshold: 25
|
||||
# Optional: Minimum size in pixels in the resized motion image that counts as motion (default: 30)
|
||||
# Increasing this value will prevent smaller areas of motion from being detected. Decreasing will
|
||||
# make motion detection more sensitive to smaller moving objects.
|
||||
# As a rule of thumb:
|
||||
# - 15 - high sensitivity
|
||||
# - 30 - medium sensitivity
|
||||
# - 50 - low sensitivity
|
||||
contour_area: 30
|
||||
# Optional: Alpha value passed to cv2.accumulateWeighted when averaging the motion delta across multiple frames (default: shown below)
|
||||
# Higher values mean the current frame impacts the delta a lot, and a single raindrop may register as motion.
|
||||
# Too low and a fast moving person wont be detected as motion.
|
||||
delta_alpha: 0.2
|
||||
# Optional: Alpha value passed to cv2.accumulateWeighted when averaging frames to determine the background (default: shown below)
|
||||
# Higher values mean the current frame impacts the average a lot, and a new object will be averaged into the background faster.
|
||||
# Low values will cause things like moving shadows to be detected as motion for longer.
|
||||
# https://www.geeksforgeeks.org/background-subtraction-in-an-image-using-concept-of-running-average/
|
||||
frame_alpha: 0.2
|
||||
# Optional: Height of the resized motion frame (default: 50)
|
||||
# This operates as an efficient blur alternative. Higher values will result in more granular motion detection at the expense
|
||||
# of higher CPU usage. Lower values result in less CPU, but small changes may not register as motion.
|
||||
frame_height: 50
|
||||
# Optional: motion mask
|
||||
# NOTE: see docs for more detailed info on creating masks
|
||||
mask: 0,900,1080,900,1080,1920,0,1920
|
||||
# Optional: improve contrast (default: shown below)
|
||||
# Enables dynamic contrast improvement. This should help improve night detections at the cost of making motion detection more sensitive
|
||||
# for daytime.
|
||||
improve_contrast: False
|
||||
# Optional: Delay when updating camera motion through MQTT from ON -> OFF (default: shown below).
|
||||
mqtt_off_delay: 30
|
||||
|
||||
# Optional: Record configuration
|
||||
# NOTE: Can be overridden at the camera level
|
||||
record:
|
||||
# Optional: Enable recording (default: shown below)
|
||||
# WARNING: If recording is disabled in the config, turning it on via
|
||||
# the UI or MQTT later will have no effect.
|
||||
# WARNING: Frigate does not currently support limiting recordings based
|
||||
# on available disk space automatically. If using recordings,
|
||||
# you must specify retention settings for a number of days that
|
||||
# will fit within the available disk space of your drive or Frigate
|
||||
# will crash.
|
||||
enabled: False
|
||||
# Optional: Number of minutes to wait between cleanup runs (default: shown below)
|
||||
# This can be used to reduce the frequency of deleting recording segments from disk if you want to minimize i/o
|
||||
expire_interval: 60
|
||||
# Optional: Retention settings for recording
|
||||
retain:
|
||||
# Optional: Number of days to retain recordings regardless of events (default: shown below)
|
||||
# NOTE: This should be set to 0 and retention should be defined in events section below
|
||||
# if you only want to retain recordings of events.
|
||||
days: 0
|
||||
# Optional: Mode for retention. Available options are: all, motion, and active_objects
|
||||
# all - save all recording segments regardless of activity
|
||||
# motion - save all recordings segments with any detected motion
|
||||
# active_objects - save all recording segments with active/moving objects
|
||||
# NOTE: this mode only applies when the days setting above is greater than 0
|
||||
mode: all
|
||||
# Optional: Event recording settings
|
||||
events:
|
||||
# Optional: Number of seconds before the event to include (default: shown below)
|
||||
pre_capture: 5
|
||||
# Optional: Number of seconds after the event to include (default: shown below)
|
||||
post_capture: 5
|
||||
# Optional: Objects to save recordings for. (default: all tracked objects)
|
||||
objects:
|
||||
- person
|
||||
# Optional: Restrict recordings to objects that entered any of the listed zones (default: no required zones)
|
||||
required_zones: []
|
||||
# Optional: Retention settings for recordings of events
|
||||
retain:
|
||||
# Required: Default retention days (default: shown below)
|
||||
default: 10
|
||||
# Optional: Mode for retention. (default: shown below)
|
||||
# all - save all recording segments for events regardless of activity
|
||||
# motion - save all recordings segments for events with any detected motion
|
||||
# active_objects - save all recording segments for event with active/moving objects
|
||||
#
|
||||
# NOTE: If the retain mode for the camera is more restrictive than the mode configured
|
||||
# here, the segments will already be gone by the time this mode is applied.
|
||||
# For example, if the camera retain mode is "motion", the segments without motion are
|
||||
# never stored, so setting the mode to "all" here won't bring them back.
|
||||
mode: motion
|
||||
# Optional: Per object retention days
|
||||
objects:
|
||||
person: 15
|
||||
|
||||
# Optional: Configuration for the jpg snapshots written to the clips directory for each event
|
||||
# NOTE: Can be overridden at the camera level
|
||||
snapshots:
|
||||
# Optional: Enable writing jpg snapshot to /media/frigate/clips (default: shown below)
|
||||
# This value can be set via MQTT and will be updated in startup based on retained value
|
||||
enabled: False
|
||||
# Optional: save a clean PNG copy of the snapshot image (default: shown below)
|
||||
clean_copy: True
|
||||
# Optional: print a timestamp on the snapshots (default: shown below)
|
||||
timestamp: False
|
||||
# Optional: draw bounding box on the snapshots (default: shown below)
|
||||
bounding_box: False
|
||||
# Optional: crop the snapshot (default: shown below)
|
||||
crop: False
|
||||
# Optional: height to resize the snapshot to (default: original size)
|
||||
height: 175
|
||||
# Optional: Restrict snapshots to objects that entered any of the listed zones (default: no required zones)
|
||||
required_zones: []
|
||||
# Optional: Camera override for retention settings (default: global values)
|
||||
retain:
|
||||
# Required: Default retention days (default: shown below)
|
||||
default: 10
|
||||
# Optional: Per object retention days
|
||||
objects:
|
||||
person: 15
|
||||
|
||||
# Optional: RTMP configuration
|
||||
# NOTE: Can be overridden at the camera level
|
||||
rtmp:
|
||||
# Optional: Enable the RTMP stream (default: True)
|
||||
enabled: True
|
||||
|
||||
# Optional: Live stream configuration for WebUI
|
||||
# NOTE: Can be overridden at the camera level
|
||||
live:
|
||||
# Optional: Set the height of the live stream. (default: 720)
|
||||
# This must be less than or equal to the height of the detect stream. Lower resolutions
|
||||
# reduce bandwidth required for viewing the live stream. Width is computed to match known aspect ratio.
|
||||
height: 720
|
||||
# Optional: Set the encode quality of the live stream (default: shown below)
|
||||
# 1 is the highest quality, and 31 is the lowest. Lower quality feeds utilize less CPU resources.
|
||||
quality: 8
|
||||
|
||||
# Optional: in-feed timestamp style configuration
|
||||
# NOTE: Can be overridden at the camera level
|
||||
timestamp_style:
|
||||
# Optional: Position of the timestamp (default: shown below)
|
||||
# "tl" (top left), "tr" (top right), "bl" (bottom left), "br" (bottom right)
|
||||
position: "tl"
|
||||
# Optional: Format specifier conform to the Python package "datetime" (default: shown below)
|
||||
# Additional Examples:
|
||||
# german: "%d.%m.%Y %H:%M:%S"
|
||||
format: "%m/%d/%Y %H:%M:%S"
|
||||
# Optional: Color of font
|
||||
color:
|
||||
# All Required when color is specified (default: shown below)
|
||||
red: 255
|
||||
green: 255
|
||||
blue: 255
|
||||
# Optional: Line thickness of font (default: shown below)
|
||||
thickness: 2
|
||||
# Optional: Effect of lettering (default: shown below)
|
||||
# None (No effect),
|
||||
# "solid" (solid background in inverse color of font)
|
||||
# "shadow" (shadow for font)
|
||||
effect: None
|
||||
|
||||
# Required
|
||||
cameras:
|
||||
# Required: name of the camera
|
||||
back:
|
||||
# Required: ffmpeg settings for the camera
|
||||
ffmpeg:
|
||||
# Required: A list of input streams for the camera. See documentation for more information.
|
||||
inputs:
|
||||
# Required: the path to the stream
|
||||
# NOTE: path may include environment variables, which must begin with 'FRIGATE_' and be referenced in {}
|
||||
- path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2
|
||||
# Required: list of roles for this stream. valid values are: detect,record,rtmp
|
||||
# NOTICE: In addition to assigning the record, and rtmp roles,
|
||||
# they must also be enabled in the camera config.
|
||||
roles:
|
||||
- detect
|
||||
- rtmp
|
||||
# Optional: stream specific global args (default: inherit)
|
||||
# global_args:
|
||||
# Optional: stream specific hwaccel args (default: inherit)
|
||||
# hwaccel_args:
|
||||
# Optional: stream specific input args (default: inherit)
|
||||
# input_args:
|
||||
# Optional: camera specific global args (default: inherit)
|
||||
# global_args:
|
||||
# Optional: camera specific hwaccel args (default: inherit)
|
||||
# hwaccel_args:
|
||||
# Optional: camera specific input args (default: inherit)
|
||||
# input_args:
|
||||
# Optional: camera specific output args (default: inherit)
|
||||
# output_args:
|
||||
|
||||
# Optional: timeout for highest scoring image before allowing it
|
||||
# to be replaced by a newer image. (default: shown below)
|
||||
best_image_timeout: 60
|
||||
|
||||
# Optional: zones for this camera
|
||||
zones:
|
||||
# Required: name of the zone
|
||||
# NOTE: This must be different than any camera names, but can match with another zone on another
|
||||
# camera.
|
||||
front_steps:
|
||||
# Required: List of x,y coordinates to define the polygon of the zone.
|
||||
# NOTE: Presence in a zone is evaluated only based on the bottom center of the objects bounding box.
|
||||
coordinates: 545,1077,747,939,788,805
|
||||
# Optional: List of objects that can trigger this zone (default: all tracked objects)
|
||||
objects:
|
||||
- person
|
||||
# Optional: Zone level object filters.
|
||||
# NOTE: The global and camera filters are applied upstream.
|
||||
filters:
|
||||
person:
|
||||
min_area: 5000
|
||||
max_area: 100000
|
||||
threshold: 0.7
|
||||
|
||||
# Optional: Configuration for the jpg snapshots published via MQTT
|
||||
mqtt:
|
||||
# Optional: Enable publishing snapshot via mqtt for camera (default: shown below)
|
||||
# NOTE: Only applies to publishing image data to MQTT via 'frigate/<camera_name>/<object_name>/snapshot'.
|
||||
# All other messages will still be published.
|
||||
enabled: True
|
||||
# Optional: print a timestamp on the snapshots (default: shown below)
|
||||
timestamp: True
|
||||
# Optional: draw bounding box on the snapshots (default: shown below)
|
||||
bounding_box: True
|
||||
# Optional: crop the snapshot (default: shown below)
|
||||
crop: True
|
||||
# Optional: height to resize the snapshot to (default: shown below)
|
||||
height: 270
|
||||
# Optional: jpeg encode quality (default: shown below)
|
||||
quality: 70
|
||||
# Optional: Restrict mqtt messages to objects that entered any of the listed zones (default: no required zones)
|
||||
required_zones: []
|
||||
|
||||
# Optional: Configuration for how camera is handled in the GUI.
|
||||
ui:
|
||||
# Optional: Adjust sort order of cameras in the UI. Larger numbers come later (default: shown below)
|
||||
# By default the cameras are sorted alphabetically.
|
||||
order: 0
|
||||
# Optional: Whether or not to show the camera in the Frigate UI (default: shown below)
|
||||
dashboard: True
|
||||
```
|
||||
77
docs/docs/configuration/masks.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
id: masks
|
||||
title: Masks
|
||||
---
|
||||
|
||||
There are two types of masks available:
|
||||
|
||||
**Motion masks**: Motion masks are used to prevent unwanted types of motion from triggering detection. Try watching the debug feed with `Motion Boxes` enabled to see what may be regularly detected as motion. For example, you want to mask out your timestamp, the sky, rooftops, etc. Keep in mind that this mask only prevents motion from being detected and does not prevent objects from being detected if object detection was started due to motion in unmasked areas. Motion is also used during object tracking to refine the object detection area in the next frame. Over masking will make it more difficult for objects to be tracked. To see this effect, create a mask, and then watch the video feed with `Motion Boxes` enabled again.
|
||||
|
||||
**Object filter masks**: Object filter masks are used to filter out false positives for a given object type based on location. These should be used to filter any areas where it is not possible for an object of that type to be. The bottom center of the detected object's bounding box is evaluated against the mask. If it is in a masked area, it is assumed to be a false positive. For example, you may want to mask out rooftops, walls, the sky, treetops for people. For cars, masking locations other than the street or your driveway will tell frigate that anything in your yard is a false positive.
|
||||
|
||||
To create a poly mask:
|
||||
|
||||
1. Visit the Web UI
|
||||
1. Click the camera you wish to create a mask for
|
||||
1. Select "Debug" at the top
|
||||
1. Expand the "Options" below the video feed
|
||||
1. Click "Mask & Zone creator"
|
||||
1. Click "Add" on the type of mask or zone you would like to create
|
||||
1. Click on the camera's latest image to create a masked area. The yaml representation will be updated in real-time
|
||||
1. When you've finished creating your mask, click "Copy" and paste the contents into your config file and restart Frigate
|
||||
|
||||
Example of a finished row corresponding to the below example image:
|
||||
|
||||
```yaml
|
||||
motion:
|
||||
mask: "0,461,3,0,1919,0,1919,843,1699,492,1344,458,1346,336,973,317,869,375,866,432"
|
||||
```
|
||||
|
||||
Multiple masks can be listed.
|
||||
|
||||
```yaml
|
||||
motion:
|
||||
mask:
|
||||
- 458,1346,336,973,317,869,375,866,432
|
||||
- 0,461,3,0,1919,0,1919,843,1699,492,1344
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Further Clarification
|
||||
|
||||
This is a response to a [question posed on reddit](https://www.reddit.com/r/homeautomation/comments/ppxdve/replacing_my_doorbell_with_a_security_camera_a_6/hd876w4?utm_source=share&utm_medium=web2x&context=3):
|
||||
|
||||
It is helpful to understand a bit about how Frigate uses motion detection and object detection together.
|
||||
|
||||
First, Frigate uses motion detection as a first line check to see if there is anything happening in the frame worth checking with object detection.
|
||||
|
||||
Once motion is detected, it tries to group up nearby areas of motion together in hopes of identifying a rectangle in the image that will capture the area worth inspecting. These are the red "motion boxes" you see in the debug viewer.
|
||||
|
||||
After the area with motion is identified, Frigate creates a "region" (the green boxes in the debug viewer) to run object detection on. The models are trained on square images, so these regions are always squares. It adds a margin around the motion area in hopes of capturing a cropped view of the object moving that fills most of the image passed to object detection, but doesn't cut anything off. It also takes into consideration the location of the bounding box from the previous frame if it is tracking an object.
|
||||
|
||||
After object detection runs, if there are detected objects that seem to be cut off, Frigate reframes the region and runs object detection again on the same frame to get a better look.
|
||||
|
||||
All of this happens for each area of motion and tracked object.
|
||||
|
||||
> Are you simply saying that INITIAL triggering of any kind of detection will only happen in un-masked areas, but that once this triggering happens, the masks become irrelevant and object detection takes precedence?
|
||||
|
||||
Essentially, yes. I wouldn't describe it as object detection taking precedence though. The motion masks just prevent those areas from being counted as motion. Those masks do not modify the regions passed to object detection in any way, so you can absolutely detect objects in areas masked for motion.
|
||||
|
||||
> If so, this is completely expected and intuitive behavior for me. Because obviously if a "foot" starts motion detection the camera should be able to check if it's an entire person before it fully crosses into the zone. The docs imply this is the behavior, so I also don't understand why this would be detrimental to object detection on the whole.
|
||||
|
||||
When just a foot is triggering motion, Frigate will zoom in and look only at the foot. If that even qualifies as a person, it will determine the object is being cut off and look again and again until it zooms back out enough to find the whole person.
|
||||
|
||||
It is also detrimental to how Frigate tracks a moving object. Motion nearby the bounding box from the previous frame is used to intelligently determine where the region should be in the next frame. With too much masking, tracking is hampered and if an object walks from an unmasked area into a fully masked area, they essentially disappear and will be picked up as a "new" object if they leave the masked area. This is important because Frigate uses the history of scores while tracking an object to determine if it is a false positive or not. It takes a minimum of 3 frames for Frigate to determine is the object type it thinks it is, and the median score must be greater than the threshold. If a person meets this threshold while on the sidewalk before they walk into your stoop, you will get an alert the instant they step a single foot into a zone.
|
||||
|
||||
> I thought the main point of this feature was to cut down on CPU use when motion is happening in unnecessary areas.
|
||||
|
||||
It is, but the definition of "unnecessary" varies. I want to ignore areas of motion that I know are definitely not being triggered by objects of interest. Timestamps, trees, sky, rooftops. I don't want to ignore motion from objects that I want to track and know where they go.
|
||||
|
||||
> For me, giving my masks ANY padding results in a lot of people detection I'm not interested in. I live in the city and catch a lot of the sidewalk on my camera. People walk by my front door all the time and the margin between the sidewalk and actually walking onto my stoop is very thin, so I basically have everything but the exact contours of my stoop masked out. This results in very tidy detections but this info keeps throwing me off. Am I just overthinking it?
|
||||
|
||||
This is what `required_zones` are for. You should define a zone (remember this is evaluated based on the bottom center of the bounding box) and make it required to save snapshots and clips (now events in 0.9.0). You can also use this in your conditions for a notification.
|
||||
|
||||
> Maybe my specific situation just warrants this. I've just been having a hard time understanding the relevance of this information - it seems to be that it's exactly what would be expected when "masking out" an area of ANY image.
|
||||
|
||||
That may be the case for you. Frigate will definitely work harder tracking people on the sidewalk to make sure it doesn't miss anyone who steps foot on your stoop. The trade off with the way you have it now is slower recognition of objects and potential misses. That may be acceptable based on your needs. Also, if your resolution is low enough on the detect stream, your regions may already be so big that they grab the entire object anyway.
|
||||
28
docs/docs/configuration/objects.mdx
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
id: objects
|
||||
title: Objects
|
||||
---
|
||||
|
||||
import labels from "../../../labelmap.txt";
|
||||
|
||||
Frigate includes the object models listed below from the Google Coral test data.
|
||||
|
||||
Please note:
|
||||
- `car` is listed twice because `truck` has been renamed to `car` by default. These object types are frequently confused.
|
||||
- `person` is the only tracked object by default. See the [full configuration reference](https://docs.frigate.video/configuration/index#full-configuration-reference) for an example of expanding the list of tracked objects.
|
||||
|
||||
<ul>
|
||||
{labels.split("\n").map((label) => (
|
||||
<li>{label.replace(/^\d+\s+/, "")}</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
## Custom Models
|
||||
|
||||
Models for both CPU and EdgeTPU (Coral) are bundled in the image. You can use your own models with volume mounts:
|
||||
|
||||
- CPU Model: `/cpu_model.tflite`
|
||||
- EdgeTPU Model: `/edgetpu_model.tflite`
|
||||
- Labels: `/labelmap.txt`
|
||||
|
||||
You also need to update the [model config](/configuration/advanced#model) if they differ from the defaults.
|
||||
76
docs/docs/configuration/record.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
id: record
|
||||
title: Recording
|
||||
---
|
||||
|
||||
Recordings can be enabled and are stored at `/media/frigate/recordings`. The folder structure for the recordings is `YYYY-MM/DD/HH/<camera_name>/MM.SS.mp4`. These recordings are written directly from your camera stream without re-encoding. Each camera supports a configurable retention policy in the config. Frigate chooses the largest matching retention value between the recording retention and the event retention when determining if a recording should be removed.
|
||||
|
||||
H265 recordings can be viewed in Edge and Safari only. All other browsers require recordings to be encoded with H264.
|
||||
|
||||
## What if I don't want 24/7 recordings?
|
||||
|
||||
If you only used clips in previous versions with recordings disabled, you can use the following config to get the same behavior. This is also the default behavior when recordings are enabled.
|
||||
|
||||
```yaml
|
||||
record:
|
||||
enabled: True
|
||||
events:
|
||||
retain:
|
||||
default: 10
|
||||
```
|
||||
|
||||
This configuration will retain recording segments that overlap with events and have active tracked objects for 10 days. Because multiple events can reference the same recording segments, this avoids storing duplicate footage for overlapping events and reduces overall storage needs.
|
||||
|
||||
When `retain -> days` is set to `0`, segments will be deleted from the cache if no events are in progress.
|
||||
|
||||
## Can I have "24/7" recordings, but only at certain times?
|
||||
|
||||
Using Frigate UI, HomeAssistant, or MQTT, cameras can be automated to only record in certain situations or at certain times.
|
||||
|
||||
**WARNING**: Recordings still must be enabled in the config. If a camera has recordings disabled in the config, enabling via the methods listed above will have no effect.
|
||||
|
||||
## What do the different retain modes mean?
|
||||
|
||||
Frigate saves from the stream with the `record` role in 10 second segments. These options determine which recording segments are kept for 24/7 recording (but can also affect events).
|
||||
|
||||
Let's say you have frigate configured so that your doorbell camera would retain the last **2** days of 24/7 recording.
|
||||
- With the `all` option all 48 hours of those two days would be kept and viewable.
|
||||
- With the `motion` option the only parts of those 48 hours would be segments that frigate detected motion. This is the middle ground option that won't keep all 48 hours, but will likely keep all segments of interest along with the potential for some extra segments.
|
||||
- With the `active_objects` option the only segments that would be kept are those where there was a true positive object that was not considered stationary.
|
||||
|
||||
The same options are available with events. Let's consider a scenario where you drive up and park in your driveway, go inside, then come back out 4 hours later.
|
||||
- With the `all` option all segments for the duration of the event would be saved for the event. This event would have 4 hours of footage.
|
||||
- With the `motion` option all segments for the duration of the event with motion would be saved. This means any segment where a car drove by in the street, person walked by, lighting changed, etc. would be saved.
|
||||
- With the `active_objects` it would only keep segments where the object was active. In this case the only segments that would be saved would be the ones where the car was driving up, you going inside, you coming outside, and the car driving away. Essentially reducing the 4 hours to a minute or two of event footage.
|
||||
|
||||
A configuration example of the above retain modes where all `motion` segments are stored for 7 days and `active objects` are stored for 14 days would be as follows:
|
||||
```yaml
|
||||
record:
|
||||
enabled: True
|
||||
retain:
|
||||
days: 7
|
||||
mode: motion
|
||||
events:
|
||||
retain:
|
||||
default: 14
|
||||
mode: active_objects
|
||||
```
|
||||
The above configuration example can be added globally or on a per camera basis.
|
||||
|
||||
### Object Specific Retention
|
||||
|
||||
You can also set specific retention length for an object type. The below configuration example builds on from above but also specifies that recordings of dogs only need to be kept for 2 days and recordings of cars should be kept for 7 days.
|
||||
```yaml
|
||||
record:
|
||||
enabled: True
|
||||
retain:
|
||||
days: 7
|
||||
mode: motion
|
||||
events:
|
||||
retain:
|
||||
default: 14
|
||||
mode: active_objects
|
||||
objects:
|
||||
dog: 2
|
||||
car: 7
|
||||
```
|
||||
8
docs/docs/configuration/rtmp.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
id: rtmp
|
||||
title: RTMP
|
||||
---
|
||||
|
||||
Frigate can re-stream your video feed as a RTMP feed for other applications such as Home Assistant to utilize it at `rtmp://<frigate_host>/live/<camera_name>`. Port 1935 must be open. This allows you to use a video feed for detection in frigate and Home Assistant live view at the same time without having to make two separate connections to the camera. The video feed is copied from the original video feed directly to avoid re-encoding. This feed does not include any annotation by Frigate.
|
||||
|
||||
Some video feeds are not compatible with RTMP. If you are experiencing issues, check to make sure your camera feed is h264 with AAC audio. If your camera doesn't support a compatible format for RTMP, you can use the ffmpeg args to re-encode it on the fly at the expense of increased CPU utilization. Some more information about it can be found [here](/faqs#audio-in-recordings).
|
||||
6
docs/docs/configuration/snapshots.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
id: snapshots
|
||||
title: Snapshots
|
||||
---
|
||||
|
||||
Frigate can save a snapshot image to `/media/frigate/clips` for each event named as `<camera>-<id>.jpg`.
|
||||
28
docs/docs/configuration/stationary_objects.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Stationary Objects
|
||||
|
||||
An object is considered stationary when it is being tracked and has been in a very similar position for a certain number of frames. This number is defined in the configuration under `detect -> stationary -> threshold`, and is 10x the frame rate (or 10 seconds) by default. Once an object is considered stationary, it will remain stationary until motion occurs near the object at which point object detection will start running again. If the object changes location, it will be considered active.
|
||||
|
||||
## Why does it matter if an object is stationary?
|
||||
|
||||
Once an object becomes stationary, object detection will not be continually run on that object. This serves to reduce resource usage and redundant detections when there has been no motion near the tracked object. This also means that Frigate is contextually aware, and can for example [filter out recording segments](record.md#what-do-the-different-retain-modes-mean) to only when the object is considered active. Motion alone does not determine if an object is "active" for active_objects segment retention. Lighting changes for a parked car won't make an object active.
|
||||
|
||||
## Tuning stationary behavior
|
||||
|
||||
The default config is:
|
||||
|
||||
```yaml
|
||||
detect:
|
||||
stationary:
|
||||
interval: 0
|
||||
threshold: 50
|
||||
```
|
||||
|
||||
`interval` is defined as the frequency for running detection on stationary objects. This means that by default once an object is considered stationary, detection will not be run on it until motion is detected. With `interval > 0`, every nth frames detection will be run to make sure the object is still there.
|
||||
|
||||
NOTE: There is no way to disable stationary object tracking with this value.
|
||||
|
||||
`threshold` is the number of frames an object needs to remain relatively still before it is considered stationary.
|
||||
|
||||
## Avoiding stationary objects
|
||||
|
||||
In some cases, like a driveway, you may prefer to only have an event when a car is coming & going vs a constant event of it stationary in the driveway. [This docs sections](../guides/stationary_objects.md) explains how to approach that scenario.
|
||||
15
docs/docs/configuration/user_interface.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
id: user_interface
|
||||
title: User Interface Configurations
|
||||
---
|
||||
|
||||
### Experimental UI
|
||||
|
||||
While developing and testing new components, users may decide to opt-in to test potential new features on the front-end.
|
||||
|
||||
```yaml
|
||||
ui:
|
||||
use_experimental: true
|
||||
```
|
||||
|
||||
Note that experimental changes may contain bugs or may be removed at any time in future releases of the software. Use of these features are presented as-is and with no functional guarantee.
|
||||
40
docs/docs/configuration/zones.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
id: zones
|
||||
title: Zones
|
||||
---
|
||||
|
||||
Zones allow you to define a specific area of the frame and apply additional filters for object types so you can determine whether or not an object is within a particular area. Presence in a zone is evaluated based on the bottom center of the bounding box for the object. It does not matter how much of the bounding box overlaps with the zone.
|
||||
|
||||
Zones cannot have the same name as a camera. If desired, a single zone can include multiple cameras if you have multiple cameras covering the same area by configuring zones with the same name for each camera.
|
||||
|
||||
During testing, enable the Zones option for the debug feed so you can adjust as needed. The zone line will increase in thickness when any object enters the zone.
|
||||
|
||||
To create a zone, follow [the steps for a "Motion mask"](/configuration/masks), but use the section of the web UI for creating a zone instead.
|
||||
|
||||
### Restricting zones to specific objects
|
||||
|
||||
Sometimes you want to limit a zone to specific object types to have more granular control of when events/snapshots are saved. The following example will limit one zone to person objects and the other to cars.
|
||||
|
||||
```yaml
|
||||
camera:
|
||||
record:
|
||||
events:
|
||||
required_zones:
|
||||
- entire_yard
|
||||
- front_yard_street
|
||||
snapshots:
|
||||
required_zones:
|
||||
- entire_yard
|
||||
- front_yard_street
|
||||
zones:
|
||||
entire_yard:
|
||||
coordinates: ... (everywhere you want a person)
|
||||
objects:
|
||||
- person
|
||||
front_yard_street:
|
||||
coordinates: ... (just the street)
|
||||
objects:
|
||||
- car
|
||||
```
|
||||
|
||||
Only car objects can trigger the `front_yard_street` zone and only person can trigger the `entire_yard`. You will get events for person objects that enter anywhere in the yard, and events for cars only if they enter the street.
|
||||
223
docs/docs/contributing.md
Normal file
@@ -0,0 +1,223 @@
|
||||
---
|
||||
id: contributing
|
||||
title: Contributing
|
||||
---
|
||||
|
||||
## Getting the source
|
||||
|
||||
### Core, Web, Docker, and Documentation
|
||||
|
||||
This repository holds the main Frigate application and all of its dependencies.
|
||||
|
||||
Fork [blakeblackshear/frigate](https://github.com/blakeblackshear/frigate.git) to your own GitHub profile, then clone the forked repo to your local machine.
|
||||
|
||||
From here, follow the guides for:
|
||||
|
||||
- [Core](#core)
|
||||
- [Web Interface](#web-interface)
|
||||
- [Documentation](#documentation)
|
||||
|
||||
### Frigate Home Assistant Addon
|
||||
|
||||
This repository holds the Home Assistant Addon, for use with Home Assistant OS and compatible installations. It is the piece that allows you to run Frigate from your Home Assistant Supervisor tab.
|
||||
|
||||
Fork [blakeblackshear/frigate-hass-addons](https://github.com/blakeblackshear/frigate-hass-addons) to your own Github profile, then clone the forked repo to your local machine.
|
||||
|
||||
### Frigate Home Assistant Integration
|
||||
|
||||
This repository holds the custom integration that allows your Home Assistant installation to automatically create entities for your Frigate instance, whether you run that with the [addon](#frigate-home-assistant-addon) or in a separate Docker instance.
|
||||
|
||||
Fork [blakeblackshear/frigate-hass-integration](https://github.com/blakeblackshear/frigate-hass-integration) to your own GitHub profile, then clone the forked repo to your local machine.
|
||||
|
||||
## Core
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Frigate source code](#frigate-core-web-and-docs)
|
||||
- GNU make
|
||||
- Docker
|
||||
- Extra Coral device (optional, but very helpful to simulate real world performance)
|
||||
|
||||
### Setup
|
||||
|
||||
#### 1. Build the version information and docker container locally by running `make`
|
||||
|
||||
#### 2. Create a local config file for testing
|
||||
|
||||
Place the file at `config/config.yml` in the root of the repo.
|
||||
|
||||
Here is an example, but modify for your needs:
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
host: mqtt
|
||||
|
||||
cameras:
|
||||
test:
|
||||
ffmpeg:
|
||||
inputs:
|
||||
- path: /media/frigate/car-stopping.mp4
|
||||
input_args: -re -stream_loop -1 -fflags +genpts
|
||||
roles:
|
||||
- detect
|
||||
- rtmp
|
||||
detect:
|
||||
height: 1080
|
||||
width: 1920
|
||||
fps: 5
|
||||
```
|
||||
|
||||
These input args tell ffmpeg to read the mp4 file in an infinite loop. You can use any valid ffmpeg input here.
|
||||
|
||||
#### 3. Gather some mp4 files for testing
|
||||
|
||||
Create and place these files in a `debug` folder in the root of the repo. This is also where recordings will be created if you enable them in your test config. Update your config from step 2 above to point at the right file. You can check the `docker-compose.yml` file in the repo to see how the volumes are mapped.
|
||||
|
||||
#### 4. Open the repo with Visual Studio Code
|
||||
|
||||
Upon opening, you should be prompted to open the project in a remote container. This will build a container on top of the base frigate container with all the development dependencies installed. This ensures everyone uses a consistent development environment without the need to install any dependencies on your host machine.
|
||||
|
||||
#### 5. Run frigate from the command line
|
||||
|
||||
VSCode will start the docker compose file for you and open a terminal window connected to `frigate-dev`.
|
||||
|
||||
- Run `python3 -m frigate` to start the backend.
|
||||
- In a separate terminal window inside VS Code, change into the `web` directory and run `npm install && npm start` to start the frontend.
|
||||
|
||||
#### 6. Teardown
|
||||
|
||||
After closing VSCode, you may still have containers running. To close everything down, just run `docker-compose down -v` to cleanup all containers.
|
||||
|
||||
### Testing
|
||||
|
||||
#### FFMPEG Hardware Acceleration
|
||||
|
||||
The following commands are used inside the container to ensure hardware acceleration is working properly.
|
||||
|
||||
**Raspberry Pi (64bit)**
|
||||
|
||||
This should show <50% CPU in top, and ~80% CPU without `-c:v h264_v4l2m2m`.
|
||||
|
||||
```shell
|
||||
ffmpeg -c:v h264_v4l2m2m -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
|
||||
```
|
||||
|
||||
**NVIDIA**
|
||||
|
||||
```shell
|
||||
ffmpeg -c:v h264_cuvid -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
|
||||
```
|
||||
|
||||
**VAAPI**
|
||||
|
||||
```shell
|
||||
ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format yuv420p -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
|
||||
```
|
||||
|
||||
**QSV**
|
||||
|
||||
```shell
|
||||
ffmpeg -c:v h264_qsv -re -stream_loop -1 -i https://streams.videolan.org/ffmpeg/incoming/720p60.mp4 -f rawvideo -pix_fmt yuv420p pipe: > /dev/null
|
||||
```
|
||||
|
||||
## Web Interface
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Frigate source code](#frigate-core-web-and-docs)
|
||||
- All [core](#core) prerequisites _or_ another running Frigate instance locally available
|
||||
- Node.js 14
|
||||
|
||||
### Making changes
|
||||
|
||||
#### 1. Set up a Frigate instance
|
||||
|
||||
The Web UI requires an instance of Frigate to interact with for all of its data. You can either run an instance locally (recommended) or attach to a separate instance accessible on your network.
|
||||
|
||||
To run the local instance, follow the [core](#core) development instructions.
|
||||
|
||||
If you won't be making any changes to the Frigate HTTP API, you can attach the web development server to any Frigate instance on your network. Skip this step and go to [3a](#3a-run-the-development-server-against-a-non-local-instance).
|
||||
|
||||
#### 2. Install dependencies
|
||||
|
||||
```console
|
||||
cd web && npm install
|
||||
```
|
||||
|
||||
#### 3. Run the development server
|
||||
|
||||
```console
|
||||
cd web && npm run dev
|
||||
```
|
||||
|
||||
#### 3a. Run the development server against a non-local instance
|
||||
|
||||
To run the development server against a non-local instance, you will need to modify the API_HOST default return in `web/src/env.js`.
|
||||
|
||||
#### 4. Making changes
|
||||
|
||||
The Web UI is built using [Vite](https://vitejs.dev/), [Preact](https://preactjs.com), and [Tailwind CSS](https://tailwindcss.com).
|
||||
|
||||
Light guidelines and advice:
|
||||
|
||||
- Avoid adding more dependencies. The web UI intends to be lightweight and fast to load.
|
||||
- Do not make large sweeping changes. [Open a discussion on GitHub](https://github.com/blakeblackshear/frigate/discussions/new) for any large or architectural ideas.
|
||||
- Ensure `lint` passes. This command will ensure basic conformance to styles, applying as many automatic fixes as possible, including Prettier formatting.
|
||||
|
||||
```console
|
||||
npm run lint
|
||||
```
|
||||
|
||||
- Add to unit tests and ensure they pass. As much as possible, you should strive to _increase_ test coverage whenever making changes. This will help ensure features do not accidentally become broken in the future.
|
||||
|
||||
```console
|
||||
npm run test
|
||||
```
|
||||
|
||||
- Test in different browsers. Firefox, Chrome, and Safari all have different quirks that make them unique targets to interact with.
|
||||
|
||||
## Documentation
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [Frigate source code](#frigate-core-web-and-docs)
|
||||
- Node.js 14
|
||||
|
||||
### Making changes
|
||||
|
||||
#### 1. Installation
|
||||
|
||||
```console
|
||||
npm install
|
||||
```
|
||||
|
||||
#### 2. Local Development
|
||||
|
||||
```console
|
||||
npm run start
|
||||
```
|
||||
|
||||
This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server.
|
||||
|
||||
The docs are built using [Docusaurus v2](https://v2.docusaurus.io). Please refer to the Docusaurus docs for more information on how to modify Frigate's documentation.
|
||||
|
||||
#### 3. Build (optional)
|
||||
|
||||
```console
|
||||
npm run build
|
||||
```
|
||||
|
||||
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
||||
|
||||
## Official builds
|
||||
|
||||
Setup buildx for multiarch
|
||||
|
||||
```
|
||||
docker buildx stop builder && docker buildx rm builder # <---- if existing
|
||||
docker run --privileged --rm tonistiigi/binfmt --install all
|
||||
docker buildx create --name builder --driver docker-container --driver-opt network=host --use
|
||||
docker buildx inspect builder --bootstrap
|
||||
make build_web
|
||||
make push
|
||||
```
|
||||
53
docs/docs/faqs.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
id: faqs
|
||||
title: Frequently Asked Questions
|
||||
---
|
||||
|
||||
### Fatal Python error: Bus error
|
||||
|
||||
This error message is due to a shm-size that is too small. Try updating your shm-size according to [this guide](/installation#calculating-required-shm-size).
|
||||
|
||||
### I am seeing a solid green image for my camera.
|
||||
|
||||
A solid green image means that frigate has not received any frames from ffmpeg. Check the logs to see why ffmpeg is exiting and adjust your ffmpeg args accordingly.
|
||||
|
||||
### How can I get sound or audio in my recordings? {#audio-in-recordings}
|
||||
|
||||
By default, Frigate removes audio from recordings to reduce the likelihood of failing for invalid data. If you would like to include audio, you need to override the output args to remove `-an` for where you want to include audio. The recommended audio codec is `aac`. Not all audio codecs are supported by RTMP, so you may need to re-encode your audio with `-c:a aac`. The default ffmpeg args are shown [here](/configuration/index/#full-configuration-reference).
|
||||
|
||||
:::tip
|
||||
|
||||
When using `-c:a aac`, do not forget to replace `-c copy` with `-c:v copy`. Example:
|
||||
|
||||
```diff title="frigate.yml"
|
||||
ffmpeg:
|
||||
output_args:
|
||||
- record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c copy -an
|
||||
+ record: -f segment -segment_time 10 -segment_format mp4 -reset_timestamps 1 -strftime 1 -c:v copy -c:a aac
|
||||
```
|
||||
|
||||
This is needed because the `-c` flag (without `:a` or `:v`) applies for both audio and video, thus making it conflicting with `-c:a aac`.
|
||||
|
||||
:::
|
||||
|
||||
### My mjpeg stream or snapshots look green and crazy
|
||||
|
||||
This almost always means that the width/height defined for your camera are not correct. Double check the resolution with vlc or another player. Also make sure you don't have the width and height values backwards.
|
||||
|
||||

|
||||
|
||||
### I can't view events or recordings in the Web UI.
|
||||
|
||||
Ensure your cameras send h264 encoded video
|
||||
|
||||
### "[mov,mp4,m4a,3gp,3g2,mj2 @ 0x5639eeb6e140] moov atom not found"
|
||||
|
||||
These messages in the logs are expected in certain situations. Frigate checks the integrity of the recordings before storing. Occasionally these cached files will be invalid and cleaned up automatically.
|
||||
|
||||
### "On connect called"
|
||||
|
||||
If you see repeated "On connect called" messages in your config, check for another instance of frigate. This happens when multiple frigate containers are trying to connect to mqtt with the same client_id.
|
||||
|
||||
### Error: Database Is Locked
|
||||
|
||||
sqlite does not work well on a network share, if the `/media` folder is mapped to a network share then [this guide](/configuration/advanced#database) should be used to move the database to a location on the internal drive.
|
||||
47
docs/docs/guides/camera_setup.md
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: camera_setup
|
||||
title: Camera setup
|
||||
---
|
||||
|
||||
Cameras configured to output H.264 video and AAC audio will offer the most compatibility with all features of Frigate and Home Assistant. H.265 has better compression, but far less compatibility. Safari and Edge are the only browsers able to play H.265. Ideally, cameras should be configured directly for the desired resolutions and frame rates you want to use in Frigate. Reducing frame rates within Frigate will waste CPU resources decoding extra frames that are discarded. There are three different goals that you want to tune your stream configurations around.
|
||||
|
||||
- **Detection**: This is the only stream that Frigate will decode for processing. Also, this is the stream where snapshots will be generated from. The resolution for detection should be tuned for the size of the objects you want to detect. See [Choosing a detect resolution](#choosing-a-detect-resolution) for more details. The recommended frame rate is 5fps, but may need to be higher for very fast moving objects. Higher resolutions and frame rates will drive higher CPU usage on your server.
|
||||
|
||||
- **Recording**: This stream should be the resolution you wish to store for reference. Typically, this will be the highest resolution your camera supports. I recommend setting this feed to 15 fps.
|
||||
|
||||
- **Stream Viewing**: This stream will be rebroadcast as is to Home Assistant for viewing with the stream component. Setting this resolution too high will use significant bandwidth when viewing streams in Home Assistant, and they may not load reliably over slower connections.
|
||||
|
||||
### Choosing a detect resolution
|
||||
|
||||
The ideal resolution for detection is one where the objects you want to detect fit inside the dimensions of the model used by Frigate (320x320). Frigate does not pass the entire camera frame to object detection. It will crop an area of motion from the full frame and look in that portion of the frame. If the area being inspected is larger than 320x320, Frigate must resize it before running object detection. Higher resolutions do not improve the detection accuracy because the additional detail is lost in the resize. Below you can see a reference for how large a 320x320 area is against common resolutions.
|
||||
|
||||
Larger resolutions **do** improve performance if the objects are very small in the frame.
|
||||
|
||||

|
||||
|
||||
### Example Camera Configuration
|
||||
|
||||
For the Dahua/Loryta 5442 camera, I use the following settings:
|
||||
|
||||
**Main Stream (Recording)**
|
||||
|
||||
- Encode Mode: H.264
|
||||
- Resolution: 2688\*1520
|
||||
- Frame Rate(FPS): 15
|
||||
- I Frame Interval: 30
|
||||
|
||||
**Sub Stream 1 (RTMP)**
|
||||
|
||||
- Enable: Sub Stream 1
|
||||
- Encode Mode: H.264
|
||||
- Resolution: 720\*576
|
||||
- Frame Rate: 10
|
||||
- I Frame Interval: 10
|
||||
|
||||
**Sub Stream 2 (Detection)**
|
||||
|
||||
- Enable: Sub Stream 2
|
||||
- Encode Mode: H.264
|
||||
- Resolution: 1280\*720
|
||||
- Frame Rate: 5
|
||||
- I Frame Interval: 5
|
||||
10
docs/docs/guides/events_setup.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
id: events_setup
|
||||
title: Setting Up Events
|
||||
---
|
||||
|
||||
[Snapshots](../configuration/snapshots.md) and/or [Recordings](../configuration/record.md) must be enabled for events to be created for detected objects.
|
||||
|
||||
## Limiting Events to Areas of Interest
|
||||
|
||||
The best way to limit events to areas of interest is to use [zones](../configuration/zones.md) along with `required_zones` for events and snapshots to only have events created in areas of interest.
|
||||
23
docs/docs/guides/false_positives.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
id: false_positives
|
||||
title: Reducing false positives
|
||||
---
|
||||
|
||||
Tune your object filters to adjust false positives: `min_area`, `max_area`, `min_ratio`, `max_ratio`, `min_score`, `threshold`.
|
||||
|
||||
The `min_area` and `max_area` values are compared against the area (number of pixels) from a given detected object. If the area is outside this range, the object will be ignored as a false positive. This allows objects that must be too small or too large to be ignored.
|
||||
|
||||
Similarly, the `min_ratio` and `max_ratio` values are compared against a given detected object's width/height ratio (in pixels). If the ratio is outside this range, the object will be ignored as a false positive. This allows objects that are proportionally too short-and-wide (higher ratio) or too tall-and-narrow (smaller ratio) to be ignored.
|
||||
|
||||
For object filters in your configuration, any single detection below `min_score` will be ignored as a false positive. `threshold` is based on the median of the history of scores (padded to 3 values) for a tracked object. Consider the following frames when `min_score` is set to 0.6 and threshold is set to 0.85:
|
||||
|
||||
| Frame | Current Score | Score History | Computed Score | Detected Object |
|
||||
| ----- | ------------- | --------------------------------- | -------------- | --------------- |
|
||||
| 1 | 0.7 | 0.0, 0, 0.7 | 0.0 | No |
|
||||
| 2 | 0.55 | 0.0, 0.7, 0.0 | 0.0 | No |
|
||||
| 3 | 0.85 | 0.7, 0.0, 0.85 | 0.7 | No |
|
||||
| 4 | 0.90 | 0.7, 0.85, 0.95, 0.90 | 0.875 | Yes |
|
||||
| 5 | 0.88 | 0.7, 0.85, 0.95, 0.90, 0.88 | 0.88 | Yes |
|
||||
| 6 | 0.95 | 0.7, 0.85, 0.95, 0.90, 0.88, 0.95 | 0.89 | Yes |
|
||||
|
||||
In frame 2, the score is below the `min_score` value, so frigate ignores it and it becomes a 0.0. The computed score is the median of the score history (padding to at least 3 values), and only when that computed score crosses the `threshold` is the object marked as a true positive. That happens in frame 4 in the example.
|
||||
207
docs/docs/guides/getting_started.md
Normal file
@@ -0,0 +1,207 @@
|
||||
---
|
||||
id: getting_started
|
||||
title: Creating a config file
|
||||
---
|
||||
|
||||
This guide walks through the steps to build a configuration file for Frigate. It assumes that you already have an environment setup as described in [Installation](/installation). You should also configure your cameras according to the [camera setup guide](/guides/camera_setup)
|
||||
|
||||
### Step 1: Configure the MQTT server
|
||||
|
||||
Frigate requires a functioning MQTT server. Start by adding the mqtt section at the top level in your config:
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
host: <ip of your mqtt server>
|
||||
```
|
||||
|
||||
If using the Mosquitto Addon in Home Assistant, a username and password is required. For example:
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
host: <ip of your mqtt server>
|
||||
user: <username>
|
||||
password: <password>
|
||||
```
|
||||
|
||||
Frigate supports many configuration options for mqtt. See the [configuration reference](/configuration/index#full-configuration-reference) for more info.
|
||||
|
||||
### Step 2: Configure detectors
|
||||
|
||||
By default, Frigate will use a single CPU detector. If you have a USB Coral, you will need to add a detectors section to your config.
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
host: <ip of your mqtt server>
|
||||
|
||||
detectors:
|
||||
coral:
|
||||
type: edgetpu
|
||||
device: usb
|
||||
```
|
||||
|
||||
More details on available detectors can be found [here](/configuration/detectors).
|
||||
|
||||
### Step 3: Add a minimal camera configuration
|
||||
|
||||
Now let's add the first camera:
|
||||
|
||||
:::caution
|
||||
|
||||
Note that passwords that contain special characters often cause issues with ffmpeg connecting to the cameara. If recieving `end-of-file` or `unauthorized` errors with a verified correct password, try changing the password to something simple to rule out the possibility that the password is the issue.
|
||||
|
||||
:::
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
host: <ip of your mqtt server>
|
||||
|
||||
detectors:
|
||||
coral:
|
||||
type: edgetpu
|
||||
device: usb
|
||||
|
||||
cameras:
|
||||
camera_1: # <------ Name the camera
|
||||
ffmpeg:
|
||||
inputs:
|
||||
- path: rtsp://10.0.10.10:554/rtsp # <----- Update for your camera
|
||||
roles:
|
||||
- detect
|
||||
- rtmp
|
||||
rtmp:
|
||||
enabled: False # <-- RTMP should be disabled if your stream is not H264
|
||||
detect:
|
||||
width: 1280 # <---- update for your camera's resolution
|
||||
height: 720 # <---- update for your camera's resolution
|
||||
```
|
||||
|
||||
### Step 4: Start Frigate
|
||||
|
||||
At this point you should be able to start Frigate and see the the video feed in the UI.
|
||||
|
||||
If you get a green image from the camera, this means ffmpeg was not able to get the video feed from your camera. Check the logs for error messages from ffmpeg. The default ffmpeg arguments are designed to work with H264 RTSP cameras that support TCP connections. If you do not have H264 cameras, make sure you have disabled RTMP. It is possible to enable it, but you must tell ffmpeg to re-encode the video with customized output args.
|
||||
|
||||
FFmpeg arguments for other types of cameras can be found [here](/configuration/camera_specific).
|
||||
|
||||
### Step 5: Configure hardware acceleration (optional)
|
||||
|
||||
Now that you have a working camera configuration, you want to setup hardware acceleration to minimize the CPU required to decode your video streams. See the [hardware acceleration](/configuration/hardware_acceleration) config reference for examples applicable to your hardware.
|
||||
|
||||
In order to best evaluate the performance impact of hardware acceleration, it is recommended to temporarily disable detection.
|
||||
|
||||
```yaml
|
||||
mqtt: ...
|
||||
|
||||
detectors: ...
|
||||
|
||||
cameras:
|
||||
camera_1:
|
||||
ffmpeg: ...
|
||||
detect:
|
||||
enabled: False
|
||||
...
|
||||
```
|
||||
|
||||
Here is an example configuration with hardware acceleration configured:
|
||||
|
||||
```yaml
|
||||
mqtt: ...
|
||||
|
||||
detectors: ...
|
||||
|
||||
cameras:
|
||||
camera_1:
|
||||
ffmpeg:
|
||||
inputs: ...
|
||||
hwaccel_args: -c:v h264_v4l2m2m
|
||||
detect: ...
|
||||
```
|
||||
|
||||
### Step 6: Setup motion masks
|
||||
|
||||
Now that you have optimized your configuration for decoding the video stream, you will want to check to see where to implement motion masks. To do this, navigate to the camera in the UI, select "Debug" at the top, and enable "Motion boxes" in the options below the video feed. Watch for areas that continuously trigger unwanted motion to be detected. Common areas to mask include camera timestamps and trees that frequently blow in the wind. The goal is to avoid wasting object detection cycles looking at these areas.
|
||||
|
||||
Now that you know where you need to mask, use the "Mask & Zone creator" in the options pane to generate the coordinates needed for your config file. More information about masks can be found [here](/configuration/masks).
|
||||
|
||||
:::caution
|
||||
|
||||
Note that motion masks should not be used to mark out areas where you do not want objects to be detected or to reduce false positives. They do not alter the image sent to object detection, so you can still get events and detections in areas with motion masks. These only prevent motion in these areas from initiating object detection.
|
||||
|
||||
:::
|
||||
|
||||
Your configuration should look similar to this now.
|
||||
|
||||
```yaml
|
||||
mqtt:
|
||||
host: mqtt.local
|
||||
|
||||
detectors:
|
||||
coral:
|
||||
type: edgetpu
|
||||
device: usb
|
||||
|
||||
cameras:
|
||||
camera_1:
|
||||
ffmpeg:
|
||||
inputs:
|
||||
- path: rtsp://10.0.10.10:554/rtsp
|
||||
roles:
|
||||
- detect
|
||||
- rtmp
|
||||
detect:
|
||||
width: 1280
|
||||
height: 720
|
||||
motion:
|
||||
mask:
|
||||
- 0,461,3,0,1919,0,1919,843,1699,492,1344,458,1346,336,973,317,869,375,866,432
|
||||
```
|
||||
|
||||
### Step 7: Enable recording (optional)
|
||||
|
||||
To enable recording video, add the `record` role to a stream and enable it in the config.
|
||||
|
||||
```yaml
|
||||
mqtt: ...
|
||||
|
||||
detectors: ...
|
||||
|
||||
cameras:
|
||||
camera_1:
|
||||
ffmpeg:
|
||||
inputs:
|
||||
- path: rtsp://10.0.10.10:554/rtsp
|
||||
roles:
|
||||
- detect
|
||||
- rtmp
|
||||
- path: rtsp://10.0.10.10:554/high_res_stream # <----- Add high res stream
|
||||
roles:
|
||||
- record
|
||||
detect: ...
|
||||
record: # <----- Enable recording
|
||||
enabled: True
|
||||
motion: ...
|
||||
```
|
||||
|
||||
If you don't have separate streams for detect and record, you would just add the record role to the list on the first input.
|
||||
|
||||
By default, Frigate will retain video of all events for 10 days. The full set of options for recording can be found [here](/configuration/index#full-configuration-reference).
|
||||
|
||||
### Step 8: Enable snapshots (optional)
|
||||
|
||||
To enable snapshots of your events, just enable it in the config.
|
||||
|
||||
```yaml
|
||||
mqtt: ...
|
||||
|
||||
detectors: ...
|
||||
|
||||
cameras:
|
||||
camera_1: ...
|
||||
detect: ...
|
||||
record: ...
|
||||
snapshots: # <----- Enable snapshots
|
||||
enabled: True
|
||||
motion: ...
|
||||
```
|
||||
|
||||
By default, Frigate will retain snapshots of all events for 10 days. The full set of options for snapshots can be found [here](/configuration/index#full-configuration-reference).
|
||||
80
docs/docs/guides/ha_notifications.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
id: ha_notifications
|
||||
title: Home Assistant notifications
|
||||
---
|
||||
|
||||
The best way to get started with notifications for Frigate is to use the [Blueprint](https://community.home-assistant.io/t/frigate-mobile-app-notifications/311091). You can use the yaml generated from the Blueprint as a starting point and customize from there.
|
||||
|
||||
It is generally recommended to trigger notifications based on the `frigate/events` mqtt topic. This provides the event_id needed to fetch [thumbnails/snapshots/clips](/integrations/home-assistant#notification-api) and other useful information to customize when and where you want to receive alerts. The data is published in the form of a change feed, which means you can reference the "previous state" of the object in the `before` section and the "current state" of the object in the `after` section. You can see an example [here](/integrations/mqtt#frigateevents).
|
||||
|
||||
Here is a simple example of a notification automation of events which will update the existing notification for each change. This means the image you see in the notification will update as frigate finds a "better" image.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
- alias: Notify of events
|
||||
trigger:
|
||||
platform: mqtt
|
||||
topic: frigate/events
|
||||
action:
|
||||
- service: notify.mobile_app_pixel_3
|
||||
data_template:
|
||||
message: 'A {{trigger.payload_json["after"]["label"]}} was detected.'
|
||||
data:
|
||||
image: 'https://your.public.hass.address.com/api/frigate/notifications/{{trigger.payload_json["after"]["id"]}}/thumbnail.jpg?format=android'
|
||||
tag: '{{trigger.payload_json["after"]["id"]}}'
|
||||
when: '{{trigger.payload_json["after"]["start_time"]|int}}'
|
||||
```
|
||||
|
||||
Note that iOS devices support live previews of cameras by adding a camera entity id to the message data.
|
||||
|
||||
```yaml
|
||||
automation:
|
||||
- alias: Security_Frigate_Notifications
|
||||
description: ""
|
||||
trigger:
|
||||
- platform: mqtt
|
||||
topic: frigate/events
|
||||
payload: new
|
||||
value_template: "{{ value_json.type }}"
|
||||
action:
|
||||
- service: notify.mobile_app_iphone
|
||||
data:
|
||||
message: 'A {{trigger.payload_json["after"]["label"]}} was detected.'
|
||||
data:
|
||||
image: >-
|
||||
https://your.public.hass.address.com/api/frigate/notifications/{{trigger.payload_json["after"]["id"]}}/thumbnail.jpg
|
||||
tag: '{{trigger.payload_json["after"]["id"]}}'
|
||||
when: '{{trigger.payload_json["after"]["start_time"]|int}}'
|
||||
entity_id: camera.{{trigger.payload_json["after"]["camera"]}}
|
||||
mode: single
|
||||
```
|
||||
|
||||
## Conditions
|
||||
|
||||
Conditions with the `before` and `after` values allow a high degree of customization for automations.
|
||||
|
||||
When a person enters a zone named yard
|
||||
|
||||
```yaml
|
||||
condition:
|
||||
- "{{ trigger.payload_json['after']['label'] == 'person' }}"
|
||||
- "{{ 'yard' in trigger.payload_json['after']['entered_zones'] }}"
|
||||
```
|
||||
|
||||
When a person leaves a zone named yard
|
||||
|
||||
```yaml
|
||||
condition:
|
||||
- "{{ trigger.payload_json['after']['label'] == 'person' }}"
|
||||
- "{{ 'yard' in trigger.payload_json['before']['current_zones'] }}"
|
||||
- "{{ not 'yard' in trigger.payload_json['after']['current_zones'] }}"
|
||||
```
|
||||
|
||||
Notify for dogs in the front with a high top score
|
||||
|
||||
```yaml
|
||||
condition:
|
||||
- "{{ trigger.payload_json['after']['label'] == 'dog' }}"
|
||||
- "{{ trigger.payload_json['after']['camera'] == 'front' }}"
|
||||
- "{{ trigger.payload_json['after']['top_score'] > 0.98 }}"
|
||||
```
|
||||
37
docs/docs/guides/stationary_objects.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
id: stationary_objects
|
||||
title: Avoiding stationary objects
|
||||
---
|
||||
|
||||
Many people use Frigate to detect cars entering their driveway, and they often run into an issue with repeated events of a parked car being repeatedly detected over the course of multiple days (for example if the car is lost at night and detected again the following morning.
|
||||
|
||||
You can use zones to restrict events and notifications to objects that have entered specific areas.
|
||||
|
||||
:::caution
|
||||
|
||||
It is not recommended to use masks to try and eliminate parked cars in your driveway. Masks are designed to prevent motion from triggering object detection and/or to indicate areas that are guaranteed false positives.
|
||||
|
||||
Frigate is designed to track objects as they move and over-masking can prevent it from knowing that an object in the current frame is the same as the previous frame. You want Frigate to detect objects everywhere and configure your events and alerts to be based on the location of the object with zones.
|
||||
|
||||
:::
|
||||
|
||||
To only be notified of cars that enter your driveway from the street, you could create multiple zones that cover your driveway. For cars, you would only notify if `entered_zones` from the events MQTT topic has more than 1 zone.
|
||||
|
||||
See [this example](/configuration/zones#restricting-zones-to-specific-objects) from the Zones documentation to see how to restrict zones to certain object types.
|
||||
|
||||

|
||||
|
||||
To limit snapshots and events, you can list the zone for the entrance of your driveway under `required_zones` in your configuration file. Example below.
|
||||
|
||||
```yaml
|
||||
camera:
|
||||
record:
|
||||
events:
|
||||
required_zones:
|
||||
- zone_2
|
||||
zones:
|
||||
zone_1:
|
||||
coordinates: ... (parking area)
|
||||
zone_2:
|
||||
coordinates: ... (entrance to driveway)
|
||||
```
|
||||
66
docs/docs/hardware.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
id: hardware
|
||||
title: Recommended hardware
|
||||
---
|
||||
|
||||
## Cameras
|
||||
|
||||
Cameras that output H.264 video and AAC audio will offer the most compatibility with all features of Frigate and Home Assistant. It is also helpful if your camera supports multiple substreams to allow different resolutions to be used for detection, streaming, and recordings without re-encoding.
|
||||
|
||||
I recommend Dahua, Hikvision, and Amcrest in that order. Dahua edges out Hikvision because they are easier to find and order, not because they are better cameras. I personally use Dahua cameras because they are easier to purchase directly. In my experience Dahua and Hikvision both have multiple streams with configurable resolutions and frame rates and rock solid streams. They also both have models with large sensors well known for excellent image quality at night. Not all the models are equal. Larger sensors are better than higher resolutions; especially at night. Amcrest is the fallback recommendation because they are rebranded Dahuas. They are rebranding the lower end models with smaller sensors or less configuration options.
|
||||
|
||||
Many users have reported various issues with Reolink cameras, so I do not recommend them. If you are using Reolink, I suggest the [Reolink specific configuration](configuration/camera_specific#reolink-410520-possibly-others). Wifi cameras are also not recommended. Their streams are less reliable and cause connection loss and/or lost video data.
|
||||
|
||||
Here are some of the camera's I recommend:
|
||||
|
||||
- <a href="https://amzn.to/3uFLtxB" target="_blank" rel="nofollow noopener sponsored">Loryta(Dahua) T5442TM-AS-LED</a> (affiliate link)
|
||||
- <a href="https://amzn.to/3isJ3gU" target="_blank" rel="nofollow noopener sponsored">Loryta(Dahua) IPC-T5442TM-AS</a> (affiliate link)
|
||||
- <a href="https://amzn.to/2ZWNWIA" target="_blank" rel="nofollow noopener sponsored">Amcrest IP5M-T1179EW-28MM</a> (affiliate link)
|
||||
|
||||
I may earn a small commission for my endorsement, recommendation, testimonial, or link to any products or services from this website.
|
||||
|
||||
## Server
|
||||
|
||||
My current favorite is the Minisforum GK41 because of the dual NICs that allow you to setup a dedicated private network for your cameras where they can be blocked from accessing the internet. There are many used workstation options on eBay that work very well. Anything with an Intel CPU and capable of running Debian should work fine. As a bonus, you may want to look for devices with a M.2 or PCIe express slot that is compatible with the Google Coral. I may earn a small commission for my endorsement, recommendation, testimonial, or link to any products or services from this website.
|
||||
|
||||
| Name | Inference Speed | Coral Compatibility | Notes |
|
||||
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Odyssey X86 Blue J4125 (<a href="https://amzn.to/3oH4BKi" target="_blank" rel="nofollow noopener sponsored">Amazon</a>) (<a href="https://www.seeedstudio.com/Frigate-NVR-with-Odyssey-Blue-and-Coral-USB-Accelerator.html?utm_source=Frigate" target="_blank" rel="nofollow noopener sponsored">SeeedStudio</a>) | 9-10ms | M.2 B+M, USB | Dual gigabit NICs for easy isolated camera network. Easily handles several 1080p cameras. |
|
||||
| Minisforum GK41 (<a href="https://amzn.to/3ptnb8D" target="_blank" rel="nofollow noopener sponsored">Amazon</a>) | 9-10ms | USB | Dual gigabit NICs for easy isolated camera network. Easily handles several 1080p cameras. |
|
||||
| Beelink GK55 (<a href="https://amzn.to/35E79BC" target="_blank" rel="nofollow noopener sponsored">Amazon</a>) | 9-10ms | USB | Dual gigabit NICs for easy isolated camera network. Easily handles several 1080p cameras. |
|
||||
| Intel NUC (<a href="https://amzn.to/3psFlHi" target="_blank" rel="nofollow noopener sponsored">Amazon</a>) | 8-10ms | USB | Overkill for most, but great performance. Can handle many cameras at 5fps depending on typical amounts of motion. Requires extra parts. |
|
||||
| BMAX B2 Plus (<a href="https://amzn.to/3a6TBh8" target="_blank" rel="nofollow noopener sponsored">Amazon</a>) | 10-12ms | USB | Good balance of performance and cost. Also capable of running many other services at the same time as frigate. |
|
||||
| Atomic Pi (<a href="https://amzn.to/2YjpY9m" target="_blank" rel="nofollow noopener sponsored">Amazon</a>) | 16ms | USB | Good option for a dedicated low power board with a small number of cameras. Can leverage Intel QuickSync for stream decoding. |
|
||||
| Raspberry Pi 4 (64bit) (<a href="https://amzn.to/2YhSGHH" target="_blank" rel="nofollow noopener sponsored">Amazon</a>) | 10-15ms | USB | Can handle a small number of cameras. |
|
||||
|
||||
## Google Coral TPU
|
||||
|
||||
It is strongly recommended to use a Google Coral. Frigate is designed around the expectation that a Coral is used to achieve very low inference speeds. Offloading TensorFlow to the Google Coral is an order of magnitude faster and will reduce your CPU load dramatically. A $60 device will outperform $2000 CPU. Frigate should work with any supported Coral device from https://coral.ai
|
||||
|
||||
The USB version is compatible with the widest variety of hardware and does not require a driver on the host machine. However, it does lack the automatic throttling features of the other versions.
|
||||
|
||||
The PCIe and M.2 versions require installation of a driver on the host. Follow the instructions for your version from https://coral.ai
|
||||
|
||||
A single Coral can handle many cameras and will be sufficient for the majority of users. You can calculate the maximum performance of your Coral based on the inference speed reported by Frigate. With an inference speed of 10, your Coral will top out at `1000/10=100`, or 100 frames per second. If your detection fps is regularly getting close to that, you should first consider tuning motion masks. If those are already properly configured, a second Coral may be needed.
|
||||
|
||||
### What does Frigate use the CPU for and what does it use the Coral for? (ELI5 Version)
|
||||
|
||||
This is taken from a [user question on reddit](https://www.reddit.com/r/homeassistant/comments/q8mgau/comment/hgqbxh5/?utm_source=share&utm_medium=web2x&context=3). Modified slightly for clarity.
|
||||
|
||||
CPU Usage: I am a CPU, Mendel is a Google Coral
|
||||
|
||||
My buddy Mendel and I have been tasked with keeping the neighbor's red footed booby off my parent's yard. Now I'm really bad at identifying birds. It takes me forever, but my buddy Mendel is incredible at it.
|
||||
|
||||
Mendel however, struggles at pretty much anything else. So we make an agreement. I wait till I see something that moves, and snap a picture of it for Mendel. I then show him the picture and he tells me what it is. Most of the time it isn't anything. But eventually I see some movement and Mendel tells me it is the Booby. Score!
|
||||
|
||||
_What happens when I increase the resolution of my camera?_
|
||||
|
||||
However we realize that there is a problem. There is still booby poop all over the yard. How could we miss that! I've been watching all day! My parents check the window and realize its dirty and a bit small to see the entire yard so they clean it and put a bigger one in there. Now there is so much more to see! However I now have a much bigger area to scan for movement and have to work a lot harder! Even my buddy Mendel has to work harder, as now the pictures have a lot more detail in them that he has to look at to see if it is our sneaky booby.
|
||||
|
||||
Basically - When you increase the resolution and/or the frame rate of the stream there is now significantly more data for the CPU to parse. That takes additional computing power. The Google Coral is really good at doing object detection, but it doesn't have time to look everywhere all the time (especially when there are many windows to check). To balance it, Frigate uses the CPU to look for movement, then sends those frames to the Coral to do object detection. This allows the Coral to be available to a large number of cameras and not overload it.
|
||||
|
||||
### Do hwaccel args help if I am using a Coral?
|
||||
|
||||
YES! The Coral does not help with decoding video streams.
|
||||
|
||||
Decompressing video streams takes a significant amount of CPU power. Video compression uses key frames (also known as I-frames) to send a full frame in the video stream. The following frames only include the difference from the key frame, and the CPU has to compile each frame by merging the differences with the key frame. [More detailed explanation](https://blog.video.ibm.com/streaming-video-tips/keyframes-interframe-video-compression/). Higher resolutions and frame rates mean more processing power is needed to decode the video stream, so try and set them on the camera to avoid unnecessary decoding work.
|
||||
25
docs/docs/index.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
id: index
|
||||
title: Introduction
|
||||
slug: /
|
||||
---
|
||||
|
||||
A complete and local NVR designed for Home Assistant with AI object detection. Uses OpenCV and Tensorflow to perform realtime object detection locally for IP cameras.
|
||||
|
||||
Use of a [Google Coral Accelerator](https://coral.ai/products/) is optional, but strongly recommended. CPU detection should only be used for testing purposes. The Coral will outperform even the best CPUs and can process 100+ FPS with very little overhead.
|
||||
|
||||
- Tight integration with Home Assistant via a [custom component](https://github.com/blakeblackshear/frigate-hass-integration)
|
||||
- Designed to minimize resource use and maximize performance by only looking for objects when and where it is necessary
|
||||
- Leverages multiprocessing heavily with an emphasis on realtime over processing every frame
|
||||
- Uses a very low overhead motion detection to determine where to run object detection
|
||||
- Object detection with TensorFlow runs in separate processes for maximum FPS
|
||||
- Communicates over MQTT for easy integration into other systems
|
||||
- Recording with retention based on detected objects
|
||||
- Re-streaming via RTMP to reduce the number of connections to your camera
|
||||
- A dynamic combined camera view of all tracked cameras.
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
|
||||

|
||||
219
docs/docs/installation.md
Normal file
@@ -0,0 +1,219 @@
|
||||
---
|
||||
id: installation
|
||||
title: Installation
|
||||
---
|
||||
|
||||
Frigate is a Docker container that can be run on any Docker host including as a [HassOS Addon](https://www.home-assistant.io/addons/). Note that a Home Assistant Addon is **not** the same thing as the integration. The [integration](integrations/home-assistant) is required to integrate Frigate into Home Assistant.
|
||||
|
||||
## Dependencies
|
||||
|
||||
**MQTT broker** - Frigate requires an MQTT broker. If using Home Assistant, Frigate and Home Assistant must be connected to the same MQTT broker.
|
||||
|
||||
## Preparing your hardware
|
||||
|
||||
### Operating System
|
||||
|
||||
Frigate runs best with docker installed on bare metal debian-based distributions. For ideal performance, Frigate needs access to underlying hardware for the Coral and GPU devices. Running Frigate in a VM on top of Proxmox, ESXi, Virtualbox, etc. is not recommended. The virtualization layer often introduces a sizable amount of overhead for communication with Coral devices, but [not in all circumstances](https://github.com/blakeblackshear/frigate/discussions/1837).
|
||||
|
||||
Windows is not officially supported, but some users have had success getting it to run under WSL or Virtualbox. Getting the GPU and/or Coral devices properly passed to Frigate may be difficult or impossible. Search previous discussions or issues for help.
|
||||
|
||||
### Storage
|
||||
|
||||
Frigate uses the following locations for read/write operations in the container. Docker volume mappings can be used to map these to any location on your host machine.
|
||||
|
||||
:::caution
|
||||
|
||||
Note that Frigate does not currently support limiting recordings based on available disk space automatically. If using recordings, you must specify retention settings for a number of days that will fit within the available disk space of your drive or Frigate will crash.
|
||||
|
||||
:::
|
||||
|
||||
- `/media/frigate/clips`: Used for snapshot storage. In the future, it will likely be renamed from `clips` to `snapshots`. The file structure here cannot be modified and isn't intended to be browsed or managed manually.
|
||||
- `/media/frigate/recordings`: Internal system storage for recording segments. The file structure here cannot be modified and isn't intended to be browsed or managed manually.
|
||||
- `/media/frigate/frigate.db`: Default location for the sqlite database. You will also see several files alongside this file while frigate is running. If moving the database location (often needed when using a network drive at `/media/frigate`), it is recommended to mount a volume with docker at `/db` and change the storage location of the database to `/db/frigate.db` in the config file.
|
||||
- `/tmp/cache`: Cache location for recording segments. Initial recordings are written here before being checked and converted to mp4 and moved to the recordings folder.
|
||||
- `/dev/shm`: It is not recommended to modify this directory or map it with docker. This is the location for raw decoded frames in shared memory and it's size is impacted by the `shm-size` calculations below.
|
||||
- `/config/config.yml`: Default location of the config file.
|
||||
|
||||
#### Common docker compose storage configurations
|
||||
|
||||
Writing to a local disk or external USB drive:
|
||||
|
||||
```yaml
|
||||
version: "3.9"
|
||||
services:
|
||||
frigate:
|
||||
...
|
||||
volumes:
|
||||
- /path/to/your/config.yml:/config/config.yml:ro
|
||||
- /path/to/your/storage:/media/frigate
|
||||
- type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
|
||||
target: /tmp/cache
|
||||
tmpfs:
|
||||
size: 1000000000
|
||||
...
|
||||
```
|
||||
|
||||
Writing to a network drive with database on a local drive:
|
||||
|
||||
```yaml
|
||||
version: "3.9"
|
||||
services:
|
||||
frigate:
|
||||
...
|
||||
volumes:
|
||||
- /path/to/your/config.yml:/config/config.yml:ro
|
||||
- /path/to/network/storage:/media/frigate
|
||||
- /path/to/local/disk:/db
|
||||
- type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
|
||||
target: /tmp/cache
|
||||
tmpfs:
|
||||
size: 1000000000
|
||||
...
|
||||
```
|
||||
|
||||
frigate.yml
|
||||
|
||||
```yaml
|
||||
database:
|
||||
path: /db/frigate.db
|
||||
```
|
||||
|
||||
### Calculating required shm-size
|
||||
|
||||
Frigate utilizes shared memory to store frames during processing. The default `shm-size` provided by Docker is 64m.
|
||||
|
||||
The default shm-size of 64m is fine for setups with 2 or less 1080p cameras. If frigate is exiting with "Bus error" messages, it is likely because you have too many high resolution cameras and you need to specify a higher shm size.
|
||||
|
||||
You can calculate the necessary shm-size for each camera with the following formula using the resolution specified for detect:
|
||||
|
||||
```
|
||||
(width * height * 1.5 * 9 + 270480)/1048576 = <shm size in mb>
|
||||
```
|
||||
|
||||
The shm size cannot be set per container for Home Assistant Addons. You must set `default-shm-size` in `/etc/docker/daemon.json` to increase the default shm size. This will increase the shm size for all of your docker containers. This may or may not cause issues with your setup. https://docs.docker.com/engine/reference/commandline/dockerd/#daemon-configuration-file
|
||||
|
||||
### Raspberry Pi 3/4
|
||||
|
||||
By default, the Raspberry Pi limits the amount of memory available to the GPU. In order to use ffmpeg hardware acceleration, you must increase the available memory by setting `gpu_mem` to the maximum recommended value in `config.txt` as described in the [official docs](https://www.raspberrypi.org/documentation/computers/config_txt.html#memory-options).
|
||||
|
||||
Additionally, the USB Coral draws a considerable amount of power. If using any other USB devices such as an SSD, you will experience instability due to the Pi not providing enough power to USB devices. You will need to purchase an external USB hub with it's own power supply. Some have reported success with <a href="https://amzn.to/3a2mH0P" target="_blank" rel="nofollow noopener sponsored">this</a> (affiliate link).
|
||||
|
||||
## Docker
|
||||
|
||||
Running in Docker with compose is the recommended install method:
|
||||
|
||||
```yaml
|
||||
version: "3.9"
|
||||
services:
|
||||
frigate:
|
||||
container_name: frigate
|
||||
privileged: true # this may not be necessary for all setups
|
||||
restart: unless-stopped
|
||||
image: blakeblackshear/frigate:stable
|
||||
shm_size: "64mb" # update for your cameras based on calculation above
|
||||
devices:
|
||||
- /dev/bus/usb:/dev/bus/usb # passes the USB Coral, needs to be modified for other versions
|
||||
- /dev/apex_0:/dev/apex_0 # passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux
|
||||
- /dev/dri/renderD128 # for intel hwaccel, needs to be updated for your hardware
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /path/to/your/config.yml:/config/config.yml:ro
|
||||
- /path/to/your/storage:/media/frigate
|
||||
- type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
|
||||
target: /tmp/cache
|
||||
tmpfs:
|
||||
size: 1000000000
|
||||
ports:
|
||||
- "5000:5000"
|
||||
- "1935:1935" # RTMP feeds
|
||||
environment:
|
||||
FRIGATE_RTSP_PASSWORD: "password"
|
||||
```
|
||||
|
||||
If you can't use docker compose, you can run the container with something similar to this:
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name frigate \
|
||||
--restart=unless-stopped \
|
||||
--mount type=tmpfs,target=/tmp/cache,tmpfs-size=1000000000 \
|
||||
--device /dev/bus/usb:/dev/bus/usb \
|
||||
--device /dev/dri/renderD128 \
|
||||
--shm-size=64m \
|
||||
-v /path/to/your/storage:/media/frigate \
|
||||
-v /path/to/your/config.yml:/config/config.yml:ro \
|
||||
-v /etc/localtime:/etc/localtime:ro \
|
||||
-e FRIGATE_RTSP_PASSWORD='password' \
|
||||
-p 5000:5000 \
|
||||
-p 1935:1935 \
|
||||
blakeblackshear/frigate:stable
|
||||
```
|
||||
|
||||
## Home Assistant Operating System (HassOS)
|
||||
|
||||
:::caution
|
||||
|
||||
Due to limitations in Home Assistant Operating System, utilizing external storage for recordings or snapshots requires [modifying udev rules manually](https://community.home-assistant.io/t/solved-mount-usb-drive-in-hassio-to-be-used-on-the-media-folder-with-udev-customization/258406/46).
|
||||
|
||||
:::
|
||||
|
||||
:::tip
|
||||
|
||||
If possible, it is recommended to run Frigate standalone in Docker and use [Frigate's Proxy Addon](https://github.com/blakeblackshear/frigate-hass-addons/blob/main/frigate_proxy/README.md).
|
||||
|
||||
:::
|
||||
|
||||
HassOS users can install via the addon repository.
|
||||
|
||||
1. Navigate to Supervisor > Add-on Store > Repositories
|
||||
2. Add https://github.com/blakeblackshear/frigate-hass-addons
|
||||
3. Install your desired Frigate NVR Addon and navigate to it's page
|
||||
4. Setup your network configuration in the `Configuration` tab
|
||||
5. (not for proxy addon) Create the file `frigate.yml` in your `config` directory with your detailed Frigate configuration
|
||||
6. Start the addon container
|
||||
7. (not for proxy addon) If you are using hardware acceleration for ffmpeg, you may need to disable "Protection mode"
|
||||
|
||||
There are several versions of the addon available:
|
||||
|
||||
| Addon Version | Description |
|
||||
| ------------------------------ | ---------------------------------------------------------- |
|
||||
| Frigate NVR | Current release with protection mode on |
|
||||
| Frigate NVR (Full Access) | Current release with the option to disable protection mode |
|
||||
| Frigate NVR Beta | Beta release with protection mode on |
|
||||
| Frigate NVR Beta (Full Access) | Beta release with the option to disable protection mode |
|
||||
|
||||
## Home Assistant Supervised
|
||||
|
||||
:::tip
|
||||
|
||||
If possible, it is recommended to run Frigate standalone in Docker and use [Frigate's Proxy Addon](https://github.com/blakeblackshear/frigate-hass-addons/blob/main/frigate_proxy/README.md).
|
||||
|
||||
:::
|
||||
|
||||
When running Home Assistant with the [Supervised install method](https://github.com/home-assistant/supervised-installer), you can get the benefit of running the Addon along with the ability to customize the storage used by Frigate.
|
||||
|
||||
In order to customize the storage location for Frigate, simply use `fstab` to mount the drive you want at `/usr/share/hassio/media`. Here is an example fstab entry:
|
||||
|
||||
```shell
|
||||
UUID=1a65fec6-c25f-404a-b3d2-1f2fcf6095c8 /media/data ext4 defaults 0 0
|
||||
/media/data/homeassistant/media /usr/share/hassio/media none bind 0 0
|
||||
```
|
||||
|
||||
Then follow the instructions listed for [Home Assistant Operating System](#home-assistant-operating-system-hassos).
|
||||
|
||||
## Kubernetes
|
||||
|
||||
Use the [helm chart](https://github.com/blakeblackshear/blakeshome-charts/tree/master/charts/frigate).
|
||||
|
||||
## Unraid
|
||||
|
||||
Many people have powerful enough NAS devices or home servers to also run docker. There is a Unraid Community App.
|
||||
To install make sure you have the [community app plugin here](https://forums.unraid.net/topic/38582-plug-in-community-applications/). Then search for "Frigate" in the apps section within Unraid - you can see the online store [here](https://unraid.net/community/apps?q=frigate#r)
|
||||
|
||||
## Proxmox
|
||||
|
||||
It is recommended to run Frigate in LXC for maximum performance. See [this discussion](https://github.com/blakeblackshear/frigate/discussions/1111) for more information.
|
||||
|
||||
## ESX
|
||||
|
||||
For details on running Frigate under ESX, see details [here](https://github.com/blakeblackshear/frigate/issues/305).
|
||||
266
docs/docs/integrations/api.md
Normal file
@@ -0,0 +1,266 @@
|
||||
---
|
||||
id: api
|
||||
title: HTTP API
|
||||
---
|
||||
|
||||
A web server is available on port 5000 with the following endpoints.
|
||||
|
||||
### `GET /api/<camera_name>`
|
||||
|
||||
An mjpeg stream for debugging. Keep in mind the mjpeg endpoint is for debugging only and will put additional load on the system when in use.
|
||||
|
||||
Accepts the following query string parameters:
|
||||
|
||||
| param | Type | Description |
|
||||
| ----------- | ---- | ------------------------------------------------------------------ |
|
||||
| `fps` | int | Frame rate |
|
||||
| `h` | int | Height in pixels |
|
||||
| `bbox` | int | Show bounding boxes for detected objects (0 or 1) |
|
||||
| `timestamp` | int | Print the timestamp in the upper left (0 or 1) |
|
||||
| `zones` | int | Draw the zones on the image (0 or 1) |
|
||||
| `mask` | int | Overlay the mask on the image (0 or 1) |
|
||||
| `motion` | int | Draw blue boxes for areas with detected motion (0 or 1) |
|
||||
| `regions` | int | Draw green boxes for areas where object detection was run (0 or 1) |
|
||||
|
||||
You can access a higher resolution mjpeg stream by appending `h=height-in-pixels` to the endpoint. For example `http://localhost:5000/api/back?h=1080`. You can also increase the FPS by appending `fps=frame-rate` to the URL such as `http://localhost:5000/api/back?fps=10` or both with `?fps=10&h=1000`.
|
||||
|
||||
### `GET /api/<camera_name>/latest.jpg[?h=300]`
|
||||
|
||||
The most recent frame that frigate has finished processing. It is a full resolution image by default.
|
||||
|
||||
Accepts the following query string parameters:
|
||||
|
||||
| param | Type | Description |
|
||||
| ----------- | ---- | ------------------------------------------------------------------ |
|
||||
| `h` | int | Height in pixels |
|
||||
| `bbox` | int | Show bounding boxes for detected objects (0 or 1) |
|
||||
| `timestamp` | int | Print the timestamp in the upper left (0 or 1) |
|
||||
| `zones` | int | Draw the zones on the image (0 or 1) |
|
||||
| `mask` | int | Overlay the mask on the image (0 or 1) |
|
||||
| `motion` | int | Draw blue boxes for areas with detected motion (0 or 1) |
|
||||
| `regions` | int | Draw green boxes for areas where object detection was run (0 or 1) |
|
||||
| `quality` | int | Jpeg encoding quality (0-100). Defaults to 70. |
|
||||
|
||||
Example parameters:
|
||||
|
||||
- `h=300`: resizes the image to 300 pixes tall
|
||||
|
||||
### `GET /api/stats`
|
||||
|
||||
Contains some granular debug info that can be used for sensors in Home Assistant.
|
||||
|
||||
Sample response:
|
||||
|
||||
```json
|
||||
{
|
||||
/* Per Camera Stats */
|
||||
"back": {
|
||||
/***************
|
||||
* Frames per second being consumed from your camera. If this is higher
|
||||
* than it is supposed to be, you should set -r FPS in your input_args.
|
||||
* camera_fps = process_fps + skipped_fps
|
||||
***************/
|
||||
"camera_fps": 5.0,
|
||||
/***************
|
||||
* Number of times detection is run per second. This can be higher than
|
||||
* your camera FPS because frigate often looks at the same frame multiple times
|
||||
* or in multiple locations
|
||||
***************/
|
||||
"detection_fps": 1.5,
|
||||
/***************
|
||||
* PID for the ffmpeg process that consumes this camera
|
||||
***************/
|
||||
"capture_pid": 27,
|
||||
/***************
|
||||
* PID for the process that runs detection for this camera
|
||||
***************/
|
||||
"pid": 34,
|
||||
/***************
|
||||
* Frames per second being processed by frigate.
|
||||
***************/
|
||||
"process_fps": 5.1,
|
||||
/***************
|
||||
* Frames per second skip for processing by frigate.
|
||||
***************/
|
||||
"skipped_fps": 0.0
|
||||
},
|
||||
/***************
|
||||
* Sum of detection_fps across all cameras and detectors.
|
||||
* This should be the sum of all detection_fps values from cameras.
|
||||
***************/
|
||||
"detection_fps": 5.0,
|
||||
/* Detectors Stats */
|
||||
"detectors": {
|
||||
"coral": {
|
||||
/***************
|
||||
* Timestamp when object detection started. If this value stays non-zero and constant
|
||||
* for a long time, that means the detection process is stuck.
|
||||
***************/
|
||||
"detection_start": 0.0,
|
||||
/***************
|
||||
* Time spent running object detection in milliseconds.
|
||||
***************/
|
||||
"inference_speed": 10.48,
|
||||
/***************
|
||||
* PID for the shared process that runs object detection on the Coral.
|
||||
***************/
|
||||
"pid": 25321
|
||||
}
|
||||
},
|
||||
"service": {
|
||||
/* Uptime in seconds */
|
||||
"uptime": 10,
|
||||
"version": "0.10.1-8883709",
|
||||
"latest_version": "0.10.1",
|
||||
/* Storage data in MB for important locations */
|
||||
"storage": {
|
||||
"/media/frigate/clips": {
|
||||
"total": 1000,
|
||||
"used": 700,
|
||||
"free": 300,
|
||||
"mnt_type": "ext4"
|
||||
},
|
||||
"/media/frigate/recordings": {
|
||||
"total": 1000,
|
||||
"used": 700,
|
||||
"free": 300,
|
||||
"mnt_type": "ext4"
|
||||
},
|
||||
"/tmp/cache": {
|
||||
"total": 256,
|
||||
"used": 100,
|
||||
"free": 156,
|
||||
"mnt_type": "tmpfs"
|
||||
},
|
||||
"/dev/shm": {
|
||||
"total": 256,
|
||||
"used": 100,
|
||||
"free": 156,
|
||||
"mnt_type": "tmpfs"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/config`
|
||||
|
||||
A json representation of your configuration
|
||||
|
||||
### `GET /api/version`
|
||||
|
||||
Version info
|
||||
|
||||
### `GET /api/events`
|
||||
|
||||
Events from the database. Accepts the following query string parameters:
|
||||
|
||||
| param | Type | Description |
|
||||
| -------------------- | ---- | --------------------------------------------- |
|
||||
| `before` | int | Epoch time |
|
||||
| `after` | int | Epoch time |
|
||||
| `camera` | str | Camera name |
|
||||
| `label` | str | Label name |
|
||||
| `zone` | str | Zone name |
|
||||
| `limit` | int | Limit the number of events returned |
|
||||
| `has_snapshot` | int | Filter to events that have snapshots (0 or 1) |
|
||||
| `has_clip` | int | Filter to events that have clips (0 or 1) |
|
||||
| `include_thumbnails` | int | Include thumbnails in the response (0 or 1) |
|
||||
|
||||
### `GET /api/events/summary`
|
||||
|
||||
Returns summary data for events in the database. Used by the Home Assistant integration.
|
||||
|
||||
### `GET /api/events/<id>`
|
||||
|
||||
Returns data for a single event.
|
||||
|
||||
### `DELETE /api/events/<id>`
|
||||
|
||||
Permanently deletes the event along with any clips/snapshots.
|
||||
|
||||
### `POST /api/events/<id>/retain`
|
||||
|
||||
Sets retain to true for the event id.
|
||||
|
||||
### `POST /api/events/<id>/plus`
|
||||
|
||||
Submits the snapshot of the event to Frigate+ for labeling.
|
||||
|
||||
### `DELETE /api/events/<id>/retain`
|
||||
|
||||
Sets retain to false for the event id (event may be deleted quickly after removing).
|
||||
|
||||
### `POST /api/events/<id>/sub_label`
|
||||
|
||||
Set a sub label for an event. For example to update `person` -> `person's name` if they were recognized with facial recognition.
|
||||
Sub labels must be 20 characters or shorter.
|
||||
|
||||
```json
|
||||
{
|
||||
"subLabel": "some_string"
|
||||
}
|
||||
```
|
||||
|
||||
### `GET /api/events/<id>/thumbnail.jpg`
|
||||
|
||||
Returns a thumbnail for the event id optimized for notifications. Works while the event is in progress and after completion. Passing `?format=android` will convert the thumbnail to 2:1 aspect ratio.
|
||||
|
||||
### `GET /api/<camera_name>/<label>/thumbnail.jpg`
|
||||
|
||||
Returns the thumbnail from the latest event for the given camera and label combo. Using `any` as the label will return the latest thumbnail regardless of type.
|
||||
|
||||
### `GET /api/events/<id>/clip.mp4`
|
||||
|
||||
Returns the clip for the event id. Works after the event has ended.
|
||||
|
||||
### `GET /api/events/<id>/snapshot.jpg`
|
||||
|
||||
Returns the snapshot image for the event id. Works while the event is in progress and after completion.
|
||||
|
||||
Accepts the following query string parameters, but they are only applied when an event is in progress. After the event is completed, the saved snapshot is returned from disk without modification:
|
||||
|
||||
| param | Type | Description |
|
||||
| ----------- | ---- | ------------------------------------------------- |
|
||||
| `h` | int | Height in pixels |
|
||||
| `bbox` | int | Show bounding boxes for detected objects (0 or 1) |
|
||||
| `timestamp` | int | Print the timestamp in the upper left (0 or 1) |
|
||||
| `crop` | int | Crop the snapshot to the (0 or 1) |
|
||||
| `quality` | int | Jpeg encoding quality (0-100). Defaults to 70. |
|
||||
|
||||
### `GET /api/<camera_name>/<label>/snapshot.jpg`
|
||||
|
||||
Returns the snapshot image from the latest event for the given camera and label combo. Using `any` as the label will return the latest thumbnail regardless of type.
|
||||
|
||||
### `GET /clips/<camera>-<id>.jpg`
|
||||
|
||||
JPG snapshot for the given camera and event id.
|
||||
|
||||
### `GET /vod/<year>-<month>/<day>/<hour>/<camera>/master.m3u8`
|
||||
|
||||
HTTP Live Streaming Video on Demand URL for the specified hour and camera. Can be viewed in an application like VLC.
|
||||
|
||||
### `GET /vod/event/<event-id>/index.m3u8`
|
||||
|
||||
HTTP Live Streaming Video on Demand URL for the specified event. Can be viewed in an application like VLC.
|
||||
|
||||
### `GET /vod/event/<event-id>/index.m3u8`
|
||||
|
||||
HTTP Live Streaming Video on Demand URL for the specified event. Can be viewed in an application like VLC.
|
||||
|
||||
### `GET /vod/<camera>/start/<start-timestamp>/end/<end-timestamp>/index.m3u8`
|
||||
|
||||
HTTP Live Streaming Video on Demand URL for the camera with the specified time range. Can be viewed in an application like VLC.
|
||||
|
||||
### `GET /api/<camera_name>/recordings/summary`
|
||||
|
||||
Hourly summary of recordings data for a camera.
|
||||
|
||||
### `GET /api/<camera_name>/recordings`
|
||||
|
||||
Get recording segment details for the given timestamp range.
|
||||
|
||||
| param | Type | Description |
|
||||
| -------- | ---- | ------------------------------------- |
|
||||
| `after` | int | Unix timestamp for beginning of range |
|
||||
| `before` | int | Unix timestamp for end of range |
|
||||
203
docs/docs/integrations/home-assistant.md
Normal file
@@ -0,0 +1,203 @@
|
||||
---
|
||||
id: home-assistant
|
||||
title: Home Assistant Integration
|
||||
---
|
||||
|
||||
The best way to integrate with Home Assistant is to use the [official integration](https://github.com/blakeblackshear/frigate-hass-integration).
|
||||
|
||||
## Installation
|
||||
|
||||
### Preparation
|
||||
|
||||
The Frigate integration requires the `mqtt` integration to be installed and
|
||||
manually configured first.
|
||||
|
||||
See the [MQTT integration
|
||||
documentation](https://www.home-assistant.io/integrations/mqtt/) for more
|
||||
details.
|
||||
|
||||
### Integration installation
|
||||
|
||||
Available via HACS as a default repository. To install:
|
||||
|
||||
- Use [HACS](https://hacs.xyz/) to install the integration:
|
||||
|
||||
```
|
||||
Home Assistant > HACS > Integrations > "Explore & Add Integrations" > Frigate
|
||||
```
|
||||
|
||||
- Restart Home Assistant.
|
||||
- Then add/configure the integration:
|
||||
|
||||
```
|
||||
Home Assistant > Configuration > Integrations > Add Integration > Frigate
|
||||
```
|
||||
|
||||
Note: You will also need
|
||||
[media_source](https://www.home-assistant.io/integrations/media_source/) enabled
|
||||
in your Home Assistant configuration for the Media Browser to appear.
|
||||
|
||||
### (Optional) Lovelace Card Installation
|
||||
|
||||
To install the optional companion Lovelace card, please see the [separate
|
||||
installation instructions](https://github.com/dermotduffy/frigate-hass-card) for
|
||||
that card.
|
||||
|
||||
## Configuration
|
||||
|
||||
When configuring the integration, you will be asked for the `URL` of your frigate instance which is the URL you use to access Frigate in the browser. This may look like `http://<host>:5000/`. If you are using HassOS with the addon, the URL should be one of the following depending on which addon version you are using. Note that if you are using the Proxy Addon, you do NOT point the integration at the proxy URL. Just enter the URL used to access frigate directly from your network.
|
||||
|
||||
| Addon Version | URL |
|
||||
| ------------------------------ | -------------------------------------- |
|
||||
| Frigate NVR | `http://ccab4aaf-frigate:5000` |
|
||||
| Frigate NVR (Full Access) | `http://ccab4aaf-frigate-fa:5000` |
|
||||
| Frigate NVR Beta | `http://ccab4aaf-frigate-beta:5000` |
|
||||
| Frigate NVR Beta (Full Access) | `http://ccab4aaf-frigate-fa-beta:5000` |
|
||||
|
||||
<a name="options"></a>
|
||||
|
||||
## Options
|
||||
|
||||
```
|
||||
Home Assistant > Configuration > Integrations > Frigate > Options
|
||||
```
|
||||
|
||||
| Option | Description |
|
||||
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| RTMP URL Template | A [jinja2](https://jinja.palletsprojects.com/) template that is used to override the standard RTMP stream URL (e.g. for use with reverse proxies). This option is only shown to users who have [advanced mode](https://www.home-assistant.io/blog/2019/07/17/release-96/#advanced-mode) enabled. See [RTMP streams](#streams) below. |
|
||||
|
||||
## Entities Provided
|
||||
|
||||
| Platform | Description |
|
||||
| --------------- | --------------------------------------------------------------------------------- |
|
||||
| `camera` | Live camera stream (requires RTMP), camera for image of the last detected object. |
|
||||
| `sensor` | States to monitor Frigate performance, object counts for all zones and cameras. |
|
||||
| `switch` | Switch entities to toggle detection, recordings and snapshots. |
|
||||
| `binary_sensor` | A "motion" binary sensor entity per camera/zone/object. |
|
||||
|
||||
## Media Browser Support
|
||||
|
||||
The integration provides:
|
||||
|
||||
- Browsing event recordings with thumbnails
|
||||
- Browsing snapshots
|
||||
- Browsing recordings by month, day, camera, time
|
||||
|
||||
This is accessible via "Media Browser" on the left menu panel in Home Assistant.
|
||||
|
||||
## Casting Clips To Media Devices
|
||||
|
||||
The integration supports casting clips and camera streams to supported media devices.
|
||||
|
||||
:::tip
|
||||
For clips to be castable to media devices, audio is required and may need to be [enabled for recordings](../faqs.md#audio-in-recordings).
|
||||
|
||||
**NOTE: Even if you camera does not support audio, audio will need to be enabled for Casting to be accepted.**
|
||||
|
||||
:::
|
||||
|
||||
<a name="api"></a>
|
||||
|
||||
## Notification API
|
||||
|
||||
Many people do not want to expose Frigate to the web, so the integration creates some public API endpoints that can be used for notifications.
|
||||
|
||||
To load a thumbnail for an event:
|
||||
|
||||
```
|
||||
https://HA_URL/api/frigate/notifications/<event-id>/thumbnail.jpg
|
||||
```
|
||||
|
||||
To load a snapshot for an event:
|
||||
|
||||
```
|
||||
https://HA_URL/api/frigate/notifications/<event-id>/snapshot.jpg
|
||||
```
|
||||
|
||||
To load a video clip of an event:
|
||||
|
||||
```
|
||||
https://HA_URL/api/frigate/notifications/<event-id>/clip.mp4
|
||||
```
|
||||
|
||||
<a name="streams"></a>
|
||||
|
||||
## RTMP stream
|
||||
|
||||
In order for the live streams to function they need to be accessible on the RTMP
|
||||
port (default: `1935`) at `<frigatehost>:1935`. Home Assistant will directly
|
||||
connect to that streaming port when the live camera is viewed.
|
||||
|
||||
#### RTMP URL Template
|
||||
|
||||
For advanced usecases, this behavior can be changed with the [RTMP URL
|
||||
template](#options) option. When set, this string will override the default stream
|
||||
address that is derived from the default behavior described above. This option supports
|
||||
[jinja2 templates](https://jinja.palletsprojects.com/) and has the `camera` dict
|
||||
variables from [Frigate API](https://blakeblackshear.github.io/frigate/usage/api#apiconfig)
|
||||
available for the template. Note that no Home Assistant state is available to the
|
||||
template, only the camera dict from Frigate.
|
||||
|
||||
This is potentially useful when Frigate is behind a reverse proxy, and/or when
|
||||
the default stream port is otherwise not accessible to Home Assistant (e.g.
|
||||
firewall rules).
|
||||
|
||||
###### RTMP URL Template Examples
|
||||
|
||||
Use a different port number:
|
||||
|
||||
```
|
||||
rtmp://<frigate_host>:2000/live/front_door
|
||||
```
|
||||
|
||||
Use the camera name in the stream URL:
|
||||
|
||||
```
|
||||
rtmp://<frigate_host>:2000/live/{{ name }}
|
||||
```
|
||||
|
||||
Use the camera name in the stream URL, converting it to lowercase first:
|
||||
|
||||
```
|
||||
rtmp://<frigate_host>:2000/live/{{ name|lower }}
|
||||
```
|
||||
|
||||
## Multiple Instance Support
|
||||
|
||||
The Frigate integration seamlessly supports the use of multiple Frigate servers.
|
||||
|
||||
### Requirements for Multiple Instances
|
||||
|
||||
In order for multiple Frigate instances to function correctly, the
|
||||
`topic_prefix` and `client_id` parameters must be set differently per server.
|
||||
See [MQTT
|
||||
configuration](https://blakeblackshear.github.io/frigate/configuration/index#mqtt)
|
||||
for how to set these.
|
||||
|
||||
#### API URLs
|
||||
|
||||
When multiple Frigate instances are configured, [API](#api) URLs should include an
|
||||
identifier to tell Home Assistant which Frigate instance to refer to. The
|
||||
identifier used is the MQTT `client_id` paremeter included in the configuration,
|
||||
and is used like so:
|
||||
|
||||
```
|
||||
https://HA_URL/api/frigate/<client-id>/notifications/<event-id>/thumbnail.jpg
|
||||
```
|
||||
|
||||
```
|
||||
https://HA_URL/api/frigate/<client-id>/clips/front_door-1624599978.427826-976jaa.mp4
|
||||
```
|
||||
|
||||
#### Default Treatment
|
||||
|
||||
When a single Frigate instance is configured, the `client-id` parameter need not
|
||||
be specified in URLs/identifiers -- that single instance is assumed. When
|
||||
multiple Frigate instances are configured, the user **must** explicitly specify
|
||||
which server they are referring to.
|
||||
|
||||
## FAQ
|
||||
|
||||
#### If I am detecting multiple objects, how do I assign the correct `binary_sensor` to the camera in HomeKit?
|
||||
|
||||
The [HomeKit integration](https://www.home-assistant.io/integrations/homekit/) randomly links one of the binary sensors (motion sensor entities) grouped with the camera device in Home Assistant. You can specify a `linked_motion_sensor` in the Home Assistant [HomeKit configuration](https://www.home-assistant.io/integrations/homekit/#linked_motion_sensor) for each camera.
|
||||
158
docs/docs/integrations/mqtt.md
Normal file
@@ -0,0 +1,158 @@
|
||||
---
|
||||
id: mqtt
|
||||
title: MQTT
|
||||
---
|
||||
|
||||
These are the MQTT messages generated by Frigate. The default topic_prefix is `frigate`, but can be changed in the config file.
|
||||
|
||||
### `frigate/available`
|
||||
|
||||
Designed to be used as an availability topic with Home Assistant. Possible message are:
|
||||
"online": published when frigate is running (on startup)
|
||||
"offline": published right before frigate stops
|
||||
|
||||
### `frigate/restart`
|
||||
|
||||
Causes frigate to exit. Docker should be configured to automatically restart the container on exit.
|
||||
|
||||
### `frigate/<camera_name>/<object_name>`
|
||||
|
||||
Publishes the count of objects for the camera for use as a sensor in Home Assistant.
|
||||
`all` can be used as the object_name for the count of all objects for the camera.
|
||||
|
||||
### `frigate/<zone_name>/<object_name>`
|
||||
|
||||
Publishes the count of objects for the zone for use as a sensor in Home Assistant.
|
||||
`all` can be used as the object_name for the count of all objects for the zone.
|
||||
|
||||
### `frigate/<camera_name>/<object_name>/snapshot`
|
||||
|
||||
Publishes a jpeg encoded frame of the detected object type. When the object is no longer detected, the highest confidence image is published or the original image
|
||||
is published again.
|
||||
|
||||
The height and crop of snapshots can be configured in the config.
|
||||
|
||||
### `frigate/events`
|
||||
|
||||
Message published for each changed event. The first message is published when the tracked object is no longer marked as a false_positive. When frigate finds a better snapshot of the tracked object or when a zone change occurs, it will publish a message with the same id. When the event ends, a final message is published with `end_time` set.
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "update", // new, update, end
|
||||
"before": {
|
||||
"id": "1607123955.475377-mxklsc",
|
||||
"camera": "front_door",
|
||||
"frame_time": 1607123961.837752,
|
||||
"snapshot_time": 1607123961.837752,
|
||||
"label": "person",
|
||||
"top_score": 0.958984375,
|
||||
"false_positive": false,
|
||||
"start_time": 1607123955.475377,
|
||||
"end_time": null,
|
||||
"score": 0.7890625,
|
||||
"box": [424, 500, 536, 712],
|
||||
"area": 23744,
|
||||
"ratio": 2.113207,
|
||||
"region": [264, 450, 667, 853],
|
||||
"current_zones": ["driveway"],
|
||||
"entered_zones": ["yard", "driveway"],
|
||||
"thumbnail": null,
|
||||
"has_snapshot": false,
|
||||
"has_clip": false,
|
||||
"stationary": false, // whether or not the object is considered stationary
|
||||
"motionless_count": 0, // number of frames the object has been motionless
|
||||
"position_changes": 2 // number of times the object has moved from a stationary position
|
||||
},
|
||||
"after": {
|
||||
"id": "1607123955.475377-mxklsc",
|
||||
"camera": "front_door",
|
||||
"frame_time": 1607123962.082975,
|
||||
"snapshot_time": 1607123961.837752,
|
||||
"label": "person",
|
||||
"top_score": 0.958984375,
|
||||
"false_positive": false,
|
||||
"start_time": 1607123955.475377,
|
||||
"end_time": null,
|
||||
"score": 0.87890625,
|
||||
"box": [432, 496, 544, 854],
|
||||
"area": 40096,
|
||||
"ratio": 1.251397,
|
||||
"region": [218, 440, 693, 915],
|
||||
"current_zones": ["yard", "driveway"],
|
||||
"entered_zones": ["yard", "driveway"],
|
||||
"thumbnail": null,
|
||||
"has_snapshot": false,
|
||||
"has_clip": false,
|
||||
"stationary": false, // whether or not the object is considered stationary
|
||||
"motionless_count": 0, // number of frames the object has been motionless
|
||||
"position_changes": 2 // number of times the object has changed position
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `frigate/stats`
|
||||
|
||||
Same data available at `/api/stats` published at a configurable interval.
|
||||
|
||||
### `frigate/<camera_name>/detect/set`
|
||||
|
||||
Topic to turn detection for a camera on and off. Expected values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/detect/state`
|
||||
|
||||
Topic with current state of detection for a camera. Published values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/recordings/set`
|
||||
|
||||
Topic to turn recordings for a camera on and off. Expected values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/recordings/state`
|
||||
|
||||
Topic with current state of recordings for a camera. Published values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/snapshots/set`
|
||||
|
||||
Topic to turn snapshots for a camera on and off. Expected values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/snapshots/state`
|
||||
|
||||
Topic with current state of snapshots for a camera. Published values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/motion/set`
|
||||
|
||||
Topic to turn motion detection for a camera on and off. Expected values are `ON` and `OFF`.
|
||||
NOTE: Turning off motion detection will fail if detection is not disabled.
|
||||
|
||||
### `frigate/<camera_name>/motion`
|
||||
|
||||
Whether camera_name is currently detecting motion. Expected values are `ON` and `OFF`.
|
||||
NOTE: After motion is initially detected, `ON` will be set until no motion has
|
||||
been detected for `mqtt_off_delay` seconds (30 by default).
|
||||
|
||||
### `frigate/<camera_name>/motion/state`
|
||||
|
||||
Topic with current state of motion detection for a camera. Published values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/improve_contrast/set`
|
||||
|
||||
Topic to turn improve_contrast for a camera on and off. Expected values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/improve_contrast/state`
|
||||
|
||||
Topic with current state of improve_contrast for a camera. Published values are `ON` and `OFF`.
|
||||
|
||||
### `frigate/<camera_name>/motion_threshold/set`
|
||||
|
||||
Topic to adjust motion threshold for a camera. Expected value is an integer.
|
||||
|
||||
### `frigate/<camera_name>/motion_threshold/state`
|
||||
|
||||
Topic with current motion threshold for a camera. Published value is an integer.
|
||||
|
||||
### `frigate/<camera_name>/motion_contour_area/set`
|
||||
|
||||
Topic to adjust motion contour area for a camera. Expected value is an integer.
|
||||
|
||||
### `frigate/<camera_name>/motion_contour_area/state`
|
||||
|
||||
Topic with current motion contour area for a camera. Published value is an integer.
|
||||
17
docs/docs/mdx.md
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
id: mdx
|
||||
title: Powered by MDX
|
||||
---
|
||||
|
||||
You can write JSX and use React components within your Markdown thanks to [MDX](https://mdxjs.com/).
|
||||
|
||||
export const Highlight = ({children, color}) => ( <span style={{
|
||||
backgroundColor: color,
|
||||
borderRadius: '2px',
|
||||
color: '#fff',
|
||||
padding: '0.2rem',
|
||||
}}>{children}</span> );
|
||||
|
||||
<Highlight color="#25c2a0">Docusaurus green</Highlight> and <Highlight color="#1877F2">Facebook blue</Highlight> are my favorite colors.
|
||||
|
||||
I can write **Markdown** alongside my _JSX_!
|
||||
89
docs/docusaurus.config.js
Normal file
@@ -0,0 +1,89 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
title: 'Frigate',
|
||||
tagline: 'NVR With Realtime Object Detection for IP Cameras',
|
||||
url: 'https://docs.frigate.video',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'throw',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/favicon.ico',
|
||||
organizationName: 'blakeblackshear',
|
||||
projectName: 'frigate',
|
||||
themeConfig: {
|
||||
algolia: {
|
||||
apiKey: '81ec882db78f7fed05c51daf973f0362',
|
||||
indexName: 'frigate',
|
||||
},
|
||||
navbar: {
|
||||
title: 'Frigate',
|
||||
logo: {
|
||||
alt: 'Frigate',
|
||||
src: 'img/logo.svg',
|
||||
srcDark: 'img/logo-dark.svg',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
to: '/',
|
||||
activeBasePath: 'docs',
|
||||
label: 'Docs',
|
||||
position: 'left',
|
||||
},
|
||||
{
|
||||
href: 'https://frigate.video',
|
||||
label: 'Website',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://demo.frigate.video',
|
||||
label: 'Demo',
|
||||
position: 'right',
|
||||
},
|
||||
{
|
||||
href: 'https://github.com/blakeblackshear/frigate',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
sidebarCollapsible: false,
|
||||
hideableSidebar: true,
|
||||
footer: {
|
||||
style: 'dark',
|
||||
links: [
|
||||
{
|
||||
title: 'Community',
|
||||
items: [
|
||||
{
|
||||
label: 'GitHub',
|
||||
href: 'https://github.com/blakeblackshear/frigate',
|
||||
},
|
||||
{
|
||||
label: 'Discussions',
|
||||
href: 'https://github.com/blakeblackshear/frigate/discussions',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Blake Blackshear`,
|
||||
},
|
||||
},
|
||||
plugins: [path.resolve(__dirname, 'plugins', 'raw-loader')],
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
{
|
||||
docs: {
|
||||
routeBasePath: '/',
|
||||
sidebarPath: require.resolve('./sidebars.js'),
|
||||
// Please change this to your repo.
|
||||
editUrl: 'https://github.com/blakeblackshear/frigate/edit/master/docs/',
|
||||
},
|
||||
|
||||
theme: {
|
||||
customCss: require.resolve('./src/css/custom.css'),
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
};
|
||||
|
Before Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 6.0 MiB |
25529
docs/package-lock.json
generated
Normal file
38
docs/package.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"serve": "docusaurus serve",
|
||||
"clear": "docusaurus clear"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^2.0.0-beta.20",
|
||||
"@docusaurus/preset-classic": "^2.0.0-beta.20",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"clsx": "^1.1.1",
|
||||
"raw-loader": "^4.0.2",
|
||||
"react": "^16.14.0",
|
||||
"react-dom": "^16.14.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^16.14.0"
|
||||
}
|
||||
}
|
||||
12
docs/plugins/raw-loader.js
Normal file
@@ -0,0 +1,12 @@
|
||||
module.exports = function (context, options) {
|
||||
return {
|
||||
name: 'labelmap',
|
||||
configureWebpack(config, isServer, utils) {
|
||||
return {
|
||||
module: {
|
||||
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
};
|
||||
36
docs/sidebars.js
Normal file
@@ -0,0 +1,36 @@
|
||||
module.exports = {
|
||||
docs: {
|
||||
Frigate: ["index", "hardware", "installation"],
|
||||
Guides: [
|
||||
"guides/camera_setup",
|
||||
"guides/getting_started",
|
||||
"guides/events_setup",
|
||||
"guides/false_positives",
|
||||
"guides/ha_notifications",
|
||||
"guides/stationary_objects",
|
||||
],
|
||||
Configuration: [
|
||||
"configuration/index",
|
||||
"configuration/detectors",
|
||||
"configuration/cameras",
|
||||
"configuration/masks",
|
||||
"configuration/record",
|
||||
"configuration/snapshots",
|
||||
"configuration/objects",
|
||||
"configuration/rtmp",
|
||||
"configuration/zones",
|
||||
"configuration/birdseye",
|
||||
"configuration/stationary_objects",
|
||||
"configuration/advanced",
|
||||
"configuration/hardware_acceleration",
|
||||
"configuration/camera_specific",
|
||||
],
|
||||
Integrations: [
|
||||
"integrations/home-assistant",
|
||||
"integrations/api",
|
||||
"integrations/mqtt",
|
||||
],
|
||||
Troubleshooting: ["faqs"],
|
||||
Development: ["contributing"],
|
||||
},
|
||||
};
|
||||
25
docs/src/css/custom.css
Normal file
@@ -0,0 +1,25 @@
|
||||
/* stylelint-disable docusaurus/copyright-header */
|
||||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
* bundles Infima by default. Infima is a CSS framework designed to
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-color-primary: #3b82f7;
|
||||
--ifm-color-primary-dark: #1d4ed8;
|
||||
--ifm-color-primary-darker: #1e40af;
|
||||
--ifm-color-primary-darkest: #1e3a8a;
|
||||
--ifm-color-primary-light: #60a5fa;
|
||||
--ifm-color-primary-lighter: #93c5fd;
|
||||
--ifm-color-primary-lightest: #dbeafe;
|
||||
--ifm-code-font-size: 95%;
|
||||
}
|
||||
|
||||
.docusaurus-highlight-code-line {
|
||||
background-color: rgb(72, 77, 91);
|
||||
display: block;
|
||||
margin: 0 calc(-1 * var(--ifm-pre-padding));
|
||||
padding: 0 var(--ifm-pre-padding);
|
||||
}
|
||||
0
docs/static/.nojekyll
vendored
Normal file
BIN
docs/static/img/camera-ui.png
vendored
Normal file
|
After Width: | Height: | Size: 944 KiB |
0
diagram.png → docs/static/img/diagram.png
vendored
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 132 KiB |
BIN
docs/static/img/driveway_zones-min.png
vendored
Normal file
|
After Width: | Height: | Size: 195 KiB |
BIN
docs/static/img/driveway_zones.png
vendored
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
docs/static/img/events-ui.png
vendored
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
docs/static/img/example-mask-poly-min.png
vendored
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
docs/static/img/example-mask-poly.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/static/img/favicon.ico
vendored
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
docs/static/img/frigate.png
vendored
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
docs/static/img/home-ui.png
vendored
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
3
docs/static/img/logo-dark.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M130 446.5C131.6 459.3 145 468 137 470C129 472 94 406.5 86 378.5C78 350.5 73.5 319 75.4999 301C77.4999 283 181 255 181 247.5C181 240 147.5 247 146 241C144.5 235 171.3 238.6 178.5 229C189.75 214 204 216.5 213 208.5C222 200.5 233 170 235 157C237 144 215 129 209 119C203 109 222 102 268 83C314 64 460 22 462 27C464 32 414 53 379 66C344 79 287 104 287 111C287 118 290 123.5 288 139.5C286 155.5 285.76 162.971 282 173.5C279.5 180.5 277 197 282 212C286 224 299 233 305 235C310 235.333 323.8 235.8 339 235C358 234 385 236 385 241C385 246 344 243 344 250C344 257 386 249 385 256C384 263 350 260 332 260C317.6 260 296.333 259.333 287 256L285 263C281.667 263 274.7 265 267.5 265C258.5 265 258 268 241.5 268C225 268 230 267 215 266C200 265 144 308 134 322C124 336 130 370 130 385.5C130 399.428 128 430.5 130 446.5Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 936 B |
3
docs/static/img/logo.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M130 446.5C131.6 459.3 145 468 137 470C129 472 94 406.5 86 378.5C78 350.5 73.5 319 75.5 301C77.4999 283 181 255 181 247.5C181 240 147.5 247 146 241C144.5 235 171.3 238.6 178.5 229C189.75 214 204 216.5 213 208.5C222 200.5 233 170 235 157C237 144 215 129 209 119C203 109 222 102 268 83C314 64 460 22 462 27C464 32 414 53 379 66C344 79 287 104 287 111C287 118 290 123.5 288 139.5C286 155.5 285.76 162.971 282 173.5C279.5 180.5 277 197 282 212C286 224 299 233 305 235C310 235.333 323.8 235.8 339 235C358 234 385 236 385 241C385 246 344 243 344 250C344 257 386 249 385 256C384 263 350 260 332 260C317.6 260 296.333 259.333 287 256L285 263C281.667 263 274.7 265 267.5 265C258.5 265 258 268 241.5 268C225 268 230 267 215 266C200 265 144 308 134 322C124 336 130 370 130 385.5C130 399.428 128 430.5 130 446.5Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 933 B |
BIN
docs/static/img/media_browser-min.png
vendored
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
docs/static/img/media_browser.png
vendored
Normal file
|
After Width: | Height: | Size: 781 KiB |
BIN
docs/static/img/mismatched-resolution-min.jpg
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/static/img/mismatched-resolution.jpg
vendored
Normal file
|
After Width: | Height: | Size: 64 KiB |
BIN
docs/static/img/notification-min.png
vendored
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
docs/static/img/notification.png
vendored
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
docs/static/img/reolink-settings.png
vendored
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
docs/static/img/resolutions-min.jpg
vendored
Normal file
|
After Width: | Height: | Size: 48 KiB |