Aller au contenu principal

V0.5.0 — Lecture des Flux H.265 sans réencodage

Publiée le 13/10/2026.

Documentation fonctionnelle

Ce que change la version pour les collaborateurs

Pourquoi​

Beaucoup de vraies caméras diffusent leur Flux principal en H.265 (HEVC). Jusqu'ici, ArgOS ne montrait les Flux qu'en WebRTC, que les navigateurs ne lisent de façon fiable qu'en H.264 : une Caméra H.265 pouvait être ajoutée, mais restait noire dans le Live et l'Aperçu. Réencoder chaque Flux côté serveur aurait consommé du CPU en continu.

Ce qu'on peut faire maintenant​

  • Voir les Caméras H.265 dans le Live et dans l'Aperçu d'un ajout, sans réencodage : MediaMTX les sert en LL-HLS fMP4 et c'est le navigateur qui décode (Safari ; Chrome et Edge avec décodage matériel). Retard de 1 à 3 s.
  • Les Caméras H.264 restent en WebRTC, sous la seconde ; le transport est choisi seul, d'après le codec.
  • Codec de chaque Caméra retenu à l'ajout, tenu à jour par la sonde (caméra reconfigurée H.264 ↔ H.265 suivie seule) et affiché dans l'Administration.
  • Un navigateur qui ne décode pas le HEVC (Firefox le plus souvent) affiche « Ce navigateur ne lit pas le H.265 », sans nouvelle tentative ; une panne reste « Flux indisponible ».
  • En dev, une Caméra simulée 4 diffuse en H.265.
  • Documentation : transport par codec et navigateurs dans « Ajouter une Caméra », chemins HLS dans la page sécurité.

Documentation technique

Spec versionnée : docs/specs/v0.5.0-lecture-flux-h265.md

Issue parente : #45

V0.5.0 — Lecture des Flux H.265 sans réencodage

Problem Statement​

Beaucoup de vraies caméras diffusent leur Flux principal en H.265 (HEVC). ArgOS ne montre aujourd'hui les Flux qu'en WebRTC, à travers MediaMTX en pont (ADR 0001), et les navigateurs ne lisent de façon fiable que le H.264 en WebRTC. Une Caméra H.265 reste donc noire dans le Live, et son Aperçu se contente de dire « La caméra diffuse en H.265 » pendant l'ajout. L'Administrateur peut l'ajouter, mais ne la voit jamais.

Réencoder chaque Flux H.265 en H.264 côté serveur résoudrait l'affichage, au prix de CPU consommé en continu pour chaque Caméra : ce n'est pas acceptable comme chemin normal. Le Site ne sait pas non plus quel codec diffuse chaque Caméra : il ne le lit qu'au moment de l'essai d'ajout, puis l'oublie.

Solution​

Les Flux H.265 sont lus dans le navigateur en HLS (LL-HLS, fMP4) servi par MediaMTX, sans réencodage : MediaMTX remballe les images telles quelles, et c'est la puce vidéo de l'ordinateur de l'Administrateur qui décode. Les Flux H.264, et ceux dont le codec est inconnu ou autre, restent en WebRTC comme aujourd'hui.

Le Site retient le codec de chaque Caméra : relevé à l'ajout (essai), puis rafraîchi automatiquement par la sonde à chaque passage (elle fait déjà un DESCRIBE). Le front choisit le transport d'après ce codec, dans le Live comme dans l'Aperçu. L'Administration affiche le codec de chaque Caméra.

Avant de lancer la lecture HLS, le front demande au navigateur s'il décode le HEVC ; s'il ne le décode pas (Firefox, machine sans décodage matériel), il affiche « Ce navigateur ne lit pas le H.265 », sans retenter. Une coupure réseau garde « Flux indisponible » et sa nouvelle tentative. Une quatrième Caméra simulée, en H.265, permet de tout vérifier en dev.

User Stories​

