From 546e8a782f2bd4eb0c707818a5f29c6faa7cfa42 Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Sun, 5 Apr 2026 10:52:54 +0200 Subject: [PATCH] :wastebasket: Remove unused imports, macros and dead code - Drop `Path`/``State``` from unused Axum imports in config.rs and registry - Mark `_position_sec` field as `#[allow(dead_code)]`` in PositionUpdateRequest and PlayerStateReport - Remove unused macro rules (`add_action_arg!`, `add_action!``, `` add_var!)`` - Delete unused PlayerReport struct and related handler code --- Blackboard/ToThinkAbout/webrenderer.md | 529 ++++++++++++++---- Cargo.lock | 83 +-- .../src/components/unified/RendererDrawer.vue | 20 +- .../webapp/src/composables/useWebRenderer.ts | 271 +++------ pmoapp/webapp/src/services/PMOPlayer.ts | 369 ++++++++++++ pmoaudio-ext/src/sinks/streaming_flac_sink.rs | 3 + .../src/sinks/streaming_ogg_flac_sink.rs | 188 ++++++- .../src/sinks/streaming_sink_common.rs | 12 + pmoaudio/src/audio_chunk.rs | 24 + pmoserver/Cargo.toml | 2 +- pmoserver/src/lib.rs | 1 + pmoserver/src/serve_embed.rs | 90 +++ pmoserver/src/server.rs | 8 +- pmowebrenderer/Cargo.toml | 9 +- pmowebrenderer/src/config.rs | 24 +- pmowebrenderer/src/handlers.rs | 25 +- pmowebrenderer/src/messages.rs | 7 + pmowebrenderer/src/register.rs | 115 +++- pmowebrenderer/src/registry.rs | 127 ++++- pmowebrenderer/src/state.rs | 4 + pmowebrenderer/src/stream.rs | 19 +- 21 files changed, 1479 insertions(+), 451 deletions(-) create mode 100644 pmoapp/webapp/src/services/PMOPlayer.ts create mode 100644 pmoserver/src/serve_embed.rs diff --git a/Blackboard/ToThinkAbout/webrenderer.md b/Blackboard/ToThinkAbout/webrenderer.md index 07aab8ce..af6fc291 100644 --- a/Blackboard/ToThinkAbout/webrenderer.md +++ b/Blackboard/ToThinkAbout/webrenderer.md @@ -1,138 +1,443 @@ -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. +# Web Media Renderer - Architecture -- 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 +## Vision -Tu mettras une version du plan en Markdown dans le répertoire [@Architecture](file:///Users/coissac/Sync/maison/Petite_maisons/src/pmomusic/Blackboard/Architecture) . +Système de Media Renderer pilotable à distance via UPnP, exposant un flux audio vers différents types de lecteurs physiques. ---- +## Architecture globale en 4 parties -## 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 │ - └───────────────────────────┘ +```mermaid +flowchart LR + A[Media Server] -->|flux audio| B[Control Point] + B -->|commandes| C[Web Media Renderer] + C -->|flux + contrôles| D[Device physique] + + subgraph Devices physiques + D1[Browser] + D2[Android Auto] + D3[Apple CarPlay] + D4[Sonos multipoint] + D5[Chromecast] + end + + D --> D1 + D --> D2 + D --> D3 + D --> D4 + D --> D5 ``` ---- +### Rôles -## 2. Étapes détaillées +1. **Media Server** - Source audio (le flux OGG-FLAC existant) +2. **Control Point** - Interface UI qui envoie les commandes (pause, play, seek, next, prev) +3. **Web Media Renderer** - Hub qui expose le flux et traduit les commandes selon le device +4. **Physical Device** - Lecteur final (browser, voiture, Sonos, Chromecast...) -### a) Création du renderer +## Web Media Renderer - Rôle central -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()), - _ => (), +```mermaid +blockdiag +{ + block = Commandes UPnP + block -> "Web Media Renderer" -> Adaptation selon device + "Web Media Renderer" -> Device-specific protocols } ``` -* Rust met à jour l’état du renderer (AVTransport/RenderingControl) pour le Control Point. +### Rôle central: Adaptateur ---- +Le Web Media Renderer est un **adaptateur** qui: +- **Reçoit le flux** du Media Server (OGG-FLAC) +- **Reçoit les commandes** du Control Point (UPnP) +- **Les traduit** vers les devices physiques +- **Expose une API de contrôle** commune -### d) Lecture côté navigateur +### Ce qui est COMMUN (factorisé) -* Le navigateur reçoit la commande via WebSocket et pilote `