Coder Social home page Coder Social logo

birdcage's Introduction

This demo deployment is listening in to the Cornell Lab FeederWatch Cam at Sapsucker Woods and proving real time identification of the birds it hears.

BirdCAGE Screenshot

Newest stuff

(listed newest first)

  • Now setting the "retain" flag on MQTT publications. The payload also include the expected occurrence score for the species
  • Now storing spectograms to disk the first time they are generated, and deleting them when the recordings get cleaned up.
  • Added an App Health report that. I also put try/catch blocks around the main loops in the worker tasks so if there's an exception it should just try again. If you are looking at your detections and things look funny, take a look at that report and see if it indicates that exceptions are occurring. This will not tell you if your camera is offline, though it probably should.
  • Added support for PulseAudio input, meaning you can plug a mic into your soundcard and use that for audio. It wasn't that hard to add support for it in the code, but it kind of is a pain to set up. The intersection of Linux and audio inevitably involves pain. There's a new environment variable in the docker-compose file. Here's how you make it go: https://github.com/mmcc-xx/BirdCAGE/wiki/PulseAudio If there's need for ALSA support please let me know
  • Added some additional debug output around db calls, and upped some timeouts. At least one user is getting database lock problems and I'm trying to get to the bottom of that.
  • I just pushed new back end and front end images that provide a more robust mechanism for restarting tasks, and therefore loading preference and stream definition changes. More robust here means "doesn't break everyone's installs"

BirdCAGE

BirdCAGE is an application for monitoring the bird songs in audio streams. Security cameras often provide rtsp and rtmp streams that contain both video and audio. Feed the audio into BirdCAGE and see what sorts of birds are hanging around.

BirdCAGE was strongly inspired by BirdNET-Pi, but with the constraints of running in a Rasberry Pi removed. It utilizes a slightly patched version of the analysis server provided by the BirdNET-Analyzer project.

BirdCAGE is written in Python and was designed to be containerizable. It utilizes a separate back end and front end application. The back end application records streams, calls the analysis server, stores results, and serves as an API server for the front end application. The front end provides the UI. The back end application uses celery to spin up separate tasks for stream recording and analyzing and analysis. A Redis container is used to coordinate the tasks.

This is early days. Chances are things will break. Let me know what's broke in the Discussions or in an Issue or an angry letter or whatever.

To Do

  • I'm planning to work on a "satelite recorder" based on the ESP32 platform. It'll probably need a different interface to upload audio to avoid interference between the audio and WiFi.
  • Somehow integrate with the video based bird identification app WhosAtMyFeeder
  • User requested enhancements - request away!

Installing as an addon for home assistant

Word of warning, this will use the concept of docker out of docker. HA doesn't nativly (yet) support docker-compose. So this is a work around. The addon needs access to the docker api, thus the score will be 1 and protection will have to be removed. It will also generate an 'unsupport system' error because you are creating containers that aren't supervised. If updating or submitting issues to the HA dev team, stop the addon and restart HA.

How it works

Because HA doesn't support docker-compose, this addons is mainly a hack. All it does is spin up a container with docker / docker_compose installed. Then uses the S6 overlay to issue a docker-compose pull the up command as a start script. It also funnels the logs to bashio. On stopping the addon, the kill timeout is set to 60 seconds to allow the docker-compose down script to properly finish.

How to install

  • Using the samba (or ssh) addon, connect to the addon folder and create a new folder called birdcage.
  • Clone the repo.
  • Modify the new docker-compose.yml file with host IP, uncomment / comment lines for the HA addon.
  • You shouldn't need to modify the webui in the config file. But if you can't connect add the same ip from the docker-compose.yml
  • In the share folder (via samba / ssh / file editor) create a folder called 'birdcage' and two subfolders called 'db' and 'detections'.
  • Reload addons and it should appear as a local addon, if not check the logs for errors
  • You might need to refresh the webpage, once found install the addon and check for errors in the log
  • Run the addon
  • Voila

Files

The db and recodings are saved in the share folder. You can sqlite the db and extract for personal analysis.

Debugging

If it complains or doesn't start after a while (be carefull as it's pulling a couple docker images that are quite large). Use portainer and check whats going on. You can access the bash of the addon container through portainer, and check whats going on. It usally has to do with either ports or the share volumes not being there.

Todo for HA addon

  • Modify docker-compose script to use localhost ip
  • See if possible to use sysbox and run as dind without privilage.
  • Try building all contaiers with S6 overlay provided by HA and run services through S6

birdcage's People

Contributors

kchristensen avatar matthew73210 avatar mmcc-xx avatar phaeton avatar wanderingstar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

birdcage's Issues

Default credentials return an error

just installed latest everything in docker. On first login I attempt to go to preferences and get a login prompt. When I click on the "Login" button, I get "An error occurred while logging in"

Thanks!

Human voices

How are human voices treated? I've had a couple recordings with human voices in them and I can recognise who it is (neighbours calling a cat registered as an owl). If memory serves the analysis server should put out an estimated value for human voice. Probs should filter with that.

Password header is missing

Cool project, excited to get it running!

I got this error when trying to add a stream:

curl -X 'POST' 'http://192.168.86.151:7007/api/streams' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{ "name": "c7", "password": "birdcage", "address": "rtsp://192.168.86.152:8554/c7_sub", "protocol": "rtsp", "transport": "TCP"}'

{"error":"Password header is missing"}

It wasn't clear where to enter the password?

backend error after last update

I am getting an error from the backend after the most recent update. Data never makes it over to birdnetserver.