Live​

  1. En tant qu'Administrateur, je veux voir dans le Live une Caméra dont le Flux est en H.265, pour surveiller les vraies caméras qui diffusent en HEVC.
  2. En tant qu'Administrateur, je veux que les Caméras H.264 restent lues en WebRTC, pour garder leur latence très faible.
  3. En tant qu'Administrateur, je veux passer à la Caméra suivante dans le Live sans me soucier du codec de chacune : le bon transport est choisi seul.
  4. En tant qu'Administrateur, je veux accepter qu'une Caméra H.265 ait 1 à 3 s de retard et démarre un peu plus lentement, sans mention particulière à l'écran.
  5. En tant qu'Administrateur, je veux, si mon navigateur ne décode pas le H.265, lire « Ce navigateur ne lit pas le H.265 » au lieu d'un écran noir, pour comprendre que ce n'est ni la caméra ni le réseau.
  6. En tant qu'Administrateur, je veux que ce message ne déclenche pas de nouvelle tentative toutes les 5 s, puisque réessayer ne changera rien.
  7. En tant qu'Administrateur, je veux qu'une Caméra H.265 injoignable affiche « Flux indisponible » et retente comme les autres, pour distinguer panne et navigateur.
  8. En tant qu'Administrateur, je veux que le message navigateur apparaisse aussi si le navigateur prétend décoder le HEVC mais échoue en lisant.
  9. En tant qu'Administrateur, je veux qu'une Caméra au codec inconnu (jamais jointe) ou autre (MJPEG…) soit tentée en WebRTC, comme aujourd'hui.

