** Ce travail devra être réalisé en suivant scrupuleusement les consignes listées dans le fichier [@Rules_optimal.md](file:///Users/coissac/Sync/maison/Petite_maisons/src/pmomusic/Blackboard/Rules_optimal.md) ** ## Contexte Ce plan fait suite à la revue de code de `pmowebrenderer` et à l'analyse d'écart avec la vision décrite dans `Blackboard/ToThinkAbout/webrenderer.md`. La crate est fonctionnelle pour le cas browser simple, mais son architecture actuelle empêche l'ajout de nouveaux types de devices (Android Auto, Chromecast, Sonos…) sans réécriture. Ce plan prépare ces extensions sans les implémenter, tout en finissant correctement le player browser. **Périmètre** : uniquement `pmowebrenderer/` et `pmoapp/webapp/src/services/PMOPlayer.ts`. Aucune modification aux autres crates (`pmoupnp`, `pmoaudio_ext`, `pmocontrol`). --- ## Problèmes à résoudre ### P0 — Bug résiduel : `play_handler` pose `Transitioning` même sans URI `handlers.rs:23` : quand `has_uri = false`, `playback_state` est mis à `Transitioning` mais le pipeline ne joue rien — l'état reste bloqué indéfiniment. ### P1 — `RendererRegistry` mélange gestion de cycle de vie et livraison browser-spécifique Les méthodes `set_player_command`, `get_pending_command`, `has_current_uri`, `send_play_command`, `send_pause_command` sont hardcodées pour le mécanisme HTTP-polling du browser. Pour Android Auto, on devrait dupliquer la registry entière ou la modifier. ### P2 — Canal de commandes browser non typé et à slot unique `player_command: Option` dans `RendererState` : - une typo dans le type JSON passe sans erreur de compilation - une seule commande peut être en attente : `flush` suivi de `stream` écrase `flush` ### P3 — `OggFlacStreamHandle.pause()/resume()` jamais appelé Quand UPnP `Pause` est reçu, `pipeline.send(Pause)` arrête le décodeur mais le flux HTTP continue à servir les bytes déjà encodés. `flac_handle.pause()` (qui envoie du silence pour les flux continus) n'est jamais appelé. La pause n'est donc pas transmise au navigateur via le flux. ### P4 — La commande `flush` n'est jamais envoyée au browser `handleCommand('flush')` existe dans `PMOPlayer.ts` mais aucun code backend ne l'envoie. Lors d'un Stop ou d'un changement de piste, le browser a potentiellement plusieurs secondes d'audio bufférisé non vidé. Sans `flush`, les transitions de piste ont un délai de 3–5 secondes. ### P5 — `AudioContext` absent dans `PMOPlayer.ts` Le document spécifie `audioContext.suspend()` comme solution au buffer ~5s. L'`AudioContext` était déclaré mais non instancié (code mort), et a été supprimé. Il faut le réintroduire correctement : instancié, connecté à `