← Tous les manuels · Portail
↗ Ouvrir l'app

MANUAL — Prompteur (téléprompteur miroir + télécommande)

Manuel d'instructions de cette app. À LIRE avant toute intervention, et à METTRE À JOUR après chaque modification (ajouter une ligne au CHANGELOG en bas).
Dernière génération/MAJ : 2026-09-24 · Statut : en production

1. Identité

  • - Rôle : téléprompteur web pour le rig physique à miroir de Matt. Le téléphone posé dans le rig ouvre l'écran (/, texte inversé en miroir, défilement automatique, ligne de lecture) ; n'importe quel autre appareil (ordinateur posé à côté, tablette, 2e téléphone) ouvre la télécommande (/remote) et pilote tout à distance : script, lecture/pause, vitesse, taille, marges, interligne, miroir H/V, ligne de lecture, alignement, couleur, décompte, sauts, retour au début. Bibliothèque de scripts. L'AIOS peut aussi pousser un script directement (CLI).
  • - URL publique : https://prompteur.panelbay.com (écran) · https://prompteur.panelbay.com/remote (télécommande). Code d'accès à 6 chiffres, saisi une fois par appareil (cookie 180 jours).
  • - Entité : perso / contenu (tournages Matt Paraguay, RP, MOA).
  • 2. Exécution / infra

  • - Dossier : /root/workspace/apps/prompteur (code dans backend/)
  • - Stack : Python 3.12, FastAPI + uvicorn (WebSocket natif via websockets), front vanilla HTML/CSS/JS (aucune dépendance, aucun build).
  • - Service systemd : aios-prompteur.service (fichier versionné apps/prompteur/aios-prompteur.service, installé par systemctl link, Restart=always, enabled).
  • - Port : 8371 (bind 127.0.0.1, PROMPTEUR_PORT)
  • - Reverse proxy (nginx) : /etc/nginx/sites-enabled/prompteur.panelbay.com.conf (généré par expose-webapp, Cloudflare DNS + Let's Encrypt, en-têtes Upgrade/Connection pour le WebSocket, proxy_read_timeout 120s : les clients envoient un ping toutes les 20 s).
  • - Redémarrer : systemctl restart aios-prompteur après modification de app.py. Les pages HTML/JS sont relues à chaque requête (Cache-Control: no-store sur / et /remote), pas de restart pour le front.
  • - Logs : journalctl -u aios-prompteur -n 50.
  • 3. Structure & fichiers clés

  • - backend/app.py : serveur. Auth (code + cookie HMAC), état par salle (room), validation des patches (bornes, énumérations, clés inconnues ignorées), WebSocket /ws, REST, bibliothèque, persistance, en-têtes de sécurité.
  • - backend/static/index.html : l'ÉCRAN. Défilement par translateY en requestAnimationFrame (px/s = vitesse / 25 × hauteur de ligne, donc une vitesse donnée = même rythme de lecture quelle que soit la taille), miroir par transform: scale(-1, 1) sur le conteneur, paddings calculés pour que la 1re et la dernière ligne puissent se poser sur la ligne de lecture, décompte 3-2-1 mirroré, gestes (toucher = lecture/pause, glisser = déplacer le texte), feuille de réglages locale (⚙), wake lock (écran allumé), plein écran, manifest PWA (« Sur l'écran d'accueil » sur iPhone = vrai plein écran).
  • - backend/static/remote.html : la TÉLÉCOMMANDE. Transport, curseurs (envoi limité à 1 message / 60 ms pendant le glisser), toggles, éditeur de script + bibliothèque, aperçu qui suit la position de l'écran, raccourcis clavier, mobile-first.
  • - backend/static/common.js : partagé (salle depuis ?room=, appels API, rendu du texte en paragraphes via textContent uniquement, overlay de login, client WebSocket avec reconnexion et battement).
  • - backend/static/manifest.webmanifest, icon-180/192/512.png : PWA / icône écran d'accueil.
  • - backend/cli.py : CLI pour l'AIOS (voir §5).
  • - aios-prompteur.service : unité systemd.
  • 4. Données

  • - Base / stockage : fichiers JSON dans /root/aios/data/prompteur/ (hors workspace) : state.json (état de chaque salle, sauvegarde différée, jamais playing: true au démarrage), scripts.json (bibliothèque, max 200 scripts de 200 000 caractères), access_code (chmod 600).
  • - Modèle : une salle (room, défaut studio, ?room=xxx sur les deux pages pour en isoler une autre) = un état : title, text, speed 1-100, fontSize 20-160 px, lineHeight 1.0-2.2, margin 0-30 %, mirrorH, mirrorV, align center|left, color white|yellow|green|cyan, guide, guidePos 10-80 %, countdown 0-10 s, playing, position 0-1, seq. L'écran est l'autorité sur position (il la remonte 4×/s en lecture) ; le serveur est l'autorité sur tout le reste. Nouveau texte = position 0 + pause.
  • - Protocole WebSocket (JSON) : client → {t:"set", patch}, {t:"cmd", cmd: play|pause|toggle|restart|seek|jump, value}, {t:"pos", position, ended} (écran seulement), {t:"ping"} ; serveur → {t:"state", state, seek, origin, presence}, {t:"pos"} (télécommandes), {t:"cmd", cmd:"jump"} (écrans), {t:"presence"}, {t:"pong"}. Sans auth : fermeture code 4401 (le front affiche le login).
  • 5. API / endpoints

  • - GET / écran · GET /remote télécommande · GET /api/health (sans auth) · GET /manifest.webmanifest · /static/*.
  • - POST /api/login {code} (pose le cookie prompteur_auth, anti brute-force 8 échecs / 15 min par IP) · POST /api/logout · GET /api/me.
  • - Auth requise ensuite (cookie ou header X-Prompteur-Code) : GET /api/state?room= · POST /api/state?room= {patch:{...}, cmd, value} · GET /api/scripts · POST /api/scripts {title,text} · GET|PUT|DELETE /api/scripts/{id} · POST /api/scripts/{id}/load?room= (envoie le script à l'écran) · WS /ws?room=&role=display|remote.
  • - CLI côté AIOS (cd /root/workspace/apps/prompteur/backend) :
  • ```bash

    python3 cli.py load workspace/mon-script.md --title "Intro vidéo" # envoie un fichier à l'écran (repart du début)

    python3 cli.py text "Le texte..." --title "..." # idem inline

    python3 cli.py play | pause | restart | jump -3 # transport

    python3 cli.py set --speed 18 --font 60 --mirror on --align left # réglages (--help pour tout)

    python3 cli.py state | scripts | save fichier.txt --title "..." # état, bibliothèque

    ```

    Utile quand Matt demande « mets ce script dans le prompteur » : écrire le script puis cli.py load.

    6. Intégrations & secrets

  • - Intégrations : aucune externe. Portail nouvel onglet : raccourci « Prompteur (télécommande) » dans Tech & Outils.
  • - Secrets / clés : le code d'accès est dans /root/aios/data/prompteur/access_code (généré au 1er lancement), ou surchargé par PROMPTEUR_ACCESS_CODE dans le fichier d'environnement AIOS. Le changer = redémarrer le service (toutes les sessions sont invalidées, chaque appareil ressaisit le code). Ne jamais citer le code dans un fichier du workspace.
  • 7. Pièges connus / à savoir

  • - Miroir : mirrorH est ON par défaut (rig à miroir : le texte apparaît inversé sur le téléphone, à l'endroit dans le miroir). Pour lire directement sur l'écran (sans miroir), désactiver « Miroir horizontal » depuis la télécommande ou la feuille ⚙. mirrorV sert si le téléphone est monté à l'envers.
  • - Plein écran iPhone : Safari ne permet pas requestFullscreen ; l'ajout à l'écran d'accueil (manifest standalone) donne un vrai plein écran. Le wake lock (écran qui ne s'éteint pas) exige HTTPS : OK via l'URL publique, pas en http local.
  • - Vitesse : relative à la hauteur de ligne (changer la taille ne change pas le rythme de lecture). 15 ≈ rythme naturel avec une police de 56 px sur un téléphone en paysage ; ajuster à l'oreille.
  • - Décompte : uniquement quand on lance depuis le tout début du texte (position ≈ 0). Reprise en cours = immédiate.
  • - Fin de texte : l'écran s'arrête seul et passe tout le monde en pause.
  • - Deux télécommandes : possible (ordi + téléphone). L'éditeur d'une télécommande ne s'écrase pas tant qu'on y a tapé quelque chose (« dirty »).
  • - Redémarrage du service : les clients se reconnectent seuls (backoff 0,5 s → 10 s) et rechargent l'état ; l'état est persistant mais jamais « en lecture » au redémarrage.
  • - Test navigateur : le MCP Playwright ne démarre pas en root ; utiliser le package Python playwright avec --no-sandbox (script de référence utilisé à la création : /root/aios/.tmp/prompteur/browser_test.py, disposable).
  • - La résolution DNS locale du VPS peut mettre quelques minutes à voir prompteur.panelbay.com (curl 000 depuis le VPS juste après création) ; depuis l'extérieur c'est immédiat. Tester en local avec curl --resolve prompteur.panelbay.com:443:127.0.0.1 ....
  • 8. CHANGELOG

  • - 2026-09-24 : création. Serveur FastAPI + WebSocket par salle, écran miroir mobile (défilement rAF, ligne de lecture, décompte, gestes, feuille ⚙, PWA, wake lock), télécommande (transport, réglages, bibliothèque, aperçu, raccourcis clavier), CLI AIOS, service aios-prompteur (8371), exposé sur https://prompteur.panelbay.com (Cloudflare + Let's Encrypt). Tests : protocole WebSocket/REST (script Python) + navigateur réel Chromium (écran 844×390 + télécommande desktop/mobile) OK. Script d'exemple « Exemple : intro vidéo immo » chargé et enregistré dans la bibliothèque.