{"id":27036901,"url":"https://github.com/aabbtree77/surveillance","last_synced_at":"2025-09-07T17:38:20.439Z","repository":{"id":286199334,"uuid":"960689553","full_name":"aabbtree77/surveillance","owner":"aabbtree77","description":"A simple way to set up an IP camera for motion detection and video storage on Ubuntu 22.04.","archived":false,"fork":false,"pushed_at":"2025-04-06T11:57:22.000Z","size":225,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-04T05:05:42.912Z","etag":null,"topics":["1984","big-brother","camera","cctv","computer-vision","motion","motion-detection","never-mind-zoneminder","no-nonsense","onvif","rstp","storage","surveillance","ubuntu","video","visar"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aabbtree77.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-04-04T21:58:11.000Z","updated_at":"2025-04-06T12:05:50.000Z","dependencies_parsed_at":"2025-04-09T18:34:04.463Z","dependency_job_id":null,"html_url":"https://github.com/aabbtree77/surveillance","commit_stats":null,"previous_names":["aabbtree77/surveillance"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aabbtree77/surveillance","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fsurveillance","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fsurveillance/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fsurveillance/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fsurveillance/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aabbtree77","download_url":"https://codeload.github.com/aabbtree77/surveillance/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fsurveillance/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274070953,"owners_count":25217428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["1984","big-brother","camera","cctv","computer-vision","motion","motion-detection","never-mind-zoneminder","no-nonsense","onvif","rstp","storage","surveillance","ubuntu","video","visar"],"created_at":"2025-04-05T01:14:59.477Z","updated_at":"2025-09-07T17:38:20.292Z","avatar_url":"https://github.com/aabbtree77.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e \"It's the how that always stops me. Knives and razors are out for me. I have this thing about blood... Pills? I don't even have a doctor, let alone the feelgood variety. Carbon monoxide sounds good in theory, but in practice it always feels like too much like work. Getting a tube the right size to fit the exhaust pipe and long enough to reach in the side window, all the rest of it. It's like you want to kill yourself, that's fine, but first you have to remodel the basement. You end up thinking, the hell with it, I'll do it tomorrow.\"\n\u003e  \n\u003e \\- Michael Dibdin (Thanksgiving, 2000)\n\n## Introduction\n\nIt is easy to get lost when trying to find [the right software for an IP camera](https://www.youtube.com/watch?v=awQgyKJFYZo\u0026t=84s\u0026ab_channel=TheHookUp). Proprietary vs FOSS, cloud or local, GUI vs command line, \"video devices\", protocols, configuration, errors...\n\n\u003ctable align=\"center\"\u003e\n    \u003ctr\u003e\n    \u003cth align=\"center\"\u003e CCTV Camera \"viSar\" (April 2025)\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n    \u003ctd\u003e\n    \u003cimg src=\"./images/visar-2025-04-04.jpg\"  alt=\"viSar CCTV surveillance IP camera\" width=\"100%\" \u003e\n    \u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\nHere is a memo how to do automatic motion detection and video storage on Ubuntu 22.04 for a basic ONVIF-compatible or generic RTSP camera assumed to be within the same LAN as the storage PC. Everyting is FOSS and under complete control.\n\n## Test the Network and Camera\n\nGet the network address of the camera somehow:\n\n```bash\nsudo apt update\nsudo apt install nmap\nnmap -sP 192.168.0.0/24\n```\n\nIn my case, this produces\n\n```bash\nStarting Nmap 7.80 ( https://nmap.org ) at 2025-04-06 12:03 EEST\nNmap scan report for _gateway (192.168.0.1)\nHost is up (0.0012s latency).\nNmap scan report for 192.168.0.100\nHost is up (0.0096s latency).\nNmap scan report for go (192.168.0.101)\nHost is up (0.000083s latency).\nNmap scan report for 192.168.0.102\nHost is up (0.0024s latency).\nNmap done: 256 IP addresses (4 hosts up) scanned in 3.02 seconds\n```\n\nThe camera address turns out to be 192.168.0.100, which is revealed upon testing with\n\n```bash\nsudo apt install ffmpeg\nffplay rtsp://admin:admin@192.168.0.100:554/\n```\n\nThis should display a real-time video stream of the camera. The admin:admin part is likely not essential, \n`ffplay rtsp://192.168.0.100:554/` might do. \n\nInitially, it is also possible to get the error:\n\n```text\nConnection to tcp://192.168.0.100:554?timeout=0 failed: Connection refused\nrtsp://admin:admin@192.168.0.100:554/: Connection refused\n```\n\nPlug/unplug the camera, turn the camera/router power on/off until ffplay shows the video stream.\n\n## Install Motion\n\nClean up the previous versions of [Motion](https://motion-project.github.io/3.4.1/motion_guide.html):\n\n```bash\npkill motion\nsudo apt purge motion\nsudo apt autoremove --purge\nsudo rm -rf /etc/motion/\nsudo rm -rf /var/log/motion/\nsudo rm -rf /var/lib/motion/\nrm -rf ~/.motion\nrm -f ~/Videos/motion.log\nrm -f ~/Videos/*_motion.avi\nsudo systemctl disable motion.service\nsudo systemctl stop motion.service\nsudo systemctl mask motion.service\n```\n\nThe tilde `~` is not reliable for configuration. From now on I will use the explicit home path which is `/home/tokyo/` in my case.\n\nCreate the folder for the video and log files:\n\n```bash\nmkdir -p /home/tokyo/Videos\nchmod 700 /home/tokyo/Videos # Restrict access to the user only\n```\n\nInstall Motion:\n\n```bash\nsudo apt update\nsudo apt install motion\nmotion -h\nmotion Version 4.3.2, Copyright 2000-2019 Jeroen Vreeken/Folkert van Heusden/Kenneth Lavrsen/Motion-Project maintainers\nHome page :\t https://motion-project.github.io/\n```\n\n## Configure and Run Motion\n\nCreate `/home/tokyo/.motion/`.\n\nTwo configuration options are provided here. \n\nThe first is minimal, simply place `motion.conf` from `config_minimal` inside `/home/tokyo/.motion/`. It should work, but there will be some deprecation warnings, and a few settings missing.\n\nThe second one involves placing both `motion.conf` and `cam0.conf` from `config_advanced` inside `/home/tokyo/.motion/`.\n\nRun the whole thing (config_advanced):\n\n```bash\nmotion -c /home/tokyo/.motion/motion.conf\n[0:motion] [NTC] [ALL] conf_load: Processing thread 0 - config file /home/tokyo/.motion/motion.conf\n[0:motion] [NTC] [ALL] config_camera: Processing camera config file /home/tokyo/.motion/cam0.conf\n[0:motion] [NTC] [ALL] motion_startup: Logging to file (/home/tokyo/Videos/motion.log)\n```\n\nUse Ctrl+C to stop the surveillance. Just in case, kill it:\n\n```bash\nps aux | grep motion\nkill -9 12345 (process id from ps aux)\n```\nor\n```bash\npkill -f motion\nkill -9 $(pidof motion)\n```\n\nCheck the log file `/home/tokyo/Videos/motion.log`:\n\n```text\n[0:motion] [NTC] [ALL] [Apr 06 13:19:50] motion_startup: Motion 4.3.2 Started\n[0:motion] [NTC] [ALL] [Apr 06 13:19:50] motion_startup: Using default log type (ALL)\n[0:motion] [NTC] [ALL] [Apr 06 13:19:50] motion_startup: Using log type (ALL) log level (NTC)\n[0:motion] [NTC] [ENC] [Apr 06 13:19:50] ffmpeg_global_init: ffmpeg libavcodec version 58.134.100 libavformat version 58.76.100\n[0:motion] [NTC] [ALL] [bal. 06 13:19:0] translate_init: Language: English\n[0:motion] [NTC] [ALL] [bal. 06 13:19:0] motion_start_thread: Camera ID: 1 is from /home/tokyo/.motion/cam0.conf\n[0:motion] [NTC] [ALL] [bal. 06 13:19:0] motion_start_thread: Camera ID: 1 Camera Name: VISAR Service: rtsp:\n[0:motion] [NTC] [ALL] [bal. 06 13:19:0] main: Waiting for threads to finish, pid: 13698\n[1:ml1:VISAR] [NTC] [ALL] [bal. 06 13:19:0] motion_init: Camera 1 started: motion detection Enabled\n[1:ml1:VISAR] [NTC] [VID] [bal. 06 13:19:0] vid_start: Opening Netcam RTSP\n[1:ml1:VISAR] [NTC] [NET] [bal. 06 13:19:0] netcam_rtsp_connect: Normal resolution: Camera (VISAR) connected\n[1:ml1:VISAR] [CRT] [NET] [bal. 06 13:19:0] motion_init: Substream not available.  Image sizes not modulo 16.\n[1:ml1:VISAR] [NTC] [ALL] [bal. 06 13:19:0] image_ring_resize: Resizing pre_capture buffer to 1 items\n[2:nc2:VISAR] [NTC] [NET] [bal. 06 13:19:0] netcam_rtsp_handler: Normal resolution: Camera handler thread [2] started\n[2:nc2:VISAR] [NTC] [NET] [bal. 06 13:19:0] netcam_rtsp_connect: Normal resolution: Camera (VISAR) connected\n[1:ml1:VISAR] [NTC] [ALL] [bal. 06 13:19:0] image_ring_resize: Resizing pre_capture buffer to 5 items\n[1:ml1:VISAR] [NTC] [EVT] [bal. 06 13:20:0] event_newfile: File of type 8 saved to: /home/tokyo/Videos/2025-04-06_13-20-02.mkv\n[1:ml1:VISAR] [NTC] [ALL] [bal. 06 13:20:0] motion_detected: Motion detected - starting event 1\n[1:ml1:VISAR] [NTC] [ALL] [bal. 06 13:21:0] mlp_actions: End of event 1\n```\n\n## cam0.conf \n\n* `event_gap 30` - more than 30s. of non-motion completes the video of an event. Non-motion moments during the event are not stored.\n\n* `threshold 1500` - quite sensitive for 2592 x 1944, less so for 640 x 480. Lights on/off or changing the intensity will trigger an event. 1500 @ 2592 x 1944 will trigger an event even from tiny motion reflected from the surface of a matte/glossy door. Use `10000` to make it insensitive to such changes.\n\n* `noise_tune on` - dynamically adjusts the detection based on background noise, might be needed to avoid insect motion-based triggering. One may have to experiment with `noise_level 32` too.\n\n* Roughly 3MB per 10s for 640 x 480, and 3MB per 1s for 2592 x 1944, but this may vary.\n\n* `lightswitch 40` and `smart_mask_speed 5` - ignores sudden light changes (due to clouds or headlights).\n\n* `movie_filename %Y-%m-%d_%H-%M-%S` leads to filenames such as `2025-04-06_13-20-02.mkv`. One can use text in names directly, e.g. `area51_%Y-%m-%d_%H-%M-%S` will prepend `area51_`. `%v` can be used as an event counter, but it is not recommended to name files with it. Running `motion -c...` again after Ctrl+C may restart the counter, but it will append the old `motion.log` with new events.\n\n* `mask_file`. I have not applied it, but one can create a B/W mask `mask.pgm` and add it to `cam0.conf`:\n\n    ```text\n    mask_file /home/tokyo/.motion/mask.pgm\n    ```\n    \n    Black color = ignore motion, white color = detect motion. This might enable one to ignore the sky or trees, or save on storage by defining a region of interest.\n    \n    \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faabbtree77%2Fsurveillance","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faabbtree77%2Fsurveillance","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faabbtree77%2Fsurveillance/lists"}