video-surveillance-app/deploy/mediamtx/mediamtx.yml.template
Adam Belkacemi d017ba4958 Sonde de presence video : la camera muette devient un evenement capteur
Le domaine connaissait deja CAMERA_OFFLINE, classe CRITICAL, mais rien ne
l'emettait. CameraLivenessProbe interroge l'API du serveur media et comble
ce trou.

Elle passe par le meme port IngestSensorEventUseCase que l'endpoint REST
et le simulateur : trois producteurs de natures tres differentes, un seul
contrat d'entree, et le meme trajet Kafka -> agregat ensuite. Si l'alarme
est desarmee, une coupure video ne reveille personne - c'est l'agregat qui
tranche, pas la sonde.

Le seuil est la partie qui compte. Sur un lien 4G le flux tombe
regulierement sans que personne n'ait touche au telephone : tunnel,
bascule d'antenne, congestion. Alerter des la premiere sonde ratee
produirait plusieurs CRITICAL par jour, et on apprend vite a ignorer des
alertes qui crient pour rien - y compris le jour ou elles ont raison.
Trois sondes consecutives, soit une minute d'absence reelle. Six tests
couvrent ce comportement, dont la remise a zero du compteur au retour du
flux.

Utilisateur d'API dedie cote MediaMTX, restreint au reseau Docker interne.

41 tests au vert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 18:24:45 +02:00

115 lines
4 KiB
Text

###############################################################################
# MediaMTX - serveur media du systeme d'alarme.
#
# Role : recevoir le flux pousse par l'iPhone (SRT ou RTMP) et le re-publier
# dans des formats lisibles par un navigateur (WebRTC, HLS).
#
# Pourquoi un service separe et pas du code Java : transporter de la video est
# un probleme resolu, temps-reel et gourmand en I/O. Le faire transiter par la
# JVM n'apporterait rien et couterait cher. L'application Spring Boot garde le
# domaine d'alarme ; le media passe a cote.
#
# Pourquoi le telephone POUSSE au lieu d'etre interroge : en 4G comme derriere
# la box du studio, l'iPhone n'a pas d'adresse joignable depuis Internet
# (CGNAT operateur, NAT domestique, UPnP indisponible). Seule une connexion
# sortante depuis le telephone fonctionne dans les deux cas.
#
# CE FICHIER EST GENERE depuis mediamtx.yml.template - ne pas l'editer a la main.
###############################################################################
logLevel: info
logDestinations: [stdout]
readTimeout: 10s
writeTimeout: 10s
# API interne, utilisee pour la sonde de sante. Non publiee sur l'hote.
api: yes
apiAddress: :9997
###############################################################################
# Authentification
#
# Lecture publique : choix assume, le flux est une vitrine.
# Publication authentifiee : sans ca, n'importe qui sur Internet pourrait
# pousser sa propre video sur "biblio" et remplacer l'image du studio.
###############################################################################
authMethod: internal
authInternalUsers:
- user: any
pass:
ips: []
permissions:
- action: read
- action: playback
# Lecture seule de l'API, pour la sonde de presence de l'application.
# Restreinte au reseau Docker interne : l'API n'est de toute facon pas
# publiee sur l'hote, mais deux verrous valent mieux qu'un.
- user: probe
pass: __API_PASSWORD__
ips: ['172.16.0.0/12']
permissions:
- action: api
- user: iphone
pass: __PUBLISH_PASSWORD__
ips: []
permissions:
- action: publish
path: biblio
###############################################################################
# Entrees : ce que l'iPhone peut utiliser pour pousser
###############################################################################
# SRT - a privilegier. UDP avec retransmission : encaisse la perte de paquets
# d'un lien mobile la ou RTMP (TCP) se met a bufferiser puis decroche.
srt: yes
srtAddress: :8890
# RTMP - repli. Plus universellement supporte par les applications mobiles.
rtmp: yes
rtmpAddress: :1935
rtmpEncryption: "no"
# MoQ (Media over QUIC) : experimental, aucun navigateur ne le consomme
# aujourd'hui et la console ne l'utilise pas. Desactive.
moq: no
# RTSP desactive : l'iPhone n'est pas joignable en entrant, ce protocole
# n'aurait aucun usage ici et ouvrirait une surface d'attaque de plus.
rtsp: no
###############################################################################
# Sorties : ce que le navigateur consomme
###############################################################################
# WebRTC - chemin principal, latence inferieure a la seconde.
webrtc: yes
webrtcAddress: :8889
webrtcAllowOrigins: ['*']
webrtcLocalUDPAddress: :8189
# Le conteneur ne voit qu'une IP privee ; sans cette declaration, les
# candidats ICE annonces seraient inutilisables depuis l'exterieur.
webrtcIPsFromInterfaces: no
webrtcAdditionalHosts: [__PUBLIC_IP__]
# HLS - repli universel, ~6 s de latence. Couvre les reseaux d'entreprise
# qui filtrent l'UDP et donc WebRTC.
hls: yes
hlsAddress: :8888
hlsAllowOrigins: ['*']
hlsVariant: lowLatency
hlsSegmentCount: 7
hlsSegmentDuration: 1s
hlsPartDuration: 200ms
hlsAlwaysRemux: no
###############################################################################
# Flux
###############################################################################
paths:
# Le capteur du studio. Nom volontairement aligne sur le deviceId utilise
# par le domaine d'alarme (iphone-biblio).
biblio: