Refactor WebRenderer to use server-side streaming with OGG-FLAC sink

This commit refactors the WebRenderer to use a server-side streaming architecture with OGG-FLAC sink instead of the previous WebSocket-based approach. The changes include:

- Replaced WebSocket communication with HTTP streaming using DirectOggFlacSink
- Implemented a new pipeline architecture with dedicated handlers for UPnP commands
- Added new modules for registration, registry, and streaming
- Updated the renderer to work with a pipeline control system
- Removed old WebSocket session management
- Added support for HTTP streaming with gapless playback
- Updated dependencies and features for the new architecture

The WebRenderer now acts as a MediaRenderer UPnP device that serves audio streams via HTTP endpoints, with commands relayed to the audio pipeline through a new control system.
This commit is contained in:
2026-02-26 19:58:37 +01:00
parent 4b3e8a961c
commit 306e691c61
32 changed files with 2797 additions and 1653 deletions

View File

@@ -1,10 +1,9 @@
//! État partagé du renderer (backend ↔ navigateur)
//! État partagé du renderer (backend ↔ pipeline)
use parking_lot::RwLock;
use std::sync::Arc;
use tokio::sync::mpsc;
use crate::messages::{PlaybackState, ServerMessage};
use crate::messages::PlaybackState;
/// État temps-réel du renderer (partagé backend ↔ navigateur)
#[derive(Debug, Clone)]
@@ -38,34 +37,3 @@ impl Default for RendererState {
/// Alias pour l'état partagé
pub type SharedState = Arc<RwLock<RendererState>>;
/// Sender WebSocket partagé et remplaçable entre les reconnexions.
///
/// Les handlers UPnP capturent ce `Arc` à la création du device. À chaque
/// reconnexion WebSocket (reload de page), on remplace le sender interne via
/// `set()`, sans avoir à recréer le device ni ses handlers.
#[derive(Clone)]
pub struct SharedSender(Arc<RwLock<Option<mpsc::UnboundedSender<ServerMessage>>>>);
impl SharedSender {
pub fn new(sender: mpsc::UnboundedSender<ServerMessage>) -> Self {
Self(Arc::new(RwLock::new(Some(sender))))
}
/// Envoie un message au navigateur. Ignore silencieusement si déconnecté.
pub fn send(&self, msg: ServerMessage) {
if let Some(tx) = self.0.read().as_ref() {
let _ = tx.send(msg);
}
}
/// Remplace le sender (appelé à la reconnexion WebSocket).
pub fn set(&self, sender: mpsc::UnboundedSender<ServerMessage>) {
*self.0.write() = Some(sender);
}
/// Retire le sender (appelé à la déconnexion).
pub fn clear(&self) {
*self.0.write() = None;
}
}