[2023-06-06 15:15:59,810: ERROR/MainProcess] Task handler raised error: Task of kind 'app.stream_processing.record_stream' never registered, please make sure it's imported.
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/billiard/pool.py", line 362, in workloop
    result = (True, prepare_result(fun(*args, **kwargs)))
  File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 649, in fast_trace_task
    R, I, T, Rstr = tasks[task].__trace__(
  File "/usr/local/lib/python3.10/site-packages/celery/app/registry.py", line 18, in __missing__
    raise self.NotRegistered(key)
celery.exceptions.NotRegistered: 'app.stream_processing.record_stream'
[2023-06-06 15:15:59,820: ERROR/MainProcess] Task handler raised error: Task of kind 'app.stream_processing.analyze_recordings' never registered, please make sure it's imported.
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/billiard/pool.py", line 362, in workloop
    result = (True, prepare_result(fun(*args, **kwargs)))
  File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 649, in fast_trace_task
    R, I, T, Rstr = tasks[task].__trace__(
  File "/usr/local/lib/python3.10/site-packages/celery/app/registry.py", line 18, in __missing__
    raise self.NotRegistered(key)
celery.exceptions.NotRegistered: 'app.stream_processing.analyze_recordings'

Localization not working on 2.4

I was using german locale on 2.3.
I updated to 2.4 and now the names are back to english.
I changed the locale to en and back to de in preferences but it stays english.
Any ideas?

Prebuilt analyzer image?

Any chance you'd build the docker image and upload to docker hub or similar? That way, possible future changes to it would also be easier to deploy, as people can just update their container (Watchtower or other similar tools will even auto update it, or notify of an update).

missing requirements.txt

Hey,

In the frontend container, I was having a go at building it local to do some work and it's missing the requirements.txt and thus won't build. Is is the same as the backend ?

Cheers

No space left on device ffmpeg?

A couple of minutes after starting the app:

birdcage-birdcage_backend-1   | [2023-05-23 06:53:53,189: INFO/MainProcess] Task app.stream_processing.record_stream[e96a1804-b4f7-49f0-9533-498501bbf974] received
birdcage-birdcage_backend-1   | [2023-05-23 06:53:53,196: INFO/MainProcess] Task app.stream_processing.record_stream[72ccb0d9-d551-4aef-8282-28c09023effb] received
birdcage-birdcage_backend-1   | [2023-05-23 06:53:53,209: INFO/MainProcess] Task app.stream_processing.record_stream[fdfc459f-9c70-4c8a-928b-1bc81076f3ea] received
birdcage-birdcage_backend-1   | [2023-05-23 06:53:53,225: INFO/MainProcess] Task app.stream_processing.analyze_recordings[7d9c8ed6-d884-4f5c-b916-58d566c40b8c] received
birdcage-birdcage_backend-1   | [2023-05-23 06:54:08,405: WARNING/ForkPoolWorker-1] Recording successful. File saved to: /app/../tmp/01dc7e2d0d2c4d22be7cd6d61a599a60.wav
birdcage-birdcage_backend-1   | [2023-05-23 06:54:24,629: WARNING/ForkPoolWorker-1] Recording successful. File saved to: /app/../tmp/c40c82589b4a4cc4b1da690c8b22d389.wav
birdcage-birdcage_backend-1   | [2023-05-23 06:54:40,981: WARNING/ForkPoolWorker-1] Recording successful. File saved to: /app/../tmp/1611058f51eb4307837829a51cb5410b.wav
birdcage-birdcage_backend-1   | [2023-05-23 06:54:57,151: WARNING/ForkPoolWorker-1] Recording successful. File saved to: /app/../tmp/6c806fdd70914f2faa912fe54e1455ce.wav
birdcage-birdcage_backend-1   | [2023-05-23 06:55:13,367: WARNING/ForkPoolWorker-1] Recording successful. File saved to: /app/../tmp/f99913c16d204fd38bf4af21874e7bde.wav
birdcage-birdcage_backend-1   | av_interleaved_write_frame(): No space left on device
birdcage-birdcage_backend-1   | Error writing trailer of /app/../tmp/29c32bb919c94d548f418ce37d311eb0.wav: No space left on device
birdcage-birdcage_backend-1   | [2023-05-23 06:55:26,827: WARNING/ForkPoolWorker-1] Error: ffmpeg error (see stderr output for detail)
birdcage-birdcage_backend-1   | [2023-05-23 06:55:26,827: WARNING/ForkPoolWorker-1] Recording failed. Error: ffmpeg error (see stderr output for detail)

Clearly I have plenty of space. Odd!

[root@homedocker1 ~]# df -h
Filesystem                       Size  Used Avail Use% Mounted on
devtmpfs                         2.0G     0  2.0G   0% /dev
tmpfs                            2.0G     0  2.0G   0% /dev/shm
tmpfs                            2.0G   18M  2.0G   1% /run
tmpfs                            2.0G     0  2.0G   0% /sys/fs/cgroup
/dev/mapper/centos-root          150G   60G   91G  40% /
/dev/mapper/centos-home           42G  1.3G   40G   3% /home
/dev/sda1                       1014M  156M  859M  16% /boot
overlay                          150G   60G   91G  40% /var/lib/docker/overlay2/b811da5f34bbbcba628e46a87b25df3a16e808fcea8ab3887b948b98f5e4f269/merged
overlay                          150G   60G   91G  40% /var/lib/docker/overlay2/f6488296b205ad41f22d44dddda125dac660c90a3df79589ba00e617849f0682/merged
overlay                          150G   60G   91G  40% /var/lib/docker/overlay2/a9ba92bc3f9911070240b4b0d7457f9e1cfe1c4add8ab7ca621b2914f42f82fb/merged
overlay                          150G   60G   91G  40% /var/lib/docker/overlay2/900782b1e17c2cbdbc733c4130171e2796cec3b91bfb73daba099192b356339d/merged
tmpfs                            396M     0  396M   0% /run/user/0
overlay                          150G   60G   91G  40% /var/lib/docker/overlay2/6c44a375c3f726a495f9af742aa70777ea7eab7806381b6179f8cabd5a574feb/merged
overlay                          150G   60G   91G  40% /var/lib/docker/overlay2/6b10720f7bc30a4058181c7fe6fa808cf2597431ecc67119d20426de83e0eee7/merged
overlay                          150G   60G   91G  40% /var/lib/docker/overlay2/e25837eb93c2babadc836add6be8d6479c39897e4e8c2f54c73e5a0b7f62ce73/merged
overlay                          150G   60G   91G  40% /var/lib/docker/overlay2/604448a1ad41468051a055f5610fb843e14e23f8c9aa78b2a2721dcd73c5a852/merged

Reverse proxy support

Greetings! First thanks for this project! I've been setting this up on my docker host, and noticed that unless I'm missing something there's no support for setting a HTTP root. I run all of my docker containers behind a reverse proxy so I can terminate SSL, and prefer the subfolder style of doing so (e.g. https://myhost.com/birdcage/).

It would be swell to be able to set an environment variable for the backend and frontend containers so that when they craft links for redirection and what not that they are prefixed with the appropriate host and path to make this more reverse proxy friendly.

I haven't had a chance to dig in too much but it seems like prepending the prefix to the SWAGGER_URL and API_URL here might be enough to do it on the backend.

Do you have any plans to support such a thing in the roadmap? If not, I can likely take a swing at it, but I didn't want to get too into the weeds since there's another PR out there with some niceties that would factor into such a PR (like this).

FFMPEG Issues

I'm getting the error:

"rtmp://fqdn/bcs/channel0_main.bcs?user=admin&password=$PASS: No such file or directory"
"Error: ffmpeg error (see stderr output for detail)"
" Recording failed. Error: ffmpeg error (see stderr output for detail)"

How can I redirect the stderr to the docker log?

Further, I had similar issues with this (Reolink) camera in Frigate and had to add specific ffmpeg directives. Specifically:

    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'

From my frigate config.

Dedupe between streams

Is it possible to deduplicate bird IDs that are found in two streams simultaneously? I have two cameras feeding from opposite sides of my house and there's some overlap in detection depending on where and how far the bird is. Could check if two IDs from different streams match species and have the same timestamp within a margin of error, then eliminate the one with lower confidence?

Docker related - Not all containers starting at boot

Upon a reboot or a restart of docker I notice that the containers for redis,birdcage_frontend, and birdcage_backend will be stopped, however, birdnetserver will be running. I can start them manually and everything works as it should. Adding "restart: unless-stopped" under each container in the docker compose file seems to resolve this issue.

Worker Timeout After Restart

Not a show stopper, but a consistent issue I am seeing. The first time you try and review a detection after a system restart, I get a timeout of the initial worker. This happens if you play audio or navigate to the Detection Details page. Once the new worker is booted, everything runs as expected.

[2023-06-07 15:58:36 -0400] [7] [CRITICAL] WORKER TIMEOUT (pid:18)
Exception ignored on calling ctypes callback function: <function ExecutionEngine._raw_object_cache_notify at 0x7f48250c3880>
Traceback (most recent call last):
 File "/usr/local/lib/python3.10/site-packages/llvmlite/binding/executionengine.py", line 171, in _raw_object_cache_notify
   def _raw_object_cache_notify(self, data):
 File "/usr/local/lib/python3.10/site-packages/gunicorn/workers/base.py", line 203, in handle_abort
   sys.exit(1)
SystemExit: 1
[2023-06-07 15:58:37 -0400] [7] [WARNING] Worker with pid 18 was terminated due to signal 9
[2023-06-07 15:58:37 -0400] [524] [INFO] Booting worker with pid: 524

Login handled in-browser

The login page has a JavaScript function that handles login, which means the web browser needs to be able to contact the backend.

This is not ideal, because it forces the backend to be exposed externally, rather than just safely hidden away in a docker network with the other containers.

Ideally, only the frontend should be exposed externally (and ideally proxied behind something like Traefik that can add a layer of isolation).

wrong version - docker-compose

Following your installation guide, I copy the file into docker-compose.yml but when I try to do the docker-compose, I get a message about a string error in the version. I removed some strange characters and left Version "3.8"....but then I get Version is unsupported. I just installed docker and docker-compose so there's some mismatch going on here.

Error on backend

Hi. I've set up the containers, and configured 2 camera streams. However, nothing seems to be happening. I've restarted the containers after configuration to no avail. In the backend, I see an error:

2023-05-25T10:37:23.241605221Z Starting API Server
2023-05-25T10:37:23.241661045Z Starting celery_worker
2023-05-25T10:37:23.241701984Z Sleeping indefinitely
2023-05-25T10:37:23.336256582Z [2023-05-25 12:37:23 +0200] [6] [INFO] Starting gunicorn 20.1.0
2023-05-25T10:37:23.336269325Z [2023-05-25 12:37:23 +0200] [6] [INFO] Listening at: http://0.0.0.0:7007 (6)
2023-05-25T10:37:23.336271695Z [2023-05-25 12:37:23 +0200] [6] [INFO] Using worker: sync
2023-05-25T10:37:23.339509878Z [2023-05-25 12:37:23 +0200] [17] [INFO] Booting worker with pid: 17
2023-05-25T10:37:23.817438280Z Starting celery worker in celery_worker.py
2023-05-25T10:37:24.054679750Z /usr/local/lib/python3.10/site-packages/celery/platforms.py:840: SecurityWarning: You're running the worker with superuser privileges: this is
2023-05-25T10:37:24.054694710Z absolutely not recommended!
2023-05-25T10:37:24.054696952Z 
2023-05-25T10:37:24.054698597Z Please specify a different user using the --uid option.
2023-05-25T10:37:24.054700099Z 
2023-05-25T10:37:24.054701425Z User information: uid=0 euid=0 gid=0 egid=0
2023-05-25T10:37:24.054702844Z 
2023-05-25T10:37:24.054704172Z   warnings.warn(SecurityWarning(ROOT_DISCOURAGED.format(
2023-05-25T10:37:24.060113621Z  
2023-05-25T10:37:24.060117771Z  -------------- celery@birdcage_backend v5.2.7 (dawn-chorus)
2023-05-25T10:37:24.060119556Z --- ***** ----- 
2023-05-25T10:37:24.060121119Z -- ******* ---- Linux-5.19.0-42-generic-x86_64-with-glibc2.31 2023-05-25 12:37:24
2023-05-25T10:37:24.060122678Z - *** --- * --- 
2023-05-25T10:37:24.060124037Z - ** ---------- [config]
2023-05-25T10:37:24.060125439Z - ** ---------- .> app:         app:0x7f73dbc0dab0
2023-05-25T10:37:24.060127102Z - ** ---------- .> transport:   redis://redis:6379/0
2023-05-25T10:37:24.060128598Z - ** ---------- .> results:     redis://redis:6379/0
2023-05-25T10:37:24.060130072Z - *** --- * --- .> concurrency: 10 (prefork)
2023-05-25T10:37:24.060131515Z -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
2023-05-25T10:37:24.060133013Z --- ***** ----- 
2023-05-25T10:37:24.060134357Z  -------------- [queues]
2023-05-25T10:37:24.060135743Z                 .> celery           exchange=celery(direct) key=celery
2023-05-25T10:37:24.060137242Z                 
2023-05-25T10:37:24.060138785Z 
2023-05-25T10:37:24.060140145Z [tasks]
2023-05-25T10:37:24.060141513Z   . app.stream_processing.analyze_recordings
2023-05-25T10:37:24.060142894Z   . app.stream_processing.record_stream
2023-05-25T10:37:24.060144310Z   . update_birdsoftheweek_table_task
2023-05-25T10:37:24.060145693Z 
2023-05-25T10:37:24.060344298Z [2023-05-25 12:37:24,060: WARNING/MainProcess] /usr/local/lib/python3.10/site-packages/celery/app/utils.py:204: CDeprecationWarning: 
2023-05-25T10:37:24.060354765Z     The 'CELERY_RESULT_BACKEND' setting is deprecated and scheduled for removal in
2023-05-25T10:37:24.060356712Z     version 6.0.0. Use the result_backend instead
2023-05-25T10:37:24.060358179Z 
2023-05-25T10:37:24.060359470Z   deprecated.warn(description=f'The {setting!r} setting',
2023-05-25T10:37:24.060360965Z 
2023-05-25T10:37:24.060362346Z [2023-05-25 12:37:24,060: WARNING/MainProcess] Please run `celery upgrade settings path/to/settings.py` to avoid these warnings and to allow a smoother upgrade to Celery 6.0.
2023-05-25T10:37:24.272962009Z [2023-05-25 12:37:24,272: INFO/MainProcess] Connected to redis://redis:6379/0
2023-05-25T10:37:24.273853769Z [2023-05-25 12:37:24,273: INFO/MainProcess] mingle: searching for neighbors
2023-05-25T10:37:24.277082360Z [2023-05-25 12:37:24,276: CRITICAL/MainProcess] Unrecoverable error: ContentDisallowed('Refusing to deserialize untrusted content of type pickle (application/x-python-serialize)')
2023-05-25T10:37:24.277085834Z Traceback (most recent call last):
2023-05-25T10:37:24.277087760Z   File "/usr/local/lib/python3.10/site-packages/celery/worker/worker.py", line 203, in start
2023-05-25T10:37:24.277101795Z     self.blueprint.start(self)
2023-05-25T10:37:24.277103279Z   File "/usr/local/lib/python3.10/site-packages/celery/bootsteps.py", line 116, in start
2023-05-25T10:37:24.277104999Z     step.start(parent)
2023-05-25T10:37:24.277106429Z   File "/usr/local/lib/python3.10/site-packages/celery/bootsteps.py", line 365, in start
2023-05-25T10:37:24.277107924Z     return self.obj.start()
2023-05-25T10:37:24.277109326Z   File "/usr/local/lib/python3.10/site-packages/celery/worker/consumer/consumer.py", line 332, in start
2023-05-25T10:37:24.277110853Z     blueprint.start(self)
2023-05-25T10:37:24.277112253Z   File "/usr/local/lib/python3.10/site-packages/celery/bootsteps.py", line 116, in start
2023-05-25T10:37:24.277113762Z     step.start(parent)
2023-05-25T10:37:24.277115157Z   File "/usr/local/lib/python3.10/site-packages/celery/worker/consumer/mingle.py", line 37, in start
2023-05-25T10:37:24.277116723Z     self.sync(c)
2023-05-25T10:37:24.277118109Z   File "/usr/local/lib/python3.10/site-packages/celery/worker/consumer/mingle.py", line 41, in sync
2023-05-25T10:37:24.277119654Z     replies = self.send_hello(c)
2023-05-25T10:37:24.277121000Z   File "/usr/local/lib/python3.10/site-packages/celery/worker/consumer/mingle.py", line 54, in send_hello
2023-05-25T10:37:24.277122556Z     replies = inspect.hello(c.hostname, our_revoked._data) or {}
2023-05-25T10:37:24.277123944Z   File "/usr/local/lib/python3.10/site-packages/celery/app/control.py", line 389, in hello
2023-05-25T10:37:24.277125381Z     return self._request('hello', from_node=from_node, revoked=revoked)
2023-05-25T10:37:24.277126805Z   File "/usr/local/lib/python3.10/site-packages/celery/app/control.py", line 106, in _request
2023-05-25T10:37:24.277142227Z     return self._prepare(self.app.control.broadcast(
2023-05-25T10:37:24.277144190Z   File "/usr/local/lib/python3.10/site-packages/celery/app/control.py", line 741, in broadcast
2023-05-25T10:37:24.277145796Z     return self.mailbox(conn)._broadcast(
2023-05-25T10:37:24.277147207Z   File "/usr/local/lib/python3.10/site-packages/kombu/pidbox.py", line 344, in _broadcast
2023-05-25T10:37:24.277148695Z     return self._collect(reply_ticket, limit=limit,
2023-05-25T10:37:24.277150069Z   File "/usr/local/lib/python3.10/site-packages/kombu/pidbox.py", line 386, in _collect
2023-05-25T10:37:24.277151512Z     self.connection.drain_events(timeout=timeout)
2023-05-25T10:37:24.277153295Z   File "/usr/local/lib/python3.10/site-packages/kombu/connection.py", line 316, in drain_events
2023-05-25T10:37:24.277154923Z     return self.transport.drain_events(self.connection, **kwargs)
2023-05-25T10:37:24.277156321Z   File "/usr/local/lib/python3.10/site-packages/kombu/transport/virtual/base.py", line 971, in drain_events
2023-05-25T10:37:24.277157868Z     get(self._deliver, timeout=timeout)
2023-05-25T10:37:24.277159212Z   File "/usr/local/lib/python3.10/site-packages/kombu/transport/redis.py", line 584, in get
2023-05-25T10:37:24.277160644Z     ret = self.handle_event(fileno, event)
2023-05-25T10:37:24.277162011Z   File "/usr/local/lib/python3.10/site-packages/kombu/transport/redis.py", line 566, in handle_event
2023-05-25T10:37:24.277163443Z     return self.on_readable(fileno), self
2023-05-25T10:37:24.277164787Z   File "/usr/local/lib/python3.10/site-packages/kombu/transport/redis.py", line 562, in on_readable
2023-05-25T10:37:24.277166270Z     chan.handlers[type]()
2023-05-25T10:37:24.277167615Z   File "/usr/local/lib/python3.10/site-packages/kombu/transport/redis.py", line 967, in _brpop_read
2023-05-25T10:37:24.277169032Z     self.connection._deliver(loads(bytes_to_str(item)), dest)
2023-05-25T10:37:24.277170479Z   File "/usr/local/lib/python3.10/site-packages/kombu/transport/virtual/base.py", line 991, in _deliver
2023-05-25T10:37:24.277173133Z     callback(message)
2023-05-25T10:37:24.277174581Z   File "/usr/local/lib/python3.10/site-packages/kombu/transport/virtual/base.py", line 624, in _callback
2023-05-25T10:37:24.277176079Z     return callback(message)
2023-05-25T10:37:24.277177446Z   File "/usr/local/lib/python3.10/site-packages/kombu/messaging.py", line 620, in _receive_callback
2023-05-25T10:37:24.277178939Z     decoded = None if on_m else message.decode()
2023-05-25T10:37:24.277180434Z   File "/usr/local/lib/python3.10/site-packages/kombu/message.py", line 194, in decode
2023-05-25T10:37:24.277181840Z     self._decoded_cache = self._decode()
2023-05-25T10:37:24.277183208Z   File "/usr/local/lib/python3.10/site-packages/kombu/message.py", line 198, in _decode
2023-05-25T10:37:24.277184655Z     return loads(self.body, self.content_type,
2023-05-25T10:37:24.277188712Z   File "/usr/local/lib/python3.10/site-packages/kombu/serialization.py", line 242, in loads
2023-05-25T10:37:24.277190432Z     raise self._for_untrusted_content(content_type, 'untrusted')
2023-05-25T10:37:24.277191862Z kombu.exceptions.ContentDisallowed: Refusing to deserialize untrusted content of type pickle (application/x-python-serialize)

SQLite locked DB

Sometimes on startup, a DB is locked, preventing the app from proceeding. Not the same table every time, and sometimes I get this multiple times in a row.

birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,619: WARNING/MainProcess] Broker URL:
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,619: WARNING/MainProcess]  
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,619: WARNING/MainProcess] redis://redis:6379/0
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,620: WARNING/MainProcess] Result Backend URL:
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,620: WARNING/MainProcess]  
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,620: WARNING/MainProcess] redis://redis:6379/0
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,621: WARNING/MainProcess] Starting recording and analyze tasks
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,630: INFO/MainProcess] mingle: all alone
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,666: INFO/MainProcess] celery@b512e2e6bb55 ready.
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,694: INFO/MainProcess] Task app.stream_processing.record_stream[119a7d2f-3233-452b-936e-f81fafa6b8cf] received
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,699: WARNING/ForkPoolWorker-7] Starting record_stream for Shed
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,710: INFO/MainProcess] Task app.stream_processing.record_stream[083aee89-1c5b-43e4-a240-17ed38eae8db] received
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,716: INFO/MainProcess] Task app.stream_processing.analyze_recordings[13d2fd11-108e-4a3a-84c8-d513a44b2c13] received
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,718: WARNING/ForkPoolWorker-8] Starting record_stream for FrontYard
birdcage-birdcage_backend-1   | [2023-06-06 19:53:34,725: WARNING/ForkPoolWorker-1] Starting analyze_recordings
birdcage-birdcage_backend-1   | [2023-06-06 19:53:50,172: WARNING/ForkPoolWorker-7] Recording successful. File saved to: /app/../tmp/9428da7046774fc4b32755ce529631fe.wav
birdcage-birdcage_backend-1   | [2023-06-06 19:53:50,233: WARNING/ForkPoolWorker-8] Recording successful. File saved to: /app/../tmp/cb15f0ac04b7446dbdc8f5048fcd0ef0.wav
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,201: ERROR/ForkPoolWorker-7] Task app.stream_processing.record_stream[119a7d2f-3233-452b-936e-f81fafa6b8cf] raised unexpected: OperationalError('database is locked')
birdcage-birdcage_backend-1   | Traceback (most recent call last):
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task
birdcage-birdcage_backend-1   |     R = retval = fun(*args, **kwargs)
birdcage-birdcage_backend-1   |   File "/app/__init__.py", line 84, in __call__
birdcage-birdcage_backend-1   |     return TaskBase.__call__(self, *args, **kwargs)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__
birdcage-birdcage_backend-1   |     return self.run(*args, **kwargs)
birdcage-birdcage_backend-1   |   File "/app/stream_processing.py", line 114, in record_stream
birdcage-birdcage_backend-1   |     set_metadata(os.path.basename(tmp_filename),
birdcage-birdcage_backend-1   |   File "/app/models/recording_metadata.py", line 59, in set_metadata
birdcage-birdcage_backend-1   |     connection.commit()
birdcage-birdcage_backend-1   | sqlite3.OperationalError: database is locked
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,750: WARNING/MainProcess] Exception in thread 
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,750: WARNING/MainProcess] Thread-2 (run_process_streams)
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,750: WARNING/MainProcess] :
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,750: WARNING/MainProcess] Traceback (most recent call last):
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,750: WARNING/MainProcess]   File "/usr/local/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,864: WARNING/MainProcess]     
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,864: WARNING/MainProcess] self.run()
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,865: WARNING/MainProcess]   File "/usr/local/lib/python3.10/threading.py", line 953, in run
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,866: WARNING/MainProcess]     
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,866: WARNING/MainProcess] self._target(*self._args, **self._kwargs)
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,867: WARNING/MainProcess]   File "//celery_worker.py", line 18, in run_process_streams
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,867: WARNING/MainProcess]     
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,867: WARNING/MainProcess] process_streams(app)
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,868: WARNING/MainProcess]   File "/app/stream_processing.py", line 353, in process_streams
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,868: WARNING/MainProcess]     
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,869: WARNING/MainProcess] if check_command_value('restart'):
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,869: WARNING/MainProcess]   File "/app/models/commands.py", line 35, in check_command_value
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,869: WARNING/MainProcess]     
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,870: WARNING/MainProcess] cursor.execute('SELECT value FROM commands WHERE name = ?', (command_name,))
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,870: WARNING/MainProcess] sqlite3
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,871: WARNING/MainProcess] .
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,871: WARNING/MainProcess] OperationalError
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,871: WARNING/MainProcess] : 
birdcage-birdcage_backend-1   | [2023-06-06 19:53:55,871: WARNING/MainProcess] database is locked
birdcage-birdcage_backend-1   | [2023-06-06 19:54:00,283: ERROR/ForkPoolWorker-1] Task app.stream_processing.analyze_recordings[13d2fd11-108e-4a3a-84c8-d513a44b2c13] raised unexpected: OperationalError('database is locked')
birdcage-birdcage_backend-1   | Traceback (most recent call last):
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task
birdcage-birdcage_backend-1   |     R = retval = fun(*args, **kwargs)
birdcage-birdcage_backend-1   |   File "/app/__init__.py", line 84, in __call__
birdcage-birdcage_backend-1   |     return TaskBase.__call__(self, *args, **kwargs)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__
birdcage-birdcage_backend-1   |     return self.run(*args, **kwargs)
birdcage-birdcage_backend-1   |   File "/app/stream_processing.py", line 258, in analyze_recordings
birdcage-birdcage_backend-1   |     recording_metadata = get_metadata_by_filename(filename)
birdcage-birdcage_backend-1   |   File "/app/models/recording_metadata.py", line 24, in get_metadata_by_filename
birdcage-birdcage_backend-1   |     cursor.execute("SELECT * FROM recording_metadata WHERE filename = ?", (filename,))
birdcage-birdcage_backend-1   | sqlite3.OperationalError: database is locked
birdcage-birdcage_backend-1   | [2023-06-06 19:54:00,289: ERROR/ForkPoolWorker-8] Task app.stream_processing.record_stream[083aee89-1c5b-43e4-a240-17ed38eae8db] raised unexpected: OperationalError('database is locked')
birdcage-birdcage_backend-1   | Traceback (most recent call last):
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task
birdcage-birdcage_backend-1   |     R = retval = fun(*args, **kwargs)
birdcage-birdcage_backend-1   |   File "/app/__init__.py", line 84, in __call__
birdcage-birdcage_backend-1   |     return TaskBase.__call__(self, *args, **kwargs)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__
birdcage-birdcage_backend-1   |     return self.run(*args, **kwargs)
birdcage-birdcage_backend-1   |   File "/app/stream_processing.py", line 114, in record_stream
birdcage-birdcage_backend-1   |     set_metadata(os.path.basename(tmp_filename),
birdcage-birdcage_backend-1   |   File "/app/models/recording_metadata.py", line 59, in set_metadata
birdcage-birdcage_backend-1   |     connection.commit()
birdcage-birdcage_backend-1   | sqlite3.OperationalError: database is locked
birdcage-birdcage_backend-1   | [2023-06-06 20:05:15,374: WARNING/MainProcess] Broker URL:
birdcage-birdcage_backend-1   | [2023-06-06 20:05:15,374: WARNING/MainProcess]  
birdcage-birdcage_backend-1   | [2023-06-06 20:05:15,374: WARNING/MainProcess] redis://redis:6379/0
birdcage-birdcage_backend-1   | [2023-06-06 20:05:15,374: WARNING/MainProcess] Result Backend URL:
birdcage-birdcage_backend-1   | [2023-06-06 20:05:15,375: WARNING/MainProcess]  
birdcage-birdcage_backend-1   | [2023-06-06 20:05:15,375: WARNING/MainProcess] redis://redis:6379/0
birdcage-birdcage_backend-1   | [2023-06-06 20:05:15,375: WARNING/MainProcess] Starting recording and analyze tasks
birdcage-birdcage_backend-1   | [2023-06-06 20:05:16,111: INFO/MainProcess] Connected to redis://redis:6379/0
birdcage-birdcage_backend-1   | [2023-06-06 20:05:16,119: INFO/MainProcess] mingle: searching for neighbors
birdcage-birdcage_backend-1   | [2023-06-06 20:05:17,128: INFO/MainProcess] mingle: all alone
birdcage-birdcage_backend-1   | [2023-06-06 20:05:17,157: INFO/MainProcess] celery@002fca5374d5 ready.
birdcage-birdcage_backend-1   | [2023-06-06 20:05:17,165: INFO/MainProcess] Task app.stream_processing.record_stream[48ff1b93-442a-4ffe-8a5b-3046a5d8137f] received
birdcage-birdcage_backend-1   | [2023-06-06 20:05:17,169: WARNING/ForkPoolWorker-7] Starting record_stream for Shed
birdcage-birdcage_backend-1   | [2023-06-06 20:05:17,172: INFO/MainProcess] Task app.stream_processing.record_stream[35cf2d6d-4595-4ff5-9f8f-759dedfe7421] received
birdcage-birdcage_backend-1   | [2023-06-06 20:05:17,177: INFO/MainProcess] Task app.stream_processing.analyze_recordings[b80a3354-514e-4b34-9ad3-29fa988b25f5] received
birdcage-birdcage_backend-1   | [2023-06-06 20:05:17,180: WARNING/ForkPoolWorker-8] Starting record_stream for FrontYard
birdcage-birdcage_backend-1   | [2023-06-06 20:05:17,181: WARNING/ForkPoolWorker-1] Starting analyze_recordings
birdcage-birdcage_backend-1   | [2023-06-06 20:05:22,221: ERROR/ForkPoolWorker-1] Task app.stream_processing.analyze_recordings[b80a3354-514e-4b34-9ad3-29fa988b25f5] raised unexpected: OperationalError('database is locked')
birdcage-birdcage_backend-1   | Traceback (most recent call last):
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 451, in trace_task
birdcage-birdcage_backend-1   |     R = retval = fun(*args, **kwargs)
birdcage-birdcage_backend-1   |   File "/app/__init__.py", line 84, in __call__
birdcage-birdcage_backend-1   |     return TaskBase.__call__(self, *args, **kwargs)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/celery/app/trace.py", line 734, in __protected_call__
birdcage-birdcage_backend-1   |     return self.run(*args, **kwargs)
birdcage-birdcage_backend-1   |   File "/app/stream_processing.py", line 234, in analyze_recordings
birdcage-birdcage_backend-1   |     preferences = get_all_user_preferences(0)
birdcage-birdcage_backend-1   |   File "/app/models/preferences.py", line 67, in get_all_user_preferences
birdcage-birdcage_backend-1   |     cursor.execute('SELECT preference_key, preference_value FROM user_preferences WHERE user_id = ?',
birdcage-birdcage_backend-1   | sqlite3.OperationalError: database is locked

Preferences and Stram Setting - doesn't save

I have it up and running but when I go to the Preference or Stream Settings, I enter in the information and hit save - nothing happens. And I don't see a way to navigate back to the main page. I go to Preferences or Streams - data I entered is not saved.

Backend container seems to stop processing randomly

I've experienced this pretty reliably about 1-2x a week since using BirdCAGE and I haven't actually tracked down the cause yet, so this issue is to hopefully brainstorm what is going on.

The only thing I see in my backend container logs before things stop processing are:

[2023-06-27 07:51:00,806: WARNING/ForkPoolWorker-6] Recording successful. File saved to: /app/../tmp/75476791e76c4d7a8f85b5e9faeefa52.wav Now setting metadata
[2023-06-27 07:51:00,809: WARNING/ForkPoolWorker-6] Metadata set for: /app/../tmp/75476791e76c4d7a8f85b5e9faeefa52.wav
[2023-06-27 07:51:01,153: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/75476791e76c4d7a8f85b5e9faeefa52.wav
[2023-06-27 07:51:01,696: WARNING/ForkPoolWorker-8] Detected: House Finch Action: record
[2023-06-27 07:51:01,963: WARNING/ForkPoolWorker-8] Adding detection
[2023-06-27 07:51:01,966: WARNING/ForkPoolWorker-8] Detection added
[2023-06-27 07:51:01,967: WARNING/ForkPoolWorker-8] Notifying
[2023-06-27 07:51:01,967: ERROR/ForkPoolWorker-8] There are no service(s) to notify
[2023-06-27 07:51:01,967: WARNING/ForkPoolWorker-8] MQTT not being used. Skipping publication.
[2023-06-27 07:51:01,975: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:51:01,977: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:51:15,044: WARNING/ForkPoolWorker-7] Recording successful. File saved to: /app/../tmp/48b4d97f936b43b8a3a514e8b8ef24d0.wav Now setting metadata
[2023-06-27 07:51:15,047: WARNING/ForkPoolWorker-7] Metadata set for: /app/../tmp/48b4d97f936b43b8a3a514e8b8ef24d0.wav
[2023-06-27 07:51:16,031: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/48b4d97f936b43b8a3a514e8b8ef24d0.wav
[2023-06-27 07:51:16,621: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:51:16,624: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:51:17,108: WARNING/ForkPoolWorker-6] Recording successful. File saved to: /app/../tmp/e4eec42c234e42a98713b088988897c6.wav Now setting metadata
[2023-06-27 07:51:17,112: WARNING/ForkPoolWorker-6] Metadata set for: /app/../tmp/e4eec42c234e42a98713b088988897c6.wav
[2023-06-27 07:51:17,629: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/e4eec42c234e42a98713b088988897c6.wav
[2023-06-27 07:51:18,189: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:51:18,191: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:51:31,347: WARNING/ForkPoolWorker-7] Recording successful. File saved to: /app/../tmp/f141526ab0a34591bb70e9d5996b5656.wav Now setting metadata
[2023-06-27 07:51:31,350: WARNING/ForkPoolWorker-7] Metadata set for: /app/../tmp/f141526ab0a34591bb70e9d5996b5656.wav
[2023-06-27 07:51:32,245: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/f141526ab0a34591bb70e9d5996b5656.wav
[2023-06-27 07:51:32,816: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:51:32,820: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:51:33,142: WARNING/ForkPoolWorker-6] Recording successful. File saved to: /app/../tmp/83450105207747b789f3e570d8c43369.wav Now setting metadata
[2023-06-27 07:51:33,146: WARNING/ForkPoolWorker-6] Metadata set for: /app/../tmp/83450105207747b789f3e570d8c43369.wav
[2023-06-27 07:51:33,824: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/83450105207747b789f3e570d8c43369.wav
[2023-06-27 07:51:34,387: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:51:34,389: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:51:47,550: WARNING/ForkPoolWorker-7] Recording successful. File saved to: /app/../tmp/8e92edd130e14a5fbf2c42adc0de17d9.wav Now setting metadata
[2023-06-27 07:51:47,554: WARNING/ForkPoolWorker-7] Metadata set for: /app/../tmp/8e92edd130e14a5fbf2c42adc0de17d9.wav
[2023-06-27 07:51:48,444: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/8e92edd130e14a5fbf2c42adc0de17d9.wav
[2023-06-27 07:51:49,020: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:51:49,023: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:51:49,680: WARNING/ForkPoolWorker-6] Recording successful. File saved to: /app/../tmp/a23b5e5677e344e0ba28bcb206af44c6.wav Now setting metadata
[2023-06-27 07:51:49,684: WARNING/ForkPoolWorker-6] Metadata set for: /app/../tmp/a23b5e5677e344e0ba28bcb206af44c6.wav
[2023-06-27 07:51:50,027: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/a23b5e5677e344e0ba28bcb206af44c6.wav
[2023-06-27 07:51:50,556: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:51:50,559: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:52:03,851: WARNING/ForkPoolWorker-7] Recording successful. File saved to: /app/../tmp/fbfeee420c874d3088c31cbe7e2caf42.wav Now setting metadata
[2023-06-27 07:52:03,855: WARNING/ForkPoolWorker-7] Metadata set for: /app/../tmp/fbfeee420c874d3088c31cbe7e2caf42.wav
[2023-06-27 07:52:04,627: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/fbfeee420c874d3088c31cbe7e2caf42.wav
[2023-06-27 07:52:05,188: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:52:05,191: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:52:05,914: WARNING/ForkPoolWorker-6] Recording successful. File saved to: /app/../tmp/8af7051efc3941b8828220bd5233fd2d.wav Now setting metadata
[2023-06-27 07:52:05,917: WARNING/ForkPoolWorker-6] Metadata set for: /app/../tmp/8af7051efc3941b8828220bd5233fd2d.wav
[2023-06-27 07:52:06,196: WARNING/ForkPoolWorker-8] Requesting analysis for /app/../tmp/8af7051efc3941b8828220bd5233fd2d.wav
[2023-06-27 07:52:06,731: WARNING/ForkPoolWorker-8] Deleting metadata
[2023-06-27 07:52:06,734: WARNING/ForkPoolWorker-8] Metadata deleted
[2023-06-27 07:57:11,193: WARNING/ForkPoolWorker-8] There is no metadata and the file is old. Deleted file: 86970b09eb8f4705a37f70762c2ca1a6.wav
[2023-06-27 07:57:21,237: WARNING/ForkPoolWorker-8] There is no metadata and the file is old. Deleted file: 7198642279614db28f60d298317e4918.wav

7:57 corresponds when processing activity ceases. A container restart and it'll pick back up again. Unsure if this is related to #35 in any way, but that's all I have to work off of so far.

"exec ./start_app.sh: exec format error" on Dietpi Pi4

Im using an Pi4 4GB, with Dietpi 8.17.2 (latest atm)
I modified the docker-compose.yaml IP, created the directories and pulled the container.
But I get a exec format error.
The complete docker-compose up log is:

birdcage-redis-1 | 1:C 26 May 2023 07:08:24.062 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
birdcage-redis-1 | 1:C 26 May 2023 07:08:24.062 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
birdcage-redis-1 | 1:C 26 May 2023 07:08:24.063 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
birdcage-redis-1 | 1:M 26 May 2023 07:08:24.076 * monotonic clock: POSIX clock_gettime
birdcage-redis-1 | 1:M 26 May 2023 07:08:24.091 * Running mode=standalone, port=6379.
birdcage-redis-1 | 1:M 26 May 2023 07:08:24.091 # Server initialized
birdcage-redis-1 | 1:M 26 May 2023 07:08:24.092 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can can also cause failures without low memory condition, see jemalloc/jemalloc#1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
birdcage-redis-1 | 1:M 26 May 2023 07:08:24.122 * Ready to accept connections
birdcage-birdnetserver-1 | exec /usr/local/bin/python3: exec format error
birdcage-birdcage_backend-1 | exec ./start_app.sh: exec format error
birdcage-birdcage_frontend-1 | exec ./start_app.sh: exec format error
birdcage-birdnetserver-1 exited with code 1
birdcage-birdcage_backend-1 exited with code 1
birdcage-birdnetserver-1 exited with code 1
birdcage-birdcage_frontend-1 exited with code 1

Am I missing something?

Preferences Information

Can you explain what all the preferences do? I understand Lat/Long & Confidence, but what about the other ones? Thanks.

Ability to disable CORS

I am running on Unraid so docker compose is not an option for me. I have the separate containers running but of course the frontend and backend share different ports which means the CORS is going to fail. I'd like to be able to disable it or some way to accept cross origin requests. I tried setting the variable to * but it did not work.

Apprise MQTT record is missing sound file

Thanks for adding the new Apprise notification option! Is partly working for me:

  • gmail record works! I get an email with name, score, stream name, time, and an attachment with the mp3 file
  • gmail log and alert options do not seem to do anything. Not sure what these are for, seems the record data has all I need
  • mqtt record partly works. I get the same data I got in gmail, except it is missing the mp3 data.

The new Title option works also. Thanks for all your efforts!

[SECURITY] Login protected pages are accessible without a password

As I mentioned elsewhere, I noticed that all of the authentication for protected pages is done in javascript, so all it takes to access a protected page is using a client that doesn't support javascript.

The good news is, trying to update your password without a valid JWT fails:

❯ curl -X POST -d json='{user_id: 0, preference_key: "password", preference_value: "testing"}' https://docker.mydomain.com/birdcage/api/preferences
{"msg":"Missing Authorization Header"}

The bad news is, you can view stuff like any MQTT password you have set without a valid JWT:

❯ curl -s https://docker.mydomain.com/birdcage/preferences 2>&1 | grep THIS_IS_A_PASSWORD
            <td><input type="text" name="mqttpassword" value="THIS_IS_A_PASSWORD"></td>

tl;dr it looks like relying on client side JWT validation is insufficient, but I'm not entirely sure what the proper way to do this in Flask is.

Daylight Savings time

I can't see any way to change the time or a setting for timezone to compensate for daylight savings time. My recordings are an hour out. Is it possible to add this?

Analyzer Container won't start: TypeError: 'type' object is not subscriptable

Have followed the instructions to get your modified BirdNET-Analyzer up and running, built the container. Then:

[root@homedocker1 BirdNET-Analyzer]# docker-compose up 
birdnet-analyzer_birdnetserver_1 is up-to-date
Attaching to birdnet-analyzer_birdnetserver_1
birdnetserver_1  | Traceback (most recent call last):
birdnetserver_1  |   File "server.py", line 12, in <module>
birdnetserver_1  |     import config as cfg
birdnetserver_1  |   File "/config.py", line 115, in <module>
birdnetserver_1  |     LABELS: list[str] = []
birdnetserver_1  | TypeError: 'type' object is not subscriptable
birdnetserver_1  | Traceback (most recent call last):
birdnetserver_1  |   File "server.py", line 12, in <module>
birdnetserver_1  |     import config as cfg
birdnetserver_1  |   File "/config.py", line 115, in <module>
birdnetserver_1  |     LABELS: list[str] = []
birdnetserver_1  | TypeError: 'type' object is not subscriptable
birdnetserver_1  | Traceback (most recent call last):
birdnetserver_1  |   File "server.py", line 12, in <module>
birdnetserver_1  |     import config as cfg
birdnetserver_1  |   File "/config.py", line 115, in <module>
birdnetserver_1  |     LABELS: list[str] = []
birdnetserver_1  | TypeError: 'type' object is not subscriptable
birdnet-analyzer_birdnetserver_1 exited with code 1

Code Analysis security / automation

Probs a good idea if you add the following to this repo :
DeepSource for code analysis (Or SonarQube, why not both)
Travis CI for autobuilds (are you building yourself and pushing to docker ? Can be good for autotest if you have them)
CodeFactor

RuntimeError: cannot cache function

I've been getting this error (and broken spectrogram links):

birdcage-birdcage_backend-1   | [2023-09-03 19:32:10,419] ERROR in app: Exception on /api/spectrogram/thumb/43626abc-3a49-465f-aa87-18513ff810fd.mp3.png [GET]
birdcage-birdcage_backend-1   | Traceback (most recent call last):
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 2190, in wsgi_app
birdcage-birdcage_backend-1   |     response = self.full_dispatch_request()
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1486, in full_dispatch_request
birdcage-birdcage_backend-1   |     rv = self.handle_user_exception(e)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/flask_cors/extension.py", line 165, in wrapped_function
birdcage-birdcage_backend-1   |     return cors_after_request(app.make_response(f(*args, **kwargs)))
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1484, in full_dispatch_request
birdcage-birdcage_backend-1   |     rv = self.dispatch_request()
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/flask/app.py", line 1469, in dispatch_request
birdcage-birdcage_backend-1   |     return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
birdcage-birdcage_backend-1   |   File "/app/views/audio_files.py", line 79, in serve_thumb_spectrogram
birdcage-birdcage_backend-1   |     image_binary = create_spectrogram(audio_path, height=70)
birdcage-birdcage_backend-1   |   File "/app/views/audio_files.py", line 20, in create_spectrogram
birdcage-birdcage_backend-1   |     clip, sample_rate = librosa.load(fn_audio, sr=None)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/lazy_loader/__init__.py", line 77, in __getattr__
birdcage-birdcage_backend-1   |     attr = getattr(submod, name)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/lazy_loader/__init__.py", line 76, in __getattr__
birdcage-birdcage_backend-1   |     submod = importlib.import_module(submod_path)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
birdcage-birdcage_backend-1   |     return _bootstrap._gcd_import(name[level:], package, level)
birdcage-birdcage_backend-1   |   File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
birdcage-birdcage_backend-1   |   File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
birdcage-birdcage_backend-1   |   File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
birdcage-birdcage_backend-1   |   File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
birdcage-birdcage_backend-1   |   File "<frozen importlib._bootstrap_external>", line 883, in exec_module
birdcage-birdcage_backend-1   |   File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/librosa/core/audio.py", line 19, in <module>
birdcage-birdcage_backend-1   |     from .convert import frames_to_samples, time_to_samples
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/librosa/core/convert.py", line 7, in <module>
birdcage-birdcage_backend-1   |     from . import notation
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/librosa/core/notation.py", line 800, in <module>
birdcage-birdcage_backend-1   |     def __o_fold(d):
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/numba/core/decorators.py", line 234, in wrapper
birdcage-birdcage_backend-1   |     disp.enable_caching()
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/numba/core/dispatcher.py", line 863, in enable_caching
birdcage-birdcage_backend-1   |     self._cache = FunctionCache(self.py_func)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/numba/core/caching.py", line 601, in __init__
birdcage-birdcage_backend-1   |     self._impl = self._impl_class(py_func)
birdcage-birdcage_backend-1   |   File "/usr/local/lib/python3.10/site-packages/numba/core/caching.py", line 337, in __init__
birdcage-birdcage_backend-1   |     raise RuntimeError("cannot cache function %r: no locator available "
birdcage-birdcage_backend-1   | RuntimeError: cannot cache function '__o_fold': no locator available for file '/usr/local/lib/python3.10/site-packages/librosa/core/notation.py'

I've been able to fix it with this, based on this SO answer: https://stackoverflow.com/questions/59290386/runtimeerror-at-cannot-cache-function-shear-dense-no-locator-available-fo

  birdcage_backend:
    environment:
      NUMBA_CACHE_DIR: /tmp

But I'm not sure whether anything changed to cause it in the first place.

Cannot save stream settings or preferences

The docker container is running, and I'm able to see the web interface. After setting 'Stream Settings' clicking 'Create Stream' does nothing. Having the same issue with preferences. Tried Firefox and Chrome and neither seems to work. Nothing shows up in the docker logs as having an error, etc.

Tried stopping and starting the docker as suggested and still having the same issue

Docker version 20.10.23-ce

Persisted XSS in a number of fields

Try adding a "Species Override" named <script>alert("All your birds are belong to us")</script> and you'll see it pop up an alert, plus an alert whenever that page is loaded again.

Translations & more info

So.. after setting this up, I've realized that I have no idea what all the birds in my area are called in English. So I'm checking each and every one of them in wikipedia and then change it to the page of my country.
Would it be possible to show the localized names of the birds in the UI? I'm not completely sure about any online resources that would be reliable to implement while free to use.
Also as a side-note. It would be great to be able to read more about the bird and see a photo without having to google it. Again, it would probably require an external resource. Or at the very least, maybe a link to the bird on wikipedia (or another online bird database, whichever you find suitable).

Modify backend behaviour (if time_difference_in_minutes > 5)

Would it be poss to have this as a option in prefences? Say for what ever reason the server is lagging behind because you are doing something that's using lots of resources. You may lose some birddata if the files are older than 5 mins. In my case I wouldn't mind it being a day.
stream_processing.py
`
if recording_metadata is None:
# Check if the file is older than 5 minutes
file_creation_time = os.path.getctime(file_path)
current_time = time.time()
time_difference_in_seconds = current_time - file_creation_time
time_difference_in_minutes = time_difference_in_seconds / 60

                if time_difference_in_minutes > 5:
                    # Delete the file
                    os.remove(file_path)
                    print(f"There is no metadata and the file is old. Deleted file: {filename}", flush=True)

`

Add weather reporting to db

Had a quick look at the backend, and it shouldn't be too hard to the stream_processing.py a function that grabs the weather every hour and appends it to the db. Using the mdata variable. + also changing various files etc..
conditions: rainy, sun etc
temp : lol
hum : xx
pressure :

I suppose that air quality could also be added and where the sun is at (can be calucated from lat/log + time)

I'll give it a go sometime and do a pr, unless you want to have a go at it too.

no space left on device

I'm having the same issue as #15

After some hours of correct operation, recordings start piling up in the backend /tmp because nothing is being analyzed. My images are all up to date as of this minute. In normal operation, /tmp stays under 1 MB utilized. No error logs that I could see, I'll try to capture a copy next time and paste it here. I have 2 streams, concurrency set to 10. Restarting redis and birdnet doesn't help, a full stack restart does.

BirdWeather Reporting

Hey just got this installed,
I think its working but still need to get some kind of audio source.

I was wondering how this would be able to integrate with BirdWeather if at all?

Thanks!

Notification customization options

First, thanks for crating birdCAGE!

I have birdCAGE notifying Home Assistant via MQTT. All is good, except that I'm not knowledgeable enough to create a HA template to reformat the notification to be more readable when viewed in HA.

Here is an example of a notification that birdCAGE sends:

changed to log level bird: White-winged Dove
Common Name: White-winged Dove
Scientific Name: Zenaida asiatica
Confidence Score: 0.9559
Stream Name: Side Driveway
Time: 2023-07-21 09:34:10

It would be neat to be able to customize this message. For example, to be:

White-winged Dove - Zenaida asiatica - Confidence:0.9559

Model in use?

Just wondered what model was in use? I've been running with some camera RTSP streams in Ireland for a now, but no Ireland/European birds have been identified.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.