Aperçu (ajout d'une Caméra)​

  1. En tant qu'Administrateur, je veux voir en Aperçu le Flux H.265 d'un Candidat, pour vérifier l'image avant d'ajouter la Caméra.
  2. En tant qu'Administrateur, je veux que le message « La caméra diffuse en H.265 » de la 0.4.1 disparaisse quand l'Aperçu se lit.
  3. En tant qu'Administrateur, je veux garder ce message pour un codec ni H.264 ni H.265, puisqu'ArgOS ne sait toujours pas le montrer.
  4. En tant qu'Administrateur, je veux lire « Ce navigateur ne lit pas le H.265 » dans l'Aperçu si mon navigateur ne le décode pas, l'ajout restant permis.

Codec de chaque Caméra​

  1. En tant qu'Administrateur, je veux qu'ArgOS retienne le codec d'une Caméra dès son ajout, sans rien saisir.
  2. En tant qu'Administrateur, je veux que le codec soit mis à jour seul si quelqu'un reconfigure la caméra (H.264 ↔ H.265), pour que le Live suive.
  3. En tant qu'Administrateur, je veux que les Caméras ajoutées avant cette version reçoivent leur codec au passage suivant de la sonde, sans migration manuelle.
  4. En tant qu'Administrateur, je veux voir le codec de chaque Caméra dans l'Administration (« H.265 », « H.264 », « MJPEG », « inconnu »), en lecture seule, à côté de son état, pour comprendre pourquoi une Caméra se comporte autrement.
  5. En tant qu'exploitant du Site, je veux un log INFO de la sonde quand le codec d'une Caméra change, pour diagnostiquer après coup.

Caméras simulées et dev​

  1. En tant que développeur, je veux une quatrième Caméra simulée qui diffuse en H.265, pour développer et tester la lecture HEVC sans vraie caméra.
  2. En tant que développeur, je veux qu'elle se comporte comme une caméra style Hikvision sans identifiants, pour que la Détection et l'ajout la trouvent comme les autres.
  3. En tant que développeur, je veux que sa vidéo soit documentée et reproductible (commande d'encodage dans le README des Caméras simulées), comme les trois autres.

Documentation et sécurité​

  1. En tant que mainteneur, je veux un ADR qui explique pourquoi deux transports coexistent (WebRTC pour H.264, HLS pour H.265) plutôt que du réencodage ou du H.265 en WebRTC.
  2. En tant qu'Administrateur, je veux que la page sécurité dise que les chemins HLS sont, comme WHEP, lisibles sans authentification sur le réseau local.
  3. En tant que mainteneur, je veux que la feuille de route porte une 0.5.1 « réencodage H.265 → H.264 à la demande », pour les navigateurs qui ne décodent pas le HEVC.

Implementation Decisions​

  • Codec sur la Caméra : nouvelle colonne nullable codec (nom d'encodage tel que lu dans le SDP : H264, H265, MJPEG…, null si jamais lu). Migration additive, sans valeur par défaut.
  • Remplissage : à l'ajout, le codec vient du résultat de l'essai. La sonde d'état, qui fait déjà un DESCRIBE avant de chercher des paquets RTP, renvoie aussi le codec lu ; la surveillance l'enregistre s'il a changé (et logue INFO « codec de la Caméra <id> : <ancien> → <nouveau> »). Une sonde sans réponse ne l'efface pas.
  • API : la Caméra lue expose codec (lecture seule ; ni création ni modification ne l'acceptent).
  • Pont MediaMTX : rien ne change dans la réconciliation : les chemins camera-\<id> et apercu-* sont déjà servis par MediaMTX sur tous ses lecteurs, HLS compris (port 8888 déjà publié). Configuration HLS de MediaMTX : variante low-latency fMP4 (défaut), vérifiée explicitement.
  • Lecteur front : le lecteur de Flux reçoit le codec. H265 → lecture HLS (hls.js ; HLS natif de Safari quand il est là) sur le même hôte que WHEP, port HLS. Tout autre codec ou null → WHEP comme aujourd'hui.
  • Support navigateur : avant HLS, test MediaSource.isTypeSupported (et canPlayType pour le HLS natif) sur un type video/mp4; codecs="hvc1…". Négatif → état codec non supporté : message « Ce navigateur ne lit pas le H.265 », sans nouvelle tentative. Erreur de décodage fatale de hls.js (ou de la balise vidéo) → même état. Erreur réseau ou de playlist → état indisponible avec la nouvelle tentative existante (5 s).
  • Aperçu : le codec de l'essai choisit le transport. Le message codec de la 0.4.1 n'apparaît plus pour H264 et H265 ; il reste pour les autres codecs.
  • Administration : le codec s'affiche par Caméra, à côté de l'état (H265 écrit « H.265 », null « inconnu »).
  • Caméra simulée 4 : cam4.mp4 = cam1.mp4 réencodée en libx265 (1280×720, 15 i/s, sans B-frames, GOP 30, tag hvc1, sans audio). Hôte 172.30.0.14, MAC 02:a6:05:00:00:04, chemin Streaming/Channels/101, sans identifiants, dans la simulation seulement.
  • ADR 0004 « HLS pour les Flux H.265 » : options considérées (réencodage serveur, H.265 en WebRTC, HLS pour tous, essai WebRTC puis repli) ; ADR 0001 garde son histoire.
  • Feuille de route : ajout de la 0.5.1 (réencodage H.265 → H.264 à la demande : chemin camera-\<id>-h264, ffmpeg seulement quand un navigateur qui ne décode pas le HEVC regarde), retrait de l'entrée « Plus tard — Réencodage ».
  • Glossaire : inchangé (transport, HLS, WebRTC, codec sont des détails d'implémentation).

Testing Decisions​

  • Un bon test vérifie un comportement observable : réponse HTTP, playlist et codec servis par MediaMTX, écran du navigateur. Jamais le choix interne du lecteur autrement que par ce qu'il demande au réseau et affiche.
  • tests/api/ (stack avec simulation), prior art : test_essai.py, tests de la sonde et de la surveillance 0.4.2 :
    • l'essai sur la Caméra simulée 4 renvoie H265 ; la Caméra ajoutée garde codec = "H265" ;
    • une Caméra sans codec reçoit le sien au passage de la sonde ;
    • un codec changé est mis à jour (log INFO) ; une sonde sans réponse ne l'efface pas ;
    • codec ignoré ou refusé en création / modification.
  • tests/flux/, prior art : test_cameras_simulees.py, test_mediamtx_en_pont.py :
    • la Caméra simulée 4 diffuse du HEVC (ffprobe) ;
    • le pont sert pour sa Caméra une playlist HLS dont le codec est hvc1 (playlist maîtresse, puis segment d'init lu par ffprobe).
  • tests/web/ (Chromium headless, qui ne décode pas le HEVC), prior art : test_ajout_camera.py :
    • Live sur une Caméra H.265 : aucune requête WHEP, message « Ce navigateur ne lit pas le H.265 », pas de nouvelle tentative ;
    • Live sur une Caméra H.264 : WebRTC comme avant ;
    • Aperçu d'un Candidat H.265 : même message, plus le message codec 0.4.1, ajout permis ;
    • Administration : codec affiché.
  • Vérification manuelle avant Finalise : image d'une Caméra H.265 dans le Live et l'Aperçu sous Safari et Chrome (machine avec décodage HEVC). Elle figure au Test plan de la PR.

Out of Scope​

  • Réencodage H.265 → H.264 (0.5.1).
  • H.265 en WebRTC.
  • HLS pour les Flux H.264.
  • Authentification des Flux (HLS comme WHEP restent ouverts sur le réseau local).
  • Lecture de codecs autres que H.264 et H.265 (MJPEG…).
  • Choix du transport par l'Administrateur.
  • Audio.

Further Notes​

  • « Matériel » s'entend côté navigateur : Chrome et Edge décodent le HEVC si la machine a un décodeur matériel (Mac M1 et suivants, PC Intel/AMD récents) ; Safari le lit ; Firefox le plus souvent non.
  • MediaMTX 1.21.1 sait aussi pousser du H.265 en WebRTC, mais le support navigateur est plus étroit que HLS : écarté.
  • Contexte : feuille de route de dev (section 0.5.0), spec 0.3.0 (#12), 0.4.1 (#25), ADR 0001, docs/securite.md, media/simulated/README.md.