Petite app locale pour surveiller la camera du Mac depuis une page web protegee.
Elle capture la camera sur le Mac, affiche un flux en direct, garde un historique limite des mouvements, et peut envoyer un email digest avec les images.
Version actuelle : 0.1.0 public preview limitee.
- Par defaut, le serveur ecoute seulement sur
127.0.0.1. - Active toujours un mot de passe long avec
WATCH_PASSWORD. - N'utilise
--no-authque pour un test local sur127.0.0.1. - N'expose pas le serveur HTTP directement sur Internet. Utilise Tailscale, un VPN, ou un reverse proxy HTTPS avec authentification.
- Ne commit jamais
.env,data/,recordings/, les APKs generes, ni les logs. - Ne fais pas d'upload manuel du dossier complet vers GitHub. Publie via Git avec ce
.gitignore, ou depuis un export propre. - Les actions web qui modifient l'etat utilisent un token CSRF de session.
Utilise des tags GitHub en SemVer avec prefixe v :
v0.1.0pour cette premiere version publique limitee.v0.1.1pour une correction compatible.v0.2.0pour une nouvelle fonctionnalite compatible.v1.0.0seulement quand l'API, la configuration et l'installation sont considerees stables.
Evite v.001 : ce n'est pas un format SemVer clair. Le tag GitHub peut avoir un v devant, mais la version elle-meme doit rester du type 0.1.0.
python3.11 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
WATCH_PASSWORD="un-mot-de-passe-long" python webcam_watch.py --open-browserOuvre ensuite http://localhost:8765.
Identifiant par defaut : watch.
Au premier lancement, macOS peut demander l'autorisation Camera pour Terminal ou Python. Si le flux ne demarre pas, va dans Reglages Systeme > Confidentialite et securite > Camera, puis autorise Terminal/Python et relance l'app.
Le plus simple et le plus fidele a la securite : installe Tailscale sur le Mac et sur l'appareil qui regarde le flux, connecte les deux au meme compte, puis lance :
WATCH_HOST=0.0.0.0 WATCH_PASSWORD="un-mot-de-passe-long" python webcam_watch.pyDepuis l'autre appareil, ouvre l'adresse Tailscale du Mac :
http://nom-du-mac:8765
ou :
http://100.x.y.z:8765
N'expose pas ce serveur directement sur Internet. Utilise un reseau prive, un VPN ou un tunnel avec authentification.
Depuis la page web :
Demarrerlance l'enregistrement continu.Arreterstoppe l'enregistrement continu.Mouvementactive la detection de mouvement.Clipsaffiche les fichiers deja sauvegardes.
Lancer directement avec detection de mouvement :
WATCH_PASSWORD="un-mot-de-passe-long" python webcam_watch.py --motion-recordPar defaut, les mouvements ne creent plus de clips video. Ils creent seulement une image + details dans l'historique, pour eviter de remplir le disque. Les clips de mouvement ne reviennent que si WATCH_RECORD_MOTION_CLIPS=1.
Le mode actuel garde seulement les 10 derniers mouvements :
- heure UTC de detection,
- score de mouvement,
- image JPEG du mouvement,
- lien vers l'evenement dans l'historique.
Quand 10 mouvements sont en file et que l'email est configure, l'app envoie un email digest avec les 10 lignes de details et les 10 images en pieces jointes. Si l'envoi reussit, la file est videe. Si l'email n'est pas encore configure, les 10 derniers mouvements restent localement et aucun email n'est envoye.
Reglages .env :
WATCH_HISTORY_LIMIT=10
WATCH_MOTION_DIGEST_SIZE=10
WATCH_RECORD_MOTION_CLIPS=0
WATCH_DIGEST_EMAIL_TO=you@example.com
WATCH_DIGEST_EMAIL_FROM=mac-watch@example.com
WATCH_SMTP_HOST=smtp.example.com
WATCH_SMTP_PORT=587
WATCH_SMTP_USER=mac-watch@example.com
WATCH_SMTP_PASSWORD=app-password
WATCH_SMTP_STARTTLS=1
WATCH_SMTP_SSL=0Exemple Gmail : utilise un mot de passe d'application Google, pas ton mot de passe principal.
L'interface web est installable comme app mobile depuis l'adresse ou tourne ton serveur :
http://adresse-du-mac:8765/
Sur iPhone, ouvre l'URL dans Safari, connecte-toi, puis utilise Partager > Ajouter a l'ecran d'accueil. Ouvre ensuite l'app depuis l'ecran d'accueil et touche Notifier pour autoriser les notifications.
Sur Android, ouvre l'URL dans Chrome, connecte-toi, puis utilise Ajouter a l'ecran d'accueil ou Installer l'app. Touche ensuite Notifier.
Le bouton Test notif envoie une notification de verification au telephone deja abonne. L'historique est visible depuis Historique et sauvegarde les evenements de mouvement avec miniature et lien de clip quand un clip existe.
Dans Historique, chaque shot a un bouton Supprimer. Le bouton retire l'evenement de l'historique, supprime sa miniature locale et l'enleve aussi de la file email digest si elle l'attendait encore. Le bouton Vider shots supprime tous les shots de l'historique. Les clips video deja enregistres ne sont pas effaces automatiquement.
Une app Android native peut aussi etre construite localement :
cd mobile/android/MacWatch
./gradlew assembleDebugL'APK debug est cree dans mobile/android/MacWatch/app/build/outputs/apk/debug/. Il sert au test local, pas a une distribution publique. Configure l'URL HTTPS, le login et le mot de passe au premier lancement de l'app. Pour un acces HTTP local simple, prefere l'installation PWA depuis Chrome.
Copie l'exemple d'environnement :
cp .env.example .envEdite .env, mets un vrai WATCH_PASSWORD, puis installe le LaunchAgent :
python3 scripts/install_launch_agent.pyPour l'arreter et le supprimer :
python3 scripts/uninstall_launch_agent.pyL'installation durable utilise une copie dans :
~/Library/Application Support/MacWatchAi
Les logs sont dans :
~/Library/Logs/MacWatchAi
Le demarrage automatique garde l'app visible dans les logs du projet :
macwatchai.out.logmacwatchai.err.log
Variables possibles dans .env :
WATCH_HOST=127.0.0.1
WATCH_PORT=8765
WATCH_USER=watch
WATCH_PASSWORD=change-this-long-password
WATCH_EXTRA_ARGS="--motion-record"
WATCH_CAMERA_INDEX=0
WATCH_WIDTH=1280
WATCH_HEIGHT=720
WATCH_FPS=15
WATCH_STREAM_FPS=10
WATCH_JPEG_QUALITY=82
WATCH_HISTORY_LIMIT=10
WATCH_MOTION_DIGEST_SIZE=10
WATCH_RECORD_MOTION_CLIPS=0Pour Tailscale, mets WATCH_HOST=0.0.0.0.
Le fichier .env est la source de configuration du serveur Mac :
WATCH_USERetWATCH_PASSWORDdeviennent les identifiants Basic Auth du dashboard, de l'API, de la PWA et de l'app Android.WATCH_PUBLIC_URLsert aux liens envoyes dans les notifications push et les emails digest.WATCH_ANDROID_APKsert seulement a l'endpoint prive de telechargement APK quand tu fournis un chemin local.WATCH_DIGEST_EMAIL_*etWATCH_SMTP_*servent seulement a l'envoi du digest email.TUNNEL_*sert seulement au relais SSH optionnel.
L'app Android native ne lit pas .env directement. Elle stocke son URL, son login et son mot de passe dans ses reglages locaux apres configuration au premier lancement.
Les scripts install_launch_agent.py et install_remote_tunnel.py copient une version propre du projet et le .env dans ~/Library/Application Support/MacWatchAi, puis lancent cette copie durable.
La charge CPU vient presque entierement du Mac : capture camera, detection de mouvement, compression JPEG pour le direct, puis enregistrement quand il y a un mouvement. Le relais SSH optionnel consomme tres peu, et l'app Android reste legere : elle affiche le direct et verifie l'historique toutes les 30 secondes pour les notifications.
Mesure observee pendant le direct : environ 25% a 40% CPU pour le processus camera selon le mouvement, la lumiere et le nombre de vues ouvertes.
Reglages actuels :
WATCH_WIDTH=1280
WATCH_HEIGHT=720
WATCH_FPS=15
WATCH_STREAM_FPS=10
WATCH_JPEG_QUALITY=82Mode economie recommande si le Mac chauffe ou si la batterie baisse trop vite :
WATCH_WIDTH=960
WATCH_HEIGHT=540
WATCH_FPS=8
WATCH_STREAM_FPS=5
WATCH_JPEG_QUALITY=70Effet attendu : moins de charge CPU et moins de bande passante, avec un direct un peu moins fluide et une image un peu moins fine. Pour garder une bonne detection de mouvement, il vaut mieux baisser d'abord la resolution et le FPS avant de toucher au seuil de mouvement.
Le projet contient aussi un relais SSH optionnel. Il garde l'app webcam liee a 127.0.0.1 sur le Mac, puis ouvre un tunnel vers un serveur que tu controles.
Reglages dans .env :
TUNNEL_REMOTE_HOST=your-server.example.com
TUNNEL_REMOTE_USER=your-user
TUNNEL_REMOTE_BIND=127.0.0.1
TUNNEL_REMOTE_PORT=18765
TUNNEL_LOCAL_HOST=127.0.0.1
TUNNEL_LOCAL_PORT=8765Test manuel :
scripts/run_remote_tunnel.shInstallation au demarrage :
python3 scripts/install_remote_tunnel.pyAvec TUNNEL_REMOTE_BIND=127.0.0.1, le flux n'est disponible que depuis le serveur lui-meme ou depuis un proxy HTTPS installe sur le serveur. Pour le rendre visible publiquement, configure plutot un proxy HTTPS avec authentification cote serveur.