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>
115 lines
4 KiB
Text
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:
|