diff --git a/Blackboard/ToThinkAbout/webrenderer.md b/Blackboard/ToThinkAbout/webrenderer.md new file mode 100644 index 00000000..b678f635 --- /dev/null +++ b/Blackboard/ToThinkAbout/webrenderer.md @@ -0,0 +1,139 @@ +Parfait. Voici un **schéma fonctionnel minimal** pour un **MediaRenderer UPnP privé par navigateur** avec **token**. L’idée est de rester fidèle à ton backend Rust existant et à la webapp Vue.js. En s'appuyant sur l'architecture de PMOMusic, j'aimerais que tu proposes un plan détaillé pour implémenter un tel système de Média Renderer. + +- L'application web se trouve dans: [@webapp](file:///Users/coissac/Sync/maison/Petite_maisons/src/pmomusic/pmoapp/webapp) +- Tu as un prototype de Média Renderer dans: [@pmomediarenderer](file:///Users/coissac/Sync/maison/Petite_maisons/src/pmomusic/pmomediarenderer) +- Le contrôle point est dans : [@pmocontrol](file:///Users/coissac/Sync/maison/Petite_maisons/src/pmomusic/pmocontrol) +- Tu implémenteras ce nouveau système de Média Renderer dans la CRATe pmowebrenderer + +Tu mettras une version du plan en Markdown dans le répertoire Architecture. + +--- + +## 1. Flow général + +``` +Browser (Vue.js Control Point) + ┌───────────────┐ + │ UI / audio │ + │ WebSocket │ + └───────▲───────┘ + │ token + │ + ▼ +Rust backend (UPnP MediaRenderer) + ┌───────────────────────────┐ + │ Token → Renderer mapping │ + │ Device XML / SOAP endpoints│ + │ Play/Pause/Stop → WS → Browser │ + └───────────────────────────┘ +``` + +--- + +## 2. Étapes détaillées + +### a) Création du renderer + +1. Le navigateur se connecte via WebSocket ou HTTP. +2. Rust génère un token unique pour ce client : + + ```rust + use uuid::Uuid; + let token = Uuid::new_v4().to_string(); + ``` +3. Rust crée une instance MediaRenderer **privée**, associée à ce token : + + * Device description XML : `/renderer//desc.xml` + * AVTransport SOAP : `/renderer//avtransport` + * RenderingControl SOAP : `/renderer//renderingcontrol` + +--- + +### b) Control Point + +* La webapp Vue.js reçoit le token et la “déclare” au Control Point : + +```js +const renderer = { + token: "abcd-1234-efgh", + name: "Browser Renderer" +}; + +// Ajout au control point local +controlPoint.addRenderer(renderer); +``` + +* Toutes les commandes Play/Pause/Stop incluent ce token : + +```js +ws.send(JSON.stringify({ + token: renderer.token, + action: "play", + uri: "http://localhost:8080/media.mp3" +})); +``` + +--- + +### c) Backend Rust : dispatcher les commandes + +* Rust reçoit le JSON avec le token. +* Vérifie que le token correspond à un renderer actif. +* Transmet la commande au navigateur via WebSocket (ou HTTP push) : + +```rust +match msg.action.as_str() { + "play" => send_ws_to_browser(&token, format!("play:{}", msg.uri)), + "pause" => send_ws_to_browser(&token, "pause".to_string()), + "stop" => send_ws_to_browser(&token, "stop".to_string()), + _ => (), +} +``` + +* Rust met à jour l’état du renderer (AVTransport/RenderingControl) pour le Control Point. + +--- + +### d) Lecture côté navigateur + +* Le navigateur reçoit la commande via WebSocket et pilote `